mirror of
https://github.com/status-im/nim-blscurve-backup.git
synced 2025-02-23 06:58:19 +00:00
406 lines
11 KiB
Nim
406 lines
11 KiB
Nim
#!/usr/bin/env -S nim e
|
|
mode = ScriptMode.Verbose
|
|
|
|
## ## This script is Nim's replacement for config[32/64].py files of Milagro
|
|
## library. It performs configuration of BLS381 curve for both 32bit and
|
|
## 64bit limbs. It also removes random/hash/crypto related functions.
|
|
##
|
|
## Usage:
|
|
##
|
|
## nim -e milagro.nims <srcpath> <dstpath>
|
|
##
|
|
## <srcpath> - source path of milagro's C sources. By default current working
|
|
## path will be used.
|
|
## <dstpath> - destination path where two directories `32` and `64` will be
|
|
## created and populated with generated BLS381 sources. By default current
|
|
## working path will be used.
|
|
import ospaths, strutils
|
|
|
|
const amclh = """/*
|
|
Licensed to the Apache Software Foundation (ASF) under one
|
|
or more contributor license agreements. See the NOTICE file
|
|
distributed with this work for additional information
|
|
regarding copyright ownership. The ASF licenses this file
|
|
to you under the Apache License, Version 2.0 (the
|
|
"License"); you may not use this file except in compliance
|
|
with the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing,
|
|
software distributed under the License is distributed on an
|
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
KIND, either express or implied. See the License for the
|
|
specific language governing permissions and limitations
|
|
under the License.
|
|
*/
|
|
|
|
|
|
#ifndef AMCL_H
|
|
#define AMCL_H
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdbool.h>
|
|
#include <inttypes.h>
|
|
#include "arch.h"
|
|
|
|
/* modulus types */
|
|
|
|
#define NOT_SPECIAL 0 /**< Modulus of no exploitable form */
|
|
#define PSEUDO_MERSENNE 1 /**< Pseudo-mersenne modulus of form $2^n-c$ */
|
|
#define MONTGOMERY_FRIENDLY 3 /**< Montgomery Friendly modulus of form $2^a(2^b-c)-1$ */
|
|
#define GENERALISED_MERSENNE 2 /**< Generalised-mersenne modulus of form $2^n-2^m-1$, GOLDILOCKS only */
|
|
|
|
/* Curve types */
|
|
|
|
#define WEIERSTRASS 0 /**< Short Weierstrass form curve */
|
|
#define EDWARDS 1 /**< Edwards or Twisted Edwards curve */
|
|
#define MONTGOMERY 2 /**< Montgomery form curve */
|
|
|
|
/* Pairing-Friendly types */
|
|
|
|
#define NOT 0
|
|
#define BN 1
|
|
#define BLS 2
|
|
|
|
#define D_TYPE 0
|
|
#define M_TYPE 1
|
|
|
|
/**
|
|
@brief Portable representation of a big positive number
|
|
*/
|
|
|
|
typedef struct
|
|
{
|
|
int len; /**< length in bytes */
|
|
int max; /**< max length allowed - enforce truncation */
|
|
char *val; /**< byte array */
|
|
} octet;
|
|
|
|
#endif
|
|
"""
|
|
|
|
proc commentFunction(data, name: string): string =
|
|
## Procedure iterates over all lines in ``data`` and perform search for
|
|
## substring ``name`` and if it found starts with commenting all the lines
|
|
## until ``}`` will not be met.
|
|
result = ""
|
|
var state = 0
|
|
for line in splitLines(data):
|
|
if state == 0:
|
|
if line.find(name) == -1:
|
|
result.add(line & "\n")
|
|
continue
|
|
else:
|
|
state = 1
|
|
if state == 1:
|
|
result.add("// " & line & "\n")
|
|
if line.startsWith("}"):
|
|
state = 2
|
|
continue
|
|
result.add(line & "\n")
|
|
|
|
proc commentLine(data, name: string): string =
|
|
## Procedure iterates over all lines in ``data`` and perform search for
|
|
## substring ``name``, if it found it will comment such line in ``C`` way.
|
|
## Returns modified ``data``.
|
|
result = ""
|
|
for line in splitLines(data):
|
|
if line.find(name) == -1:
|
|
result.add(line & "\n")
|
|
else:
|
|
result.add("// " & line & "\n")
|
|
|
|
proc checkFiles(src, tc: string): bool =
|
|
## Returns ``true`` if all the files in ``files`` array present in filesystem.
|
|
let files = [
|
|
"arch.h",
|
|
"config_big.h",
|
|
"config_field.h",
|
|
"config_curve.h",
|
|
"big.h", "big.c",
|
|
"fp.h", "fp.c",
|
|
"fp2.h", "fp2.c",
|
|
"fp4.h", "fp4.c",
|
|
"fp12.h", "fp12.c",
|
|
"ecp.h", "ecp.c",
|
|
"ecp2.h", "ecp.c",
|
|
"pair.h", "pair.c",
|
|
"rom_curve_" & tc & ".c",
|
|
"rom_field_" & tc & ".c",
|
|
"oct.c"
|
|
]
|
|
result = true
|
|
for item in files:
|
|
if not fileExists(src / item):
|
|
echo "ERROR: File [" & (src / item) & "] is missing!"
|
|
result = false
|
|
break
|
|
|
|
proc clearFiles(dst, tb, tf, tc, base: string) =
|
|
## Clear files in destination directory ``dst``.
|
|
let bd = tb & "_" & base
|
|
let files = [
|
|
dst / ("amcl.h"),
|
|
dst / ("arch.h"),
|
|
dst / ("config_big_" & tb & "_" & base & ".h"),
|
|
dst / ("config_field_" & tf & ".h"),
|
|
dst / ("config_curve_" & tc & ".h"),
|
|
dst / ("big_" & bd & ".c"),
|
|
dst / ("big_" & bd & ".h"),
|
|
dst / ("fp_" & tf & ".c"),
|
|
dst / ("fp_" & tf & ".h"),
|
|
dst / ("fp2_" & tf & ".c"),
|
|
dst / ("fp2_" & tf & ".h"),
|
|
dst / ("fp4_" & tf & ".c"),
|
|
dst / ("fp4_" & tf & ".h"),
|
|
dst / ("fp12_" & tf & ".c"),
|
|
dst / ("fp12_" & tf & ".h"),
|
|
dst / ("ecp_" & tc & ".c"),
|
|
dst / ("ecp_" & tc & ".h"),
|
|
dst / ("ecp2_" & tc & ".c"),
|
|
dst / ("ecp2_" & tc & ".h"),
|
|
dst / ("pair_" & tc & ".c"),
|
|
dst / ("pair_" & tc & ".h"),
|
|
dst / ("rom_curve_" & tc & ".c"),
|
|
dst / ("rom_field_" & tc & ".c"),
|
|
dst / ("oct.c")
|
|
]
|
|
for item in files:
|
|
if fileExists(item):
|
|
rmFile(item)
|
|
|
|
proc curveSet(src, dst, tb, tf, tc, nb, base, nbt, m8, mt, ct, pf, stw, sx,
|
|
cs: string) =
|
|
let bd = tb & "_" & base
|
|
var fnameh, data: string
|
|
var nmax: int
|
|
|
|
# amcl.h
|
|
fnameh = dst / "amcl.h"
|
|
data = amclh.replace("@OS@", buildOS)
|
|
writeFile(fnameh, data)
|
|
|
|
# arch.h
|
|
fnameh = dst / "arch.h"
|
|
data = readFile(src / "arch.h")
|
|
if base == "58":
|
|
data = data.replace("@WL@", "64")
|
|
nmax = 30
|
|
else:
|
|
data = data.replace("@WL@", "32")
|
|
nmax = 14
|
|
writeFile(fnameh, data)
|
|
|
|
# config_big.h
|
|
fnameh = dst / "config_big_" & bd & ".h"
|
|
data = readFile(src / "config_big.h")
|
|
data = data.replace("XXX", bd)
|
|
data = data.replace("@NB@", nb)
|
|
data = data.replace("@BASE@", base)
|
|
writeFile(fnameh, data)
|
|
|
|
# config_field.h
|
|
fnameh = dst / "config_field_" & tf & ".h"
|
|
data = readFile(src / "config_field.h")
|
|
data = data.replace("XXX", bd)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("@NBT@", nbt)
|
|
data = data.replace("@M8@", m8)
|
|
data = data.replace("@MT@", mt)
|
|
var ib = parseInt(base)
|
|
var inb = parseInt(nb)
|
|
var inbt = parseInt(nbt)
|
|
var sh = ib * (1 + ((8 * inb - 1) div ib)) - inbt
|
|
if sh > nmax:
|
|
sh = nmax
|
|
data = data.replace("@SH@", $sh)
|
|
writeFile(fnameh, data)
|
|
|
|
# config_curve.h
|
|
fnameh = dst / "config_curve_" & tc & ".h"
|
|
data = readFile(src / "config_curve.h")
|
|
data = data.replace("XXX", bd)
|
|
data = data.replace("YYY",tf)
|
|
data = data.replace("ZZZ",tc)
|
|
data = data.replace("@CT@",ct)
|
|
data = data.replace("@PF@",pf)
|
|
data = data.replace("@ST@",stw)
|
|
data = data.replace("@SX@",sx)
|
|
data = data.replace("@CS@",cs)
|
|
writeFile(fnameh, data)
|
|
|
|
# big.c & big.h
|
|
for item in ["big.c", "big.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "big_" & bd & ".h"
|
|
else:
|
|
fnameh = dst / "big_" & bd & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("XXX", bd)
|
|
if item.endsWith(".c"):
|
|
if base == "58":
|
|
data = data.commentFunction("BIG_384_58_random(")
|
|
data = data.commentFunction("BIG_384_58_randomnum(")
|
|
else:
|
|
data = data.commentFunction("BIG_384_29_random(")
|
|
data = data.commentFunction("BIG_384_29_randomnum(")
|
|
else:
|
|
if base == "58":
|
|
data = data.commentLine("BIG_384_58_random(")
|
|
data = data.commentLine("BIG_384_58_randomnum(")
|
|
else:
|
|
data = data.commentLine("BIG_384_29_random(")
|
|
data = data.commentLine("BIG_384_29_randomnum(")
|
|
|
|
writeFile(fnameh, data)
|
|
|
|
# fp.c & fp.h
|
|
for item in ["fp.c", "fp.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "fp_" & tf & ".h"
|
|
else:
|
|
fnameh = dst / "fp_" & tf & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("XXX", bd)
|
|
writeFile(fnameh, data)
|
|
|
|
# ecp.c & ecp.h
|
|
for item in ["ecp.c", "ecp.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "ecp_" & tc & ".h"
|
|
else:
|
|
fnameh = dst / "ecp_" & tc & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("ZZZ", tc)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("XXX", bd)
|
|
writeFile(fnameh, data)
|
|
|
|
# rom_curve_<>.c
|
|
fnameh = dst / "rom_curve_" & tc & ".c"
|
|
data = readFile(src / "rom_curve_" & tc & ".c")
|
|
writeFile(fnameh, data)
|
|
|
|
# rom_field_<>.c
|
|
fnameh = dst / "rom_field_" & tc & ".c"
|
|
data = readFile(src / "rom_field_" & tc & ".c")
|
|
writeFile(fnameh, data)
|
|
|
|
# fp2.h & fp2.c
|
|
for item in ["fp2.c", "fp2.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "fp2_" & tf & ".h"
|
|
else:
|
|
fnameh = dst / "fp2_" & tf & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("XXX", bd)
|
|
writeFile(fnameh, data)
|
|
|
|
# fp4.h & fp4.c
|
|
for item in ["fp4.c", "fp4.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "fp4_" & tf & ".h"
|
|
else:
|
|
fnameh = dst / "fp4_" & tf & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("XXX", bd)
|
|
data = data.replace("ZZZ", tc)
|
|
writeFile(fnameh, data)
|
|
|
|
# fp12.h & fp12.c
|
|
for item in ["fp12.c", "fp12.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "fp12_" & tf & ".h"
|
|
else:
|
|
fnameh = dst / "fp12_" & tf & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("XXX", bd)
|
|
writeFile(fnameh, data)
|
|
|
|
# ecp2.h & ecp2.c
|
|
for item in ["ecp2.c", "ecp2.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "ecp2_" & tf & ".h"
|
|
else:
|
|
fnameh = dst / "ecp2_" & tf & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("ZZZ", tc)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("XXX", bd)
|
|
writeFile(fnameh, data)
|
|
|
|
# pair.h & pair.c
|
|
for item in ["pair.c", "pair.h"]:
|
|
if item.endsWith(".h"):
|
|
fnameh = dst / "pair_" & tc & ".h"
|
|
else:
|
|
fnameh = dst / "pair_" & tc & ".c"
|
|
data = readFile(src / item)
|
|
data = data.replace("ZZZ", tc)
|
|
data = data.replace("YYY", tf)
|
|
data = data.replace("XXX", bd)
|
|
writeFile(fnameh, data)
|
|
|
|
# oct.c
|
|
data = readFile(src / "oct.c")
|
|
data = data.commentFunction("OCT_rand")
|
|
writeFile(dst / "oct.c", data)
|
|
|
|
const
|
|
dstDirectory32 = "32"
|
|
dstDirectory64 = "64"
|
|
tb = "384"
|
|
tf = "BLS381"
|
|
tc = "BLS381"
|
|
base32 = "29"
|
|
base64 = "58"
|
|
|
|
var
|
|
srcPath = "."
|
|
dstPath = "."
|
|
|
|
if paramStr(0).toLowerAscii() == "nim" and paramCount() == 4:
|
|
srcPath = paramStr(3)
|
|
dstPath = paramStr(4)
|
|
else:
|
|
discard
|
|
|
|
## Check if source pattern files are present.
|
|
if not checkFiles(srcPath, tc):
|
|
quit("FATAL: Could not find required files in [" & srcPath & "]!")
|
|
|
|
## Check if destination directory exists.
|
|
if not dirExists(dstPath):
|
|
quit("FATAL: Destination path did not exists!")
|
|
|
|
let dstPath32 = dstPath / dstDirectory32
|
|
let dstPath64 = dstPath / dstDirectory64
|
|
|
|
## Check if directory for 32bit library is already present in filesystem
|
|
if not dirExists(dstPath32):
|
|
mkDir(dstPath32)
|
|
else:
|
|
clearFiles(dstPath32, tb, tf, tc, base32)
|
|
|
|
## Check if directory for 64bit library is already present in filesystem
|
|
if not dirExists(dstPath64):
|
|
mkDir(dstPath64)
|
|
else:
|
|
clearFiles(dstPath64, tb, tf, tc, base64)
|
|
|
|
## Generating 32bit version of library.
|
|
curveSet(srcPath, dstPath32, "384", "BLS381", "BLS381",
|
|
"48", "29", "381", "3", "NOT_SPECIAL", "WEIERSTRASS", "BLS",
|
|
"M_TYPE", "NEGATIVEX", "128")
|
|
## Generating 64bit version of library
|
|
curveSet(srcPath, dstPath64, "384", "BLS381", "BLS381",
|
|
"48", "58", "381", "3", "NOT_SPECIAL", "WEIERSTRASS", "BLS",
|
|
"M_TYPE", "NEGATIVEX", "128")
|
|
echo "SUCCESS: Milagro source files was successfully prepared!"
|