From ebd2d935065450742eb3292a1c6f805449bda18b Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sun, 6 Oct 2024 22:01:17 +0530 Subject: [PATCH 01/21] c bindings for verkle --- constantine/commitments/eth_verkle_ipa.nim | 12 +- constantine/ethereum_verkle_ipa.nim | 16 +- .../protocols/ethereum_verkle_ipa.h | 228 ++++++++++++++++++ 3 files changed, 245 insertions(+), 11 deletions(-) create mode 100644 include/constantine/protocols/ethereum_verkle_ipa.h diff --git a/constantine/commitments/eth_verkle_ipa.nim b/constantine/commitments/eth_verkle_ipa.nim index 252f0bae..e244d00a 100644 --- a/constantine/commitments/eth_verkle_ipa.nim +++ b/constantine/commitments/eth_verkle_ipa.nim @@ -17,6 +17,10 @@ import constantine/math/io/io_fields, constantine/platforms/[abstractions, views] +import constantine/zoo_exports + +const prefix_ipa = "ctt_eth_verkle_" + ## ############################################################ ## ## Inner Product Arguments @@ -139,7 +143,7 @@ func innerProduct[F](r: var F, a, b: distinct(View[F] or MutableView[F])) = func ipa_commit*[N: static int, EC, F]( crs: PolynomialEval[N, EC], r: var EC, - poly: PolynomialEval[N, F]) = + poly: PolynomialEval[N, F]) {.libPrefix: prefix_ipa.} = crs.pedersen_commit(r, poly) func ipa_prove*[N, logN: static int, EcAff, F]( @@ -330,7 +334,7 @@ func ipa_verify*[N, logN: static int, EcAff, F]( commitment: EcAff, opening_challenge: F, eval_at_challenge: F, - proof: IpaProof[logN, EcAff, F]): bool = + proof: IpaProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = # We want to check ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # with @@ -661,7 +665,7 @@ func ipa_multi_prove*[N, logN: static int, EcAff, F]( proof: var IpaMultiProof[logN, EcAff, F], polys: openArray[PolynomialEval[N, F]], commitments: openArray[EcAff], - opening_challenges_in_domain: openArray[SomeUnsignedInt]) = + opening_challenges_in_domain: openArray[SomeUnsignedInt]) {.libPrefix: prefix_ipa.} = ## Create a combined proof that ## allow verifying the list of triplets ## (polynomial, commitment, opening challenge) @@ -838,7 +842,7 @@ func ipa_multi_verify*[N, logN: static int, EcAff, F]( commitments: openArray[EcAff], opening_challenges_in_domain: openArray[SomeUnsignedInt], evals_at_challenges: openArray[F], - proof: IpaMultiProof[logN, EcAff, F]): bool = + proof: IpaMultiProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = ## Batch verification of commitments to multiple polynomials ## using a single multiproof ## diff --git a/constantine/ethereum_verkle_ipa.nim b/constantine/ethereum_verkle_ipa.nim index f5b9afb6..a346035a 100644 --- a/constantine/ethereum_verkle_ipa.nim +++ b/constantine/ethereum_verkle_ipa.nim @@ -20,6 +20,8 @@ import ./serialization/endians, ./math/io/[io_bigints, io_fields] +import ./zoo_exports + const EthVerkleSeed* = "eth_verkle_oct_2021" func generate_random_points*(r: var openArray[EC_TwEdw_Aff[Fp[Banderwagon]]]) = @@ -149,7 +151,7 @@ type func serialize*(dst: var EthVerkleIpaProofBytes, src: IpaProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.discardable.} = + ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = # Note: We store 1 out of 2 coordinates of an EC point, so size(Fp[Banderwagon]) const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -168,7 +170,7 @@ func serialize*(dst: var EthVerkleIpaProofBytes, return cttEthVerkleIpa_Success func deserialize*(dst: var EthVerkleIpaProof, - src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus = + src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -188,7 +190,7 @@ func deserialize*(dst: var EthVerkleIpaProof, func serialize*(dst: var EthVerkleIpaMultiProofBytes, src: IpaMultiProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.discardable.} = + ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](dst.addr) @@ -200,7 +202,7 @@ func serialize*(dst: var EthVerkleIpaMultiProofBytes, func deserialize*(dst: var EthVerkleIpaMultiProof, src: EthVerkleIpaMultiProofBytes - ): cttEthVerkleIpaStatus = + ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa.} = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](src.unsafeAddr) @@ -215,7 +217,7 @@ func deserialize*(dst: var EthVerkleIpaMultiProof, # TODO: refactor, this shouldn't use curves_primitives but internal functions import ./lowlevel_fields -func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) = +func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = ## The mapping chosen for the Banderwagon Curve is x/y ## ## This function takes a Banderwagon element & then @@ -227,7 +229,7 @@ func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) = invY.inv(p.y) # invY = 1/Y dst.prod(p.x, invY) # dst = (X) * (1/Y) -func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.discardable.} = +func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = ## This function takes the x/y value from the above function as Fp element ## and convert that to bytes in Big Endian, ## and then load that to a Fr element @@ -246,7 +248,7 @@ func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): func batchMapToScalarField*( res: var openArray[Fr[Banderwagon]], - points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.discardable, noinline.} = + points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.libPrefix: prefix_ipa, discardable, noinline.} = ## This function performs the `mapToScalarField` operation ## on a batch of points ## diff --git a/include/constantine/protocols/ethereum_verkle_ipa.h b/include/constantine/protocols/ethereum_verkle_ipa.h new file mode 100644 index 00000000..21edd503 --- /dev/null +++ b/include/constantine/protocols/ethereum_verkle_ipa.h @@ -0,0 +1,228 @@ +/** 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. + */ +#ifndef __CTT_H_ETHEREUM_VERKLE_IPA__ +#define __CTT_H_ETHEREUM_VERKLE_IPA__ + +#include "constantine/core/datatypes.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum __attribute__((__packed__)) { + cttEthVerkleIpa_Success, + cttEthVerkleIpa_VerificationFailure, + cttEthVerkleIpa_InputsLengthsMismatch, + cttEthVerkleIpa_ScalarZero, + cttEthVerkleIpa_ScalarLargerThanCurveOrder, + cttEthVerkleIpa_EccInvalidEncoding, + cttEthVerkleIpa_EccCoordinateGreaterThanOrEqualModulus, + cttEthVerkleIpa_EccPointNotOnCurve, + cttEthVerkleIpa_EccPointNotInSubGroup +} ctt_eth_verkle_ipa_status; + +static const char* ctt_eth_verkle_ipa_status_to_string(ctt_eth_verkle_ipa_status status) { + static const char* const statuses[] = { + "cttEthVerkleIpa_Success", + "cttEthVerkleIpa_VerificationFailure", + "cttEthVerkleIpa_InputsLengthsMismatch", + "cttEthVerkleIpa_ScalarZero", + "cttEthVerkleIpa_ScalarLargerThanCurveOrder", + "cttEthVerkleIpa_EccInvalidEncoding", + "cttEthVerkleIpa_EccCoordinateGreaterThanOrEqualModulus", + "cttEthVerkleIpa_EccPointNotOnCurve", + "cttEthVerkleIpa_EccPointNotInSubGroup" + }; + size_t length = sizeof statuses / sizeof *statuses; + if (0 <= status && status < length) { + return statuses[status]; + } + return "cttEthVerkleIpa_InvalidStatusCode"; +} + +// Opaque types for Nim-defined types +typedef struct Fr Fr; +typedef struct Banderwagon Banderwagon; +typedef struct EC_TwEdw EC_TwEdw; +typedef struct Fp Fp; + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + unsigned int u; +} SomeUnsignedInt; + +typedef struct { + SomeUnsignedInt* values; + size_t length; +} SomeUnsignedInt_Array; + +// Define types for openArray +typedef struct { + Fr* data; + size_t len; +} Fr_BanderWagon_OpenArray; + +typedef struct { + EC_TwEdw* data; + size_t len; +} EC_TwEdw_Fp_Banderwagon_OpenArray; + +typedef struct { + byte value[32]; // 32-byte array for field element +} Fp_Banderwagon; + +typedef struct { + byte value[32]; // 32-byte array for field element +} Fr_Banderwagon; + +typedef struct { + byte x[32]; // 32-byte x-coordinate + byte y[32]; // 32-byte y-coordinate +} EC_TwEdw_Fp_Banderwagon; + +typedef struct { + byte x[32]; // 32-byte x-coordinate + byte y[32]; // 32-byte y-coordinate +} EC; + +typedef struct { + EC* points; + size_t length; +} PolynomialEval_EC; + +typedef struct { + Fr* points; + size_t length; +} PolynomialEval_Fr; + +typedef struct { + EC* points; + size_t length; +} PolynomialEval_EcAff; + +typedef struct { + Fr* domain_values; + size_t length; +} PolyEvalLinearDomain_Fr; + +typedef struct { + EC* ec_points; + Fr* field_elements; + size_t logN; +} IpaProof_EcAff_Fr; + +typedef struct { + EC* ec_points; + Fr* field_elements; + size_t logN; +} IpaMultiProof_EcAff_Fr; + +typedef struct { + EC* ec_points; + size_t length; +} EcAffArray; + +typedef struct EthVerkleIpaProof EthVerkleIpaProof; +typedef struct EthVerkleIpaMultiProof EthVerkleIpaMultiProof; +typedef struct IpaProof IpaProof; +typedef struct IpaMultiProof IpaMultiProof; +typedef struct EthVerkleTranscript EthVerkleTranscript; + +typedef byte EthVerkleIpaProofBytes[544]; // Array of 544 bytes +typedef byte EthVerkleIpaMultiProofBytes[576]; + + +ctt_eth_verkle_ipa_status ctt_eth_verkle_serialize( + EthVerkleIpaProofBytes* dst, + const IpaProof* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_serialize( + EthVerkleIpaMultiProofBytes* dst, + const IpaMultiProof* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( + const EthVerkleIpaProof* dst, + EthVerkleIpaProofBytes* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( + const EthVerkleIpaMultiProof* dst, + EthVerkleIpaMultiProofBytes* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToBaseField( + Fp_Banderwagon* dst, const EC_TwEdw_Fp_Banderwagon* p + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToScalarField( + Fr_Banderwagon* res, const EC_TwEdw_Fp_Banderwagon* p + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_batchMapToScalarField( + Fr_BanderWagon_OpenArray* res, const EC_TwEdw_Fp_Banderwagon_OpenArray* p + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_commit( + const PolynomialEval_EC* crs, + EC* r, + const PolynomialEval_Fr* poly + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_prove( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + Fr* eval_at_challenge, + IpaProof_EcAff_Fr* proof, + const PolynomialEval_Fr* poly, + const EC* commitment, + const Fr* opening_challenge + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_verify( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + const EC* commitment, + const Fr* opening_challenge, + Fr* eval_at_challenge, + IpaProof_EcAff_Fr* proof + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_prove( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + IpaMultiProof_EcAff_Fr* proof, + const PolynomialEval_Fr* polys, + const EC_TwEdw_Fp_Banderwagon_OpenArray* commitments, + const Fr_BanderWagon_OpenArray* opening_challenges_in_domain + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_verify( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + const EC_TwEdw_Fp_Banderwagon_OpenArray* commitments, + const Fr_BanderWagon_OpenArray* opening_challenges_in_domain, + Fr_BanderWagon_OpenArray* evals_at_challenges, + IpaMultiProof_EcAff_Fr* proof + ) __attribute__((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif // __CTT_H_ETHEREUM_EVM_PRECOMPILES__ From d2aac2419f8faae6ce3713db6e2acf9519fc9806 Mon Sep 17 00:00:00 2001 From: iri <76250660+Richa-iitr@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:01:09 +0530 Subject: [PATCH 02/21] comments correction Co-authored-by: Mamy Ratsimbazafy --- include/constantine/protocols/ethereum_verkle_ipa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/constantine/protocols/ethereum_verkle_ipa.h b/include/constantine/protocols/ethereum_verkle_ipa.h index 21edd503..d88f71aa 100644 --- a/include/constantine/protocols/ethereum_verkle_ipa.h +++ b/include/constantine/protocols/ethereum_verkle_ipa.h @@ -225,4 +225,4 @@ ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_verify( } #endif -#endif // __CTT_H_ETHEREUM_EVM_PRECOMPILES__ +#endif // __CTT_H_ETHEREUM_VERKLE_IPA__ From 664de5069802efc4fcc6bcb26be34c4b6d125923 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Mon, 7 Oct 2024 22:43:59 +0530 Subject: [PATCH 03/21] refactoring: --- constantine/ethereum_verkle_ipa.nim | 6 +++--- include/constantine/protocols/ethereum_verkle_ipa.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/constantine/ethereum_verkle_ipa.nim b/constantine/ethereum_verkle_ipa.nim index a346035a..686b1be5 100644 --- a/constantine/ethereum_verkle_ipa.nim +++ b/constantine/ethereum_verkle_ipa.nim @@ -217,7 +217,7 @@ func deserialize*(dst: var EthVerkleIpaMultiProof, # TODO: refactor, this shouldn't use curves_primitives but internal functions import ./lowlevel_fields -func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = +func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = ## The mapping chosen for the Banderwagon Curve is x/y ## ## This function takes a Banderwagon element & then @@ -229,7 +229,7 @@ func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.li invY.inv(p.y) # invY = 1/Y dst.prod(p.x, invY) # dst = (X) * (1/Y) -func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = +func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = ## This function takes the x/y value from the above function as Fp element ## and convert that to bytes in Big Endian, ## and then load that to a Fr element @@ -246,7 +246,7 @@ func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): return check1 and check2 -func batchMapToScalarField*( +func batch_map_to_scalar_field*( res: var openArray[Fr[Banderwagon]], points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.libPrefix: prefix_ipa, discardable, noinline.} = ## This function performs the `mapToScalarField` operation diff --git a/include/constantine/protocols/ethereum_verkle_ipa.h b/include/constantine/protocols/ethereum_verkle_ipa.h index d88f71aa..23a498ce 100644 --- a/include/constantine/protocols/ethereum_verkle_ipa.h +++ b/include/constantine/protocols/ethereum_verkle_ipa.h @@ -162,15 +162,15 @@ ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( EthVerkleIpaMultiProofBytes* src ) __attribute__((warn_unused_result)); -ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToBaseField( +ctt_eth_verkle_ipa_status ctt_eth_verkle_map_to_base_field( Fp_Banderwagon* dst, const EC_TwEdw_Fp_Banderwagon* p ) __attribute__((warn_unused_result)); -ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToScalarField( +ctt_eth_verkle_ipa_status ctt_eth_verkle_map_to_scalar_field( Fr_Banderwagon* res, const EC_TwEdw_Fp_Banderwagon* p ) __attribute__((warn_unused_result)); -ctt_eth_verkle_ipa_status ctt_eth_verkle_batchMapToScalarField( +ctt_eth_verkle_ipa_status ctt_eth_verkle_batch_map_to_base_field( Fr_BanderWagon_OpenArray* res, const EC_TwEdw_Fp_Banderwagon_OpenArray* p ) __attribute__((warn_unused_result)); From 42094111441b55a6eed853913b0ca03b4e5d77e2 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Mon, 14 Oct 2024 23:14:32 +0530 Subject: [PATCH 04/21] curve decl for ed --- bindings/c_curve_decls.nim | 87 ++++++++++++++++++++++++ constantine/lowlevel_elliptic_curves.nim | 38 +++++++++++ 2 files changed, 125 insertions(+) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index 9d2d9508..b30928d2 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -431,6 +431,93 @@ template genBindings_EC_ShortW_NonAffine*(EC, EcAff, ScalarBig, ScalarField: unt {.pop.} +template genBindings_EC_TwistedEd_Affine*(EC, Field: untyped) = + when appType == "lib": + {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed + else: + {.push noconv, exportc, raises: [].} # No exceptions allowed + + # -------------------------------------------------------------------------------------- + func `ctt _ EC _ is_eq`(P, Q: EC): SecretBool = + P == Q + + func `ctt _ EC _ is_neutral`(P: EC): SecretBool = + P.isNeutral() + + func `ctt _ EC _ set_neutral`(P: var EC) = + P.setNeutral() + + func `ctt _ EC _ ccopy`(P: var EC, Q: EC, ctl: SecretBool) = + P.ccopy(Q, ctl) + + func `ctt _ EC _ is_on_curve`(x, y: Field): SecretBool = + isOnCurve(x, y) + + func `ctt _ EC _ neg`(P: var EC, Q: EC) = + P.neg(Q) + + func `ctt _ EC _ neg_in_place`(P: var EC) = + P.neg() + + func `ctt _ EC _ cneg`(P: var EC, ctl: SecretBool) = + P.cneg(ctl) + + {.pop.} + +template genBindings_EC_TwistedEd_Projective*(EC, EcAff, Field: untyped) = + when appType == "lib": + {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed + else: + {.push noconv, exportc, raises: [].} # No exceptions allowed + + # -------------------------------------------------------------------------------------- + func `ctt _ EC _ is_eq`(P, Q: EC): SecretBool = + P == Q + + func `ctt _ EC _ is_neutral`(P: EC): SecretBool = + P.isNeutral() + + func `ctt _ EC _ set_neutral`(P: var EC) = + P.setNeutral() + + func `ctt _ EC _ ccopy`(P: var EC, Q: EC, ctl: SecretBool) = + P.ccopy(Q, ctl) + + func `ctt _ EC _ neg`(P: var EC, Q: EC) = + P.neg(Q) + + func `ctt _ EC _ neg_in_place`(P: var EC) = + P.neg() + + func `ctt _ EC _ cneg`(P: var EC, ctl: SecretBool) = + P.cneg(ctl) + + func `ctt _ EC _ sum`(r: var EC, P, Q: EC) = + r.sum(P, Q) + + func `ctt _ EC _ double`(r: var EC, P: EC) = + r.double(P) + + func `ctt _ EC _ add_in_place`(P: var EC, Q: EC) = + P += Q + + func `ctt _ EC _ diff`(r: var EC, P, Q: EC) = + r.diff(P,Q) + + func `ctt _ EC _ diff_in_place`(P: var EC, Q: EC) = + P -= Q + + func `ctt _ EC _ mixed_diff_in_place`(P: var EC, Q: EcAff) = + P -= Q + + func `ctt _ EC _ affine`(dst: var EcAff, src: EC) = + dst.affine(src) + + func `ctt _ EC _ from_affine`(dst: var EC, src: EcAff) = + dst.fromAffine(src) + + {.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 diff --git a/constantine/lowlevel_elliptic_curves.nim b/constantine/lowlevel_elliptic_curves.nim index 97250ef5..c5119168 100644 --- a/constantine/lowlevel_elliptic_curves.nim +++ b/constantine/lowlevel_elliptic_curves.nim @@ -11,6 +11,7 @@ import ./named/algebras, ./named/[zoo_subgroups, zoo_generators], ./math/ec_shortweierstrass, + ./math/ec_twistededwards, ./math/elliptic/[ ec_scalar_mul_vartime, ec_multi_scalar_mul], @@ -58,6 +59,13 @@ export affine, jacobian, projective, projectiveFromJacobian +export + ec_twistededwards.EC_TwEdw_Aff, + ec_twistededwards.EC_TwEdw_Prj, + ec_twistededwards.EC_TwEdw, + ec_twistededwards.getName, + affine, projective + export ec_shortweierstrass.`==` export ec_shortweierstrass.isNeutral export ec_shortweierstrass.setNeutral @@ -87,6 +95,36 @@ export ec_shortweierstrass.scalarMul export ec_scalar_mul_vartime.scalarMul_vartime export ec_multi_scalar_mul.multiScalarMul_vartime +# Twisted edwards curve +export ec_twistededwards.`==` +export ec_twistededwards.isNeutral +export ec_twistededwards.setNeutral +export ec_twistededwards.ccopy +export ec_twistededwards.isOnCurve +export ec_twistededwards.neg +export ec_twistededwards.cneg + +export ec_twistededwards.sum +export ec_twistededwards.mixedSum +export ec_twistededwards.double +export ec_twistededwards.`+=` +export ec_twistededwards.diff +export ec_twistededwards.mixedDiff +export ec_twistededwards.`-=` +export ec_twistededwards.affine +export ec_twistededwards.projective +export ec_twistededwards.fromAffine +export ec_twistededwards.sum_vartime +export ec_twistededwards.mixedSum_vartime +export ec_twistededwards.diff_vartime +export ec_twistededwards.mixedDiff_vartime +export ec_twistededwards.`~+=` +export ec_twistededwards.`~-=` +export ec_twistededwards.`+` +export ec_twistededwards.`~+` +export ec_twistededwards.`-` +export ec_twistededwards.`~-` + export zoo_generators.getGenerator export zoo_subgroups.clearCofactor export zoo_subgroups.isInSubgroup From 42624ffc7c7def9c59e0eae80c1fd8397e5e3e4d Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Tue, 15 Oct 2024 22:33:21 +0530 Subject: [PATCH 05/21] gen bindings for twedw --- bindings/c_curve_decls.nim | 4 ++-- bindings/lib_curves.nim | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index b30928d2..70bbfc48 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -431,7 +431,7 @@ template genBindings_EC_ShortW_NonAffine*(EC, EcAff, ScalarBig, ScalarField: unt {.pop.} -template genBindings_EC_TwistedEd_Affine*(EC, Field: untyped) = +template genBindings_EC_TwEdw_Affine*(EC, Field: untyped) = when appType == "lib": {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed else: @@ -464,7 +464,7 @@ template genBindings_EC_TwistedEd_Affine*(EC, Field: untyped) = {.pop.} -template genBindings_EC_TwistedEd_Projective*(EC, EcAff, Field: untyped) = +template genBindings_EC_TwEdw_Projective*(EC, EcAff, Field: untyped) = when appType == "lib": {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed else: diff --git a/bindings/lib_curves.nim b/bindings/lib_curves.nim index 2f988dfc..9f4e3a39 100644 --- a/bindings/lib_curves.nim +++ b/bindings/lib_curves.nim @@ -20,11 +20,13 @@ export c_curve_decls, c_curve_decls_parallel type big254 = BigInt[254] + big253 = BigInt[253] big255 = BigInt[255] big381 = BigInt[381] collectBindings(cBindings_big): genBindingsBig(big254) + genBindingsBig(big253) genBindingsBig(big255) genBindingsBig(big381) @@ -140,3 +142,16 @@ collectBindings(cBindings_vesta_parallel): genParallelBindings_EC_ShortW_NonAffine(vesta_ec_prj, vesta_ec_aff, vesta_fr) # ---------------------------------------------------------- + +type + banderwagon_fr = Fr[Banderwagon] + banderwagon_fp = Fp[Banderwagon] + banderwagon_twedw_aff = EC_TwEdw_Aff[Fp[Banderwagon]] + banderwagon_twedw_prj = EC_TwEdw_Prj[Fp[Banderwagon]] + +collectBindings(cBindings_banderwagon): + genBindingsField(big253, banderwagon_fr) + genBindingsField(big255, banderwagon_fp) + genBindingsFieldSqrt(banderwagon_fp) + genBindings_EC_TwEdw_Affine(banderwagon_twedw_aff, banderwagon_fp) + genBindings_EC_TwEdw_Projective(banderwagon_twedw_prj, banderwagon_twedw_aff, banderwagon_fr) \ No newline at end of file From ed100a6a0f669ccde43b6105e6780f7f3b6bb0f6 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Wed, 16 Oct 2024 23:11:40 +0530 Subject: [PATCH 06/21] bigint bandderwagon types --- include/constantine/curves/bigints.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/constantine/curves/bigints.h b/include/constantine/curves/bigints.h index e7c441fc..1ed744d6 100644 --- a/include/constantine/curves/bigints.h +++ b/include/constantine/curves/bigints.h @@ -18,6 +18,7 @@ extern "C" { 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; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(253)]; } big253; ctt_bool ctt_big254_unmarshalBE(big254* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_big254_marshalBE(byte dst[], size_t dst_len, const big254* src) __attribute__((warn_unused_result)); @@ -25,6 +26,8 @@ ctt_bool ctt_big255_unmarshalBE(big255* dst, const byte src[], size_t src_len ctt_bool ctt_big255_marshalBE(byte dst[], size_t dst_len, const big255* src) __attribute__((warn_unused_result)); ctt_bool ctt_big381_unmarshalBE(big381* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_big381_marshalBE(byte dst[], size_t dst_len, const big381* src) __attribute__((warn_unused_result)); +ctt_bool ctt_big253_unmarshalBE(big253* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_big253_marshalBE(byte dst[], size_t dst_len, const big253* src) __attribute__((warn_unused_result)); #ifdef __cplusplus } From 51d5372fd11e592b94b6ca2e111faeda4b1f6bb4 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sun, 20 Oct 2024 14:41:19 +0530 Subject: [PATCH 07/21] banderwagon header --- include/constantine/curves/banderwagon.h | 126 +++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 include/constantine/curves/banderwagon.h diff --git a/include/constantine/curves/banderwagon.h b/include/constantine/curves/banderwagon.h new file mode 100644 index 00000000..a6ccd9b6 --- /dev/null +++ b/include/constantine/curves/banderwagon.h @@ -0,0 +1,126 @@ +/** 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. + */ +#ifndef __CTT_H_BANDERWAGON__ +#define __CTT_H_BANDERWAGON__ + +#include "constantine/core/datatypes.h" +#include "constantine/curves/bigints.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(253)]; } banderwagon_fr; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } banderwagon_fp; +typedef struct { banderwagon_fp x, y; } banderwagon_ec_aff; +typedef struct { banderwagon_fp x, y, z; } banderwagon_ec_prj; + +void ctt_big253_from_banderwagon_fr(big253* dst, const banderwagon_fr* src); +void ctt_banderwagon_fr_from_big253(banderwagon_fr* dst, const big253* src); +ctt_bool ctt_banderwagon_fr_unmarshalBE(banderwagon_fr* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_banderwagon_fr_marshalBE(byte dst[], size_t dst_len, const banderwagon_fr* src) __attribute__((warn_unused_result)); +secret_bool ctt_banderwagon_fr_is_eq(const banderwagon_fr* a, const banderwagon_fr* b); +secret_bool ctt_banderwagon_fr_is_zero(const banderwagon_fr* a); +secret_bool ctt_banderwagon_fr_is_one(const banderwagon_fr* a); +secret_bool ctt_banderwagon_fr_is_minus_one(const banderwagon_fr* a); +void ctt_banderwagon_fr_set_zero(banderwagon_fr* a); +void ctt_banderwagon_fr_set_one(banderwagon_fr* a); +void ctt_banderwagon_fr_set_minus_one(banderwagon_fr* a); +void ctt_banderwagon_fr_neg(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_neg_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_sum(banderwagon_fr* r, const banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_add_in_place(banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_diff(banderwagon_fr* r, const banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_sub_in_place(banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_double(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_double_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_prod(banderwagon_fr* r, const banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_mul_in_place(banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_square(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_square_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_div2(banderwagon_fr* a); +void ctt_banderwagon_fr_inv(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_inv_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_ccopy(banderwagon_fr* a, const banderwagon_fr* b, secret_bool ctl); +void ctt_banderwagon_fr_cswap(banderwagon_fr* a, banderwagon_fr* b, secret_bool ctl); +void ctt_banderwagon_fr_cset_zero(banderwagon_fr* a, secret_bool ctl); +void ctt_banderwagon_fr_cset_one(banderwagon_fr* a, secret_bool ctl); +void ctt_banderwagon_fr_cneg_in_place(banderwagon_fr* a, secret_bool ctl); +void ctt_banderwagon_fr_cadd_in_place(banderwagon_fr* a, const banderwagon_fr* b, secret_bool ctl); +void ctt_banderwagon_fr_csub_in_place(banderwagon_fr* a, const banderwagon_fr* b, secret_bool ctl); +void ctt_big253_from_banderwagon_fp(big253* dst, const banderwagon_fp* src); +void ctt_banderwagon_fp_from_big253(banderwagon_fp* dst, const big253* src); +ctt_bool ctt_banderwagon_fp_unmarshalBE(banderwagon_fp* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_banderwagon_fp_marshalBE(byte dst[], size_t dst_len, const banderwagon_fp* src) __attribute__((warn_unused_result)); +secret_bool ctt_banderwagon_fp_is_eq(const banderwagon_fp* a, const banderwagon_fp* b); +secret_bool ctt_banderwagon_fp_is_zero(const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_is_one(const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_is_minus_one(const banderwagon_fp* a); +void ctt_banderwagon_fp_set_zero(banderwagon_fp* a); +void ctt_banderwagon_fp_set_one(banderwagon_fp* a); +void ctt_banderwagon_fp_set_minus_one(banderwagon_fp* a); +void ctt_banderwagon_fp_neg(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_neg_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_sum(banderwagon_fp* r, const banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_add_in_place(banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_diff(banderwagon_fp* r, const banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_sub_in_place(banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_double(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_double_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_prod(banderwagon_fp* r, const banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_mul_in_place(banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_square(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_square_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_div2(banderwagon_fp* a); +void ctt_banderwagon_fp_inv(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_inv_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_ccopy(banderwagon_fp* a, const banderwagon_fp* b, secret_bool ctl); +void ctt_banderwagon_fp_cswap(banderwagon_fp* a, banderwagon_fp* b, secret_bool ctl); +void ctt_banderwagon_fp_cset_zero(banderwagon_fp* a, secret_bool ctl); +void ctt_banderwagon_fp_cset_one(banderwagon_fp* a, secret_bool ctl); +void ctt_banderwagon_fp_cneg_in_place(banderwagon_fp* a, secret_bool ctl); +void ctt_banderwagon_fp_cadd_in_place(banderwagon_fp* a, const banderwagon_fp* b, secret_bool ctl); +void ctt_banderwagon_fp_csub_in_place(banderwagon_fp* a, const banderwagon_fp* b, secret_bool ctl); +secret_bool ctt_banderwagon_fp_is_square(const banderwagon_fp* a); +void ctt_banderwagon_fp_invsqrt(banderwagon_fp* r, const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_invsqrt_in_place(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_sqrt_in_place(banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_sqrt_if_square_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_sqrt_invsqrt(banderwagon_fp* sqrt, banderwagon_fp* invsqrt, const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_sqrt_invsqrt_if_square(banderwagon_fp* sqrt, banderwagon_fp* invsqrt, const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_sqrt_ratio_if_square(banderwagon_fp* r, const banderwagon_fp* u, const banderwagon_fp* v); +secret_bool ctt_banderwagon_ec_aff_is_eq(const banderwagon_ec_aff* P, const banderwagon_ec_aff* Q); +secret_bool ctt_banderwagon_ec_aff_is_neutral(const banderwagon_ec_aff* P); +void ctt_banderwagon_ec_aff_set_neutral(banderwagon_ec_aff* P); +void ctt_banderwagon_ec_aff_ccopy(banderwagon_ec_aff* dst, const banderwagon_ec_aff* src, secret_bool ctl); +secret_bool ctt_banderwagon_ec_aff_is_on_curve(const banderwagon_fp* x, const banderwagon_fp* y); +void ctt_banderwagon_ec_neg(banderwagon_ec_aff* P, const banderwagon_ec_aff* Q); +void ctt_banderwagon_ec_neg_in_place(banderwagon_ec_aff* P); +void ctt_banderwagon_ec_cneg(banderwagon_ec_aff* P, const secret_bool ctl); +secret_bool ctt_banderwagon_ec_prj_is_eq(const banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +secret_bool ctt_banderwagon_ec_prj_is_neutral(const banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_set_neutral(banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_ccopy(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q, secret_bool ctl); +secret_bool ctt_banderwagon_ec_prj_neg(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_neg_in_place(banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_cneg(banderwagon_ec_prj* P, const secret_bool ctl); +void ctt_banderwagon_ec_prj_sum(banderwagon_ec_prj* r, const banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_double(banderwagon_ec_prj* r, const banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_add_in_place(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_diff(banderwagon_ec_prj* r, const banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_diff_in_place(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_mixed_diff_in_place(banderwagon_ec_prj* P, const banderwagon_ec_aff* Q); +void ctt_banderwagon_ec_prj_affine(banderwagon_ec_aff* dst, const banderwagon_ec_prj* src); +void ctt_banderwagon_ec_prj_from_affine(banderwagon_ec_prj* dst, const banderwagon_ec_aff* src); + +#ifdef __cplusplus +} +#endif + +#endif // __CTT_H_BANDERWAGON__ From 3667f27380638576ccc29a5dfb9c9e3f550a01b3 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sun, 20 Oct 2024 15:09:33 +0530 Subject: [PATCH 08/21] undo exportc of generic functions --- constantine/commitments/eth_verkle_ipa.nim | 12 ++++-------- constantine/ethereum_verkle_ipa.nim | 16 +++++++--------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/constantine/commitments/eth_verkle_ipa.nim b/constantine/commitments/eth_verkle_ipa.nim index e244d00a..252f0bae 100644 --- a/constantine/commitments/eth_verkle_ipa.nim +++ b/constantine/commitments/eth_verkle_ipa.nim @@ -17,10 +17,6 @@ import constantine/math/io/io_fields, constantine/platforms/[abstractions, views] -import constantine/zoo_exports - -const prefix_ipa = "ctt_eth_verkle_" - ## ############################################################ ## ## Inner Product Arguments @@ -143,7 +139,7 @@ func innerProduct[F](r: var F, a, b: distinct(View[F] or MutableView[F])) = func ipa_commit*[N: static int, EC, F]( crs: PolynomialEval[N, EC], r: var EC, - poly: PolynomialEval[N, F]) {.libPrefix: prefix_ipa.} = + poly: PolynomialEval[N, F]) = crs.pedersen_commit(r, poly) func ipa_prove*[N, logN: static int, EcAff, F]( @@ -334,7 +330,7 @@ func ipa_verify*[N, logN: static int, EcAff, F]( commitment: EcAff, opening_challenge: F, eval_at_challenge: F, - proof: IpaProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = + proof: IpaProof[logN, EcAff, F]): bool = # We want to check ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # with @@ -665,7 +661,7 @@ func ipa_multi_prove*[N, logN: static int, EcAff, F]( proof: var IpaMultiProof[logN, EcAff, F], polys: openArray[PolynomialEval[N, F]], commitments: openArray[EcAff], - opening_challenges_in_domain: openArray[SomeUnsignedInt]) {.libPrefix: prefix_ipa.} = + opening_challenges_in_domain: openArray[SomeUnsignedInt]) = ## Create a combined proof that ## allow verifying the list of triplets ## (polynomial, commitment, opening challenge) @@ -842,7 +838,7 @@ func ipa_multi_verify*[N, logN: static int, EcAff, F]( commitments: openArray[EcAff], opening_challenges_in_domain: openArray[SomeUnsignedInt], evals_at_challenges: openArray[F], - proof: IpaMultiProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = + proof: IpaMultiProof[logN, EcAff, F]): bool = ## Batch verification of commitments to multiple polynomials ## using a single multiproof ## diff --git a/constantine/ethereum_verkle_ipa.nim b/constantine/ethereum_verkle_ipa.nim index 686b1be5..acfb974a 100644 --- a/constantine/ethereum_verkle_ipa.nim +++ b/constantine/ethereum_verkle_ipa.nim @@ -20,8 +20,6 @@ import ./serialization/endians, ./math/io/[io_bigints, io_fields] -import ./zoo_exports - const EthVerkleSeed* = "eth_verkle_oct_2021" func generate_random_points*(r: var openArray[EC_TwEdw_Aff[Fp[Banderwagon]]]) = @@ -151,7 +149,7 @@ type func serialize*(dst: var EthVerkleIpaProofBytes, src: IpaProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = + ): cttEthVerkleIpaStatus {.discardable.} = # Note: We store 1 out of 2 coordinates of an EC point, so size(Fp[Banderwagon]) const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -170,7 +168,7 @@ func serialize*(dst: var EthVerkleIpaProofBytes, return cttEthVerkleIpa_Success func deserialize*(dst: var EthVerkleIpaProof, - src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = + src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus {.discardable.} = const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -190,7 +188,7 @@ func deserialize*(dst: var EthVerkleIpaProof, func serialize*(dst: var EthVerkleIpaMultiProofBytes, src: IpaMultiProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = + ): cttEthVerkleIpaStatus {.discardable.} = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](dst.addr) @@ -202,7 +200,7 @@ func serialize*(dst: var EthVerkleIpaMultiProofBytes, func deserialize*(dst: var EthVerkleIpaMultiProof, src: EthVerkleIpaMultiProofBytes - ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa.} = + ): cttEthVerkleIpaStatus = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](src.unsafeAddr) @@ -217,7 +215,7 @@ func deserialize*(dst: var EthVerkleIpaMultiProof, # TODO: refactor, this shouldn't use curves_primitives but internal functions import ./lowlevel_fields -func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = +func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.discardable.} = ## The mapping chosen for the Banderwagon Curve is x/y ## ## This function takes a Banderwagon element & then @@ -229,7 +227,7 @@ func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) { invY.inv(p.y) # invY = 1/Y dst.prod(p.x, invY) # dst = (X) * (1/Y) -func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = +func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.discardable.} = ## This function takes the x/y value from the above function as Fp element ## and convert that to bytes in Big Endian, ## and then load that to a Fr element @@ -248,7 +246,7 @@ func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]] func batch_map_to_scalar_field*( res: var openArray[Fr[Banderwagon]], - points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.libPrefix: prefix_ipa, discardable, noinline.} = + points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.discardable, noinline.} = ## This function performs the `mapToScalarField` operation ## on a batch of points ## From 200334227b031a5f204d90a441897b7030832d24 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Mon, 21 Oct 2024 23:56:25 +0530 Subject: [PATCH 09/21] add scalar mul --- bindings/c_curve_decls.nim | 15 ++++++++++++++- bindings/lib_curves.nim | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index 70bbfc48..f76b2b87 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -464,7 +464,7 @@ template genBindings_EC_TwEdw_Affine*(EC, Field: untyped) = {.pop.} -template genBindings_EC_TwEdw_Projective*(EC, EcAff, Field: untyped) = +template genBindings_EC_TwEdw_Projective*(EC, EcAff, ScalarBig, ScalarField: untyped) = when appType == "lib": {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed else: @@ -515,6 +515,19 @@ template genBindings_EC_TwEdw_Projective*(EC, EcAff, Field: untyped) = func `ctt _ EC _ from_affine`(dst: var EC, src: EcAff) = dst.fromAffine(src) + + func `ctt _ EC _ batch_affine`(dst: ptr UncheckedArray[EcAff], src: ptr UncheckedArray[EC], n: csize_t) = + dst.batchAffine(src, cast[int](n)) + + func `ctt _ EC _ scalar_mul_big_coef`( + P: var EC, scalar: ScalarBig) = + + P.scalarMul(scalar) + + func `ctt _ EC _ scalar_mul_fr_coef`( + P: var EC, scalar: ScalarField) = + + P.scalarMul(scalar) {.pop.} diff --git a/bindings/lib_curves.nim b/bindings/lib_curves.nim index 9f4e3a39..ffe06ccf 100644 --- a/bindings/lib_curves.nim +++ b/bindings/lib_curves.nim @@ -154,4 +154,4 @@ collectBindings(cBindings_banderwagon): genBindingsField(big255, banderwagon_fp) genBindingsFieldSqrt(banderwagon_fp) genBindings_EC_TwEdw_Affine(banderwagon_twedw_aff, banderwagon_fp) - genBindings_EC_TwEdw_Projective(banderwagon_twedw_prj, banderwagon_twedw_aff, banderwagon_fr) \ No newline at end of file + genBindings_EC_TwEdw_Projective(banderwagon_twedw_prj, banderwagon_twedw_aff, big253, banderwagon_fr) \ No newline at end of file From b28307960962eb9ef7c451170e318c0ee427e73c Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Tue, 22 Oct 2024 23:01:11 +0530 Subject: [PATCH 10/21] more exports for banderwagon scalar mul --- bindings/c_curve_decls.nim | 26 +++++++++++++++++++----- constantine/lowlevel_elliptic_curves.nim | 1 + include/constantine/curves/banderwagon.h | 7 +++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index f76b2b87..db263e83 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -519,15 +519,31 @@ template genBindings_EC_TwEdw_Projective*(EC, EcAff, ScalarBig, ScalarField: unt func `ctt _ EC _ batch_affine`(dst: ptr UncheckedArray[EcAff], src: ptr UncheckedArray[EC], n: csize_t) = dst.batchAffine(src, cast[int](n)) - func `ctt _ EC _ scalar_mul_big_coef`( - P: var EC, scalar: ScalarBig) = + func `ctt _ EC _ scalar_mul_big_coef`(P: var EC, scalar: ScalarBig) = + P.scalarMul(scalar) + func `ctt _ EC _ scalar_mul_fr_coef`(P: var EC, scalar: ScalarField) = P.scalarMul(scalar) - func `ctt _ EC _ scalar_mul_fr_coef`( - P: var EC, scalar: ScalarField) = + func `ctt _ EC _ scalar_mul_big_coef_vartime`(P: var EC, scalar: ScalarBig) = + P.scalarMul_vartime(scalar) - P.scalarMul(scalar) + func `ctt _ EC _ scalar_mul_fr_coef_vartime`(P: var EC, scalar: ScalarField) = + P.scalarMul_vartime(scalar) + + func `ctt _ EC _ multi_scalar_mul_big_coefs_vartime`( + r: var EC, + coefs: ptr UncheckedArray[ScalarBig], + points: ptr UncheckedArray[EcAff], + len: csize_t) = + r.multiScalarMul_vartime(coefs, points, cast[int](len)) + + func `ctt _ EC _ multi_scalar_mul_fr_coefs_vartime`( + r: var EC, + coefs: ptr UncheckedArray[ScalarField], + points: ptr UncheckedArray[EcAff], + len: csize_t)= + r.multiScalarMul_vartime(coefs, points, cast[int](len)) {.pop.} diff --git a/constantine/lowlevel_elliptic_curves.nim b/constantine/lowlevel_elliptic_curves.nim index c5119168..03577ae5 100644 --- a/constantine/lowlevel_elliptic_curves.nim +++ b/constantine/lowlevel_elliptic_curves.nim @@ -114,6 +114,7 @@ export ec_twistededwards.`-=` export ec_twistededwards.affine export ec_twistededwards.projective export ec_twistededwards.fromAffine +export ec_twistededwards.batchAffine export ec_twistededwards.sum_vartime export ec_twistededwards.mixedSum_vartime export ec_twistededwards.diff_vartime diff --git a/include/constantine/curves/banderwagon.h b/include/constantine/curves/banderwagon.h index a6ccd9b6..82102b2d 100644 --- a/include/constantine/curves/banderwagon.h +++ b/include/constantine/curves/banderwagon.h @@ -118,6 +118,13 @@ void ctt_banderwagon_ec_prj_diff_in_place(banderwagon_ec_prj* P, const banderwag void ctt_banderwagon_ec_prj_mixed_diff_in_place(banderwagon_ec_prj* P, const banderwagon_ec_aff* Q); void ctt_banderwagon_ec_prj_affine(banderwagon_ec_aff* dst, const banderwagon_ec_prj* src); void ctt_banderwagon_ec_prj_from_affine(banderwagon_ec_prj* dst, const banderwagon_ec_aff* src); +void ctt_banderwagon_ec_prj_batch_affine(const banderwagon_ec_aff dst[], const banderwagon_ec_prj src[], size_t n); +void ctt_banderwagon_ec_prj_scalar_mul_big_coef(banderwagon_ec_prj* P, const big253* scalar); +void ctt_banderwagon_ec_prj_scalar_mul_fr_coef(banderwagon_ec_prj* P, const banderwagon_fr* scalar); +void ctt_banderwagon_ec_prj_scalar_mul_big_coef_vartime(banderwagon_ec_prj* P, const big253* scalar); +void ctt_banderwagon_ec_prj_scalar_mul_fr_coef_vartime(banderwagon_ec_prj* P, const banderwagon_fr* scalar); +void ctt_banderwagon_ec_prj_multi_scalar_mul_big_coefs_vartime(banderwagon_ec_prj* r, const big253 coefs[], const banderwagon_ec_aff points[], size_t len); +void ctt_banderwagon_ec_prj_multi_scalar_mul_fr_coefs_vartime(banderwagon_ec_prj* r, const banderwagon_fr coefs[], const banderwagon_ec_aff points[], size_t len); #ifdef __cplusplus } From e4f40fc28c0fe40a1c63b54557c8f398221dc3bc Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sun, 6 Oct 2024 22:01:17 +0530 Subject: [PATCH 11/21] c bindings for verkle --- constantine/commitments/eth_verkle_ipa.nim | 12 +- constantine/ethereum_verkle_ipa.nim | 16 +- .../protocols/ethereum_verkle_ipa.h | 228 ++++++++++++++++++ 3 files changed, 245 insertions(+), 11 deletions(-) create mode 100644 include/constantine/protocols/ethereum_verkle_ipa.h diff --git a/constantine/commitments/eth_verkle_ipa.nim b/constantine/commitments/eth_verkle_ipa.nim index 252f0bae..e244d00a 100644 --- a/constantine/commitments/eth_verkle_ipa.nim +++ b/constantine/commitments/eth_verkle_ipa.nim @@ -17,6 +17,10 @@ import constantine/math/io/io_fields, constantine/platforms/[abstractions, views] +import constantine/zoo_exports + +const prefix_ipa = "ctt_eth_verkle_" + ## ############################################################ ## ## Inner Product Arguments @@ -139,7 +143,7 @@ func innerProduct[F](r: var F, a, b: distinct(View[F] or MutableView[F])) = func ipa_commit*[N: static int, EC, F]( crs: PolynomialEval[N, EC], r: var EC, - poly: PolynomialEval[N, F]) = + poly: PolynomialEval[N, F]) {.libPrefix: prefix_ipa.} = crs.pedersen_commit(r, poly) func ipa_prove*[N, logN: static int, EcAff, F]( @@ -330,7 +334,7 @@ func ipa_verify*[N, logN: static int, EcAff, F]( commitment: EcAff, opening_challenge: F, eval_at_challenge: F, - proof: IpaProof[logN, EcAff, F]): bool = + proof: IpaProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = # We want to check ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # with @@ -661,7 +665,7 @@ func ipa_multi_prove*[N, logN: static int, EcAff, F]( proof: var IpaMultiProof[logN, EcAff, F], polys: openArray[PolynomialEval[N, F]], commitments: openArray[EcAff], - opening_challenges_in_domain: openArray[SomeUnsignedInt]) = + opening_challenges_in_domain: openArray[SomeUnsignedInt]) {.libPrefix: prefix_ipa.} = ## Create a combined proof that ## allow verifying the list of triplets ## (polynomial, commitment, opening challenge) @@ -838,7 +842,7 @@ func ipa_multi_verify*[N, logN: static int, EcAff, F]( commitments: openArray[EcAff], opening_challenges_in_domain: openArray[SomeUnsignedInt], evals_at_challenges: openArray[F], - proof: IpaMultiProof[logN, EcAff, F]): bool = + proof: IpaMultiProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = ## Batch verification of commitments to multiple polynomials ## using a single multiproof ## diff --git a/constantine/ethereum_verkle_ipa.nim b/constantine/ethereum_verkle_ipa.nim index f5b9afb6..a346035a 100644 --- a/constantine/ethereum_verkle_ipa.nim +++ b/constantine/ethereum_verkle_ipa.nim @@ -20,6 +20,8 @@ import ./serialization/endians, ./math/io/[io_bigints, io_fields] +import ./zoo_exports + const EthVerkleSeed* = "eth_verkle_oct_2021" func generate_random_points*(r: var openArray[EC_TwEdw_Aff[Fp[Banderwagon]]]) = @@ -149,7 +151,7 @@ type func serialize*(dst: var EthVerkleIpaProofBytes, src: IpaProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.discardable.} = + ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = # Note: We store 1 out of 2 coordinates of an EC point, so size(Fp[Banderwagon]) const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -168,7 +170,7 @@ func serialize*(dst: var EthVerkleIpaProofBytes, return cttEthVerkleIpa_Success func deserialize*(dst: var EthVerkleIpaProof, - src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus = + src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -188,7 +190,7 @@ func deserialize*(dst: var EthVerkleIpaProof, func serialize*(dst: var EthVerkleIpaMultiProofBytes, src: IpaMultiProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.discardable.} = + ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](dst.addr) @@ -200,7 +202,7 @@ func serialize*(dst: var EthVerkleIpaMultiProofBytes, func deserialize*(dst: var EthVerkleIpaMultiProof, src: EthVerkleIpaMultiProofBytes - ): cttEthVerkleIpaStatus = + ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa.} = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](src.unsafeAddr) @@ -215,7 +217,7 @@ func deserialize*(dst: var EthVerkleIpaMultiProof, # TODO: refactor, this shouldn't use curves_primitives but internal functions import ./lowlevel_fields -func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) = +func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = ## The mapping chosen for the Banderwagon Curve is x/y ## ## This function takes a Banderwagon element & then @@ -227,7 +229,7 @@ func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) = invY.inv(p.y) # invY = 1/Y dst.prod(p.x, invY) # dst = (X) * (1/Y) -func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.discardable.} = +func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = ## This function takes the x/y value from the above function as Fp element ## and convert that to bytes in Big Endian, ## and then load that to a Fr element @@ -246,7 +248,7 @@ func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): func batchMapToScalarField*( res: var openArray[Fr[Banderwagon]], - points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.discardable, noinline.} = + points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.libPrefix: prefix_ipa, discardable, noinline.} = ## This function performs the `mapToScalarField` operation ## on a batch of points ## diff --git a/include/constantine/protocols/ethereum_verkle_ipa.h b/include/constantine/protocols/ethereum_verkle_ipa.h new file mode 100644 index 00000000..21edd503 --- /dev/null +++ b/include/constantine/protocols/ethereum_verkle_ipa.h @@ -0,0 +1,228 @@ +/** 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. + */ +#ifndef __CTT_H_ETHEREUM_VERKLE_IPA__ +#define __CTT_H_ETHEREUM_VERKLE_IPA__ + +#include "constantine/core/datatypes.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum __attribute__((__packed__)) { + cttEthVerkleIpa_Success, + cttEthVerkleIpa_VerificationFailure, + cttEthVerkleIpa_InputsLengthsMismatch, + cttEthVerkleIpa_ScalarZero, + cttEthVerkleIpa_ScalarLargerThanCurveOrder, + cttEthVerkleIpa_EccInvalidEncoding, + cttEthVerkleIpa_EccCoordinateGreaterThanOrEqualModulus, + cttEthVerkleIpa_EccPointNotOnCurve, + cttEthVerkleIpa_EccPointNotInSubGroup +} ctt_eth_verkle_ipa_status; + +static const char* ctt_eth_verkle_ipa_status_to_string(ctt_eth_verkle_ipa_status status) { + static const char* const statuses[] = { + "cttEthVerkleIpa_Success", + "cttEthVerkleIpa_VerificationFailure", + "cttEthVerkleIpa_InputsLengthsMismatch", + "cttEthVerkleIpa_ScalarZero", + "cttEthVerkleIpa_ScalarLargerThanCurveOrder", + "cttEthVerkleIpa_EccInvalidEncoding", + "cttEthVerkleIpa_EccCoordinateGreaterThanOrEqualModulus", + "cttEthVerkleIpa_EccPointNotOnCurve", + "cttEthVerkleIpa_EccPointNotInSubGroup" + }; + size_t length = sizeof statuses / sizeof *statuses; + if (0 <= status && status < length) { + return statuses[status]; + } + return "cttEthVerkleIpa_InvalidStatusCode"; +} + +// Opaque types for Nim-defined types +typedef struct Fr Fr; +typedef struct Banderwagon Banderwagon; +typedef struct EC_TwEdw EC_TwEdw; +typedef struct Fp Fp; + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; + uint64_t u64; + unsigned int u; +} SomeUnsignedInt; + +typedef struct { + SomeUnsignedInt* values; + size_t length; +} SomeUnsignedInt_Array; + +// Define types for openArray +typedef struct { + Fr* data; + size_t len; +} Fr_BanderWagon_OpenArray; + +typedef struct { + EC_TwEdw* data; + size_t len; +} EC_TwEdw_Fp_Banderwagon_OpenArray; + +typedef struct { + byte value[32]; // 32-byte array for field element +} Fp_Banderwagon; + +typedef struct { + byte value[32]; // 32-byte array for field element +} Fr_Banderwagon; + +typedef struct { + byte x[32]; // 32-byte x-coordinate + byte y[32]; // 32-byte y-coordinate +} EC_TwEdw_Fp_Banderwagon; + +typedef struct { + byte x[32]; // 32-byte x-coordinate + byte y[32]; // 32-byte y-coordinate +} EC; + +typedef struct { + EC* points; + size_t length; +} PolynomialEval_EC; + +typedef struct { + Fr* points; + size_t length; +} PolynomialEval_Fr; + +typedef struct { + EC* points; + size_t length; +} PolynomialEval_EcAff; + +typedef struct { + Fr* domain_values; + size_t length; +} PolyEvalLinearDomain_Fr; + +typedef struct { + EC* ec_points; + Fr* field_elements; + size_t logN; +} IpaProof_EcAff_Fr; + +typedef struct { + EC* ec_points; + Fr* field_elements; + size_t logN; +} IpaMultiProof_EcAff_Fr; + +typedef struct { + EC* ec_points; + size_t length; +} EcAffArray; + +typedef struct EthVerkleIpaProof EthVerkleIpaProof; +typedef struct EthVerkleIpaMultiProof EthVerkleIpaMultiProof; +typedef struct IpaProof IpaProof; +typedef struct IpaMultiProof IpaMultiProof; +typedef struct EthVerkleTranscript EthVerkleTranscript; + +typedef byte EthVerkleIpaProofBytes[544]; // Array of 544 bytes +typedef byte EthVerkleIpaMultiProofBytes[576]; + + +ctt_eth_verkle_ipa_status ctt_eth_verkle_serialize( + EthVerkleIpaProofBytes* dst, + const IpaProof* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_serialize( + EthVerkleIpaMultiProofBytes* dst, + const IpaMultiProof* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( + const EthVerkleIpaProof* dst, + EthVerkleIpaProofBytes* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( + const EthVerkleIpaMultiProof* dst, + EthVerkleIpaMultiProofBytes* src + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToBaseField( + Fp_Banderwagon* dst, const EC_TwEdw_Fp_Banderwagon* p + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToScalarField( + Fr_Banderwagon* res, const EC_TwEdw_Fp_Banderwagon* p + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_batchMapToScalarField( + Fr_BanderWagon_OpenArray* res, const EC_TwEdw_Fp_Banderwagon_OpenArray* p + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_commit( + const PolynomialEval_EC* crs, + EC* r, + const PolynomialEval_Fr* poly + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_prove( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + Fr* eval_at_challenge, + IpaProof_EcAff_Fr* proof, + const PolynomialEval_Fr* poly, + const EC* commitment, + const Fr* opening_challenge + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_verify( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + const EC* commitment, + const Fr* opening_challenge, + Fr* eval_at_challenge, + IpaProof_EcAff_Fr* proof + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_prove( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + IpaMultiProof_EcAff_Fr* proof, + const PolynomialEval_Fr* polys, + const EC_TwEdw_Fp_Banderwagon_OpenArray* commitments, + const Fr_BanderWagon_OpenArray* opening_challenges_in_domain + ) __attribute__((warn_unused_result)); + +ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_verify( + const PolynomialEval_EcAff* crs, + const PolyEvalLinearDomain_Fr* domain, + EthVerkleTranscript* transcript, + const EC_TwEdw_Fp_Banderwagon_OpenArray* commitments, + const Fr_BanderWagon_OpenArray* opening_challenges_in_domain, + Fr_BanderWagon_OpenArray* evals_at_challenges, + IpaMultiProof_EcAff_Fr* proof + ) __attribute__((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif // __CTT_H_ETHEREUM_EVM_PRECOMPILES__ From 66d9abf6678c90770d60d97ea9b4ac9d863fff2e Mon Sep 17 00:00:00 2001 From: iri <76250660+Richa-iitr@users.noreply.github.com> Date: Mon, 7 Oct 2024 21:01:09 +0530 Subject: [PATCH 12/21] comments correction Co-authored-by: Mamy Ratsimbazafy --- include/constantine/protocols/ethereum_verkle_ipa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/constantine/protocols/ethereum_verkle_ipa.h b/include/constantine/protocols/ethereum_verkle_ipa.h index 21edd503..d88f71aa 100644 --- a/include/constantine/protocols/ethereum_verkle_ipa.h +++ b/include/constantine/protocols/ethereum_verkle_ipa.h @@ -225,4 +225,4 @@ ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_verify( } #endif -#endif // __CTT_H_ETHEREUM_EVM_PRECOMPILES__ +#endif // __CTT_H_ETHEREUM_VERKLE_IPA__ From d3097e414b68b8874a8a276811b0306d31b8c0b3 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Mon, 7 Oct 2024 22:43:59 +0530 Subject: [PATCH 13/21] refactoring: --- constantine/ethereum_verkle_ipa.nim | 6 +++--- include/constantine/protocols/ethereum_verkle_ipa.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/constantine/ethereum_verkle_ipa.nim b/constantine/ethereum_verkle_ipa.nim index a346035a..686b1be5 100644 --- a/constantine/ethereum_verkle_ipa.nim +++ b/constantine/ethereum_verkle_ipa.nim @@ -217,7 +217,7 @@ func deserialize*(dst: var EthVerkleIpaMultiProof, # TODO: refactor, this shouldn't use curves_primitives but internal functions import ./lowlevel_fields -func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = +func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = ## The mapping chosen for the Banderwagon Curve is x/y ## ## This function takes a Banderwagon element & then @@ -229,7 +229,7 @@ func mapToBaseField*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.li invY.inv(p.y) # invY = 1/Y dst.prod(p.x, invY) # dst = (X) * (1/Y) -func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = +func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = ## This function takes the x/y value from the above function as Fp element ## and convert that to bytes in Big Endian, ## and then load that to a Fr element @@ -246,7 +246,7 @@ func mapToScalarField*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): return check1 and check2 -func batchMapToScalarField*( +func batch_map_to_scalar_field*( res: var openArray[Fr[Banderwagon]], points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.libPrefix: prefix_ipa, discardable, noinline.} = ## This function performs the `mapToScalarField` operation diff --git a/include/constantine/protocols/ethereum_verkle_ipa.h b/include/constantine/protocols/ethereum_verkle_ipa.h index d88f71aa..23a498ce 100644 --- a/include/constantine/protocols/ethereum_verkle_ipa.h +++ b/include/constantine/protocols/ethereum_verkle_ipa.h @@ -162,15 +162,15 @@ ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( EthVerkleIpaMultiProofBytes* src ) __attribute__((warn_unused_result)); -ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToBaseField( +ctt_eth_verkle_ipa_status ctt_eth_verkle_map_to_base_field( Fp_Banderwagon* dst, const EC_TwEdw_Fp_Banderwagon* p ) __attribute__((warn_unused_result)); -ctt_eth_verkle_ipa_status ctt_eth_verkle_mapToScalarField( +ctt_eth_verkle_ipa_status ctt_eth_verkle_map_to_scalar_field( Fr_Banderwagon* res, const EC_TwEdw_Fp_Banderwagon* p ) __attribute__((warn_unused_result)); -ctt_eth_verkle_ipa_status ctt_eth_verkle_batchMapToScalarField( +ctt_eth_verkle_ipa_status ctt_eth_verkle_batch_map_to_base_field( Fr_BanderWagon_OpenArray* res, const EC_TwEdw_Fp_Banderwagon_OpenArray* p ) __attribute__((warn_unused_result)); From bc0db2208a8af996c2690c3921b248c015a7f7b3 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Mon, 14 Oct 2024 23:14:32 +0530 Subject: [PATCH 14/21] curve decl for ed --- bindings/c_curve_decls.nim | 87 ++++++++++++++++++++++++ constantine/lowlevel_elliptic_curves.nim | 38 +++++++++++ 2 files changed, 125 insertions(+) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index 9d2d9508..b30928d2 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -431,6 +431,93 @@ template genBindings_EC_ShortW_NonAffine*(EC, EcAff, ScalarBig, ScalarField: unt {.pop.} +template genBindings_EC_TwistedEd_Affine*(EC, Field: untyped) = + when appType == "lib": + {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed + else: + {.push noconv, exportc, raises: [].} # No exceptions allowed + + # -------------------------------------------------------------------------------------- + func `ctt _ EC _ is_eq`(P, Q: EC): SecretBool = + P == Q + + func `ctt _ EC _ is_neutral`(P: EC): SecretBool = + P.isNeutral() + + func `ctt _ EC _ set_neutral`(P: var EC) = + P.setNeutral() + + func `ctt _ EC _ ccopy`(P: var EC, Q: EC, ctl: SecretBool) = + P.ccopy(Q, ctl) + + func `ctt _ EC _ is_on_curve`(x, y: Field): SecretBool = + isOnCurve(x, y) + + func `ctt _ EC _ neg`(P: var EC, Q: EC) = + P.neg(Q) + + func `ctt _ EC _ neg_in_place`(P: var EC) = + P.neg() + + func `ctt _ EC _ cneg`(P: var EC, ctl: SecretBool) = + P.cneg(ctl) + + {.pop.} + +template genBindings_EC_TwistedEd_Projective*(EC, EcAff, Field: untyped) = + when appType == "lib": + {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed + else: + {.push noconv, exportc, raises: [].} # No exceptions allowed + + # -------------------------------------------------------------------------------------- + func `ctt _ EC _ is_eq`(P, Q: EC): SecretBool = + P == Q + + func `ctt _ EC _ is_neutral`(P: EC): SecretBool = + P.isNeutral() + + func `ctt _ EC _ set_neutral`(P: var EC) = + P.setNeutral() + + func `ctt _ EC _ ccopy`(P: var EC, Q: EC, ctl: SecretBool) = + P.ccopy(Q, ctl) + + func `ctt _ EC _ neg`(P: var EC, Q: EC) = + P.neg(Q) + + func `ctt _ EC _ neg_in_place`(P: var EC) = + P.neg() + + func `ctt _ EC _ cneg`(P: var EC, ctl: SecretBool) = + P.cneg(ctl) + + func `ctt _ EC _ sum`(r: var EC, P, Q: EC) = + r.sum(P, Q) + + func `ctt _ EC _ double`(r: var EC, P: EC) = + r.double(P) + + func `ctt _ EC _ add_in_place`(P: var EC, Q: EC) = + P += Q + + func `ctt _ EC _ diff`(r: var EC, P, Q: EC) = + r.diff(P,Q) + + func `ctt _ EC _ diff_in_place`(P: var EC, Q: EC) = + P -= Q + + func `ctt _ EC _ mixed_diff_in_place`(P: var EC, Q: EcAff) = + P -= Q + + func `ctt _ EC _ affine`(dst: var EcAff, src: EC) = + dst.affine(src) + + func `ctt _ EC _ from_affine`(dst: var EC, src: EcAff) = + dst.fromAffine(src) + + {.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 diff --git a/constantine/lowlevel_elliptic_curves.nim b/constantine/lowlevel_elliptic_curves.nim index 97250ef5..c5119168 100644 --- a/constantine/lowlevel_elliptic_curves.nim +++ b/constantine/lowlevel_elliptic_curves.nim @@ -11,6 +11,7 @@ import ./named/algebras, ./named/[zoo_subgroups, zoo_generators], ./math/ec_shortweierstrass, + ./math/ec_twistededwards, ./math/elliptic/[ ec_scalar_mul_vartime, ec_multi_scalar_mul], @@ -58,6 +59,13 @@ export affine, jacobian, projective, projectiveFromJacobian +export + ec_twistededwards.EC_TwEdw_Aff, + ec_twistededwards.EC_TwEdw_Prj, + ec_twistededwards.EC_TwEdw, + ec_twistededwards.getName, + affine, projective + export ec_shortweierstrass.`==` export ec_shortweierstrass.isNeutral export ec_shortweierstrass.setNeutral @@ -87,6 +95,36 @@ export ec_shortweierstrass.scalarMul export ec_scalar_mul_vartime.scalarMul_vartime export ec_multi_scalar_mul.multiScalarMul_vartime +# Twisted edwards curve +export ec_twistededwards.`==` +export ec_twistededwards.isNeutral +export ec_twistededwards.setNeutral +export ec_twistededwards.ccopy +export ec_twistededwards.isOnCurve +export ec_twistededwards.neg +export ec_twistededwards.cneg + +export ec_twistededwards.sum +export ec_twistededwards.mixedSum +export ec_twistededwards.double +export ec_twistededwards.`+=` +export ec_twistededwards.diff +export ec_twistededwards.mixedDiff +export ec_twistededwards.`-=` +export ec_twistededwards.affine +export ec_twistededwards.projective +export ec_twistededwards.fromAffine +export ec_twistededwards.sum_vartime +export ec_twistededwards.mixedSum_vartime +export ec_twistededwards.diff_vartime +export ec_twistededwards.mixedDiff_vartime +export ec_twistededwards.`~+=` +export ec_twistededwards.`~-=` +export ec_twistededwards.`+` +export ec_twistededwards.`~+` +export ec_twistededwards.`-` +export ec_twistededwards.`~-` + export zoo_generators.getGenerator export zoo_subgroups.clearCofactor export zoo_subgroups.isInSubgroup From e2488479bf5ee0963fcd2746be47a514c60b8899 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Tue, 15 Oct 2024 22:33:21 +0530 Subject: [PATCH 15/21] gen bindings for twedw --- bindings/c_curve_decls.nim | 4 ++-- bindings/lib_curves.nim | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index b30928d2..70bbfc48 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -431,7 +431,7 @@ template genBindings_EC_ShortW_NonAffine*(EC, EcAff, ScalarBig, ScalarField: unt {.pop.} -template genBindings_EC_TwistedEd_Affine*(EC, Field: untyped) = +template genBindings_EC_TwEdw_Affine*(EC, Field: untyped) = when appType == "lib": {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed else: @@ -464,7 +464,7 @@ template genBindings_EC_TwistedEd_Affine*(EC, Field: untyped) = {.pop.} -template genBindings_EC_TwistedEd_Projective*(EC, EcAff, Field: untyped) = +template genBindings_EC_TwEdw_Projective*(EC, EcAff, Field: untyped) = when appType == "lib": {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed else: diff --git a/bindings/lib_curves.nim b/bindings/lib_curves.nim index 2f988dfc..9f4e3a39 100644 --- a/bindings/lib_curves.nim +++ b/bindings/lib_curves.nim @@ -20,11 +20,13 @@ export c_curve_decls, c_curve_decls_parallel type big254 = BigInt[254] + big253 = BigInt[253] big255 = BigInt[255] big381 = BigInt[381] collectBindings(cBindings_big): genBindingsBig(big254) + genBindingsBig(big253) genBindingsBig(big255) genBindingsBig(big381) @@ -140,3 +142,16 @@ collectBindings(cBindings_vesta_parallel): genParallelBindings_EC_ShortW_NonAffine(vesta_ec_prj, vesta_ec_aff, vesta_fr) # ---------------------------------------------------------- + +type + banderwagon_fr = Fr[Banderwagon] + banderwagon_fp = Fp[Banderwagon] + banderwagon_twedw_aff = EC_TwEdw_Aff[Fp[Banderwagon]] + banderwagon_twedw_prj = EC_TwEdw_Prj[Fp[Banderwagon]] + +collectBindings(cBindings_banderwagon): + genBindingsField(big253, banderwagon_fr) + genBindingsField(big255, banderwagon_fp) + genBindingsFieldSqrt(banderwagon_fp) + genBindings_EC_TwEdw_Affine(banderwagon_twedw_aff, banderwagon_fp) + genBindings_EC_TwEdw_Projective(banderwagon_twedw_prj, banderwagon_twedw_aff, banderwagon_fr) \ No newline at end of file From f86132568f22ef717450ea46bca5d71f9e67f246 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Wed, 16 Oct 2024 23:11:40 +0530 Subject: [PATCH 16/21] bigint bandderwagon types --- include/constantine/curves/bigints.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/constantine/curves/bigints.h b/include/constantine/curves/bigints.h index e7c441fc..1ed744d6 100644 --- a/include/constantine/curves/bigints.h +++ b/include/constantine/curves/bigints.h @@ -18,6 +18,7 @@ extern "C" { 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; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(253)]; } big253; ctt_bool ctt_big254_unmarshalBE(big254* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_big254_marshalBE(byte dst[], size_t dst_len, const big254* src) __attribute__((warn_unused_result)); @@ -25,6 +26,8 @@ ctt_bool ctt_big255_unmarshalBE(big255* dst, const byte src[], size_t src_len ctt_bool ctt_big255_marshalBE(byte dst[], size_t dst_len, const big255* src) __attribute__((warn_unused_result)); ctt_bool ctt_big381_unmarshalBE(big381* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); ctt_bool ctt_big381_marshalBE(byte dst[], size_t dst_len, const big381* src) __attribute__((warn_unused_result)); +ctt_bool ctt_big253_unmarshalBE(big253* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_big253_marshalBE(byte dst[], size_t dst_len, const big253* src) __attribute__((warn_unused_result)); #ifdef __cplusplus } From c8ed6d36574d3aac00b256e4afba9bdad4b3e49a Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sun, 20 Oct 2024 14:41:19 +0530 Subject: [PATCH 17/21] banderwagon header --- include/constantine/curves/banderwagon.h | 126 +++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 include/constantine/curves/banderwagon.h diff --git a/include/constantine/curves/banderwagon.h b/include/constantine/curves/banderwagon.h new file mode 100644 index 00000000..a6ccd9b6 --- /dev/null +++ b/include/constantine/curves/banderwagon.h @@ -0,0 +1,126 @@ +/** 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. + */ +#ifndef __CTT_H_BANDERWAGON__ +#define __CTT_H_BANDERWAGON__ + +#include "constantine/core/datatypes.h" +#include "constantine/curves/bigints.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(253)]; } banderwagon_fr; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } banderwagon_fp; +typedef struct { banderwagon_fp x, y; } banderwagon_ec_aff; +typedef struct { banderwagon_fp x, y, z; } banderwagon_ec_prj; + +void ctt_big253_from_banderwagon_fr(big253* dst, const banderwagon_fr* src); +void ctt_banderwagon_fr_from_big253(banderwagon_fr* dst, const big253* src); +ctt_bool ctt_banderwagon_fr_unmarshalBE(banderwagon_fr* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_banderwagon_fr_marshalBE(byte dst[], size_t dst_len, const banderwagon_fr* src) __attribute__((warn_unused_result)); +secret_bool ctt_banderwagon_fr_is_eq(const banderwagon_fr* a, const banderwagon_fr* b); +secret_bool ctt_banderwagon_fr_is_zero(const banderwagon_fr* a); +secret_bool ctt_banderwagon_fr_is_one(const banderwagon_fr* a); +secret_bool ctt_banderwagon_fr_is_minus_one(const banderwagon_fr* a); +void ctt_banderwagon_fr_set_zero(banderwagon_fr* a); +void ctt_banderwagon_fr_set_one(banderwagon_fr* a); +void ctt_banderwagon_fr_set_minus_one(banderwagon_fr* a); +void ctt_banderwagon_fr_neg(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_neg_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_sum(banderwagon_fr* r, const banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_add_in_place(banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_diff(banderwagon_fr* r, const banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_sub_in_place(banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_double(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_double_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_prod(banderwagon_fr* r, const banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_mul_in_place(banderwagon_fr* a, const banderwagon_fr* b); +void ctt_banderwagon_fr_square(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_square_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_div2(banderwagon_fr* a); +void ctt_banderwagon_fr_inv(banderwagon_fr* r, const banderwagon_fr* a); +void ctt_banderwagon_fr_inv_in_place(banderwagon_fr* a); +void ctt_banderwagon_fr_ccopy(banderwagon_fr* a, const banderwagon_fr* b, secret_bool ctl); +void ctt_banderwagon_fr_cswap(banderwagon_fr* a, banderwagon_fr* b, secret_bool ctl); +void ctt_banderwagon_fr_cset_zero(banderwagon_fr* a, secret_bool ctl); +void ctt_banderwagon_fr_cset_one(banderwagon_fr* a, secret_bool ctl); +void ctt_banderwagon_fr_cneg_in_place(banderwagon_fr* a, secret_bool ctl); +void ctt_banderwagon_fr_cadd_in_place(banderwagon_fr* a, const banderwagon_fr* b, secret_bool ctl); +void ctt_banderwagon_fr_csub_in_place(banderwagon_fr* a, const banderwagon_fr* b, secret_bool ctl); +void ctt_big253_from_banderwagon_fp(big253* dst, const banderwagon_fp* src); +void ctt_banderwagon_fp_from_big253(banderwagon_fp* dst, const big253* src); +ctt_bool ctt_banderwagon_fp_unmarshalBE(banderwagon_fp* dst, const byte src[], size_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_banderwagon_fp_marshalBE(byte dst[], size_t dst_len, const banderwagon_fp* src) __attribute__((warn_unused_result)); +secret_bool ctt_banderwagon_fp_is_eq(const banderwagon_fp* a, const banderwagon_fp* b); +secret_bool ctt_banderwagon_fp_is_zero(const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_is_one(const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_is_minus_one(const banderwagon_fp* a); +void ctt_banderwagon_fp_set_zero(banderwagon_fp* a); +void ctt_banderwagon_fp_set_one(banderwagon_fp* a); +void ctt_banderwagon_fp_set_minus_one(banderwagon_fp* a); +void ctt_banderwagon_fp_neg(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_neg_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_sum(banderwagon_fp* r, const banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_add_in_place(banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_diff(banderwagon_fp* r, const banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_sub_in_place(banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_double(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_double_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_prod(banderwagon_fp* r, const banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_mul_in_place(banderwagon_fp* a, const banderwagon_fp* b); +void ctt_banderwagon_fp_square(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_square_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_div2(banderwagon_fp* a); +void ctt_banderwagon_fp_inv(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_inv_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_ccopy(banderwagon_fp* a, const banderwagon_fp* b, secret_bool ctl); +void ctt_banderwagon_fp_cswap(banderwagon_fp* a, banderwagon_fp* b, secret_bool ctl); +void ctt_banderwagon_fp_cset_zero(banderwagon_fp* a, secret_bool ctl); +void ctt_banderwagon_fp_cset_one(banderwagon_fp* a, secret_bool ctl); +void ctt_banderwagon_fp_cneg_in_place(banderwagon_fp* a, secret_bool ctl); +void ctt_banderwagon_fp_cadd_in_place(banderwagon_fp* a, const banderwagon_fp* b, secret_bool ctl); +void ctt_banderwagon_fp_csub_in_place(banderwagon_fp* a, const banderwagon_fp* b, secret_bool ctl); +secret_bool ctt_banderwagon_fp_is_square(const banderwagon_fp* a); +void ctt_banderwagon_fp_invsqrt(banderwagon_fp* r, const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_invsqrt_in_place(banderwagon_fp* r, const banderwagon_fp* a); +void ctt_banderwagon_fp_sqrt_in_place(banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_sqrt_if_square_in_place(banderwagon_fp* a); +void ctt_banderwagon_fp_sqrt_invsqrt(banderwagon_fp* sqrt, banderwagon_fp* invsqrt, const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_sqrt_invsqrt_if_square(banderwagon_fp* sqrt, banderwagon_fp* invsqrt, const banderwagon_fp* a); +secret_bool ctt_banderwagon_fp_sqrt_ratio_if_square(banderwagon_fp* r, const banderwagon_fp* u, const banderwagon_fp* v); +secret_bool ctt_banderwagon_ec_aff_is_eq(const banderwagon_ec_aff* P, const banderwagon_ec_aff* Q); +secret_bool ctt_banderwagon_ec_aff_is_neutral(const banderwagon_ec_aff* P); +void ctt_banderwagon_ec_aff_set_neutral(banderwagon_ec_aff* P); +void ctt_banderwagon_ec_aff_ccopy(banderwagon_ec_aff* dst, const banderwagon_ec_aff* src, secret_bool ctl); +secret_bool ctt_banderwagon_ec_aff_is_on_curve(const banderwagon_fp* x, const banderwagon_fp* y); +void ctt_banderwagon_ec_neg(banderwagon_ec_aff* P, const banderwagon_ec_aff* Q); +void ctt_banderwagon_ec_neg_in_place(banderwagon_ec_aff* P); +void ctt_banderwagon_ec_cneg(banderwagon_ec_aff* P, const secret_bool ctl); +secret_bool ctt_banderwagon_ec_prj_is_eq(const banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +secret_bool ctt_banderwagon_ec_prj_is_neutral(const banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_set_neutral(banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_ccopy(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q, secret_bool ctl); +secret_bool ctt_banderwagon_ec_prj_neg(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_neg_in_place(banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_cneg(banderwagon_ec_prj* P, const secret_bool ctl); +void ctt_banderwagon_ec_prj_sum(banderwagon_ec_prj* r, const banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_double(banderwagon_ec_prj* r, const banderwagon_ec_prj* P); +void ctt_banderwagon_ec_prj_add_in_place(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_diff(banderwagon_ec_prj* r, const banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_diff_in_place(banderwagon_ec_prj* P, const banderwagon_ec_prj* Q); +void ctt_banderwagon_ec_prj_mixed_diff_in_place(banderwagon_ec_prj* P, const banderwagon_ec_aff* Q); +void ctt_banderwagon_ec_prj_affine(banderwagon_ec_aff* dst, const banderwagon_ec_prj* src); +void ctt_banderwagon_ec_prj_from_affine(banderwagon_ec_prj* dst, const banderwagon_ec_aff* src); + +#ifdef __cplusplus +} +#endif + +#endif // __CTT_H_BANDERWAGON__ From cc1706268c601a81f7a4575bb9f0270e4b02b9b4 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Sun, 20 Oct 2024 15:09:33 +0530 Subject: [PATCH 18/21] undo exportc of generic functions --- constantine/commitments/eth_verkle_ipa.nim | 12 ++++-------- constantine/ethereum_verkle_ipa.nim | 16 +++++++--------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/constantine/commitments/eth_verkle_ipa.nim b/constantine/commitments/eth_verkle_ipa.nim index e244d00a..252f0bae 100644 --- a/constantine/commitments/eth_verkle_ipa.nim +++ b/constantine/commitments/eth_verkle_ipa.nim @@ -17,10 +17,6 @@ import constantine/math/io/io_fields, constantine/platforms/[abstractions, views] -import constantine/zoo_exports - -const prefix_ipa = "ctt_eth_verkle_" - ## ############################################################ ## ## Inner Product Arguments @@ -143,7 +139,7 @@ func innerProduct[F](r: var F, a, b: distinct(View[F] or MutableView[F])) = func ipa_commit*[N: static int, EC, F]( crs: PolynomialEval[N, EC], r: var EC, - poly: PolynomialEval[N, F]) {.libPrefix: prefix_ipa.} = + poly: PolynomialEval[N, F]) = crs.pedersen_commit(r, poly) func ipa_prove*[N, logN: static int, EcAff, F]( @@ -334,7 +330,7 @@ func ipa_verify*[N, logN: static int, EcAff, F]( commitment: EcAff, opening_challenge: F, eval_at_challenge: F, - proof: IpaProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = + proof: IpaProof[logN, EcAff, F]): bool = # We want to check ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # ∑ᵢ[uᵢ]Lᵢ + C' + ∑ᵢ[uᵢ⁻¹]Rᵢ = a₀G₀ + [a₀.b₀]Q # with @@ -665,7 +661,7 @@ func ipa_multi_prove*[N, logN: static int, EcAff, F]( proof: var IpaMultiProof[logN, EcAff, F], polys: openArray[PolynomialEval[N, F]], commitments: openArray[EcAff], - opening_challenges_in_domain: openArray[SomeUnsignedInt]) {.libPrefix: prefix_ipa.} = + opening_challenges_in_domain: openArray[SomeUnsignedInt]) = ## Create a combined proof that ## allow verifying the list of triplets ## (polynomial, commitment, opening challenge) @@ -842,7 +838,7 @@ func ipa_multi_verify*[N, logN: static int, EcAff, F]( commitments: openArray[EcAff], opening_challenges_in_domain: openArray[SomeUnsignedInt], evals_at_challenges: openArray[F], - proof: IpaMultiProof[logN, EcAff, F]): bool {.libPrefix: prefix_ipa.} = + proof: IpaMultiProof[logN, EcAff, F]): bool = ## Batch verification of commitments to multiple polynomials ## using a single multiproof ## diff --git a/constantine/ethereum_verkle_ipa.nim b/constantine/ethereum_verkle_ipa.nim index 686b1be5..acfb974a 100644 --- a/constantine/ethereum_verkle_ipa.nim +++ b/constantine/ethereum_verkle_ipa.nim @@ -20,8 +20,6 @@ import ./serialization/endians, ./math/io/[io_bigints, io_fields] -import ./zoo_exports - const EthVerkleSeed* = "eth_verkle_oct_2021" func generate_random_points*(r: var openArray[EC_TwEdw_Aff[Fp[Banderwagon]]]) = @@ -151,7 +149,7 @@ type func serialize*(dst: var EthVerkleIpaProofBytes, src: IpaProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = + ): cttEthVerkleIpaStatus {.discardable.} = # Note: We store 1 out of 2 coordinates of an EC point, so size(Fp[Banderwagon]) const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -170,7 +168,7 @@ func serialize*(dst: var EthVerkleIpaProofBytes, return cttEthVerkleIpa_Success func deserialize*(dst: var EthVerkleIpaProof, - src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = + src: EthVerkleIpaProofBytes): cttEthVerkleIpaStatus {.discardable.} = const fpb = sizeof(Fp[Banderwagon]) const frb = sizeof(Fr[Banderwagon]) @@ -190,7 +188,7 @@ func deserialize*(dst: var EthVerkleIpaProof, func serialize*(dst: var EthVerkleIpaMultiProofBytes, src: IpaMultiProof[8, EC_TwEdw[Fp[Banderwagon]], Fr[Banderwagon]] - ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa, discardable.} = + ): cttEthVerkleIpaStatus {.discardable.} = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](dst.addr) @@ -202,7 +200,7 @@ func serialize*(dst: var EthVerkleIpaMultiProofBytes, func deserialize*(dst: var EthVerkleIpaMultiProof, src: EthVerkleIpaMultiProofBytes - ): cttEthVerkleIpaStatus {.libPrefix: prefix_ipa.} = + ): cttEthVerkleIpaStatus = const frb = sizeof(Fr[Banderwagon]) let D = cast[ptr array[frb, byte]](src.unsafeAddr) @@ -217,7 +215,7 @@ func deserialize*(dst: var EthVerkleIpaMultiProof, # TODO: refactor, this shouldn't use curves_primitives but internal functions import ./lowlevel_fields -func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.libPrefix: prefix_ipa, discardable.} = +func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) {.discardable.} = ## The mapping chosen for the Banderwagon Curve is x/y ## ## This function takes a Banderwagon element & then @@ -229,7 +227,7 @@ func map_to_base_field*(dst: var Fp[Banderwagon],p: EC_TwEdw[Fp[Banderwagon]]) { invY.inv(p.y) # invY = 1/Y dst.prod(p.x, invY) # dst = (X) * (1/Y) -func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.libPrefix: prefix_ipa, discardable.} = +func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]]): bool {.discardable.} = ## This function takes the x/y value from the above function as Fp element ## and convert that to bytes in Big Endian, ## and then load that to a Fr element @@ -248,7 +246,7 @@ func map_to_scalar_field*(res: var Fr[Banderwagon], p: EC_TwEdw[Fp[Banderwagon]] func batch_map_to_scalar_field*( res: var openArray[Fr[Banderwagon]], - points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.libPrefix: prefix_ipa, discardable, noinline.} = + points: openArray[EC_TwEdw[Fp[Banderwagon]]]): bool {.discardable, noinline.} = ## This function performs the `mapToScalarField` operation ## on a batch of points ## From 945756622969d81619e573a9febd8db0d0f676bd Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Mon, 21 Oct 2024 23:56:25 +0530 Subject: [PATCH 19/21] add scalar mul --- bindings/c_curve_decls.nim | 15 ++++++++++++++- bindings/lib_curves.nim | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index 70bbfc48..f76b2b87 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -464,7 +464,7 @@ template genBindings_EC_TwEdw_Affine*(EC, Field: untyped) = {.pop.} -template genBindings_EC_TwEdw_Projective*(EC, EcAff, Field: untyped) = +template genBindings_EC_TwEdw_Projective*(EC, EcAff, ScalarBig, ScalarField: untyped) = when appType == "lib": {.push noconv, dynlib, exportc, raises: [].} # No exceptions allowed else: @@ -515,6 +515,19 @@ template genBindings_EC_TwEdw_Projective*(EC, EcAff, Field: untyped) = func `ctt _ EC _ from_affine`(dst: var EC, src: EcAff) = dst.fromAffine(src) + + func `ctt _ EC _ batch_affine`(dst: ptr UncheckedArray[EcAff], src: ptr UncheckedArray[EC], n: csize_t) = + dst.batchAffine(src, cast[int](n)) + + func `ctt _ EC _ scalar_mul_big_coef`( + P: var EC, scalar: ScalarBig) = + + P.scalarMul(scalar) + + func `ctt _ EC _ scalar_mul_fr_coef`( + P: var EC, scalar: ScalarField) = + + P.scalarMul(scalar) {.pop.} diff --git a/bindings/lib_curves.nim b/bindings/lib_curves.nim index 9f4e3a39..ffe06ccf 100644 --- a/bindings/lib_curves.nim +++ b/bindings/lib_curves.nim @@ -154,4 +154,4 @@ collectBindings(cBindings_banderwagon): genBindingsField(big255, banderwagon_fp) genBindingsFieldSqrt(banderwagon_fp) genBindings_EC_TwEdw_Affine(banderwagon_twedw_aff, banderwagon_fp) - genBindings_EC_TwEdw_Projective(banderwagon_twedw_prj, banderwagon_twedw_aff, banderwagon_fr) \ No newline at end of file + genBindings_EC_TwEdw_Projective(banderwagon_twedw_prj, banderwagon_twedw_aff, big253, banderwagon_fr) \ No newline at end of file From a87638b378427bb31402ab1d5940241992bb2458 Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Tue, 22 Oct 2024 23:01:11 +0530 Subject: [PATCH 20/21] more exports for banderwagon scalar mul --- bindings/c_curve_decls.nim | 26 +++++++++++++++++++----- constantine/lowlevel_elliptic_curves.nim | 1 + include/constantine/curves/banderwagon.h | 7 +++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/bindings/c_curve_decls.nim b/bindings/c_curve_decls.nim index f76b2b87..db263e83 100644 --- a/bindings/c_curve_decls.nim +++ b/bindings/c_curve_decls.nim @@ -519,15 +519,31 @@ template genBindings_EC_TwEdw_Projective*(EC, EcAff, ScalarBig, ScalarField: unt func `ctt _ EC _ batch_affine`(dst: ptr UncheckedArray[EcAff], src: ptr UncheckedArray[EC], n: csize_t) = dst.batchAffine(src, cast[int](n)) - func `ctt _ EC _ scalar_mul_big_coef`( - P: var EC, scalar: ScalarBig) = + func `ctt _ EC _ scalar_mul_big_coef`(P: var EC, scalar: ScalarBig) = + P.scalarMul(scalar) + func `ctt _ EC _ scalar_mul_fr_coef`(P: var EC, scalar: ScalarField) = P.scalarMul(scalar) - func `ctt _ EC _ scalar_mul_fr_coef`( - P: var EC, scalar: ScalarField) = + func `ctt _ EC _ scalar_mul_big_coef_vartime`(P: var EC, scalar: ScalarBig) = + P.scalarMul_vartime(scalar) - P.scalarMul(scalar) + func `ctt _ EC _ scalar_mul_fr_coef_vartime`(P: var EC, scalar: ScalarField) = + P.scalarMul_vartime(scalar) + + func `ctt _ EC _ multi_scalar_mul_big_coefs_vartime`( + r: var EC, + coefs: ptr UncheckedArray[ScalarBig], + points: ptr UncheckedArray[EcAff], + len: csize_t) = + r.multiScalarMul_vartime(coefs, points, cast[int](len)) + + func `ctt _ EC _ multi_scalar_mul_fr_coefs_vartime`( + r: var EC, + coefs: ptr UncheckedArray[ScalarField], + points: ptr UncheckedArray[EcAff], + len: csize_t)= + r.multiScalarMul_vartime(coefs, points, cast[int](len)) {.pop.} diff --git a/constantine/lowlevel_elliptic_curves.nim b/constantine/lowlevel_elliptic_curves.nim index c5119168..03577ae5 100644 --- a/constantine/lowlevel_elliptic_curves.nim +++ b/constantine/lowlevel_elliptic_curves.nim @@ -114,6 +114,7 @@ export ec_twistededwards.`-=` export ec_twistededwards.affine export ec_twistededwards.projective export ec_twistededwards.fromAffine +export ec_twistededwards.batchAffine export ec_twistededwards.sum_vartime export ec_twistededwards.mixedSum_vartime export ec_twistededwards.diff_vartime diff --git a/include/constantine/curves/banderwagon.h b/include/constantine/curves/banderwagon.h index a6ccd9b6..82102b2d 100644 --- a/include/constantine/curves/banderwagon.h +++ b/include/constantine/curves/banderwagon.h @@ -118,6 +118,13 @@ void ctt_banderwagon_ec_prj_diff_in_place(banderwagon_ec_prj* P, const banderwag void ctt_banderwagon_ec_prj_mixed_diff_in_place(banderwagon_ec_prj* P, const banderwagon_ec_aff* Q); void ctt_banderwagon_ec_prj_affine(banderwagon_ec_aff* dst, const banderwagon_ec_prj* src); void ctt_banderwagon_ec_prj_from_affine(banderwagon_ec_prj* dst, const banderwagon_ec_aff* src); +void ctt_banderwagon_ec_prj_batch_affine(const banderwagon_ec_aff dst[], const banderwagon_ec_prj src[], size_t n); +void ctt_banderwagon_ec_prj_scalar_mul_big_coef(banderwagon_ec_prj* P, const big253* scalar); +void ctt_banderwagon_ec_prj_scalar_mul_fr_coef(banderwagon_ec_prj* P, const banderwagon_fr* scalar); +void ctt_banderwagon_ec_prj_scalar_mul_big_coef_vartime(banderwagon_ec_prj* P, const big253* scalar); +void ctt_banderwagon_ec_prj_scalar_mul_fr_coef_vartime(banderwagon_ec_prj* P, const banderwagon_fr* scalar); +void ctt_banderwagon_ec_prj_multi_scalar_mul_big_coefs_vartime(banderwagon_ec_prj* r, const big253 coefs[], const banderwagon_ec_aff points[], size_t len); +void ctt_banderwagon_ec_prj_multi_scalar_mul_fr_coefs_vartime(banderwagon_ec_prj* r, const banderwagon_fr coefs[], const banderwagon_ec_aff points[], size_t len); #ifdef __cplusplus } From 078ea23259194c5c9809cb7611f9acaa75e7d3cd Mon Sep 17 00:00:00 2001 From: Richa-iitr Date: Mon, 28 Oct 2024 21:10:20 +0530 Subject: [PATCH 21/21] remove verkle header file changes --- .../protocols/ethereum_verkle_ipa.h | 228 ------------------ 1 file changed, 228 deletions(-) delete mode 100644 include/constantine/protocols/ethereum_verkle_ipa.h diff --git a/include/constantine/protocols/ethereum_verkle_ipa.h b/include/constantine/protocols/ethereum_verkle_ipa.h deleted file mode 100644 index 23a498ce..00000000 --- a/include/constantine/protocols/ethereum_verkle_ipa.h +++ /dev/null @@ -1,228 +0,0 @@ -/** 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. - */ -#ifndef __CTT_H_ETHEREUM_VERKLE_IPA__ -#define __CTT_H_ETHEREUM_VERKLE_IPA__ - -#include "constantine/core/datatypes.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum __attribute__((__packed__)) { - cttEthVerkleIpa_Success, - cttEthVerkleIpa_VerificationFailure, - cttEthVerkleIpa_InputsLengthsMismatch, - cttEthVerkleIpa_ScalarZero, - cttEthVerkleIpa_ScalarLargerThanCurveOrder, - cttEthVerkleIpa_EccInvalidEncoding, - cttEthVerkleIpa_EccCoordinateGreaterThanOrEqualModulus, - cttEthVerkleIpa_EccPointNotOnCurve, - cttEthVerkleIpa_EccPointNotInSubGroup -} ctt_eth_verkle_ipa_status; - -static const char* ctt_eth_verkle_ipa_status_to_string(ctt_eth_verkle_ipa_status status) { - static const char* const statuses[] = { - "cttEthVerkleIpa_Success", - "cttEthVerkleIpa_VerificationFailure", - "cttEthVerkleIpa_InputsLengthsMismatch", - "cttEthVerkleIpa_ScalarZero", - "cttEthVerkleIpa_ScalarLargerThanCurveOrder", - "cttEthVerkleIpa_EccInvalidEncoding", - "cttEthVerkleIpa_EccCoordinateGreaterThanOrEqualModulus", - "cttEthVerkleIpa_EccPointNotOnCurve", - "cttEthVerkleIpa_EccPointNotInSubGroup" - }; - size_t length = sizeof statuses / sizeof *statuses; - if (0 <= status && status < length) { - return statuses[status]; - } - return "cttEthVerkleIpa_InvalidStatusCode"; -} - -// Opaque types for Nim-defined types -typedef struct Fr Fr; -typedef struct Banderwagon Banderwagon; -typedef struct EC_TwEdw EC_TwEdw; -typedef struct Fp Fp; - -typedef union { - uint8_t u8; - uint16_t u16; - uint32_t u32; - uint64_t u64; - unsigned int u; -} SomeUnsignedInt; - -typedef struct { - SomeUnsignedInt* values; - size_t length; -} SomeUnsignedInt_Array; - -// Define types for openArray -typedef struct { - Fr* data; - size_t len; -} Fr_BanderWagon_OpenArray; - -typedef struct { - EC_TwEdw* data; - size_t len; -} EC_TwEdw_Fp_Banderwagon_OpenArray; - -typedef struct { - byte value[32]; // 32-byte array for field element -} Fp_Banderwagon; - -typedef struct { - byte value[32]; // 32-byte array for field element -} Fr_Banderwagon; - -typedef struct { - byte x[32]; // 32-byte x-coordinate - byte y[32]; // 32-byte y-coordinate -} EC_TwEdw_Fp_Banderwagon; - -typedef struct { - byte x[32]; // 32-byte x-coordinate - byte y[32]; // 32-byte y-coordinate -} EC; - -typedef struct { - EC* points; - size_t length; -} PolynomialEval_EC; - -typedef struct { - Fr* points; - size_t length; -} PolynomialEval_Fr; - -typedef struct { - EC* points; - size_t length; -} PolynomialEval_EcAff; - -typedef struct { - Fr* domain_values; - size_t length; -} PolyEvalLinearDomain_Fr; - -typedef struct { - EC* ec_points; - Fr* field_elements; - size_t logN; -} IpaProof_EcAff_Fr; - -typedef struct { - EC* ec_points; - Fr* field_elements; - size_t logN; -} IpaMultiProof_EcAff_Fr; - -typedef struct { - EC* ec_points; - size_t length; -} EcAffArray; - -typedef struct EthVerkleIpaProof EthVerkleIpaProof; -typedef struct EthVerkleIpaMultiProof EthVerkleIpaMultiProof; -typedef struct IpaProof IpaProof; -typedef struct IpaMultiProof IpaMultiProof; -typedef struct EthVerkleTranscript EthVerkleTranscript; - -typedef byte EthVerkleIpaProofBytes[544]; // Array of 544 bytes -typedef byte EthVerkleIpaMultiProofBytes[576]; - - -ctt_eth_verkle_ipa_status ctt_eth_verkle_serialize( - EthVerkleIpaProofBytes* dst, - const IpaProof* src - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_serialize( - EthVerkleIpaMultiProofBytes* dst, - const IpaMultiProof* src - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( - const EthVerkleIpaProof* dst, - EthVerkleIpaProofBytes* src - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_deserialize( - const EthVerkleIpaMultiProof* dst, - EthVerkleIpaMultiProofBytes* src - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_map_to_base_field( - Fp_Banderwagon* dst, const EC_TwEdw_Fp_Banderwagon* p - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_map_to_scalar_field( - Fr_Banderwagon* res, const EC_TwEdw_Fp_Banderwagon* p - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_batch_map_to_base_field( - Fr_BanderWagon_OpenArray* res, const EC_TwEdw_Fp_Banderwagon_OpenArray* p - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_commit( - const PolynomialEval_EC* crs, - EC* r, - const PolynomialEval_Fr* poly - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_prove( - const PolynomialEval_EcAff* crs, - const PolyEvalLinearDomain_Fr* domain, - EthVerkleTranscript* transcript, - Fr* eval_at_challenge, - IpaProof_EcAff_Fr* proof, - const PolynomialEval_Fr* poly, - const EC* commitment, - const Fr* opening_challenge - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_verify( - const PolynomialEval_EcAff* crs, - const PolyEvalLinearDomain_Fr* domain, - EthVerkleTranscript* transcript, - const EC* commitment, - const Fr* opening_challenge, - Fr* eval_at_challenge, - IpaProof_EcAff_Fr* proof - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_prove( - const PolynomialEval_EcAff* crs, - const PolyEvalLinearDomain_Fr* domain, - EthVerkleTranscript* transcript, - IpaMultiProof_EcAff_Fr* proof, - const PolynomialEval_Fr* polys, - const EC_TwEdw_Fp_Banderwagon_OpenArray* commitments, - const Fr_BanderWagon_OpenArray* opening_challenges_in_domain - ) __attribute__((warn_unused_result)); - -ctt_eth_verkle_ipa_status ctt_eth_verkle_ipa_multi_verify( - const PolynomialEval_EcAff* crs, - const PolyEvalLinearDomain_Fr* domain, - EthVerkleTranscript* transcript, - const EC_TwEdw_Fp_Banderwagon_OpenArray* commitments, - const Fr_BanderWagon_OpenArray* opening_challenges_in_domain, - Fr_BanderWagon_OpenArray* evals_at_challenges, - IpaMultiProof_EcAff_Fr* proof - ) __attribute__((warn_unused_result)); - -#ifdef __cplusplus -} -#endif - -#endif // __CTT_H_ETHEREUM_VERKLE_IPA__