From 2aac21daeecf90aac02e4b662257d432c31b4d92 Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Thu, 11 Jan 2024 11:05:18 +0100 Subject: [PATCH] C-API missing features (#338) * c-api: add scalar mul on G1 and G2 - followup #332 * add conversion/codecs procs between bigints and field elements * update Rust bindings --- bindings/c_curve_decls.nim | 99 ++++++++++------- bindings/lib_curves.nim | 22 ++-- bindings/lib_headers.nim | 8 +- .../constantine-sys/src/bindings32.rs | 102 ++++++++++++++++++ .../constantine-sys/src/bindings64.rs | 102 ++++++++++++++++++ constantine/curves_primitives.nim | 15 ++- .../elliptic/ec_multi_scalar_mul_parallel.nim | 4 +- constantine/math/extension_fields/towers.nim | 6 +- include/constantine/curves/bigints.h | 8 ++ include/constantine/curves/bls12_381.h | 28 +++++ include/constantine/curves/bn254_snarks.h | 28 +++++ include/constantine/curves/pallas.h | 16 +++ include/constantine/curves/vesta.h | 16 +++ 13 files changed, 401 insertions(+), 53 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index 1da5b604a..45b515d9d 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -19,14 +19,39 @@ export curves, curves_primitives, extension_fields # # This files provides template for C bindings generation -template genBindingsField*(Field: untyped) = +template genBindingsBig*(Big: untyped) = when appType == "lib": {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed else: {.push noconv, exportc, raises: [].} # No exceptions allowed + func `ctt _ Big _ unmarshalBE`(dst: var Big, src: openarray[byte]): bool = + unmarshalBE(dst, src) + + func `ctt _ Big _ marshalBE`(dst: var openarray[byte], src: Big): bool = + marshalBE(dst, src) + + {.pop.} + +template genBindingsField*(Big, Field: untyped) = + when appType == "lib": + {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed + else: + {.push noconv, exportc, raises: [].} # No exceptions allowed + + func `ctt _ Big _ from _ Field`(dst: var Big, src: Field) = + fromField(dst, src) + + func `ctt _ Field _ from _ Big`(dst: var Field, src: Big) = + ## Note: conversion will not fail if the bigint is bigger than the modulus, + ## It will be reduced modulo the field modulus. + ## For protocol that want to prevent this malleability + ## use `unmarchalBE` to convert directly from bytes to field elements instead of + ## bytes -> bigint -> field element + fromBig(dst, src) + + # -------------------------------------------------------------------------------------- func `ctt _ Field _ unmarshalBE`(dst: var Field, src: openarray[byte]): bool = - ## Deserialize unmarshalBE(dst, src) func `ctt _ Field _ marshalBE`(dst: var openarray[byte], src: Field): bool = @@ -359,54 +384,50 @@ template genBindings_EC_ShortW_NonAffine*(ECP, ECP_Aff, ScalarBig, ScalarField: func `ctt _ ECP _ batch_affine`(dst: ptr UncheckedArray[ECP_Aff], src: ptr UncheckedArray[ECP], n: csize_t) = dst.batchAffine(src, cast[int](n)) - when ECP.G == G1: - # Workaround gensym issue in templates like mulCheckSparse - # for {.noInit.} temporaries and probably generic sandwich - - func `ctt _ ECP _ scalar_mul_big_coef`( - P: var ECP, scalar: ScalarBig) = + func `ctt _ ECP _ scalar_mul_big_coef`( + P: var ECP, scalar: ScalarBig) = - P.scalarMul(scalar) + P.scalarMul(scalar) - func `ctt _ ECP _ scalar_mul_fr_coef`( - P: var ECP, scalar: ScalarField) = + func `ctt _ ECP _ scalar_mul_fr_coef`( + P: var ECP, scalar: ScalarField) = - var big: ScalarBig # TODO: {.noInit.} - big.fromField(scalar) - P.scalarMul(big) + var big: ScalarBig # TODO: {.noInit.} + big.fromField(scalar) + P.scalarMul(big) - func `ctt _ ECP _ scalar_mul_big_coef_vartime`( - P: var ECP, scalar: ScalarBig) = + func `ctt _ ECP _ scalar_mul_big_coef_vartime`( + P: var ECP, scalar: ScalarBig) = - P.scalarMul_vartime(scalar) + P.scalarMul_vartime(scalar) - func `ctt _ ECP _ scalar_mul_fr_coef_vartime`( - P: var ECP, scalar: ScalarField) = + func `ctt _ ECP _ scalar_mul_fr_coef_vartime`( + P: var ECP, scalar: ScalarField) = - var big: ScalarBig # TODO: {.noInit.} - big.fromField(scalar) - P.scalarMul_vartime(big) + var big: ScalarBig # TODO: {.noInit.} + big.fromField(scalar) + P.scalarMul_vartime(big) - func `ctt _ ECP _ multi_scalar_mul_big_coefs_vartime`( - r: var ECP, - coefs: ptr UncheckedArray[ScalarBig], - points: ptr UncheckedArray[ECP_Aff], - len: csize_t) = - r.multiScalarMul_vartime(coefs, points, cast[int](len)) + func `ctt _ ECP _ multi_scalar_mul_big_coefs_vartime`( + r: var ECP, + coefs: ptr UncheckedArray[ScalarBig], + points: ptr UncheckedArray[ECP_Aff], + len: csize_t) = + r.multiScalarMul_vartime(coefs, points, cast[int](len)) - func `ctt _ ECP _ multi_scalar_mul_fr_coefs_vartime`( - r: var ECP, - coefs: ptr UncheckedArray[ScalarField], - points: ptr UncheckedArray[ECP_Aff], - len: csize_t)= + func `ctt _ ECP _ multi_scalar_mul_fr_coefs_vartime`( + r: var ECP, + coefs: ptr UncheckedArray[ScalarField], + points: ptr UncheckedArray[ECP_Aff], + len: csize_t)= - let n = cast[int](len) - let coefs_fr = allocHeapArrayAligned(ScalarBig, n, alignment = 64) + let n = cast[int](len) + let coefs_fr = allocHeapArrayAligned(ScalarBig, n, alignment = 64) - for i in 0 ..< n: - coefs_fr[i].fromField(coefs[i]) - r.multiScalarMul_vartime(coefs_fr, points, n) + for i in 0 ..< n: + coefs_fr[i].fromField(coefs[i]) + r.multiScalarMul_vartime(coefs_fr, points, n) - freeHeapAligned(coefs_fr) + freeHeapAligned(coefs_fr) {.pop.} \ No newline at end of file diff --git a/bindings/lib_curves.nim b/bindings/lib_curves.nim index b99135d23..ed2e6128c 100644 --- a/bindings/lib_curves.nim +++ b/bindings/lib_curves.nim @@ -21,6 +21,12 @@ export c_curve_decls, c_curve_decls_parallel type big254 = BigInt[254] big255 = BigInt[255] + big381 = BigInt[381] + +collectBindings(cBindings_big): + genBindingsBig(big254) + genBindingsBig(big255) + genBindingsBig(big381) # ---------------------------------------------------------- @@ -36,8 +42,8 @@ type bls12_381_g2_prj = ECP_ShortW_Prj[Fp2[BLS12_381], G2] collectBindings(cBindings_bls12_381): - genBindingsField(bls12_381_fr) - genBindingsField(bls12_381_fp) + genBindingsField(big255, bls12_381_fr) + genBindingsField(big381, bls12_381_fp) genBindingsFieldSqrt(bls12_381_fp) genBindingsExtField(bls12_381_fp2) genBindingsExtFieldSqrt(bls12_381_fp2) @@ -65,8 +71,8 @@ type bn254_snarks_g2_prj = ECP_ShortW_Prj[Fp2[BN254_Snarks], G2] collectBindings(cBindings_bn254_snarks): - genBindingsField(bn254_snarks_fr) - genBindingsField(bn254_snarks_fp) + genBindingsField(big254, bn254_snarks_fr) + genBindingsField(big254, bn254_snarks_fp) genBindingsFieldSqrt(bn254_snarks_fp) genBindingsExtField(bn254_snarks_fp2) genBindingsExtFieldSqrt(bn254_snarks_fp2) @@ -91,8 +97,8 @@ type pallas_ec_prj = ECP_ShortW_Prj[Fp[Pallas], G1] collectBindings(cBindings_pallas): - genBindingsField(pallas_fr) - genBindingsField(pallas_fp) + genBindingsField(big255, pallas_fr) + genBindingsField(big255, pallas_fp) genBindingsFieldSqrt(pallas_fp) genBindings_EC_ShortW_Affine(pallas_ec_aff, pallas_fp) genBindings_EC_ShortW_NonAffine(pallas_ec_jac, pallas_ec_aff, big255, pallas_fr) @@ -110,8 +116,8 @@ type vesta_ec_prj = ECP_ShortW_Prj[Fp[Vesta], G1] collectBindings(cBindings_vesta): - genBindingsField(vesta_fr) - genBindingsField(vesta_fp) + genBindingsField(big255, vesta_fr) + genBindingsField(big255, vesta_fp) genBindingsFieldSqrt(vesta_fp) genBindings_EC_ShortW_Affine(vesta_ec_aff, vesta_fp) genBindings_EC_ShortW_NonAffine(vesta_ec_jac, vesta_ec_aff, big255, vesta_fr) diff --git a/bindings/lib_headers.nim b/bindings/lib_headers.nim index 97edb8d46..828c73d9b 100644 --- a/bindings/lib_headers.nim +++ b/bindings/lib_headers.nim @@ -108,7 +108,7 @@ proc writeParallelHeader(dirPath: string, C: static Curve, curve_decls: string) writeFile(relPath, header) echo "Generated header: ", relPath -proc writeBigIntHeader(dirPath: string, bigSizes: IntSet) = +proc writeBigIntHeader(dirPath: string, bigSizes: IntSet, big_codecs: string) = let relPath = dirPath/"constantine"/"curves"/"bigints.h" var header = "\n" @@ -117,6 +117,9 @@ proc writeBigIntHeader(dirPath: string, bigSizes: IntSet) = header &= genBigInt(size) header &= '\n' + header &= big_codecs + header &= '\n' + header = "\n" & genCpp(header) header = genHeaderGuardAndInclude("BIGINTS", header) header = genHeaderLicense() & header @@ -151,9 +154,10 @@ proc writeCurveParallelHeaders(dir: string) = staticFor i, 0, curveMappings.len: writeParallelHeader(dir, curveMappings[i][0], curveMappings[i][1]) + bigSizes.incl(curveMappings[i][0].getCurveBitWidth()) bigSizes.incl(curveMappings[i][0].getCurveOrderBitWidth()) - dir.writeBigIntHeader(bigSizes) + dir.writeBigIntHeader(bigSizes, cBindings_big) when isMainModule: proc main() {.inline.} = diff --git a/constantine-rust/constantine-sys/src/bindings32.rs b/constantine-rust/constantine-sys/src/bindings32.rs index 3d06a5748..a72aa2fc2 100644 --- a/constantine-rust/constantine-sys/src/bindings32.rs +++ b/constantine-rust/constantine-sys/src/bindings32.rs @@ -124,6 +124,36 @@ extern "C" { } #[repr(C)] #[derive(Copy, Clone)] +pub struct big381 { + limbs: [secret_word; 12usize], +} +#[test] +fn bindgen_test_layout_big381() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(big381)) + ); + assert_eq!( + ::core::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(big381)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(big381), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] pub struct big255 { limbs: [secret_word; 8usize], } @@ -182,6 +212,30 @@ fn bindgen_test_layout_big254() { ) ); } +extern "C" { + #[must_use] + pub fn ctt_big254_unmarshalBE(dst: *mut big254, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big254_marshalBE(dst: *mut byte, dst_len: isize, src: *const big254) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big255_unmarshalBE(dst: *mut big255, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big255_marshalBE(dst: *mut byte, dst_len: isize, src: *const big255) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big381_unmarshalBE(dst: *mut big381, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big381_marshalBE(dst: *mut byte, dst_len: isize, src: *const big381) -> bool; +} #[repr(C)] #[derive(Copy, Clone)] pub struct bls12_381_fr { @@ -562,6 +616,12 @@ fn bindgen_test_layout_bls12_381_g2_prj() { ) ); } +extern "C" { + pub fn ctt_big255_from_bls12_381_fr(dst: *mut big255, src: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_from_big255(dst: *mut bls12_381_fr, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_bls12_381_fr_unmarshalBE( @@ -685,6 +745,12 @@ extern "C" { ctl: secret_bool, ); } +extern "C" { + pub fn ctt_big381_from_bls12_381_fp(dst: *mut big381, src: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_from_big381(dst: *mut bls12_381_fp, src: *const big381); +} extern "C" { #[must_use] pub fn ctt_bls12_381_fp_unmarshalBE( @@ -1850,6 +1916,12 @@ fn bindgen_test_layout_bn254_snarks_g2_prj() { ) ); } +extern "C" { + pub fn ctt_big254_from_bn254_snarks_fr(dst: *mut big254, src: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_from_big254(dst: *mut bn254_snarks_fr, src: *const big254); +} extern "C" { #[must_use] pub fn ctt_bn254_snarks_fr_unmarshalBE( @@ -1984,6 +2056,12 @@ extern "C" { ctl: secret_bool, ); } +extern "C" { + pub fn ctt_big254_from_bn254_snarks_fp(dst: *mut big254, src: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_from_big254(dst: *mut bn254_snarks_fp, src: *const big254); +} extern "C" { #[must_use] pub fn ctt_bn254_snarks_fp_unmarshalBE( @@ -3017,6 +3095,12 @@ fn bindgen_test_layout_pallas_ec_prj() { ) ); } +extern "C" { + pub fn ctt_big255_from_pallas_fr(dst: *mut big255, src: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_from_big255(dst: *mut pallas_fr, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_pallas_fr_unmarshalBE(dst: *mut pallas_fr, src: *const byte, src_len: isize) @@ -3113,6 +3197,12 @@ extern "C" { extern "C" { pub fn ctt_pallas_fr_csub_in_place(a: *mut pallas_fr, b: *const pallas_fr, ctl: secret_bool); } +extern "C" { + pub fn ctt_big255_from_pallas_fp(dst: *mut big255, src: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_from_big255(dst: *mut pallas_fp, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_pallas_fp_unmarshalBE(dst: *mut pallas_fp, src: *const byte, src_len: isize) @@ -3668,6 +3758,12 @@ fn bindgen_test_layout_vesta_ec_prj() { ) ); } +extern "C" { + pub fn ctt_big255_from_vesta_fr(dst: *mut big255, src: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_from_big255(dst: *mut vesta_fr, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_vesta_fr_unmarshalBE(dst: *mut vesta_fr, src: *const byte, src_len: isize) -> bool; @@ -3763,6 +3859,12 @@ extern "C" { extern "C" { pub fn ctt_vesta_fr_csub_in_place(a: *mut vesta_fr, b: *const vesta_fr, ctl: secret_bool); } +extern "C" { + pub fn ctt_big255_from_vesta_fp(dst: *mut big255, src: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_from_big255(dst: *mut vesta_fp, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_vesta_fp_unmarshalBE(dst: *mut vesta_fp, src: *const byte, src_len: isize) -> bool; diff --git a/constantine-rust/constantine-sys/src/bindings64.rs b/constantine-rust/constantine-sys/src/bindings64.rs index d0178da8c..13e960d8e 100644 --- a/constantine-rust/constantine-sys/src/bindings64.rs +++ b/constantine-rust/constantine-sys/src/bindings64.rs @@ -124,6 +124,36 @@ extern "C" { } #[repr(C)] #[derive(Copy, Clone)] +pub struct big381 { + limbs: [secret_word; 6usize], +} +#[test] +fn bindgen_test_layout_big381() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(big381)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(big381)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(big381), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] pub struct big255 { limbs: [secret_word; 4usize], } @@ -182,6 +212,30 @@ fn bindgen_test_layout_big254() { ) ); } +extern "C" { + #[must_use] + pub fn ctt_big254_unmarshalBE(dst: *mut big254, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big254_marshalBE(dst: *mut byte, dst_len: isize, src: *const big254) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big255_unmarshalBE(dst: *mut big255, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big255_marshalBE(dst: *mut byte, dst_len: isize, src: *const big255) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big381_unmarshalBE(dst: *mut big381, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_big381_marshalBE(dst: *mut byte, dst_len: isize, src: *const big381) -> bool; +} #[repr(C)] #[derive(Copy, Clone)] pub struct bls12_381_fr { @@ -562,6 +616,12 @@ fn bindgen_test_layout_bls12_381_g2_prj() { ) ); } +extern "C" { + pub fn ctt_big255_from_bls12_381_fr(dst: *mut big255, src: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_from_big255(dst: *mut bls12_381_fr, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_bls12_381_fr_unmarshalBE( @@ -685,6 +745,12 @@ extern "C" { ctl: secret_bool, ); } +extern "C" { + pub fn ctt_big381_from_bls12_381_fp(dst: *mut big381, src: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_from_big381(dst: *mut bls12_381_fp, src: *const big381); +} extern "C" { #[must_use] pub fn ctt_bls12_381_fp_unmarshalBE( @@ -1850,6 +1916,12 @@ fn bindgen_test_layout_bn254_snarks_g2_prj() { ) ); } +extern "C" { + pub fn ctt_big254_from_bn254_snarks_fr(dst: *mut big254, src: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_from_big254(dst: *mut bn254_snarks_fr, src: *const big254); +} extern "C" { #[must_use] pub fn ctt_bn254_snarks_fr_unmarshalBE( @@ -1984,6 +2056,12 @@ extern "C" { ctl: secret_bool, ); } +extern "C" { + pub fn ctt_big254_from_bn254_snarks_fp(dst: *mut big254, src: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_from_big254(dst: *mut bn254_snarks_fp, src: *const big254); +} extern "C" { #[must_use] pub fn ctt_bn254_snarks_fp_unmarshalBE( @@ -3017,6 +3095,12 @@ fn bindgen_test_layout_pallas_ec_prj() { ) ); } +extern "C" { + pub fn ctt_big255_from_pallas_fr(dst: *mut big255, src: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_from_big255(dst: *mut pallas_fr, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_pallas_fr_unmarshalBE(dst: *mut pallas_fr, src: *const byte, src_len: isize) @@ -3113,6 +3197,12 @@ extern "C" { extern "C" { pub fn ctt_pallas_fr_csub_in_place(a: *mut pallas_fr, b: *const pallas_fr, ctl: secret_bool); } +extern "C" { + pub fn ctt_big255_from_pallas_fp(dst: *mut big255, src: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_from_big255(dst: *mut pallas_fp, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_pallas_fp_unmarshalBE(dst: *mut pallas_fp, src: *const byte, src_len: isize) @@ -3668,6 +3758,12 @@ fn bindgen_test_layout_vesta_ec_prj() { ) ); } +extern "C" { + pub fn ctt_big255_from_vesta_fr(dst: *mut big255, src: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_from_big255(dst: *mut vesta_fr, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_vesta_fr_unmarshalBE(dst: *mut vesta_fr, src: *const byte, src_len: isize) -> bool; @@ -3763,6 +3859,12 @@ extern "C" { extern "C" { pub fn ctt_vesta_fr_csub_in_place(a: *mut vesta_fr, b: *const vesta_fr, ctl: secret_bool); } +extern "C" { + pub fn ctt_big255_from_vesta_fp(dst: *mut big255, src: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_from_big255(dst: *mut vesta_fp, src: *const big255); +} extern "C" { #[must_use] pub fn ctt_vesta_fp_unmarshalBE(dst: *mut vesta_fp, src: *const byte, src_len: isize) -> bool; diff --git a/constantine/curves_primitives.nim b/constantine/curves_primitives.nim index daad79c29..76628ce29 100644 --- a/constantine/curves_primitives.nim +++ b/constantine/curves_primitives.nim @@ -46,6 +46,19 @@ export abstractions, curves.Curve +# BigInt +# ------------------------------------------------------------ + +func unmarshalBE*(dst: var BigInt, src: openarray[byte]): bool = + ## Return true on success + ## Return false if destination is too small compared to source + return dst.unmarshal(src, bigEndian) + +func marshalBE*(dst: var openarray[byte], src: BigInt): bool = + ## Return true on success + ## Return false if destination is too small compared to source + return dst.marshal(src, bigEndian) + # Scalar field Fr and Prime Field Fp # ------------------------------------------------------------ @@ -69,7 +82,7 @@ func marshalBE*(dst: var openarray[byte], src: FF): bool = ## Return false if destination is too small compared to source var raw {.noInit.}: typeof src.mres raw.fromField(src) - return dst.marshal(src, bigEndian) + return dst.marshal(raw, bigEndian) export arithmetic.fromBig export arithmetic.fromField diff --git a/constantine/math/elliptic/ec_multi_scalar_mul_parallel.nim b/constantine/math/elliptic/ec_multi_scalar_mul_parallel.nim index 9a4894d1c..fe1c87003 100644 --- a/constantine/math/elliptic/ec_multi_scalar_mul_parallel.nim +++ b/constantine/math/elliptic/ec_multi_scalar_mul_parallel.nim @@ -143,7 +143,7 @@ proc bucketAccumReduce_zeroMem[bits: static int, EC, ECaff]( zeroMem(buckets, sizeof(EC) * numBuckets) bucketAccumReduce(windowSum[], buckets, bitIndex, miniMsmKind, c, coefs, points, N) -proc msm_vartime_parallel*[bits: static int, EC, ECaff]( +proc msm_vartime_parallel[bits: static int, EC, ECaff]( tp: Threadpool, r: ptr EC, coefs: ptr UncheckedArray[BigInt[bits]], points: ptr UncheckedArray[EC_aff], @@ -321,7 +321,7 @@ proc bucketAccumReduce_parallel[bits: static int, EC, ECaff]( # Parallel MSM Affine - window-level only # --------------------------------------- -proc msmAffine_vartime_parallel*[bits: static int, EC, ECaff]( +proc msmAffine_vartime_parallel[bits: static int, EC, ECaff]( tp: Threadpool, r: ptr EC, coefs: ptr UncheckedArray[BigInt[bits]], points: ptr UncheckedArray[ECaff], diff --git a/constantine/math/extension_fields/towers.nim b/constantine/math/extension_fields/towers.nim index 79ebe74fc..eccbff1dc 100644 --- a/constantine/math/extension_fields/towers.nim +++ b/constantine/math/extension_fields/towers.nim @@ -1439,12 +1439,14 @@ func mul_sparse_by_x0*(a: var QuadraticExt, sparseB: QuadraticExt) = ## Sparse in-place multiplication a.mul_sparse_by_x0(a, sparseB) -template mulCheckSparse*(a: var QuadraticExt, b: QuadraticExt) = +func mulCheckSparse*(a: var QuadraticExt, b: static QuadraticExt) {.inline.} = when isOne(b).bool: discard elif isMinusOne(b).bool: a.neg() elif isZero(c0(b)).bool and isOne(c1(b)).bool: + # TODO: raise upstream, in Nim v2 templates {.noInit.} temporaries use incorrect t`gensymXXXX + # hence we use an inline function with static argument var t {.noInit.}: type(a.c0) when fromComplexExtension(b): t.neg(a.c1) @@ -1455,6 +1457,8 @@ template mulCheckSparse*(a: var QuadraticExt, b: QuadraticExt) = a.c1 = a.c0 a.c0 = t elif isZero(c0(b)).bool and isMinusOne(c1(b)).bool: + # TODO: raise upstream, in Nim v2 templates {.noInit.} temporaries use incorrect t`gensymXXXX + # hence we use an inline function with static argument var t {.noInit.}: type(a.c0) when fromComplexExtension(b): t = a.c1 diff --git a/include/constantine/curves/bigints.h b/include/constantine/curves/bigints.h index 40cfefa37..cb73ec455 100644 --- a/include/constantine/curves/bigints.h +++ b/include/constantine/curves/bigints.h @@ -15,9 +15,17 @@ extern "C" { #endif +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(381)]; } big381; typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } big255; typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(254)]; } big254; +ctt_bool ctt_big254_unmarshalBE(big254* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_big254_marshalBE(byte dst[], ptrdiff_t dst_len, const big254* src) __attribute__((warn_unused_result)); +ctt_bool ctt_big255_unmarshalBE(big255* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_big255_marshalBE(byte dst[], ptrdiff_t dst_len, const big255* src) __attribute__((warn_unused_result)); +ctt_bool ctt_big381_unmarshalBE(big381* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_big381_marshalBE(byte dst[], ptrdiff_t dst_len, const big381* src) __attribute__((warn_unused_result)); + #ifdef __cplusplus } #endif diff --git a/include/constantine/curves/bls12_381.h b/include/constantine/curves/bls12_381.h index 0958b974a..7d2c6f2f0 100644 --- a/include/constantine/curves/bls12_381.h +++ b/include/constantine/curves/bls12_381.h @@ -26,6 +26,8 @@ typedef struct { bls12_381_fp2 x, y; } bls12_381_g2_aff; typedef struct { bls12_381_fp2 x, y, z; } bls12_381_g2_jac; typedef struct { bls12_381_fp2 x, y, z; } bls12_381_g2_prj; +void ctt_big255_from_bls12_381_fr(big255* dst, const bls12_381_fr* src); +void ctt_bls12_381_fr_from_big255(bls12_381_fr* dst, const big255* src); ctt_bool ctt_bls12_381_fr_unmarshalBE(bls12_381_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_bls12_381_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12_381_fr* src) __attribute__((warn_unused_result)); secret_bool ctt_bls12_381_fr_is_eq(const bls12_381_fr* a, const bls12_381_fr* b); @@ -57,6 +59,8 @@ void ctt_bls12_381_fr_cset_one(bls12_381_fr* a, secret_bool ctl); void ctt_bls12_381_fr_cneg_in_place(bls12_381_fr* a, secret_bool ctl); void ctt_bls12_381_fr_cadd_in_place(bls12_381_fr* a, const bls12_381_fr* b, secret_bool ctl); void ctt_bls12_381_fr_csub_in_place(bls12_381_fr* a, const bls12_381_fr* b, secret_bool ctl); +void ctt_big381_from_bls12_381_fp(big381* dst, const bls12_381_fp* src); +void ctt_bls12_381_fp_from_big381(bls12_381_fp* dst, const big381* src); ctt_bool ctt_bls12_381_fp_unmarshalBE(bls12_381_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_bls12_381_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12_381_fp* src) __attribute__((warn_unused_result)); secret_bool ctt_bls12_381_fp_is_eq(const bls12_381_fp* a, const bls12_381_fp* b); @@ -152,6 +156,12 @@ void ctt_bls12_381_g1_jac_double_in_place(bls12_381_g1_jac* P); void ctt_bls12_381_g1_jac_affine(bls12_381_g1_aff* dst, const bls12_381_g1_jac* src); void ctt_bls12_381_g1_jac_from_affine(bls12_381_g1_jac* dst, const bls12_381_g1_aff* src); void ctt_bls12_381_g1_jac_batch_affine(const bls12_381_g1_aff dst[], const bls12_381_g1_jac src[], size_t n); +void ctt_bls12_381_g1_jac_scalar_mul_big_coef(bls12_381_g1_jac* P, const big255* scalar); +void ctt_bls12_381_g1_jac_scalar_mul_fr_coef(bls12_381_g1_jac* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g1_jac_scalar_mul_big_coef_vartime(bls12_381_g1_jac* P, const big255* scalar); +void ctt_bls12_381_g1_jac_scalar_mul_fr_coef_vartime(bls12_381_g1_jac* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g1_jac_multi_scalar_mul_big_coefs_vartime(bls12_381_g1_jac* r, const big255 coefs[], const bls12_381_g1_aff points[], size_t len); +void ctt_bls12_381_g1_jac_multi_scalar_mul_fr_coefs_vartime(bls12_381_g1_jac* r, const bls12_381_fr coefs[], const bls12_381_g1_aff points[], size_t len); secret_bool ctt_bls12_381_g1_prj_is_eq(const bls12_381_g1_prj* P, const bls12_381_g1_prj* Q); secret_bool ctt_bls12_381_g1_prj_is_inf(const bls12_381_g1_prj* P); void ctt_bls12_381_g1_prj_set_inf(bls12_381_g1_prj* P); @@ -167,6 +177,12 @@ void ctt_bls12_381_g1_prj_double_in_place(bls12_381_g1_prj* P); void ctt_bls12_381_g1_prj_affine(bls12_381_g1_aff* dst, const bls12_381_g1_prj* src); void ctt_bls12_381_g1_prj_from_affine(bls12_381_g1_prj* dst, const bls12_381_g1_aff* src); void ctt_bls12_381_g1_prj_batch_affine(const bls12_381_g1_aff dst[], const bls12_381_g1_prj src[], size_t n); +void ctt_bls12_381_g1_prj_scalar_mul_big_coef(bls12_381_g1_prj* P, const big255* scalar); +void ctt_bls12_381_g1_prj_scalar_mul_fr_coef(bls12_381_g1_prj* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g1_prj_scalar_mul_big_coef_vartime(bls12_381_g1_prj* P, const big255* scalar); +void ctt_bls12_381_g1_prj_scalar_mul_fr_coef_vartime(bls12_381_g1_prj* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g1_prj_multi_scalar_mul_big_coefs_vartime(bls12_381_g1_prj* r, const big255 coefs[], const bls12_381_g1_aff points[], size_t len); +void ctt_bls12_381_g1_prj_multi_scalar_mul_fr_coefs_vartime(bls12_381_g1_prj* r, const bls12_381_fr coefs[], const bls12_381_g1_aff points[], size_t len); secret_bool ctt_bls12_381_g2_aff_is_eq(const bls12_381_g2_aff* P, const bls12_381_g2_aff* Q); secret_bool ctt_bls12_381_g2_aff_is_inf(const bls12_381_g2_aff* P); void ctt_bls12_381_g2_aff_set_inf(bls12_381_g2_aff* P); @@ -189,6 +205,12 @@ void ctt_bls12_381_g2_jac_double_in_place(bls12_381_g2_jac* P); void ctt_bls12_381_g2_jac_affine(bls12_381_g2_aff* dst, const bls12_381_g2_jac* src); void ctt_bls12_381_g2_jac_from_affine(bls12_381_g2_jac* dst, const bls12_381_g2_aff* src); void ctt_bls12_381_g2_jac_batch_affine(const bls12_381_g2_aff dst[], const bls12_381_g2_jac src[], size_t n); +void ctt_bls12_381_g2_jac_scalar_mul_big_coef(bls12_381_g2_jac* P, const big255* scalar); +void ctt_bls12_381_g2_jac_scalar_mul_fr_coef(bls12_381_g2_jac* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g2_jac_scalar_mul_big_coef_vartime(bls12_381_g2_jac* P, const big255* scalar); +void ctt_bls12_381_g2_jac_scalar_mul_fr_coef_vartime(bls12_381_g2_jac* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g2_jac_multi_scalar_mul_big_coefs_vartime(bls12_381_g2_jac* r, const big255 coefs[], const bls12_381_g2_aff points[], size_t len); +void ctt_bls12_381_g2_jac_multi_scalar_mul_fr_coefs_vartime(bls12_381_g2_jac* r, const bls12_381_fr coefs[], const bls12_381_g2_aff points[], size_t len); secret_bool ctt_bls12_381_g2_prj_is_eq(const bls12_381_g2_prj* P, const bls12_381_g2_prj* Q); secret_bool ctt_bls12_381_g2_prj_is_inf(const bls12_381_g2_prj* P); void ctt_bls12_381_g2_prj_set_inf(bls12_381_g2_prj* P); @@ -204,6 +226,12 @@ void ctt_bls12_381_g2_prj_double_in_place(bls12_381_g2_prj* P); void ctt_bls12_381_g2_prj_affine(bls12_381_g2_aff* dst, const bls12_381_g2_prj* src); void ctt_bls12_381_g2_prj_from_affine(bls12_381_g2_prj* dst, const bls12_381_g2_aff* src); void ctt_bls12_381_g2_prj_batch_affine(const bls12_381_g2_aff dst[], const bls12_381_g2_prj src[], size_t n); +void ctt_bls12_381_g2_prj_scalar_mul_big_coef(bls12_381_g2_prj* P, const big255* scalar); +void ctt_bls12_381_g2_prj_scalar_mul_fr_coef(bls12_381_g2_prj* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g2_prj_scalar_mul_big_coef_vartime(bls12_381_g2_prj* P, const big255* scalar); +void ctt_bls12_381_g2_prj_scalar_mul_fr_coef_vartime(bls12_381_g2_prj* P, const bls12_381_fr* scalar); +void ctt_bls12_381_g2_prj_multi_scalar_mul_big_coefs_vartime(bls12_381_g2_prj* r, const big255 coefs[], const bls12_381_g2_aff points[], size_t len); +void ctt_bls12_381_g2_prj_multi_scalar_mul_fr_coefs_vartime(bls12_381_g2_prj* r, const bls12_381_fr coefs[], const bls12_381_g2_aff points[], size_t len); #ifdef __cplusplus } diff --git a/include/constantine/curves/bn254_snarks.h b/include/constantine/curves/bn254_snarks.h index b88cdca7d..1839202c2 100644 --- a/include/constantine/curves/bn254_snarks.h +++ b/include/constantine/curves/bn254_snarks.h @@ -26,6 +26,8 @@ typedef struct { bn254_snarks_fp2 x, y; } bn254_snarks_g2_aff; typedef struct { bn254_snarks_fp2 x, y, z; } bn254_snarks_g2_jac; typedef struct { bn254_snarks_fp2 x, y, z; } bn254_snarks_g2_prj; +void ctt_big254_from_bn254_snarks_fr(big254* dst, const bn254_snarks_fr* src); +void ctt_bn254_snarks_fr_from_big254(bn254_snarks_fr* dst, const big254* src); ctt_bool ctt_bn254_snarks_fr_unmarshalBE(bn254_snarks_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_bn254_snarks_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const bn254_snarks_fr* src) __attribute__((warn_unused_result)); secret_bool ctt_bn254_snarks_fr_is_eq(const bn254_snarks_fr* a, const bn254_snarks_fr* b); @@ -57,6 +59,8 @@ void ctt_bn254_snarks_fr_cset_one(bn254_snarks_fr* a, secret_bool ctl); void ctt_bn254_snarks_fr_cneg_in_place(bn254_snarks_fr* a, secret_bool ctl); void ctt_bn254_snarks_fr_cadd_in_place(bn254_snarks_fr* a, const bn254_snarks_fr* b, secret_bool ctl); void ctt_bn254_snarks_fr_csub_in_place(bn254_snarks_fr* a, const bn254_snarks_fr* b, secret_bool ctl); +void ctt_big254_from_bn254_snarks_fp(big254* dst, const bn254_snarks_fp* src); +void ctt_bn254_snarks_fp_from_big254(bn254_snarks_fp* dst, const big254* src); ctt_bool ctt_bn254_snarks_fp_unmarshalBE(bn254_snarks_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_bn254_snarks_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const bn254_snarks_fp* src) __attribute__((warn_unused_result)); secret_bool ctt_bn254_snarks_fp_is_eq(const bn254_snarks_fp* a, const bn254_snarks_fp* b); @@ -152,6 +156,12 @@ void ctt_bn254_snarks_g1_jac_double_in_place(bn254_snarks_g1_jac* P); void ctt_bn254_snarks_g1_jac_affine(bn254_snarks_g1_aff* dst, const bn254_snarks_g1_jac* src); void ctt_bn254_snarks_g1_jac_from_affine(bn254_snarks_g1_jac* dst, const bn254_snarks_g1_aff* src); void ctt_bn254_snarks_g1_jac_batch_affine(const bn254_snarks_g1_aff dst[], const bn254_snarks_g1_jac src[], size_t n); +void ctt_bn254_snarks_g1_jac_scalar_mul_big_coef(bn254_snarks_g1_jac* P, const big254* scalar); +void ctt_bn254_snarks_g1_jac_scalar_mul_fr_coef(bn254_snarks_g1_jac* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g1_jac_scalar_mul_big_coef_vartime(bn254_snarks_g1_jac* P, const big254* scalar); +void ctt_bn254_snarks_g1_jac_scalar_mul_fr_coef_vartime(bn254_snarks_g1_jac* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g1_jac_multi_scalar_mul_big_coefs_vartime(bn254_snarks_g1_jac* r, const big254 coefs[], const bn254_snarks_g1_aff points[], size_t len); +void ctt_bn254_snarks_g1_jac_multi_scalar_mul_fr_coefs_vartime(bn254_snarks_g1_jac* r, const bn254_snarks_fr coefs[], const bn254_snarks_g1_aff points[], size_t len); secret_bool ctt_bn254_snarks_g1_prj_is_eq(const bn254_snarks_g1_prj* P, const bn254_snarks_g1_prj* Q); secret_bool ctt_bn254_snarks_g1_prj_is_inf(const bn254_snarks_g1_prj* P); void ctt_bn254_snarks_g1_prj_set_inf(bn254_snarks_g1_prj* P); @@ -167,6 +177,12 @@ void ctt_bn254_snarks_g1_prj_double_in_place(bn254_snarks_g1_prj* P); void ctt_bn254_snarks_g1_prj_affine(bn254_snarks_g1_aff* dst, const bn254_snarks_g1_prj* src); void ctt_bn254_snarks_g1_prj_from_affine(bn254_snarks_g1_prj* dst, const bn254_snarks_g1_aff* src); void ctt_bn254_snarks_g1_prj_batch_affine(const bn254_snarks_g1_aff dst[], const bn254_snarks_g1_prj src[], size_t n); +void ctt_bn254_snarks_g1_prj_scalar_mul_big_coef(bn254_snarks_g1_prj* P, const big254* scalar); +void ctt_bn254_snarks_g1_prj_scalar_mul_fr_coef(bn254_snarks_g1_prj* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g1_prj_scalar_mul_big_coef_vartime(bn254_snarks_g1_prj* P, const big254* scalar); +void ctt_bn254_snarks_g1_prj_scalar_mul_fr_coef_vartime(bn254_snarks_g1_prj* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g1_prj_multi_scalar_mul_big_coefs_vartime(bn254_snarks_g1_prj* r, const big254 coefs[], const bn254_snarks_g1_aff points[], size_t len); +void ctt_bn254_snarks_g1_prj_multi_scalar_mul_fr_coefs_vartime(bn254_snarks_g1_prj* r, const bn254_snarks_fr coefs[], const bn254_snarks_g1_aff points[], size_t len); secret_bool ctt_bn254_snarks_g2_aff_is_eq(const bn254_snarks_g2_aff* P, const bn254_snarks_g2_aff* Q); secret_bool ctt_bn254_snarks_g2_aff_is_inf(const bn254_snarks_g2_aff* P); void ctt_bn254_snarks_g2_aff_set_inf(bn254_snarks_g2_aff* P); @@ -189,6 +205,12 @@ void ctt_bn254_snarks_g2_jac_double_in_place(bn254_snarks_g2_jac* P); void ctt_bn254_snarks_g2_jac_affine(bn254_snarks_g2_aff* dst, const bn254_snarks_g2_jac* src); void ctt_bn254_snarks_g2_jac_from_affine(bn254_snarks_g2_jac* dst, const bn254_snarks_g2_aff* src); void ctt_bn254_snarks_g2_jac_batch_affine(const bn254_snarks_g2_aff dst[], const bn254_snarks_g2_jac src[], size_t n); +void ctt_bn254_snarks_g2_jac_scalar_mul_big_coef(bn254_snarks_g2_jac* P, const big254* scalar); +void ctt_bn254_snarks_g2_jac_scalar_mul_fr_coef(bn254_snarks_g2_jac* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g2_jac_scalar_mul_big_coef_vartime(bn254_snarks_g2_jac* P, const big254* scalar); +void ctt_bn254_snarks_g2_jac_scalar_mul_fr_coef_vartime(bn254_snarks_g2_jac* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g2_jac_multi_scalar_mul_big_coefs_vartime(bn254_snarks_g2_jac* r, const big254 coefs[], const bn254_snarks_g2_aff points[], size_t len); +void ctt_bn254_snarks_g2_jac_multi_scalar_mul_fr_coefs_vartime(bn254_snarks_g2_jac* r, const bn254_snarks_fr coefs[], const bn254_snarks_g2_aff points[], size_t len); secret_bool ctt_bn254_snarks_g2_prj_is_eq(const bn254_snarks_g2_prj* P, const bn254_snarks_g2_prj* Q); secret_bool ctt_bn254_snarks_g2_prj_is_inf(const bn254_snarks_g2_prj* P); void ctt_bn254_snarks_g2_prj_set_inf(bn254_snarks_g2_prj* P); @@ -204,6 +226,12 @@ void ctt_bn254_snarks_g2_prj_double_in_place(bn254_snarks_g2_prj* P); void ctt_bn254_snarks_g2_prj_affine(bn254_snarks_g2_aff* dst, const bn254_snarks_g2_prj* src); void ctt_bn254_snarks_g2_prj_from_affine(bn254_snarks_g2_prj* dst, const bn254_snarks_g2_aff* src); void ctt_bn254_snarks_g2_prj_batch_affine(const bn254_snarks_g2_aff dst[], const bn254_snarks_g2_prj src[], size_t n); +void ctt_bn254_snarks_g2_prj_scalar_mul_big_coef(bn254_snarks_g2_prj* P, const big254* scalar); +void ctt_bn254_snarks_g2_prj_scalar_mul_fr_coef(bn254_snarks_g2_prj* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g2_prj_scalar_mul_big_coef_vartime(bn254_snarks_g2_prj* P, const big254* scalar); +void ctt_bn254_snarks_g2_prj_scalar_mul_fr_coef_vartime(bn254_snarks_g2_prj* P, const bn254_snarks_fr* scalar); +void ctt_bn254_snarks_g2_prj_multi_scalar_mul_big_coefs_vartime(bn254_snarks_g2_prj* r, const big254 coefs[], const bn254_snarks_g2_aff points[], size_t len); +void ctt_bn254_snarks_g2_prj_multi_scalar_mul_fr_coefs_vartime(bn254_snarks_g2_prj* r, const bn254_snarks_fr coefs[], const bn254_snarks_g2_aff points[], size_t len); #ifdef __cplusplus } diff --git a/include/constantine/curves/pallas.h b/include/constantine/curves/pallas.h index de66a000e..a6123ac96 100644 --- a/include/constantine/curves/pallas.h +++ b/include/constantine/curves/pallas.h @@ -22,6 +22,8 @@ typedef struct { pallas_fp x, y; } pallas_ec_aff; typedef struct { pallas_fp x, y, z; } pallas_ec_jac; typedef struct { pallas_fp x, y, z; } pallas_ec_prj; +void ctt_big255_from_pallas_fr(big255* dst, const pallas_fr* src); +void ctt_pallas_fr_from_big255(pallas_fr* dst, const big255* src); ctt_bool ctt_pallas_fr_unmarshalBE(pallas_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_pallas_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fr* src) __attribute__((warn_unused_result)); secret_bool ctt_pallas_fr_is_eq(const pallas_fr* a, const pallas_fr* b); @@ -53,6 +55,8 @@ void ctt_pallas_fr_cset_one(pallas_fr* a, secret_bool ctl); void ctt_pallas_fr_cneg_in_place(pallas_fr* a, secret_bool ctl); void ctt_pallas_fr_cadd_in_place(pallas_fr* a, const pallas_fr* b, secret_bool ctl); void ctt_pallas_fr_csub_in_place(pallas_fr* a, const pallas_fr* b, secret_bool ctl); +void ctt_big255_from_pallas_fp(big255* dst, const pallas_fp* src); +void ctt_pallas_fp_from_big255(pallas_fp* dst, const big255* src); ctt_bool ctt_pallas_fp_unmarshalBE(pallas_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_pallas_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fp* src) __attribute__((warn_unused_result)); secret_bool ctt_pallas_fp_is_eq(const pallas_fp* a, const pallas_fp* b); @@ -114,6 +118,12 @@ 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); void ctt_pallas_ec_jac_batch_affine(const pallas_ec_aff dst[], const pallas_ec_jac src[], size_t n); +void ctt_pallas_ec_jac_scalar_mul_big_coef(pallas_ec_jac* P, const big255* scalar); +void ctt_pallas_ec_jac_scalar_mul_fr_coef(pallas_ec_jac* P, const pallas_fr* scalar); +void ctt_pallas_ec_jac_scalar_mul_big_coef_vartime(pallas_ec_jac* P, const big255* scalar); +void ctt_pallas_ec_jac_scalar_mul_fr_coef_vartime(pallas_ec_jac* P, const pallas_fr* scalar); +void ctt_pallas_ec_jac_multi_scalar_mul_big_coefs_vartime(pallas_ec_jac* r, const big255 coefs[], const pallas_ec_aff points[], size_t len); +void ctt_pallas_ec_jac_multi_scalar_mul_fr_coefs_vartime(pallas_ec_jac* r, const pallas_fr coefs[], const pallas_ec_aff points[], size_t len); 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); @@ -129,6 +139,12 @@ 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); void ctt_pallas_ec_prj_batch_affine(const pallas_ec_aff dst[], const pallas_ec_prj src[], size_t n); +void ctt_pallas_ec_prj_scalar_mul_big_coef(pallas_ec_prj* P, const big255* scalar); +void ctt_pallas_ec_prj_scalar_mul_fr_coef(pallas_ec_prj* P, const pallas_fr* scalar); +void ctt_pallas_ec_prj_scalar_mul_big_coef_vartime(pallas_ec_prj* P, const big255* scalar); +void ctt_pallas_ec_prj_scalar_mul_fr_coef_vartime(pallas_ec_prj* P, const pallas_fr* scalar); +void ctt_pallas_ec_prj_multi_scalar_mul_big_coefs_vartime(pallas_ec_prj* r, const big255 coefs[], const pallas_ec_aff points[], size_t len); +void ctt_pallas_ec_prj_multi_scalar_mul_fr_coefs_vartime(pallas_ec_prj* r, const pallas_fr coefs[], const pallas_ec_aff points[], size_t len); #ifdef __cplusplus } diff --git a/include/constantine/curves/vesta.h b/include/constantine/curves/vesta.h index 7a225d79f..9da114264 100644 --- a/include/constantine/curves/vesta.h +++ b/include/constantine/curves/vesta.h @@ -22,6 +22,8 @@ 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; +void ctt_big255_from_vesta_fr(big255* dst, const vesta_fr* src); +void ctt_vesta_fr_from_big255(vesta_fr* dst, const big255* src); ctt_bool ctt_vesta_fr_unmarshalBE(vesta_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_vesta_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fr* src) __attribute__((warn_unused_result)); secret_bool ctt_vesta_fr_is_eq(const vesta_fr* a, const vesta_fr* b); @@ -53,6 +55,8 @@ void ctt_vesta_fr_cset_one(vesta_fr* a, secret_bool ctl); void ctt_vesta_fr_cneg_in_place(vesta_fr* a, secret_bool ctl); void ctt_vesta_fr_cadd_in_place(vesta_fr* a, const vesta_fr* b, secret_bool ctl); void ctt_vesta_fr_csub_in_place(vesta_fr* a, const vesta_fr* b, secret_bool ctl); +void ctt_big255_from_vesta_fp(big255* dst, const vesta_fp* src); +void ctt_vesta_fp_from_big255(vesta_fp* dst, const big255* src); ctt_bool ctt_vesta_fp_unmarshalBE(vesta_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_vesta_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fp* src) __attribute__((warn_unused_result)); secret_bool ctt_vesta_fp_is_eq(const vesta_fp* a, const vesta_fp* b); @@ -114,6 +118,12 @@ 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); void ctt_vesta_ec_jac_batch_affine(const vesta_ec_aff dst[], const vesta_ec_jac src[], size_t n); +void ctt_vesta_ec_jac_scalar_mul_big_coef(vesta_ec_jac* P, const big255* scalar); +void ctt_vesta_ec_jac_scalar_mul_fr_coef(vesta_ec_jac* P, const vesta_fr* scalar); +void ctt_vesta_ec_jac_scalar_mul_big_coef_vartime(vesta_ec_jac* P, const big255* scalar); +void ctt_vesta_ec_jac_scalar_mul_fr_coef_vartime(vesta_ec_jac* P, const vesta_fr* scalar); +void ctt_vesta_ec_jac_multi_scalar_mul_big_coefs_vartime(vesta_ec_jac* r, const big255 coefs[], const vesta_ec_aff points[], size_t len); +void ctt_vesta_ec_jac_multi_scalar_mul_fr_coefs_vartime(vesta_ec_jac* r, const vesta_fr coefs[], const vesta_ec_aff points[], size_t len); 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); @@ -129,6 +139,12 @@ 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); void ctt_vesta_ec_prj_batch_affine(const vesta_ec_aff dst[], const vesta_ec_prj src[], size_t n); +void ctt_vesta_ec_prj_scalar_mul_big_coef(vesta_ec_prj* P, const big255* scalar); +void ctt_vesta_ec_prj_scalar_mul_fr_coef(vesta_ec_prj* P, const vesta_fr* scalar); +void ctt_vesta_ec_prj_scalar_mul_big_coef_vartime(vesta_ec_prj* P, const big255* scalar); +void ctt_vesta_ec_prj_scalar_mul_fr_coef_vartime(vesta_ec_prj* P, const vesta_fr* scalar); +void ctt_vesta_ec_prj_multi_scalar_mul_big_coefs_vartime(vesta_ec_prj* r, const big255 coefs[], const vesta_ec_aff points[], size_t len); +void ctt_vesta_ec_prj_multi_scalar_mul_fr_coefs_vartime(vesta_ec_prj* r, const vesta_fr coefs[], const vesta_ec_aff points[], size_t len); #ifdef __cplusplus }