Example+Test C API vs GMP (#203)
* Example+Test C API vs GMP * Create build directory for bindings test * --nimMainPrefix is 1.6 only * Add libdl for dynamic loading * absolute paths * add static link test * Fix man main, rename Nimmain to init_NimMain * Deal with MacOS annoying linker w.r.t. static libraries * use .exe extension to satisfy windows (?) * annoying GCC which doesn't create paths * Try skipping DLL test on windows * windows extensions ... * no lib prefix on windows
This commit is contained in:
parent
962e7ccf49
commit
df048112c3
|
@ -7,7 +7,7 @@ jobs:
|
|||
fail-fast: false
|
||||
max-parallel: 20
|
||||
matrix:
|
||||
nim_version: [version-1-4, version-1-6] # [version-1-4, devel]
|
||||
nim_version: [version-1-6] # [version-1-4, devel]
|
||||
target:
|
||||
- os: linux
|
||||
cpu: amd64
|
||||
|
@ -197,21 +197,27 @@ jobs:
|
|||
nimble refresh --verbose -y
|
||||
nimble install --verbose -y gmp stew jsony asynctools
|
||||
|
||||
- name: Run Constantine tests (UNIX with Assembler)
|
||||
- name: Run Constantine tests (UNIX with Assembly)
|
||||
if: runner.os != 'Windows' && matrix.target.BACKEND == 'ASM'
|
||||
shell: bash
|
||||
run: |
|
||||
cd constantine
|
||||
nimble bindings --verbose
|
||||
nimble test_bindings --verbose
|
||||
nimble test_parallel --verbose
|
||||
- name: Run Constantine tests (UNIX no Assembler)
|
||||
- name: Run Constantine tests (UNIX no Assembly)
|
||||
if: runner.os != 'Windows' && matrix.target.BACKEND == 'NO_ASM'
|
||||
shell: bash
|
||||
run: |
|
||||
cd constantine
|
||||
nimble bindings --verbose
|
||||
nimble test_bindings --verbose
|
||||
nimble test_parallel_no_asm --verbose
|
||||
- name: Run Constantine tests (Windows no Assembler)
|
||||
- name: Run Constantine tests (Windows no Assembly)
|
||||
if: runner.os == 'Windows' && matrix.target.BACKEND == 'NO_ASM'
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
cd constantine
|
||||
nimble bindings --verbose
|
||||
nimble test_bindings --verbose
|
||||
nimble test_parallel_no_asm --verbose
|
||||
|
|
|
@ -34,10 +34,19 @@ collectBindings(cBindings):
|
|||
|
||||
# Write header
|
||||
when isMainModule and defined(CttGenerateHeaders):
|
||||
import std/os
|
||||
import std/[os, strformat]
|
||||
|
||||
proc main() =
|
||||
echo "Running bindings generation for " & getAppFilename().extractFilename()
|
||||
# echo "Running bindings generation for " & getAppFilename().extractFilename()
|
||||
|
||||
var dir = "."
|
||||
if paramCount() == 1:
|
||||
dir = paramStr(1)
|
||||
elif paramCount() > 1:
|
||||
let exeName = getAppFilename().extractFilename()
|
||||
echo &"Usage: {exeName} <optional directory to save header to>"
|
||||
echo "Found more than one parameter"
|
||||
quit 1
|
||||
|
||||
var header: string
|
||||
header = genBuiltinsTypes()
|
||||
|
@ -64,15 +73,15 @@ when isMainModule and defined(CttGenerateHeaders):
|
|||
header &= '\n'
|
||||
header &= genEllipticCurvePoint("bls12381_ec_g2_prj", "x, y, z", "bls12381_fp2")
|
||||
header &= '\n'
|
||||
header &= declNimMain("bls12381")
|
||||
header &= '\n'
|
||||
header &= cBindings
|
||||
header &= '\n'
|
||||
header &= declNimMain("bls12381")
|
||||
|
||||
header = genCpp(header)
|
||||
header = genHeader("BLS12381", header)
|
||||
header = genHeaderLicense() & header
|
||||
|
||||
writeFile("constantine_bls12_381.h", header)
|
||||
|
||||
writeFile(dir/"constantine_bls12_381.h", header)
|
||||
|
||||
main()
|
|
@ -36,10 +36,20 @@ collectBindings(cBindings):
|
|||
|
||||
# Write header
|
||||
when isMainModule and defined(CttGenerateHeaders):
|
||||
import std/os
|
||||
import std/[os, strformat]
|
||||
|
||||
proc main() =
|
||||
echo "Running bindings generation for " & getAppFilename().extractFilename()
|
||||
# echo "Running bindings generation for " & getAppFilename().extractFilename()
|
||||
|
||||
var dir = "."
|
||||
if paramCount() == 1:
|
||||
dir = paramStr(1)
|
||||
elif paramCount() > 1:
|
||||
let exeName = getAppFilename().extractFilename()
|
||||
echo &"Usage: {exeName} <optional directory to save header to>"
|
||||
echo "Found more than one parameter"
|
||||
quit 1
|
||||
|
||||
|
||||
var header: string
|
||||
header = genBuiltinsTypes()
|
||||
|
@ -68,15 +78,15 @@ when isMainModule and defined(CttGenerateHeaders):
|
|||
header &= '\n'
|
||||
header &= genEllipticCurvePoint("vesta_ec_prj", "x, y, z", "vesta_fp")
|
||||
header &= '\n'
|
||||
header &= declNimMain("pasta")
|
||||
header &= '\n'
|
||||
header &= cBindings
|
||||
header &= '\n'
|
||||
header &= declNimMain("pasta")
|
||||
|
||||
header = genCpp(header)
|
||||
header = genHeader("PASTA", header)
|
||||
header = genHeaderLicense() & header
|
||||
|
||||
writeFile("constantine_pasta.h", header)
|
||||
|
||||
writeFile(dir/"constantine_pasta.h", header)
|
||||
|
||||
main()
|
|
@ -19,7 +19,7 @@ export curves, curves_primitives
|
|||
|
||||
template genBindingsField*(Field: untyped) =
|
||||
{.push cdecl, dynlib, exportc, raises: [].} # No exceptions allowed
|
||||
|
||||
|
||||
func `ctt _ Field _ unmarshalBE`(dst: var Field, src: openarray[byte]) =
|
||||
## Deserialize
|
||||
unmarshalBE(dst, src)
|
||||
|
@ -48,7 +48,10 @@ template genBindingsField*(Field: untyped) =
|
|||
func `ctt _ Field _ set_minus_one`(a: var Field) =
|
||||
a.setMinusOne()
|
||||
# --------------------------------------------------------------------------------------
|
||||
func `ctt _ Field _ neg`(a: var Field) =
|
||||
func `ctt _ Field _ neg`(r: var Field, a: Field) =
|
||||
r.neg(a)
|
||||
|
||||
func `ctt _ Field _ neg_in_place`(a: var Field) =
|
||||
a.neg()
|
||||
|
||||
func `ctt _ Field _ sum`(r: var Field, a, b: Field) =
|
||||
|
|
|
@ -55,7 +55,7 @@ extern "C" {{
|
|||
|
||||
proc genBuiltinsTypes*(): string =
|
||||
"""
|
||||
#if defined{__SIZE_TYPE__} && defined(__PTRDIFF_TYPE__)
|
||||
#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__)
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
#else
|
||||
|
@ -93,6 +93,25 @@ proc genExtField*(name: string, degree: int, basename: string): string =
|
|||
proc genEllipticCurvePoint*(name, coords, basename: string): string =
|
||||
&"typedef struct {{ {basename} {coords}; }} {name};"
|
||||
|
||||
# Nim internals
|
||||
# -------------------------------------------
|
||||
|
||||
proc declNimMain*(libName: string): string =
|
||||
## Create the NimMain function.
|
||||
## It initializes:
|
||||
## - the Nim runtime if seqs, strings or heap-allocated types are used,
|
||||
## this is the case only if Constantine is multithreaded.
|
||||
## - runtime CPU features detection
|
||||
##
|
||||
## Assumes library is compiled with --nimMainPrefix:ctt_{libName}_
|
||||
&"""
|
||||
|
||||
/*
|
||||
* Initializes the library:
|
||||
* - detect CPU features like ADX instructions support (MULX, ADCX, ADOX)
|
||||
*/
|
||||
void ctt_{libName}_init_NimMain(void);"""
|
||||
|
||||
# Subroutines' declarations
|
||||
# -------------------------------------------
|
||||
|
||||
|
@ -159,7 +178,6 @@ macro collectBindings*(cBindingsStr: untyped, body: typed): untyped =
|
|||
|
||||
for generator in body:
|
||||
generator.expectKind(nnkStmtList)
|
||||
cBindings &= "\n"
|
||||
for fnDef in generator:
|
||||
if fnDef.kind notin {nnkProcDef, nnkFuncDef}:
|
||||
continue
|
||||
|
@ -190,26 +208,3 @@ macro collectBindings*(cBindingsStr: untyped, body: typed): untyped =
|
|||
result = newConstStmt(cBindingsStr, newLit cBindings)
|
||||
else:
|
||||
result = body
|
||||
|
||||
|
||||
# Nim internals
|
||||
# -------------------------------------------
|
||||
|
||||
proc declNimMain*(libName: string): string =
|
||||
## Create the NimMain function.
|
||||
## It initializes:
|
||||
## - the Nim runtime if seqs, strings or heap-allocated types are used,
|
||||
## this is the case only if Constantine is multithreaded.
|
||||
## - runtime CPU features detection
|
||||
##
|
||||
## Assumes library is compiled with --nimMainPrefix:ctt_{libName}_
|
||||
&"""
|
||||
|
||||
/*
|
||||
* Initializes the library:
|
||||
* - the Nim runtime if heap-allocated types are used,
|
||||
* this is the case only if Constantine is multithreaded.
|
||||
* - runtime CPU features detection
|
||||
*/
|
||||
void ctt_{libName}_NimMain(void);
|
||||
"""
|
|
@ -14,7 +14,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined{__SIZE_TYPE__} && defined(__PTRDIFF_TYPE__)
|
||||
#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__)
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
#else
|
||||
|
@ -46,6 +46,11 @@ typedef struct { bls12381_fp2 x, y; } bls12381_ec_g2_aff;
|
|||
typedef struct { bls12381_fp2 x, y, z; } bls12381_ec_g2_jac;
|
||||
typedef struct { bls12381_fp2 x, y, z; } bls12381_ec_g2_prj;
|
||||
|
||||
/*
|
||||
* Initializes the library:
|
||||
* - detect CPU features like ADX instructions support (MULX, ADCX, ADOX)
|
||||
*/
|
||||
void ctt_bls12381_init_NimMain(void);
|
||||
|
||||
void ctt_bls12381_fr_unmarshalBE(bls12381_fr* dst, const byte src[], ptrdiff_t src_len);
|
||||
void ctt_bls12381_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12381_fr* src);
|
||||
|
@ -56,7 +61,8 @@ secret_bool ctt_bls12381_fr_is_minus_one(const bls12381_fr* a);
|
|||
void ctt_bls12381_fr_set_zero(bls12381_fr* a);
|
||||
void ctt_bls12381_fr_set_one(bls12381_fr* a);
|
||||
void ctt_bls12381_fr_set_minus_one(bls12381_fr* a);
|
||||
void ctt_bls12381_fr_neg(bls12381_fr* a);
|
||||
void ctt_bls12381_fr_neg(bls12381_fr* r, const bls12381_fr* a);
|
||||
void ctt_bls12381_fr_neg_in_place(bls12381_fr* a);
|
||||
void ctt_bls12381_fr_sum(bls12381_fr* r, const bls12381_fr* a, const bls12381_fr* b);
|
||||
void ctt_bls12381_fr_add_in_place(bls12381_fr* a, const bls12381_fr* b);
|
||||
void ctt_bls12381_fr_diff(bls12381_fr* r, const bls12381_fr* a, const bls12381_fr* b);
|
||||
|
@ -77,7 +83,6 @@ void ctt_bls12381_fr_cset_one(bls12381_fr* a, const secret_bool ctl);
|
|||
void ctt_bls12381_fr_cneg_in_place(bls12381_fr* a, const secret_bool ctl);
|
||||
void ctt_bls12381_fr_cadd_in_place(bls12381_fr* a, const bls12381_fr* b, const secret_bool ctl);
|
||||
void ctt_bls12381_fr_csub_in_place(bls12381_fr* a, const bls12381_fr* b, const secret_bool ctl);
|
||||
|
||||
void ctt_bls12381_fp_unmarshalBE(bls12381_fp* dst, const byte src[], ptrdiff_t src_len);
|
||||
void ctt_bls12381_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12381_fp* src);
|
||||
secret_bool ctt_bls12381_fp_is_eq(const bls12381_fp* a, const bls12381_fp* b);
|
||||
|
@ -87,7 +92,8 @@ secret_bool ctt_bls12381_fp_is_minus_one(const bls12381_fp* a);
|
|||
void ctt_bls12381_fp_set_zero(bls12381_fp* a);
|
||||
void ctt_bls12381_fp_set_one(bls12381_fp* a);
|
||||
void ctt_bls12381_fp_set_minus_one(bls12381_fp* a);
|
||||
void ctt_bls12381_fp_neg(bls12381_fp* a);
|
||||
void ctt_bls12381_fp_neg(bls12381_fp* r, const bls12381_fp* a);
|
||||
void ctt_bls12381_fp_neg_in_place(bls12381_fp* a);
|
||||
void ctt_bls12381_fp_sum(bls12381_fp* r, const bls12381_fp* a, const bls12381_fp* b);
|
||||
void ctt_bls12381_fp_add_in_place(bls12381_fp* a, const bls12381_fp* b);
|
||||
void ctt_bls12381_fp_diff(bls12381_fp* r, const bls12381_fp* a, const bls12381_fp* b);
|
||||
|
@ -108,7 +114,6 @@ void ctt_bls12381_fp_cset_one(bls12381_fp* a, const secret_bool ctl);
|
|||
void ctt_bls12381_fp_cneg_in_place(bls12381_fp* a, const secret_bool ctl);
|
||||
void ctt_bls12381_fp_cadd_in_place(bls12381_fp* a, const bls12381_fp* b, const secret_bool ctl);
|
||||
void ctt_bls12381_fp_csub_in_place(bls12381_fp* a, const bls12381_fp* b, const secret_bool ctl);
|
||||
|
||||
secret_bool ctt_bls12381_fp_is_square(const bls12381_fp* a);
|
||||
void ctt_bls12381_fp_invsqrt(bls12381_fp* r, const bls12381_fp* a);
|
||||
secret_bool ctt_bls12381_fp_invsqrt_in_place(bls12381_fp* r, const bls12381_fp* a);
|
||||
|
@ -117,7 +122,6 @@ secret_bool ctt_bls12381_fp_sqrt_if_square_in_place(bls12381_fp* a);
|
|||
void ctt_bls12381_fp_sqrt_invsqrt(bls12381_fp* sqrt, bls12381_fp* invsqrt, const bls12381_fp* a);
|
||||
secret_bool ctt_bls12381_fp_sqrt_invsqrt_if_square(bls12381_fp* sqrt, bls12381_fp* invsqrt, const bls12381_fp* a);
|
||||
secret_bool ctt_bls12381_fp_sqrt_ratio_if_square(bls12381_fp* r, const bls12381_fp* u, const bls12381_fp* v);
|
||||
|
||||
secret_bool ctt_bls12381_fp2_is_eq(const bls12381_fp2* a, const bls12381_fp2* b);
|
||||
secret_bool ctt_bls12381_fp2_is_zero(const bls12381_fp2* a);
|
||||
secret_bool ctt_bls12381_fp2_is_one(const bls12381_fp2* a);
|
||||
|
@ -149,11 +153,9 @@ void ctt_bls12381_fp2_cset_one(bls12381_fp2* a, const secret_bool ctl);
|
|||
void ctt_bls12381_fp2_cneg_in_place(bls12381_fp2* a, const secret_bool ctl);
|
||||
void ctt_bls12381_fp2_cadd_in_place(bls12381_fp2* a, const bls12381_fp2* b, const secret_bool ctl);
|
||||
void ctt_bls12381_fp2_csub_in_place(bls12381_fp2* a, const bls12381_fp2* b, const secret_bool ctl);
|
||||
|
||||
secret_bool ctt_bls12381_fp2_is_square(const bls12381_fp2* a);
|
||||
void ctt_bls12381_fp2_sqrt_in_place(bls12381_fp2* a);
|
||||
secret_bool ctt_bls12381_fp2_sqrt_if_square_in_place(bls12381_fp2* a);
|
||||
|
||||
secret_bool ctt_bls12381_ec_g1_aff_is_eq(const bls12381_ec_g1_aff* P, const bls12381_ec_g1_aff* Q);
|
||||
secret_bool ctt_bls12381_ec_g1_aff_is_inf(const bls12381_ec_g1_aff* P);
|
||||
void ctt_bls12381_ec_g1_aff_set_inf(bls12381_ec_g1_aff* P);
|
||||
|
@ -161,7 +163,6 @@ void ctt_bls12381_ec_g1_aff_ccopy(bls12381_ec_g1_aff* P, const bls12381_e
|
|||
secret_bool ctt_bls12381_ec_g1_aff_is_on_curve(const bls12381_fp* x, const bls12381_fp* y);
|
||||
void ctt_bls12381_ec_g1_aff_neg(bls12381_ec_g1_aff* P, const bls12381_ec_g1_aff* Q);
|
||||
void ctt_bls12381_ec_g1_aff_neg_in_place(bls12381_ec_g1_aff* P);
|
||||
|
||||
secret_bool ctt_bls12381_ec_g1_jac_is_eq(const bls12381_ec_g1_jac* P, const bls12381_ec_g1_jac* Q);
|
||||
secret_bool ctt_bls12381_ec_g1_jac_is_inf(const bls12381_ec_g1_jac* P);
|
||||
void ctt_bls12381_ec_g1_jac_set_inf(bls12381_ec_g1_jac* P);
|
||||
|
@ -176,7 +177,6 @@ void ctt_bls12381_ec_g1_jac_double(bls12381_ec_g1_jac* r, const bls12381_
|
|||
void ctt_bls12381_ec_g1_jac_double_in_place(bls12381_ec_g1_jac* P);
|
||||
void ctt_bls12381_ec_g1_jac_affine(bls12381_ec_g1_aff* dst, const bls12381_ec_g1_jac* src);
|
||||
void ctt_bls12381_ec_g1_jac_from_affine(bls12381_ec_g1_jac* dst, const bls12381_ec_g1_aff* src);
|
||||
|
||||
secret_bool ctt_bls12381_ec_g1_prj_is_eq(const bls12381_ec_g1_prj* P, const bls12381_ec_g1_prj* Q);
|
||||
secret_bool ctt_bls12381_ec_g1_prj_is_inf(const bls12381_ec_g1_prj* P);
|
||||
void ctt_bls12381_ec_g1_prj_set_inf(bls12381_ec_g1_prj* P);
|
||||
|
@ -191,7 +191,6 @@ void ctt_bls12381_ec_g1_prj_double(bls12381_ec_g1_prj* r, const bls12381_
|
|||
void ctt_bls12381_ec_g1_prj_double_in_place(bls12381_ec_g1_prj* P);
|
||||
void ctt_bls12381_ec_g1_prj_affine(bls12381_ec_g1_aff* dst, const bls12381_ec_g1_prj* src);
|
||||
void ctt_bls12381_ec_g1_prj_from_affine(bls12381_ec_g1_prj* dst, const bls12381_ec_g1_aff* src);
|
||||
|
||||
secret_bool ctt_bls12381_ec_g2_aff_is_eq(const bls12381_ec_g2_aff* P, const bls12381_ec_g2_aff* Q);
|
||||
secret_bool ctt_bls12381_ec_g2_aff_is_inf(const bls12381_ec_g2_aff* P);
|
||||
void ctt_bls12381_ec_g2_aff_set_inf(bls12381_ec_g2_aff* P);
|
||||
|
@ -199,7 +198,6 @@ void ctt_bls12381_ec_g2_aff_ccopy(bls12381_ec_g2_aff* P, const bls12381_e
|
|||
secret_bool ctt_bls12381_ec_g2_aff_is_on_curve(const bls12381_fp2* x, const bls12381_fp2* y);
|
||||
void ctt_bls12381_ec_g2_aff_neg(bls12381_ec_g2_aff* P, const bls12381_ec_g2_aff* Q);
|
||||
void ctt_bls12381_ec_g2_aff_neg_in_place(bls12381_ec_g2_aff* P);
|
||||
|
||||
secret_bool ctt_bls12381_ec_g2_jac_is_eq(const bls12381_ec_g2_jac* P, const bls12381_ec_g2_jac* Q);
|
||||
secret_bool ctt_bls12381_ec_g2_jac_is_inf(const bls12381_ec_g2_jac* P);
|
||||
void ctt_bls12381_ec_g2_jac_set_inf(bls12381_ec_g2_jac* P);
|
||||
|
@ -214,7 +212,6 @@ void ctt_bls12381_ec_g2_jac_double(bls12381_ec_g2_jac* r, const bls12381_
|
|||
void ctt_bls12381_ec_g2_jac_double_in_place(bls12381_ec_g2_jac* P);
|
||||
void ctt_bls12381_ec_g2_jac_affine(bls12381_ec_g2_aff* dst, const bls12381_ec_g2_jac* src);
|
||||
void ctt_bls12381_ec_g2_jac_from_affine(bls12381_ec_g2_jac* dst, const bls12381_ec_g2_aff* src);
|
||||
|
||||
secret_bool ctt_bls12381_ec_g2_prj_is_eq(const bls12381_ec_g2_prj* P, const bls12381_ec_g2_prj* Q);
|
||||
secret_bool ctt_bls12381_ec_g2_prj_is_inf(const bls12381_ec_g2_prj* P);
|
||||
void ctt_bls12381_ec_g2_prj_set_inf(bls12381_ec_g2_prj* P);
|
||||
|
@ -230,14 +227,6 @@ void ctt_bls12381_ec_g2_prj_double_in_place(bls12381_ec_g2_prj* P);
|
|||
void ctt_bls12381_ec_g2_prj_affine(bls12381_ec_g2_aff* dst, const bls12381_ec_g2_prj* src);
|
||||
void ctt_bls12381_ec_g2_prj_from_affine(bls12381_ec_g2_prj* dst, const bls12381_ec_g2_aff* src);
|
||||
|
||||
/*
|
||||
* Initializes the library:
|
||||
* - the Nim runtime if heap-allocated types are used,
|
||||
* this is the case only if Constantine is multithreaded.
|
||||
* - runtime CPU features detection
|
||||
*/
|
||||
void ctt_bls12381_NimMain(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined{__SIZE_TYPE__} && defined(__PTRDIFF_TYPE__)
|
||||
#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__)
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
#else
|
||||
|
@ -47,6 +47,11 @@ typedef struct { vesta_fp x, y; } vesta_ec_aff;
|
|||
typedef struct { vesta_fp x, y, z; } vesta_ec_jac;
|
||||
typedef struct { vesta_fp x, y, z; } vesta_ec_prj;
|
||||
|
||||
/*
|
||||
* Initializes the library:
|
||||
* - detect CPU features like ADX instructions support (MULX, ADCX, ADOX)
|
||||
*/
|
||||
void ctt_pasta_init_NimMain(void);
|
||||
|
||||
void ctt_pallas_fr_unmarshalBE(pallas_fr* dst, const byte src[], ptrdiff_t src_len);
|
||||
void ctt_pallas_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fr* src);
|
||||
|
@ -57,7 +62,8 @@ secret_bool ctt_pallas_fr_is_minus_one(const pallas_fr* a);
|
|||
void ctt_pallas_fr_set_zero(pallas_fr* a);
|
||||
void ctt_pallas_fr_set_one(pallas_fr* a);
|
||||
void ctt_pallas_fr_set_minus_one(pallas_fr* a);
|
||||
void ctt_pallas_fr_neg(pallas_fr* a);
|
||||
void ctt_pallas_fr_neg(pallas_fr* r, const pallas_fr* a);
|
||||
void ctt_pallas_fr_neg_in_place(pallas_fr* a);
|
||||
void ctt_pallas_fr_sum(pallas_fr* r, const pallas_fr* a, const pallas_fr* b);
|
||||
void ctt_pallas_fr_add_in_place(pallas_fr* a, const pallas_fr* b);
|
||||
void ctt_pallas_fr_diff(pallas_fr* r, const pallas_fr* a, const pallas_fr* b);
|
||||
|
@ -78,7 +84,6 @@ void ctt_pallas_fr_cset_one(pallas_fr* a, const secret_bool ctl);
|
|||
void ctt_pallas_fr_cneg_in_place(pallas_fr* a, const secret_bool ctl);
|
||||
void ctt_pallas_fr_cadd_in_place(pallas_fr* a, const pallas_fr* b, const secret_bool ctl);
|
||||
void ctt_pallas_fr_csub_in_place(pallas_fr* a, const pallas_fr* b, const secret_bool ctl);
|
||||
|
||||
void ctt_pallas_fp_unmarshalBE(pallas_fp* dst, const byte src[], ptrdiff_t src_len);
|
||||
void ctt_pallas_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fp* src);
|
||||
secret_bool ctt_pallas_fp_is_eq(const pallas_fp* a, const pallas_fp* b);
|
||||
|
@ -88,7 +93,8 @@ secret_bool ctt_pallas_fp_is_minus_one(const pallas_fp* a);
|
|||
void ctt_pallas_fp_set_zero(pallas_fp* a);
|
||||
void ctt_pallas_fp_set_one(pallas_fp* a);
|
||||
void ctt_pallas_fp_set_minus_one(pallas_fp* a);
|
||||
void ctt_pallas_fp_neg(pallas_fp* a);
|
||||
void ctt_pallas_fp_neg(pallas_fp* r, const pallas_fp* a);
|
||||
void ctt_pallas_fp_neg_in_place(pallas_fp* a);
|
||||
void ctt_pallas_fp_sum(pallas_fp* r, const pallas_fp* a, const pallas_fp* b);
|
||||
void ctt_pallas_fp_add_in_place(pallas_fp* a, const pallas_fp* b);
|
||||
void ctt_pallas_fp_diff(pallas_fp* r, const pallas_fp* a, const pallas_fp* b);
|
||||
|
@ -109,7 +115,6 @@ void ctt_pallas_fp_cset_one(pallas_fp* a, const secret_bool ctl);
|
|||
void ctt_pallas_fp_cneg_in_place(pallas_fp* a, const secret_bool ctl);
|
||||
void ctt_pallas_fp_cadd_in_place(pallas_fp* a, const pallas_fp* b, const secret_bool ctl);
|
||||
void ctt_pallas_fp_csub_in_place(pallas_fp* a, const pallas_fp* b, const secret_bool ctl);
|
||||
|
||||
secret_bool ctt_pallas_fp_is_square(const pallas_fp* a);
|
||||
void ctt_pallas_fp_invsqrt(pallas_fp* r, const pallas_fp* a);
|
||||
secret_bool ctt_pallas_fp_invsqrt_in_place(pallas_fp* r, const pallas_fp* a);
|
||||
|
@ -118,7 +123,6 @@ secret_bool ctt_pallas_fp_sqrt_if_square_in_place(pallas_fp* a);
|
|||
void ctt_pallas_fp_sqrt_invsqrt(pallas_fp* sqrt, pallas_fp* invsqrt, const pallas_fp* a);
|
||||
secret_bool ctt_pallas_fp_sqrt_invsqrt_if_square(pallas_fp* sqrt, pallas_fp* invsqrt, const pallas_fp* a);
|
||||
secret_bool ctt_pallas_fp_sqrt_ratio_if_square(pallas_fp* r, const pallas_fp* u, const pallas_fp* v);
|
||||
|
||||
void ctt_vesta_fr_unmarshalBE(vesta_fr* dst, const byte src[], ptrdiff_t src_len);
|
||||
void ctt_vesta_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fr* src);
|
||||
secret_bool ctt_vesta_fr_is_eq(const vesta_fr* a, const vesta_fr* b);
|
||||
|
@ -128,7 +132,8 @@ secret_bool ctt_vesta_fr_is_minus_one(const vesta_fr* a);
|
|||
void ctt_vesta_fr_set_zero(vesta_fr* a);
|
||||
void ctt_vesta_fr_set_one(vesta_fr* a);
|
||||
void ctt_vesta_fr_set_minus_one(vesta_fr* a);
|
||||
void ctt_vesta_fr_neg(vesta_fr* a);
|
||||
void ctt_vesta_fr_neg(vesta_fr* r, const vesta_fr* a);
|
||||
void ctt_vesta_fr_neg_in_place(vesta_fr* a);
|
||||
void ctt_vesta_fr_sum(vesta_fr* r, const vesta_fr* a, const vesta_fr* b);
|
||||
void ctt_vesta_fr_add_in_place(vesta_fr* a, const vesta_fr* b);
|
||||
void ctt_vesta_fr_diff(vesta_fr* r, const vesta_fr* a, const vesta_fr* b);
|
||||
|
@ -149,7 +154,6 @@ void ctt_vesta_fr_cset_one(vesta_fr* a, const secret_bool ctl);
|
|||
void ctt_vesta_fr_cneg_in_place(vesta_fr* a, const secret_bool ctl);
|
||||
void ctt_vesta_fr_cadd_in_place(vesta_fr* a, const vesta_fr* b, const secret_bool ctl);
|
||||
void ctt_vesta_fr_csub_in_place(vesta_fr* a, const vesta_fr* b, const secret_bool ctl);
|
||||
|
||||
void ctt_vesta_fp_unmarshalBE(vesta_fp* dst, const byte src[], ptrdiff_t src_len);
|
||||
void ctt_vesta_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fp* src);
|
||||
secret_bool ctt_vesta_fp_is_eq(const vesta_fp* a, const vesta_fp* b);
|
||||
|
@ -159,7 +163,8 @@ secret_bool ctt_vesta_fp_is_minus_one(const vesta_fp* a);
|
|||
void ctt_vesta_fp_set_zero(vesta_fp* a);
|
||||
void ctt_vesta_fp_set_one(vesta_fp* a);
|
||||
void ctt_vesta_fp_set_minus_one(vesta_fp* a);
|
||||
void ctt_vesta_fp_neg(vesta_fp* a);
|
||||
void ctt_vesta_fp_neg(vesta_fp* r, const vesta_fp* a);
|
||||
void ctt_vesta_fp_neg_in_place(vesta_fp* a);
|
||||
void ctt_vesta_fp_sum(vesta_fp* r, const vesta_fp* a, const vesta_fp* b);
|
||||
void ctt_vesta_fp_add_in_place(vesta_fp* a, const vesta_fp* b);
|
||||
void ctt_vesta_fp_diff(vesta_fp* r, const vesta_fp* a, const vesta_fp* b);
|
||||
|
@ -180,7 +185,6 @@ void ctt_vesta_fp_cset_one(vesta_fp* a, const secret_bool ctl);
|
|||
void ctt_vesta_fp_cneg_in_place(vesta_fp* a, const secret_bool ctl);
|
||||
void ctt_vesta_fp_cadd_in_place(vesta_fp* a, const vesta_fp* b, const secret_bool ctl);
|
||||
void ctt_vesta_fp_csub_in_place(vesta_fp* a, const vesta_fp* b, const secret_bool ctl);
|
||||
|
||||
secret_bool ctt_vesta_fp_is_square(const vesta_fp* a);
|
||||
void ctt_vesta_fp_invsqrt(vesta_fp* r, const vesta_fp* a);
|
||||
secret_bool ctt_vesta_fp_invsqrt_in_place(vesta_fp* r, const vesta_fp* a);
|
||||
|
@ -189,7 +193,6 @@ secret_bool ctt_vesta_fp_sqrt_if_square_in_place(vesta_fp* a);
|
|||
void ctt_vesta_fp_sqrt_invsqrt(vesta_fp* sqrt, vesta_fp* invsqrt, const vesta_fp* a);
|
||||
secret_bool ctt_vesta_fp_sqrt_invsqrt_if_square(vesta_fp* sqrt, vesta_fp* invsqrt, const vesta_fp* a);
|
||||
secret_bool ctt_vesta_fp_sqrt_ratio_if_square(vesta_fp* r, const vesta_fp* u, const vesta_fp* v);
|
||||
|
||||
secret_bool ctt_pallas_ec_aff_is_eq(const pallas_ec_aff* P, const pallas_ec_aff* Q);
|
||||
secret_bool ctt_pallas_ec_aff_is_inf(const pallas_ec_aff* P);
|
||||
void ctt_pallas_ec_aff_set_inf(pallas_ec_aff* P);
|
||||
|
@ -197,7 +200,6 @@ void ctt_pallas_ec_aff_ccopy(pallas_ec_aff* P, const pallas_ec_aff* Q, co
|
|||
secret_bool ctt_pallas_ec_aff_is_on_curve(const pallas_fp* x, const pallas_fp* y);
|
||||
void ctt_pallas_ec_aff_neg(pallas_ec_aff* P, const pallas_ec_aff* Q);
|
||||
void ctt_pallas_ec_aff_neg_in_place(pallas_ec_aff* P);
|
||||
|
||||
secret_bool ctt_pallas_ec_jac_is_eq(const pallas_ec_jac* P, const pallas_ec_jac* Q);
|
||||
secret_bool ctt_pallas_ec_jac_is_inf(const pallas_ec_jac* P);
|
||||
void ctt_pallas_ec_jac_set_inf(pallas_ec_jac* P);
|
||||
|
@ -212,7 +214,6 @@ void ctt_pallas_ec_jac_double(pallas_ec_jac* r, const pallas_ec_jac* P);
|
|||
void ctt_pallas_ec_jac_double_in_place(pallas_ec_jac* P);
|
||||
void ctt_pallas_ec_jac_affine(pallas_ec_aff* dst, const pallas_ec_jac* src);
|
||||
void ctt_pallas_ec_jac_from_affine(pallas_ec_jac* dst, const pallas_ec_aff* src);
|
||||
|
||||
secret_bool ctt_pallas_ec_prj_is_eq(const pallas_ec_prj* P, const pallas_ec_prj* Q);
|
||||
secret_bool ctt_pallas_ec_prj_is_inf(const pallas_ec_prj* P);
|
||||
void ctt_pallas_ec_prj_set_inf(pallas_ec_prj* P);
|
||||
|
@ -227,7 +228,6 @@ void ctt_pallas_ec_prj_double(pallas_ec_prj* r, const pallas_ec_prj* P);
|
|||
void ctt_pallas_ec_prj_double_in_place(pallas_ec_prj* P);
|
||||
void ctt_pallas_ec_prj_affine(pallas_ec_aff* dst, const pallas_ec_prj* src);
|
||||
void ctt_pallas_ec_prj_from_affine(pallas_ec_prj* dst, const pallas_ec_aff* src);
|
||||
|
||||
secret_bool ctt_vesta_ec_aff_is_eq(const vesta_ec_aff* P, const vesta_ec_aff* Q);
|
||||
secret_bool ctt_vesta_ec_aff_is_inf(const vesta_ec_aff* P);
|
||||
void ctt_vesta_ec_aff_set_inf(vesta_ec_aff* P);
|
||||
|
@ -235,7 +235,6 @@ void ctt_vesta_ec_aff_ccopy(vesta_ec_aff* P, const vesta_ec_aff* Q, const
|
|||
secret_bool ctt_vesta_ec_aff_is_on_curve(const pallas_fp* x, const pallas_fp* y);
|
||||
void ctt_vesta_ec_aff_neg(vesta_ec_aff* P, const vesta_ec_aff* Q);
|
||||
void ctt_vesta_ec_aff_neg_in_place(vesta_ec_aff* P);
|
||||
|
||||
secret_bool ctt_vesta_ec_jac_is_eq(const vesta_ec_jac* P, const vesta_ec_jac* Q);
|
||||
secret_bool ctt_vesta_ec_jac_is_inf(const vesta_ec_jac* P);
|
||||
void ctt_vesta_ec_jac_set_inf(vesta_ec_jac* P);
|
||||
|
@ -250,7 +249,6 @@ void ctt_vesta_ec_jac_double(vesta_ec_jac* r, const vesta_ec_jac* P);
|
|||
void ctt_vesta_ec_jac_double_in_place(vesta_ec_jac* P);
|
||||
void ctt_vesta_ec_jac_affine(vesta_ec_aff* dst, const vesta_ec_jac* src);
|
||||
void ctt_vesta_ec_jac_from_affine(vesta_ec_jac* dst, const vesta_ec_aff* src);
|
||||
|
||||
secret_bool ctt_vesta_ec_prj_is_eq(const vesta_ec_prj* P, const vesta_ec_prj* Q);
|
||||
secret_bool ctt_vesta_ec_prj_is_inf(const vesta_ec_prj* P);
|
||||
void ctt_vesta_ec_prj_set_inf(vesta_ec_prj* P);
|
||||
|
@ -266,14 +264,6 @@ void ctt_vesta_ec_prj_double_in_place(vesta_ec_prj* P);
|
|||
void ctt_vesta_ec_prj_affine(vesta_ec_aff* dst, const vesta_ec_prj* src);
|
||||
void ctt_vesta_ec_prj_from_affine(vesta_ec_prj* dst, const vesta_ec_aff* src);
|
||||
|
||||
/*
|
||||
* Initializes the library:
|
||||
* - the Nim runtime if heap-allocated types are used,
|
||||
* this is the case only if Constantine is multithreaded.
|
||||
* - runtime CPU features detection
|
||||
*/
|
||||
void ctt_pasta_NimMain(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -327,7 +327,7 @@ template setupBench(): untyped {.dirty.} =
|
|||
cc &= " -d:CttASM=false"
|
||||
let command = "nim " & lang & cc &
|
||||
" -d:danger --verbosity:0 -o:build/bench/" & benchName & "_" & compiler & "_" & (if useAsm: "useASM" else: "noASM") &
|
||||
" --nimcache:nimcache/" & benchName & "_" & compiler & "_" & (if useAsm: "useASM" else: "noASM") &
|
||||
" --nimcache:nimcache/benches/" & benchName & "_" & compiler & "_" & (if useAsm: "useASM" else: "noASM") &
|
||||
runFlag & "--hints:off --warnings:off benchmarks/" & benchName & ".nim"
|
||||
|
||||
proc runBench(benchName: string, compiler = "", useAsm = true) =
|
||||
|
@ -369,7 +369,7 @@ proc addBenchSet(cmdFile: var string, useAsm = true) =
|
|||
for bd in benchDesc:
|
||||
cmdFile.buildBenchBatch(bd, useASM = useASM)
|
||||
|
||||
proc genBindings(bindingsName, prefixNimMain: string) =
|
||||
proc genDynamicBindings(bindingsName, prefixNimMain: string) =
|
||||
proc compile(libName: string, flags = "") =
|
||||
# -d:danger to avoid boundsCheck, overflowChecks that would trigger exceptions or allocations in a crypto library.
|
||||
# Those are internally guaranteed at compile-time by fixed-sized array
|
||||
|
@ -378,7 +378,9 @@ proc genBindings(bindingsName, prefixNimMain: string) =
|
|||
# In the future, Constantine might use:
|
||||
# - heap-allocated sequences and objects manually managed or managed by destructors for multithreading.
|
||||
# - heap-allocated strings for hex-string or decimal strings
|
||||
echo "Compiling dynamic library: bindings/generated/" & libName
|
||||
exec "nim c -f " & flags & " --noMain -d:danger --app:lib --gc:arc " &
|
||||
" --verbosity:0 --hints:off --warnings:off " &
|
||||
" --nimMainPrefix:" & prefixNimMain &
|
||||
" --out:" & libName & " --outdir:bindings/generated " &
|
||||
" --nimcache:nimcache/bindings/" & bindingsName &
|
||||
|
@ -397,11 +399,44 @@ proc genBindings(bindingsName, prefixNimMain: string) =
|
|||
else:
|
||||
compile "lib" & bindingsName & ".so"
|
||||
|
||||
proc genStaticBindings(bindingsName, prefixNimMain: string) =
|
||||
proc compile(libName: string, flags = "") =
|
||||
# -d:danger to avoid boundsCheck, overflowChecks that would trigger exceptions or allocations in a crypto library.
|
||||
# Those are internally guaranteed at compile-time by fixed-sized array
|
||||
# and checked at runtime with an appropriate error code if any for user-input.
|
||||
# -gc:arc Constantine stack allocates everything. Inputs are through unmanaged ptr+len.
|
||||
# In the future, Constantine might use:
|
||||
# - heap-allocated sequences and objects manually managed or managed by destructors for multithreading.
|
||||
# - heap-allocated strings for hex-string or decimal strings
|
||||
echo "Compiling static library: bindings/generated/" & libName
|
||||
exec "nim c -f " & flags & " --noMain -d:danger --app:staticLib --gc:arc " &
|
||||
" --verbosity:0 --hints:off --warnings:off " &
|
||||
" --nimMainPrefix:" & prefixNimMain &
|
||||
" --out:" & libName & " --outdir:bindings/generated " &
|
||||
" --nimcache:nimcache/bindings/" & bindingsName &
|
||||
" bindings/" & bindingsName & ".nim"
|
||||
|
||||
when defined(windows):
|
||||
compile bindingsName & ".lib"
|
||||
|
||||
elif defined(macosx):
|
||||
compile "lib" & bindingsName & ".a.arm", "--cpu:arm64 -l:'-target arm64-apple-macos11' -t:'-target arm64-apple-macos11'"
|
||||
compile "lib" & bindingsName & ".a.x64", "--cpu:amd64 -l:'-target x86_64-apple-macos10.12' -t:'-target x86_64-apple-macos10.12'"
|
||||
exec "lipo bindings/generated/lib" & bindingsName & ".a.arm " &
|
||||
" bindings/generated/lib" & bindingsName & ".a.x64 " &
|
||||
" -output bindings/generated/lib" & bindingsName & ".a -create"
|
||||
|
||||
else:
|
||||
compile "lib" & bindingsName & ".a"
|
||||
|
||||
proc genHeaders(bindingsName: string) =
|
||||
exec "nim c -r -d:release -d:CttGenerateHeaders " &
|
||||
echo "Generating header: bindings/generated/" & bindingsName & ".h"
|
||||
exec "nim c -d:release -d:CttGenerateHeaders " &
|
||||
" --verbosity:0 --hints:off --warnings:off " &
|
||||
" --out:" & bindingsName & "_gen_header.exe --outdir:bindings/generated " &
|
||||
" --nimcache:nimcache/bindings/" & bindingsName & "_header" &
|
||||
" bindings/" & bindingsName & ".nim"
|
||||
exec "bindings/generated/" & bindingsName & "_gen_header.exe bindings/generated"
|
||||
|
||||
proc genParallelCmdRunner() =
|
||||
exec "nim c --verbosity:0 --hints:off --warnings:off -d:release --out:build/pararun --nimcache:nimcache/pararun helpers/pararun.nim"
|
||||
|
@ -410,11 +445,37 @@ proc genParallelCmdRunner() =
|
|||
# ----------------------------------------------------------------
|
||||
|
||||
task bindings, "Generate Constantine bindings":
|
||||
genBindings("constantine_bls12_381", "ctt_bls12381_")
|
||||
genDynamicBindings("constantine_bls12_381", "ctt_bls12381_init_")
|
||||
genStaticBindings("constantine_bls12_381", "ctt_bls12381_init_")
|
||||
genHeaders("constantine_bls12_381")
|
||||
genBindings("constantine_pasta", "ctt_pasta_")
|
||||
echo ""
|
||||
genDynamicBindings("constantine_pasta", "ctt_pasta_init_")
|
||||
genStaticBindings("constantine_pasta", "ctt_pasta_init_")
|
||||
genHeaders("constantine_pasta")
|
||||
|
||||
task test_bindings, "Test C bindings":
|
||||
exec "mkdir -p build/testsuite"
|
||||
echo "--> Testing dynamically linked library"
|
||||
when not defined(windows):
|
||||
exec "gcc -Ibindings/generated -Lbindings/generated -o build/testsuite/t_libctt_bls12_381_dl tests/bindings/t_libctt_bls12_381.c -lgmp -lconstantine_bls12_381"
|
||||
exec "LD_LIBRARY_PATH=bindings/generated ./build/testsuite/t_libctt_bls12_381_dl"
|
||||
else:
|
||||
# Put DLL near the exe as LD_LIBRARY_PATH doesn't work even in an POSIX compatible shell
|
||||
exec "gcc -Ibindings/generated -Lbindings/generated -o build/testsuite/t_libctt_bls12_381_dl.exe tests/bindings/t_libctt_bls12_381.c -lgmp -lconstantine_bls12_381"
|
||||
exec "./build/testsuite/t_libctt_bls12_381_dl.exe"
|
||||
|
||||
echo "--> Testing statically linked library"
|
||||
when not defined(windows):
|
||||
# Beware MacOS annoying linker with regards to static libraries
|
||||
# The following standard way cannot be used on MacOS
|
||||
# exec "gcc -Ibindings/generated -Lbindings/generated -o build/t_libctt_bls12_381_sl.exe tests/bindings/t_libctt_bls12_381.c -lgmp -Wl,-Bstatic -lconstantine_bls12_381 -Wl,-Bdynamic"
|
||||
|
||||
exec "gcc -Ibindings/generated -o build/testsuite/t_libctt_bls12_381_sl tests/bindings/t_libctt_bls12_381.c bindings/generated/libconstantine_bls12_381.a -lgmp"
|
||||
exec "./build/testsuite/t_libctt_bls12_381_sl"
|
||||
else:
|
||||
exec "gcc -Ibindings/generated -o build/testsuite/t_libctt_bls12_381_sl.exe tests/bindings/t_libctt_bls12_381.c bindings/generated/constantine_bls12_381.lib -lgmp"
|
||||
exec "./build/testsuite/t_libctt_bls12_381_sl.exe"
|
||||
|
||||
task test, "Run all tests":
|
||||
# -d:testingCurves is configured in a *.nim.cfg for convenience
|
||||
var cmdFile: string
|
||||
|
|
|
@ -13,8 +13,8 @@ import
|
|||
ec_shortweierstrass,
|
||||
extension_fields,
|
||||
arithmetic,
|
||||
curves/zoo_subgroups,
|
||||
curves/zoo_generators
|
||||
constants/zoo_subgroups,
|
||||
constants/zoo_generators
|
||||
],
|
||||
./math/io/[io_bigints, io_fields],
|
||||
./math/isogenies/frobenius,
|
||||
|
|
|
@ -0,0 +1,247 @@
|
|||
// Constantine
|
||||
// Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
// Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
// Licensed and distributed under either of
|
||||
// * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
// * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
// at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
#include <assert.h>
|
||||
#include <gmp.h>
|
||||
#include <constantine_bls12_381.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
// https://gmplib.org/manual/Integer-Import-and-Export.html
|
||||
const int GMP_WordLittleEndian = -1;
|
||||
const int GMP_WordNativeEndian = 0;
|
||||
const int GMP_WordBigEndian = 1;
|
||||
|
||||
const int GMP_MostSignificantWordFirst = 1;
|
||||
const int GMP_LeastSignificantWordFirst = -1;
|
||||
|
||||
#define Curve "BLS12_381"
|
||||
#define BitLength 381
|
||||
#define ByteLength ((BitLength + 7) / 8)
|
||||
#define Modulus "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||
#define Iter 24
|
||||
|
||||
void prologue(
|
||||
gmp_randstate_t gmp_rng,
|
||||
mpz_ptr a, mpz_ptr b,
|
||||
mpz_ptr p,
|
||||
bls12381_fp* a_ctt, bls12381_fp* b_ctt,
|
||||
byte a_buf[ByteLength], byte b_buf[ByteLength]) {
|
||||
|
||||
// Generate random value in the range 0 ..< 2^(bits-1)
|
||||
mpz_urandomb(a, gmp_rng, BitLength);
|
||||
mpz_urandomb(b, gmp_rng, BitLength);
|
||||
|
||||
// Set modulus to curve modulus
|
||||
mpz_set_str(p, Modulus, 0);
|
||||
|
||||
// GMP -> Constantine
|
||||
size_t aW, bW;
|
||||
mpz_export(a_buf, &aW, GMP_MostSignificantWordFirst, 1, GMP_WordNativeEndian, 0, a);
|
||||
mpz_export(b_buf, &bW, GMP_MostSignificantWordFirst, 1, GMP_WordNativeEndian, 0, b);
|
||||
|
||||
assert(ByteLength >= aW);
|
||||
assert(ByteLength >= bW);
|
||||
|
||||
ctt_bls12381_fp_unmarshalBE(a_ctt, a_buf, aW);
|
||||
ctt_bls12381_fp_unmarshalBE(b_ctt, b_buf, bW);
|
||||
}
|
||||
|
||||
void dump_hex(byte a[ByteLength]){
|
||||
printf("0x");
|
||||
for (int i = 0; i < ByteLength; ++i){
|
||||
printf("%.02x", a[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void epilogue(
|
||||
mpz_ptr r, mpz_ptr a, mpz_ptr b,
|
||||
bls12381_fp* r_ctt, bls12381_fp* a_ctt, bls12381_fp* b_ctt,
|
||||
char* operation) {
|
||||
|
||||
byte r_raw_gmp[ByteLength];
|
||||
byte r_raw_ctt[ByteLength];
|
||||
|
||||
// GMP -> Raw
|
||||
size_t rW; // number of words written
|
||||
mpz_export(r_raw_gmp, &rW, GMP_MostSignificantWordFirst, 1, GMP_WordNativeEndian, 0, r);
|
||||
|
||||
// Constantine -> Raw
|
||||
ctt_bls12381_fp_marshalBE(r_raw_ctt, ByteLength, r_ctt);
|
||||
|
||||
// Check
|
||||
for (int g = 0, c = ByteLength-rW; g < rW; g+=1, c+=1) {
|
||||
if (r_raw_gmp[g] != r_raw_ctt[c]) {
|
||||
// reexport for debugging
|
||||
byte a_buf[ByteLength], b_buf[ByteLength];
|
||||
size_t aW, bW;
|
||||
mpz_export(a_buf, &aW, GMP_MostSignificantWordFirst, 1, GMP_WordNativeEndian, 0, a);
|
||||
mpz_export(b_buf, &bW, GMP_MostSignificantWordFirst, 1, GMP_WordNativeEndian, 0, b);
|
||||
printf("\nModular %s on curve %s with operands", operation, Curve);
|
||||
printf("\n a: "); dump_hex(a_buf);
|
||||
printf("\n b: "); dump_hex(b_buf);
|
||||
printf("\nfailed:");
|
||||
printf("\n GMP: "); dump_hex(r_raw_gmp);
|
||||
printf("\n Constantine: "); dump_hex(r_raw_ctt);
|
||||
printf("\n(Note that GMP aligns bytes left while constantine aligns bytes right)\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
printf(".");
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
// Initialize the runtime. For Constantine, it populates CPU runtime detection dispatch.
|
||||
ctt_bls12381_init_NimMain();
|
||||
|
||||
gmp_randstate_t gmpRng;
|
||||
gmp_randinit_mt(gmpRng);
|
||||
// The GMP seed varies between run so that
|
||||
// test coverage increases as the library gets tested.
|
||||
// This requires to dump the seed in the console or the function inputs
|
||||
// to be able to reproduce a bug
|
||||
int seed = 0xDEADBEEF;
|
||||
printf("GMP seed: 0x%.04x\n", seed);
|
||||
gmp_randseed_ui(gmpRng, seed);
|
||||
|
||||
mpz_t a, b, p, r;
|
||||
mpz_init(a);
|
||||
mpz_init(b);
|
||||
mpz_init(p);
|
||||
mpz_init(r);
|
||||
|
||||
bls12381_fp a_ctt, b_ctt, r_ctt;
|
||||
byte a_buf[ByteLength], b_buf[ByteLength];
|
||||
|
||||
for (int i = 0; i < Iter; ++i){
|
||||
prologue(
|
||||
gmpRng,
|
||||
a, b, p,
|
||||
&a_ctt, &b_ctt,
|
||||
a_buf, b_buf
|
||||
);
|
||||
|
||||
mpz_neg(r, a);
|
||||
mpz_mod(r, r, p);
|
||||
ctt_bls12381_fp_neg(&r_ctt, &a_ctt);
|
||||
|
||||
epilogue(
|
||||
r, a, b,
|
||||
&r_ctt, &a_ctt, &b_ctt,
|
||||
"negation"
|
||||
);
|
||||
}
|
||||
printf(" SUCCESS negation\n");
|
||||
|
||||
for (int i = 0; i < Iter; ++i){
|
||||
prologue(
|
||||
gmpRng,
|
||||
a, b, p,
|
||||
&a_ctt, &b_ctt,
|
||||
a_buf, b_buf
|
||||
);
|
||||
|
||||
mpz_add(r, a, b);
|
||||
mpz_mod(r, r, p);
|
||||
ctt_bls12381_fp_sum(&r_ctt, &a_ctt, &b_ctt);
|
||||
|
||||
epilogue(
|
||||
r, a, b,
|
||||
&r_ctt, &a_ctt, &b_ctt,
|
||||
"addition"
|
||||
);
|
||||
}
|
||||
printf(" SUCCESS addition\n");
|
||||
|
||||
for (int i = 0; i < Iter; ++i){
|
||||
prologue(
|
||||
gmpRng,
|
||||
a, b, p,
|
||||
&a_ctt, &b_ctt,
|
||||
a_buf, b_buf
|
||||
);
|
||||
|
||||
mpz_mul(r, a, b);
|
||||
mpz_mod(r, r, p);
|
||||
ctt_bls12381_fp_prod(&r_ctt, &a_ctt, &b_ctt);
|
||||
|
||||
epilogue(
|
||||
r, a, b,
|
||||
&r_ctt, &a_ctt, &b_ctt,
|
||||
"multiplication"
|
||||
);
|
||||
}
|
||||
printf(" SUCCESS multiplication\n");
|
||||
|
||||
for (int i = 0; i < Iter; ++i){
|
||||
prologue(
|
||||
gmpRng,
|
||||
a, b, p,
|
||||
&a_ctt, &b_ctt,
|
||||
a_buf, b_buf
|
||||
);
|
||||
|
||||
mpz_invert(r, a, p);
|
||||
ctt_bls12381_fp_inv(&r_ctt, &a_ctt);
|
||||
|
||||
epilogue(
|
||||
r, a, b,
|
||||
&r_ctt, &a_ctt, &b_ctt,
|
||||
"inversion"
|
||||
);
|
||||
}
|
||||
printf(" SUCCESS inversion\n");
|
||||
|
||||
for (int i = 0; i < Iter; ++i){
|
||||
prologue(
|
||||
gmpRng,
|
||||
a, b, p,
|
||||
&a_ctt, &b_ctt,
|
||||
a_buf, b_buf
|
||||
);
|
||||
|
||||
int is_square_gmp = mpz_legendre(a, p) == -1 ? 0:1;
|
||||
int is_square_ctt = ctt_bls12381_fp_is_square(&a_ctt);
|
||||
|
||||
assert(is_square_gmp == is_square_ctt);
|
||||
}
|
||||
printf(" SUCCESS Legendre symbol / is_square\n");
|
||||
|
||||
// TODO: THere are a "positive" and "negative" square roots
|
||||
// for (int i = 0; i < Iter; ++i){
|
||||
// prologue(
|
||||
// gmpRng,
|
||||
// a, b, p,
|
||||
// &a_ctt, &b_ctt,
|
||||
// a_buf, b_buf
|
||||
// );
|
||||
|
||||
// if (mpz_congruent_ui_p(p, 3, 4)) {
|
||||
// // a^((p+1)/4) (mod p)
|
||||
// mpz_add_ui(b, p, 1);
|
||||
// mpz_tdiv_q_2exp(b, b, 2);
|
||||
// mpz_powm(r, a, b, p);
|
||||
// } else {
|
||||
// assert(0);
|
||||
// }
|
||||
// ctt_bls12381_fp_prod(&r_ctt, &a_ctt, &b_ctt);
|
||||
|
||||
// epilogue(
|
||||
// r, a, b,
|
||||
// &r_ctt, &a_ctt, &b_ctt,
|
||||
// "square root"
|
||||
// );
|
||||
// }
|
||||
// printf(" SUCCESS square root\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
Loading…
Reference in New Issue