From 6ba0578dfde3f95b42ee2e605afe36562e902f15 Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Fri, 19 Jul 2024 16:07:32 +0200 Subject: [PATCH] feat(public API): expose hashing to curve for BN254 and BLS12-381 --- bindings/c_curve_decls.nim | 46 +++++- bindings/lib_curves.nim | 12 ++ .../constantine-sys/src/bindings32.rs | 134 +++++++++++++++++- .../constantine-sys/src/bindings64.rs | 134 +++++++++++++++++- constantine/lowlevel_elliptic_curves.nim | 8 +- include/constantine/curves/bls12_381.h | 6 + include/constantine/curves/bn254_snarks.h | 6 + 7 files changed, 336 insertions(+), 10 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index d3fed8ac..9d2d9508 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -12,10 +12,15 @@ import lowlevel_bigints, lowlevel_fields, lowlevel_extension_fields, - lowlevel_elliptic_curves + lowlevel_elliptic_curves, + hashes ] -export algebras, lowlevel_bigints, lowlevel_fields, lowlevel_extension_fields, lowlevel_elliptic_curves +export algebras, + lowlevel_bigints, + lowlevel_fields, lowlevel_extension_fields, + lowlevel_elliptic_curves, + hashes import constantine/math/extension_fields # generic sandwich export extension_fields @@ -31,10 +36,10 @@ template genBindingsBig*(Big: untyped) = else: {.push noconv, exportc, raises: [].} # No exceptions allowed - func `ctt _ Big _ unmarshalBE`(dst: var Big, src: openarray[byte]): bool = + 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 = + func `ctt _ Big _ marshalBE`(dst: var openArray[byte], src: Big): bool = marshalBE(dst, src) {.pop.} @@ -57,10 +62,10 @@ template genBindingsField*(Big, Field: untyped) = fromBig(dst, src) # -------------------------------------------------------------------------------------- - func `ctt _ Field _ unmarshalBE`(dst: var Field, src: openarray[byte]): bool = + func `ctt _ Field _ unmarshalBE`(dst: var Field, src: openArray[byte]): bool = unmarshalBE(dst, src) - func `ctt _ Field _ marshalBE`(dst: var openarray[byte], src: Field): bool = + func `ctt _ Field _ marshalBE`(dst: var openArray[byte], src: Field): bool = marshalBE(dst, src) # -------------------------------------------------------------------------------------- func `ctt _ Field _ is_eq`(a, b: Field): SecretBool = @@ -425,3 +430,32 @@ template genBindings_EC_ShortW_NonAffine*(EC, EcAff, ScalarBig, ScalarField: unt r.multiScalarMul_vartime(coefs, points, cast[int](len)) {.pop.} + +template genBindings_EC_hash_to_curve*(EC: untyped, mapping, hash: untyped, k: static int) = + when appType == "lib": + {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed + else: + {.push noconv, exportc, raises: [].} # No exceptions allowed + + func `ctt _ EC _ mapping _ hash`( + r: var EC, + augmentation: openArray[byte], + message: openArray[byte], + domainSepTag: openArray[byte]) = + ## Hashing to Elliptic Curve for `EC` + ## with the hash function `hash` + ## using the mapping `mapping` + ## + ## The security parameter used is k = `k`-bit + when EC is EC_ShortW_Jac: + `hashToCurve _ mapping`(hash, k, r, augmentation, message, domainSepTag) + elif EC is EC_ShortW_Prj: + var jac {.noInit, inject.}: jacobian(affine(EC)) # inject to workaround jac'gensym codegen in Nim v2.0.8 (not necessary in Nim v2.2.x) - https://github.com/nim-lang/Nim/pull/23801#issue-2393452970 + `hashToCurve _ mapping`(hash, k, jac, augmentation, message, domainSepTag) + r.projectiveFromJacobian(jac) + else: + var jac {.noInit, inject.}: jacobian(EC) # inject to workaround jac'gensym codegen in Nim v2.0.8 (not necessary in Nim v2.2.x) - https://github.com/nim-lang/Nim/pull/23801#issue-2393452970 + `hashToCurve _ mapping`(hash, k, jac, augmentation, message, domainSepTag) + r.affine(jac) + + {.pop.} diff --git a/bindings/lib_curves.nim b/bindings/lib_curves.nim index 8a205099..2f988dfc 100644 --- a/bindings/lib_curves.nim +++ b/bindings/lib_curves.nim @@ -53,6 +53,12 @@ collectBindings(cBindings_bls12_381): genBindings_EC_ShortW_Affine(bls12_381_g2_aff, bls12_381_fp2) genBindings_EC_ShortW_NonAffine(bls12_381_g2_jac, bls12_381_g2_aff, big255, bls12_381_fr) genBindings_EC_ShortW_NonAffine(bls12_381_g2_prj, bls12_381_g2_aff, big255, bls12_381_fr) + genBindings_EC_hash_to_curve(bls12_381_g1_aff, sswu, sha256, k = 128) + genBindings_EC_hash_to_curve(bls12_381_g1_jac, sswu, sha256, k = 128) + genBindings_EC_hash_to_curve(bls12_381_g1_prj, sswu, sha256, k = 128) + genBindings_EC_hash_to_curve(bls12_381_g2_aff, sswu, sha256, k = 128) + genBindings_EC_hash_to_curve(bls12_381_g2_jac, sswu, sha256, k = 128) + genBindings_EC_hash_to_curve(bls12_381_g2_prj, sswu, sha256, k = 128) collectBindings(cBindings_bls12_381_parallel): genParallelBindings_EC_ShortW_NonAffine(bls12_381_g1_jac, bls12_381_g1_aff, bls12_381_fr) @@ -82,6 +88,12 @@ collectBindings(cBindings_bn254_snarks): genBindings_EC_ShortW_Affine(bn254_snarks_g2_aff, bn254_snarks_fp2) genBindings_EC_ShortW_NonAffine(bn254_snarks_g2_jac, bn254_snarks_g2_aff, big254, bn254_snarks_fr) genBindings_EC_ShortW_NonAffine(bn254_snarks_g2_prj, bn254_snarks_g2_aff, big254, bn254_snarks_fr) + genBindings_EC_hash_to_curve(bn254_snarks_g1_aff, svdw, sha256, k = 128) + genBindings_EC_hash_to_curve(bn254_snarks_g1_jac, svdw, sha256, k = 128) + genBindings_EC_hash_to_curve(bn254_snarks_g1_prj, svdw, sha256, k = 128) + genBindings_EC_hash_to_curve(bn254_snarks_g2_aff, svdw, sha256, k = 128) + genBindings_EC_hash_to_curve(bn254_snarks_g2_jac, svdw, sha256, k = 128) + genBindings_EC_hash_to_curve(bn254_snarks_g2_prj, svdw, sha256, k = 128) collectBindings(cBindings_bn254_snarks_parallel): genParallelBindings_EC_ShortW_NonAffine(bn254_snarks_g1_jac, bn254_snarks_g1_aff, bn254_snarks_fr) diff --git a/constantine-rust/constantine-sys/src/bindings32.rs b/constantine-rust/constantine-sys/src/bindings32.rs index 86d3adea..5ba7763a 100644 --- a/constantine-rust/constantine-sys/src/bindings32.rs +++ b/constantine-rust/constantine-sys/src/bindings32.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.69.4 */ +/* automatically generated by rust-bindgen 0.69.1 */ pub type secret_word = usize; pub type secret_bool = usize; @@ -1530,6 +1530,72 @@ extern "C" { len: usize, ); } +extern "C" { + pub fn ctt_bls12_381_g1_aff_sswu_sha256( + r: *mut bls12_381_g1_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g1_jac_sswu_sha256( + r: *mut bls12_381_g1_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g1_prj_sswu_sha256( + r: *mut bls12_381_g1_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g2_aff_sswu_sha256( + r: *mut bls12_381_g2_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g2_jac_sswu_sha256( + r: *mut bls12_381_g2_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g2_prj_sswu_sha256( + r: *mut bls12_381_g2_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} #[repr(C)] #[derive(Copy, Clone)] pub struct bn254_snarks_fr { @@ -2890,6 +2956,72 @@ extern "C" { len: usize, ); } +extern "C" { + pub fn ctt_bn254_snarks_g1_aff_svdw_sha256( + r: *mut bn254_snarks_g1_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g1_jac_svdw_sha256( + r: *mut bn254_snarks_g1_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g1_prj_svdw_sha256( + r: *mut bn254_snarks_g1_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g2_aff_svdw_sha256( + r: *mut bn254_snarks_g2_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g2_jac_svdw_sha256( + r: *mut bn254_snarks_g2_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g2_prj_svdw_sha256( + r: *mut bn254_snarks_g2_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} #[repr(C)] #[derive(Copy, Clone)] pub struct pallas_fr { diff --git a/constantine-rust/constantine-sys/src/bindings64.rs b/constantine-rust/constantine-sys/src/bindings64.rs index a331328b..f88f4a8a 100644 --- a/constantine-rust/constantine-sys/src/bindings64.rs +++ b/constantine-rust/constantine-sys/src/bindings64.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.69.4 */ +/* automatically generated by rust-bindgen 0.69.1 */ pub type secret_word = usize; pub type secret_bool = usize; @@ -1530,6 +1530,72 @@ extern "C" { len: usize, ); } +extern "C" { + pub fn ctt_bls12_381_g1_aff_sswu_sha256( + r: *mut bls12_381_g1_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g1_jac_sswu_sha256( + r: *mut bls12_381_g1_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g1_prj_sswu_sha256( + r: *mut bls12_381_g1_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g2_aff_sswu_sha256( + r: *mut bls12_381_g2_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g2_jac_sswu_sha256( + r: *mut bls12_381_g2_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bls12_381_g2_prj_sswu_sha256( + r: *mut bls12_381_g2_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} #[repr(C)] #[derive(Copy, Clone)] pub struct bn254_snarks_fr { @@ -2890,6 +2956,72 @@ extern "C" { len: usize, ); } +extern "C" { + pub fn ctt_bn254_snarks_g1_aff_svdw_sha256( + r: *mut bn254_snarks_g1_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g1_jac_svdw_sha256( + r: *mut bn254_snarks_g1_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g1_prj_svdw_sha256( + r: *mut bn254_snarks_g1_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g2_aff_svdw_sha256( + r: *mut bn254_snarks_g2_aff, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g2_jac_svdw_sha256( + r: *mut bn254_snarks_g2_jac, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_g2_prj_svdw_sha256( + r: *mut bn254_snarks_g2_prj, + augmentation: *const byte, + augmentation_len: usize, + message: *const byte, + message_len: usize, + domainSepTag: *const byte, + domainSepTag_len: usize, + ); +} #[repr(C)] #[derive(Copy, Clone)] pub struct pallas_fr { diff --git a/constantine/lowlevel_elliptic_curves.nim b/constantine/lowlevel_elliptic_curves.nim index fb95bf64..97250ef5 100644 --- a/constantine/lowlevel_elliptic_curves.nim +++ b/constantine/lowlevel_elliptic_curves.nim @@ -54,7 +54,9 @@ export ec_shortweierstrass.EC_ShortW_Jac, ec_shortweierstrass.EC_ShortW_Prj, ec_shortweierstrass.EC_ShortW, - ec_shortweierstrass.getName + ec_shortweierstrass.getName, + affine, jacobian, projective, + projectiveFromJacobian export ec_shortweierstrass.`==` export ec_shortweierstrass.isNeutral @@ -92,7 +94,9 @@ export zoo_subgroups.isInSubgroup # Hashing to Elliptic Curve # ------------------------------------------------------------ -export hash_to_curve.hash_to_curve +export hash_to_curve.hashToCurve +export hash_to_curve.hashToCurve_svdw +export hash_to_curve.hashToCurve_sswu # Out-of-place functions SHOULD NOT be used in performance-critical subroutines as compilers # tend to generate useless memory moves or have difficulties to minimize stack allocation diff --git a/include/constantine/curves/bls12_381.h b/include/constantine/curves/bls12_381.h index 37b4ad2d..761f4953 100644 --- a/include/constantine/curves/bls12_381.h +++ b/include/constantine/curves/bls12_381.h @@ -232,6 +232,12 @@ void ctt_bls12_381_g2_prj_scalar_mul_big_coef_vartime(bls12_381_g2_prj* P 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); +void ctt_bls12_381_g1_aff_sswu_sha256(bls12_381_g1_aff* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bls12_381_g1_jac_sswu_sha256(bls12_381_g1_jac* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bls12_381_g1_prj_sswu_sha256(bls12_381_g1_prj* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bls12_381_g2_aff_sswu_sha256(bls12_381_g2_aff* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bls12_381_g2_jac_sswu_sha256(bls12_381_g2_jac* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bls12_381_g2_prj_sswu_sha256(bls12_381_g2_prj* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); #ifdef __cplusplus } diff --git a/include/constantine/curves/bn254_snarks.h b/include/constantine/curves/bn254_snarks.h index 1d6a3e68..34661be8 100644 --- a/include/constantine/curves/bn254_snarks.h +++ b/include/constantine/curves/bn254_snarks.h @@ -232,6 +232,12 @@ void ctt_bn254_snarks_g2_prj_scalar_mul_big_coef_vartime(bn254_snarks_g2_ 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); +void ctt_bn254_snarks_g1_aff_svdw_sha256(bn254_snarks_g1_aff* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bn254_snarks_g1_jac_svdw_sha256(bn254_snarks_g1_jac* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bn254_snarks_g1_prj_svdw_sha256(bn254_snarks_g1_prj* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bn254_snarks_g2_aff_svdw_sha256(bn254_snarks_g2_aff* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bn254_snarks_g2_jac_svdw_sha256(bn254_snarks_g2_jac* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); +void ctt_bn254_snarks_g2_prj_svdw_sha256(bn254_snarks_g2_prj* r, const byte augmentation[], size_t augmentation_len, const byte message[], size_t message_len, const byte domainSepTag[], size_t domainSepTag_len); #ifdef __cplusplus }