diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 000000000..0514eb33d --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,3 @@ +[build] +# https://doc.rust-lang.org/rustc/linker-plugin-lto.html +rustflags="-Clinker-plugin-lto -Clinker=clang -Clink-arg=-fuse-ld=lld" \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6a1921d76..2352ee708 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -236,16 +236,18 @@ jobs: shell: bash run: | cd constantine - nimble bindings --verbose - nimble test_bindings --verbose + nimble make_lib --verbose + nimble make_headers --verbose + nimble test_lib --verbose nimble test_parallel --verbose - name: Run Constantine tests (UNIX no Assembly) if: runner.os != 'Windows' && matrix.target.BACKEND == 'NO_ASM' shell: bash run: | cd constantine - CTT_ASM=0 nimble bindings --verbose - nimble test_bindings --verbose + CTT_ASM=0 nimble make_lib --verbose + nimble make_headers --verbose + nimble test_lib --verbose CTT_ASM=0 nimble test_parallel --verbose - name: Run Constantine tests (Windows with Assembly) # So "test_bindings" uses C and can find GMP @@ -254,8 +256,9 @@ jobs: shell: msys2 {0} run: | cd constantine - nimble bindings --verbose - nimble test_bindings --verbose + nimble make_lib --verbose + nimble make_headers --verbose + nimble test_lib --verbose nimble test_parallel_no_gmp --verbose - name: Run Constantine tests (Windows no Assembly) # So "test_bindings" uses C and can find GMP @@ -264,6 +267,7 @@ jobs: shell: msys2 {0} run: | cd constantine - CTT_ASM=0 nimble bindings --verbose - nimble test_bindings --verbose + CTT_ASM=0 nimble make_lib --verbose + nimble make_headers --verbose + nimble test_lib --verbose CTT_ASM=0 nimble test_parallel_no_gmp --verbose diff --git a/.gitignore b/.gitignore index 0f21d0348..1c2f5bb63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1,47 @@ -nimcache/ - # Executables shall be put in an ignored build/ directory # Ignore dynamic, static libs and libtool archive files build/ *.so +*.so.* *.dylib *.a *.la -*.exe *.dll +*.exe +*.out + +# Nim +# ----------------------------------------------------------------------------------------- +nimcache/ + +# Rust +# ----------------------------------------------------------------------------------------- + +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb # Sage +# ----------------------------------------------------------------------------------------- *.sage.py -# Tests -test_*.txt +# Swap or debug +# ----------------------------------------------------------------------------------------- +*.swp +*~ + +# Perf artifacts +# ----------------------------------------------------------------------------------------- +perf.data +perf.data.old \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..efe03c756 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,23 @@ +[workspace] +resolver = "2" +members = [ + "constantine-rust/constantine-sys", + "constantine-rust/ctt-curve-bls12-381", + "constantine-rust/ctt-curve-bn254-snarks", + "constantine-rust/ctt-curve-pasta", + "constantine-rust/ctt-proto-ethereum-bls-signatures", +] + +# The Nim static library is compiled with ThinLTO, always enable it + +[profile.dev] +lto = "thin" + +[profile.test] +lto = "thin" + +[profile.release] +lto = "thin" + +[profile.bench] +lto = "thin" \ No newline at end of file diff --git a/bindings_generators/README.md b/bindings/README.md similarity index 100% rename from bindings_generators/README.md rename to bindings/README.md diff --git a/bindings_generators/gen_bindings.nim b/bindings/c_curve_decls.nim similarity index 100% rename from bindings_generators/gen_bindings.nim rename to bindings/c_curve_decls.nim diff --git a/bindings_generators/gen_header.nim b/bindings/c_typedefs.nim similarity index 72% rename from bindings_generators/gen_header.nim rename to bindings/c_typedefs.nim index 292e9daf1..1e6bd9449 100644 --- a/bindings_generators/gen_header.nim +++ b/bindings/c_typedefs.nim @@ -26,11 +26,13 @@ proc genHeaderLicense*(): string = */ """ -proc genHeader*(name, body: string): string = +proc genHeaderGuardAndInclude*(name, body: string): string = &""" #ifndef __CTT_H_{name}__ #define __CTT_H_{name}__ +#include "constantine/core/datatypes.h" + {body} #endif @@ -70,9 +72,9 @@ typedef __UINT64_TYPE__ uint64_t; #endif #if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901 -# define bool _Bool +# define ctt_bool _Bool #else -# define bool unsigned char +# define ctt_bool unsigned char #endif """ @@ -85,12 +87,12 @@ typedef uint8_t byte; proc genWordsRequired*(): string = """ -#define WordBitWidth (sizeof(secret_word)*8) -#define words_required(bits) ((bits+WordBitWidth-1)/WordBitWidth) +#define CTT_WORD_BITWIDTH (sizeof(secret_word)*8) +#define CTT_WORDS_REQUIRED(bits) ((bits+WordBitWidth-1)/WordBitWidth) """ proc genField*(name: string, bits: int): string = - &"typedef struct {{ secret_word limbs[words_required({bits})]; }} {name};" + &"typedef struct {{ secret_word limbs[CTT_WORDS_REQUIRED({bits})]; }} {name};" proc genExtField*(name: string, degree: int, basename: string): string = &"typedef struct {{ {basename} c[{degree}]; }} {name};" @@ -121,12 +123,12 @@ void ctt_{libName}_init_NimMain(void);""" # ------------------------------------------- let TypeMap {.compileTime.} = newStringTable({ - "bool": "bool", + "bool": "ctt_bool ", "SecretBool": "secret_bool", "SecretWord": "secret_word" }) -proc toCrettype(node: NimNode): string = +proc toCrettype*(node: NimNode): string = node.expectKind({nnkEmpty, nnkSym}) if node.kind == nnkEmpty: # align iwth secret_bool and secret_word @@ -134,7 +136,7 @@ proc toCrettype(node: NimNode): string = else: TypeMap[$node] -proc toCtrivialParam(name: string, typ: NimNode): string = +proc toCtrivialParam*(name: string, typ: NimNode): string = typ.expectKind({nnkVarTy, nnkSym}) let isVar = typ.kind == nnkVarTy @@ -151,7 +153,7 @@ proc toCtrivialParam(name: string, typ: NimNode): string = # Pass-by-reference constify & sTyp & "* " & name -proc toCparam(name: string, typ: NimNode): string = +proc toCparam*(name: string, typ: NimNode): string = typ.expectKind({nnkVarTy, nnkCall, nnkSym}) if typ.kind == nnkCall: @@ -174,46 +176,3 @@ proc toCparam(name: string, typ: NimNode): string = sTyp & " " & name & "[], ptrdiff_t " & name & "_len" else: toCtrivialParam(name, typ) - -macro collectBindings*(cBindingsStr: untyped, body: typed): untyped = - ## Collect function definitions from a generator template - - body.expectKind(nnkStmtList) - - var cBindings: string - - for generator in body: - generator.expectKind(nnkStmtList) - for fnDef in generator: - if fnDef.kind notin {nnkProcDef, nnkFuncDef}: - continue - - cBindings &= "\n" - # rettype name(pType0* pName0, pType1* pName1, ...); - cBindings &= fnDef.params[0].toCrettype() - cBindings &= ' ' - cBindings &= $fnDef.name - cBindings &= '(' - for i in 1 ..< fnDef.params.len: - if i != 1: cBindings &= ", " - - let paramDef = fnDef.params[i] - paramDef.expectKind(nnkIdentDefs) - let pType = paramDef[^2] - # No default value - paramDef[^1].expectKind(nnkEmpty) - - for j in 0 ..< paramDef.len - 2: - if j != 0: cBindings &= ", " - var name = $paramDef[j] - cBindings &= toCparam(name.split('`')[0], pType) - - if fnDef.params[0].eqIdent"bool": - cBindings &= ") __attribute__((warn_unused_result));" - else: - cBindings &= ");" - - if defined(CTT_GENERATE_HEADERS): - result = newConstStmt(cBindingsStr, newLit cBindings) - else: - result = body diff --git a/bindings/lib_constantine.nim b/bindings/lib_constantine.nim new file mode 100644 index 000000000..e807f8657 --- /dev/null +++ b/bindings/lib_constantine.nim @@ -0,0 +1,21 @@ +# 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. + +# ############################################################ +# +# Constantine library +# +# ############################################################ + +{.push warning[UnusedImport]: off.} + +import + ./lib_hashes, + ./lib_curves, + # Protocols + ../constantine/ethereum_bls_signatures \ No newline at end of file diff --git a/bindings/lib_curves.nim b/bindings/lib_curves.nim new file mode 100644 index 000000000..64c0ce977 --- /dev/null +++ b/bindings/lib_curves.nim @@ -0,0 +1,152 @@ +# 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. + +# ############################################################ +# +# Curves +# +# ############################################################ + +import ./c_curve_decls +export c_curve_decls + +when not defined(CTT_MAKE_HEADERS): + template collectBindings(cBindingsStr: untyped, body: typed): untyped = + body +else: + # We gate `c_typedefs` as it imports strutils + # which uses the {.rtl.} pragma and might compile in Nim Runtime Library procs + # that cannot be removed. + # + # We want to ensure its only used for header generation, not in deployment. + import ./c_typedefs + import std/[macros, strutils] + + macro collectBindings(cBindingsStr: untyped, body: typed): untyped = + ## Collect function definitions from a generator template + var cBindings: string + for generator in body: + generator.expectKind(nnkStmtList) + for fnDef in generator: + if fnDef.kind notin {nnkProcDef, nnkFuncDef}: + continue + + cBindings &= "\n" + # rettype name(pType0* pName0, pType1* pName1, ...); + cBindings &= fnDef.params[0].toCrettype() + cBindings &= ' ' + cBindings &= $fnDef.name + cBindings &= '(' + for i in 1 ..< fnDef.params.len: + if i != 1: cBindings &= ", " + + let paramDef = fnDef.params[i] + paramDef.expectKind(nnkIdentDefs) + let pType = paramDef[^2] + # No default value + paramDef[^1].expectKind(nnkEmpty) + + for j in 0 ..< paramDef.len - 2: + if j != 0: cBindings &= ", " + var name = $paramDef[j] + cBindings &= toCparam(name.split('`')[0], pType) + + if fnDef.params[0].eqIdent"bool": + cBindings &= ") __attribute__((warn_unused_result));" + else: + cBindings &= ");" + + + result = newConstStmt(nnkPostfix.newTree(ident"*", cBindingsStr), newLit cBindings) + + +# ---------------------------------------------------------- + +type + bls12_381_fr = Fr[BLS12_381] + bls12_381_fp = Fp[BLS12_381] + bls12_381_fp2 = Fp2[BLS12_381] + bls12_381_ec_g1_aff = ECP_ShortW_Aff[Fp[BLS12_381], G1] + bls12_381_ec_g1_jac = ECP_ShortW_Jac[Fp[BLS12_381], G1] + bls12_381_ec_g1_prj = ECP_ShortW_Prj[Fp[BLS12_381], G1] + bls12_381_ec_g2_aff = ECP_ShortW_Aff[Fp2[BLS12_381], G2] + bls12_381_ec_g2_jac = ECP_ShortW_Jac[Fp2[BLS12_381], G2] + bls12_381_ec_g2_prj = ECP_ShortW_Prj[Fp2[BLS12_381], G2] + +collectBindings(cBindings_bls12_381): + genBindingsField(bls12_381_fr) + genBindingsField(bls12_381_fp) + genBindingsFieldSqrt(bls12_381_fp) + genBindingsExtField(bls12_381_fp2) + genBindingsExtFieldSqrt(bls12_381_fp2) + genBindings_EC_ShortW_Affine(bls12_381_ec_g1_aff, bls12_381_fp) + genBindings_EC_ShortW_NonAffine(bls12_381_ec_g1_jac, bls12_381_ec_g1_aff, bls12_381_fp) + genBindings_EC_ShortW_NonAffine(bls12_381_ec_g1_prj, bls12_381_ec_g1_aff, bls12_381_fp) + genBindings_EC_ShortW_Affine(bls12_381_ec_g2_aff, bls12_381_fp2) + genBindings_EC_ShortW_NonAffine(bls12_381_ec_g2_jac, bls12_381_ec_g2_aff, bls12_381_fp2) + genBindings_EC_ShortW_NonAffine(bls12_381_ec_g2_prj, bls12_381_ec_g2_aff, bls12_381_fp2) + +# ---------------------------------------------------------- + +type + bn254_snarks_fr = Fr[BN254_Snarks] + bn254_snarks_fp = Fp[BN254_Snarks] + bn254_snarks_fp2 = Fp2[BN254_Snarks] + bn254_snarks_ec_g1_aff = ECP_ShortW_Aff[Fp[BN254_Snarks], G1] + bn254_snarks_ec_g1_jac = ECP_ShortW_Jac[Fp[BN254_Snarks], G1] + bn254_snarks_ec_g1_prj = ECP_ShortW_Prj[Fp[BN254_Snarks], G1] + bn254_snarks_ec_g2_aff = ECP_ShortW_Aff[Fp2[BN254_Snarks], G2] + bn254_snarks_ec_g2_jac = ECP_ShortW_Jac[Fp2[BN254_Snarks], G2] + bn254_snarks_ec_g2_prj = ECP_ShortW_Prj[Fp2[BN254_Snarks], G2] + +collectBindings(cBindings_bn254_snarks): + genBindingsField(bn254_snarks_fr) + genBindingsField(bn254_snarks_fp) + genBindingsFieldSqrt(bn254_snarks_fp) + genBindingsExtField(bn254_snarks_fp2) + genBindingsExtFieldSqrt(bn254_snarks_fp2) + genBindings_EC_ShortW_Affine(bn254_snarks_ec_g1_aff, bn254_snarks_fp) + genBindings_EC_ShortW_NonAffine(bn254_snarks_ec_g1_jac, bn254_snarks_ec_g1_aff, bn254_snarks_fp) + genBindings_EC_ShortW_NonAffine(bn254_snarks_ec_g1_prj, bn254_snarks_ec_g1_aff, bn254_snarks_fp) + genBindings_EC_ShortW_Affine(bn254_snarks_ec_g2_aff, bn254_snarks_fp2) + genBindings_EC_ShortW_NonAffine(bn254_snarks_ec_g2_jac, bn254_snarks_ec_g2_aff, bn254_snarks_fp2) + genBindings_EC_ShortW_NonAffine(bn254_snarks_ec_g2_prj, bn254_snarks_ec_g2_aff, bn254_snarks_fp2) + +# ---------------------------------------------------------- + +type + pallas_fr = Fr[Pallas] + pallas_fp = Fp[Pallas] + pallas_ec_aff = ECP_ShortW_Aff[Fp[Pallas], G1] + pallas_ec_jac = ECP_ShortW_Jac[Fp[Pallas], G1] + pallas_ec_prj = ECP_ShortW_Prj[Fp[Pallas], G1] + +collectBindings(cBindings_pallas): + genBindingsField(pallas_fr) + genBindingsField(pallas_fp) + genBindingsFieldSqrt(pallas_fp) + genBindings_EC_ShortW_Affine(pallas_ec_aff, pallas_fp) + genBindings_EC_ShortW_NonAffine(pallas_ec_jac, pallas_ec_aff, pallas_fp) + genBindings_EC_ShortW_NonAffine(pallas_ec_prj, pallas_ec_aff, pallas_fp) + +type + vesta_fr = Fr[Vesta] + vesta_fp = Fp[Vesta] + vesta_ec_aff = ECP_ShortW_Aff[Fp[Vesta], G1] + vesta_ec_jac = ECP_ShortW_Jac[Fp[Vesta], G1] + vesta_ec_prj = ECP_ShortW_Prj[Fp[Vesta], G1] + +collectBindings(cBindings_vesta): + genBindingsField(vesta_fr) + genBindingsField(vesta_fp) + genBindingsFieldSqrt(vesta_fp) + genBindings_EC_ShortW_Affine(vesta_ec_aff, vesta_fp) + genBindings_EC_ShortW_NonAffine(vesta_ec_jac, vesta_ec_aff, vesta_fp) + genBindings_EC_ShortW_NonAffine(vesta_ec_prj, vesta_ec_aff, vesta_fp) + +# ---------------------------------------------------------- diff --git a/bindings/lib_hashes.nim b/bindings/lib_hashes.nim new file mode 100644 index 000000000..3a4b0e938 --- /dev/null +++ b/bindings/lib_hashes.nim @@ -0,0 +1,34 @@ +# 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. + +# ############################################################ +# +# Hashes +# +# ############################################################ + +import ../constantine/zoo_exports + +# Modify per-module prefix if needed +# ---------------------------------------- +# static: +# prefix_sha256 = prefix_ffi & "sha256_" + +import ../constantine/hashes + +func sha256_hash(digest: var array[32, byte], message: openArray[byte], clearMem: bool) {.libPrefix: "ctt_".} = + ## Compute the SHA-256 hash of message + ## and store the result in digest. + ## Optionally, clear the memory buffer used. + + # There is an extra indirect function call as we use a generic `hash` concept but: + # - the indirection saves space (instead of duplicating `hash`) + # - minimal overhead compared to hashing time + # - Can be tail-call optimized into a goto jump instead of call/return + # - Can be LTO-optimized + sha256.hash(digest, message, clearMem) \ No newline at end of file diff --git a/bindings/lib_headers.nim b/bindings/lib_headers.nim new file mode 100644 index 000000000..503abd5c3 --- /dev/null +++ b/bindings/lib_headers.nim @@ -0,0 +1,97 @@ +# 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. + +# ############################################################ +# +# Generator for curve headers +# +# ############################################################ + +import std/[os, strformat, strutils] +import ./c_typedefs, ./lib_curves + +proc writeHeader_classicCurve(filepath: string, curve: string, modBits, orderBits: int, curve_decls: string) = + var header: string + header &= genField(&"{curve}_fr", orderBits) + header &= '\n' + header &= genField(&"{curve}_fp", modBits) + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_aff", "x, y", &"{curve}_fp") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_jac", "x, y, z", &"{curve}_fp") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_prj", "x, y, z", &"{curve}_fp") + header &= '\n' + header &= curve_decls + header &= '\n' + + header = genCpp(header) + header = genHeaderGuardAndInclude(curve.toUpperASCII(), header) + header = genHeaderLicense() & header + + writeFile(filepath, header) + +proc writeHeader_pairingFriendly(filepath: string, curve: string, modBits, orderBits: int, curve_decls: string, g2_extfield: int) = + let fpK = if g2_extfield == 1: "fp" + else: "fp" & $g2_extfield + + var header: string + header &= genField(&"{curve}_fr", orderBits) + header &= '\n' + header &= genField(&"{curve}_fp", modBits) + header &= '\n' + header &= genExtField(&"{curve}_fp2", 2, &"{curve}_fp") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_g1_aff", "x, y", &"{curve}_fp") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_g1_jac", "x, y, z", &"{curve}_fp") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_g1_prj", "x, y, z", &"{curve}_fp") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_g2_aff", "x, y", &"{curve}_{fpK}") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_g2_jac", "x, y, z", &"{curve}_{fpK}") + header &= '\n' + header &= genEllipticCurvePoint(&"{curve}_ec_g2_prj", "x, y, z", &"{curve}_{fpK}") + header &= '\n' + header &= curve_decls + header &= '\n' + + header = genCpp(header) + header = genHeaderGuardAndInclude(curve.toUpperASCII(), header) + header = genHeaderLicense() & header + + writeFile(filepath, header) + +proc writeHeader(dirPath: string, C: static Curve, curve_decls: string) = + const modBits = C.getCurveBitWidth() + const orderBits = C.getCurveOrderBitWidth() + let curve = ($C).toLowerASCII() + let relPath = dirPath/"constantine"/"curves"/curve & ".h" + + when C.family() == NoFamily: + relPath.writeHeader_classicCurve(curve, modBits, orderBits, curve_decls) + else: + const g2_extfield = C.getEmbeddingDegree() div 6 # All pairing-friendly curves use a sextic twist + relPath.writeHeader_pairingFriendly(curve, modBits, orderBits, curve_decls, g2_extfield) + + echo "Generated header: ", relPath + +proc writeCurveHeaders(dir: string) = + static: doAssert defined(CTT_MAKE_HEADERS), " Pass '-d:CTT_MAKE_HEADERS' to the compiler so that curves declarations are collected." + + writeHeader(dir, BLS12_381, cBindings_bls12_381) + writeHeader(dir, BN254_Snarks, cBindings_bn254_snarks) + writeHeader(dir, Pallas, cBindings_pallas) + writeHeader(dir, Vesta, cBindings_vesta) + +when isMainModule: + proc main() {.inline.} = + writeCurveHeaders("include") + + main() \ No newline at end of file diff --git a/bindings_generators/constantine_bls12_381.nim b/bindings_generators/constantine_bls12_381.nim deleted file mode 100644 index b34c9c8ca..000000000 --- a/bindings_generators/constantine_bls12_381.nim +++ /dev/null @@ -1,87 +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. - -import ./gen_bindings, ./gen_header - -type - bls12381_fr = Fr[BLS12_381] - bls12381_fp = Fp[BLS12_381] - bls12381_fp2 = Fp2[BLS12_381] - bls12381_ec_g1_aff = ECP_ShortW_Aff[Fp[BLS12_381], G1] - bls12381_ec_g1_jac = ECP_ShortW_Jac[Fp[BLS12_381], G1] - bls12381_ec_g1_prj = ECP_ShortW_Prj[Fp[BLS12_381], G1] - bls12381_ec_g2_aff = ECP_ShortW_Aff[Fp2[BLS12_381], G2] - bls12381_ec_g2_jac = ECP_ShortW_Jac[Fp2[BLS12_381], G2] - bls12381_ec_g2_prj = ECP_ShortW_Prj[Fp2[BLS12_381], G2] - -collectBindings(cBindings): - genBindingsField(bls12381_fr) - genBindingsField(bls12381_fp) - genBindingsFieldSqrt(bls12381_fp) - genBindingsExtField(bls12381_fp2) - genBindingsExtFieldSqrt(bls12381_fp2) - genBindings_EC_ShortW_Affine(bls12381_ec_g1_aff, bls12381_fp) - genBindings_EC_ShortW_NonAffine(bls12381_ec_g1_jac, bls12381_ec_g1_aff, bls12381_fp) - genBindings_EC_ShortW_NonAffine(bls12381_ec_g1_prj, bls12381_ec_g1_aff, bls12381_fp) - genBindings_EC_ShortW_Affine(bls12381_ec_g2_aff, bls12381_fp2) - genBindings_EC_ShortW_NonAffine(bls12381_ec_g2_jac, bls12381_ec_g2_aff, bls12381_fp2) - genBindings_EC_ShortW_NonAffine(bls12381_ec_g2_prj, bls12381_ec_g2_aff, bls12381_fp2) - -# Write header -when isMainModule and defined(CTT_GENERATE_HEADERS): - import std/[os, strformat] - - proc main() = - # echo "Running bindings generation for " & getAppFilename().extractFilename() - - var dir = "." - if paramCount() == 1: - dir = paramStr(1) - elif paramCount() > 1: - let exeName = getAppFilename().extractFilename() - echo &"Usage: {exeName} " - echo "Found more than one parameter" - quit 1 - - var header: string - header = genBuiltinsTypes() - header &= '\n' - header &= genCttBaseTypedef() - header &= '\n' - header &= genWordsRequired() - header &= '\n' - header &= genField("bls12381_fr", BLS12_381.getCurveOrderBitWidth()) - header &= '\n' - header &= genField("bls12381_fp", BLS12_381.getCurveBitWidth()) - header &= '\n' - header &= genExtField("bls12381_fp2", 2, "bls12381_fp") - header &= '\n' - header &= genEllipticCurvePoint("bls12381_ec_g1_aff", "x, y", "bls12381_fp") - header &= '\n' - header &= genEllipticCurvePoint("bls12381_ec_g1_jac", "x, y, z", "bls12381_fp") - header &= '\n' - header &= genEllipticCurvePoint("bls12381_ec_g1_prj", "x, y, z", "bls12381_fp") - header &= '\n' - header &= genEllipticCurvePoint("bls12381_ec_g2_aff", "x, y", "bls12381_fp2") - header &= '\n' - header &= genEllipticCurvePoint("bls12381_ec_g2_jac", "x, y, z", "bls12381_fp2") - header &= '\n' - header &= genEllipticCurvePoint("bls12381_ec_g2_prj", "x, y, z", "bls12381_fp2") - header &= '\n' - header &= declNimMain("bls12381") - header &= '\n' - header &= cBindings - header &= '\n' - - header = genCpp(header) - header = genHeader("BLS12381", header) - header = genHeaderLicense() & header - - writeFile(dir/"constantine_bls12_381.h", header) - - main() \ No newline at end of file diff --git a/bindings_generators/constantine_bn254_snarks.nim b/bindings_generators/constantine_bn254_snarks.nim deleted file mode 100644 index e57d69fd7..000000000 --- a/bindings_generators/constantine_bn254_snarks.nim +++ /dev/null @@ -1,87 +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. - -import ./gen_bindings, ./gen_header - -type - bn254snarks_fr = Fr[BN254_Snarks] - bn254snarks_fp = Fp[BN254_Snarks] - bn254snarks_fp2 = Fp2[BN254_Snarks] - bn254snarks_ec_g1_aff = ECP_ShortW_Aff[Fp[BN254_Snarks], G1] - bn254snarks_ec_g1_jac = ECP_ShortW_Jac[Fp[BN254_Snarks], G1] - bn254snarks_ec_g1_prj = ECP_ShortW_Prj[Fp[BN254_Snarks], G1] - bn254snarks_ec_g2_aff = ECP_ShortW_Aff[Fp2[BN254_Snarks], G2] - bn254snarks_ec_g2_jac = ECP_ShortW_Jac[Fp2[BN254_Snarks], G2] - bn254snarks_ec_g2_prj = ECP_ShortW_Prj[Fp2[BN254_Snarks], G2] - -collectBindings(cBindings): - genBindingsField(bn254snarks_fr) - genBindingsField(bn254snarks_fp) - genBindingsFieldSqrt(bn254snarks_fp) - genBindingsExtField(bn254snarks_fp2) - genBindingsExtFieldSqrt(bn254snarks_fp2) - genBindings_EC_ShortW_Affine(bn254snarks_ec_g1_aff, bn254snarks_fp) - genBindings_EC_ShortW_NonAffine(bn254snarks_ec_g1_jac, bn254snarks_ec_g1_aff, bn254snarks_fp) - genBindings_EC_ShortW_NonAffine(bn254snarks_ec_g1_prj, bn254snarks_ec_g1_aff, bn254snarks_fp) - genBindings_EC_ShortW_Affine(bn254snarks_ec_g2_aff, bn254snarks_fp2) - genBindings_EC_ShortW_NonAffine(bn254snarks_ec_g2_jac, bn254snarks_ec_g2_aff, bn254snarks_fp2) - genBindings_EC_ShortW_NonAffine(bn254snarks_ec_g2_prj, bn254snarks_ec_g2_aff, bn254snarks_fp2) - -# Write header -when isMainModule and defined(CTT_GENERATE_HEADERS): - import std/[os, strformat] - - proc main() = - # echo "Running bindings generation for " & getAppFilename().extractFilename() - - var dir = "." - if paramCount() == 1: - dir = paramStr(1) - elif paramCount() > 1: - let exeName = getAppFilename().extractFilename() - echo &"Usage: {exeName} " - echo "Found more than one parameter" - quit 1 - - var header: string - header = genBuiltinsTypes() - header &= '\n' - header &= genCttBaseTypedef() - header &= '\n' - header &= genWordsRequired() - header &= '\n' - header &= genField("bn254snarks_fr", BN254_Snarks.getCurveOrderBitWidth()) - header &= '\n' - header &= genField("bn254snarks_fp", BN254_Snarks.getCurveBitWidth()) - header &= '\n' - header &= genExtField("bn254snarks_fp2", 2, "bn254snarks_fp") - header &= '\n' - header &= genEllipticCurvePoint("bn254snarks_ec_g1_aff", "x, y", "bn254snarks_fp") - header &= '\n' - header &= genEllipticCurvePoint("bn254snarks_ec_g1_jac", "x, y, z", "bn254snarks_fp") - header &= '\n' - header &= genEllipticCurvePoint("bn254snarks_ec_g1_prj", "x, y, z", "bn254snarks_fp") - header &= '\n' - header &= genEllipticCurvePoint("bn254snarks_ec_g2_aff", "x, y", "bn254snarks_fp2") - header &= '\n' - header &= genEllipticCurvePoint("bn254snarks_ec_g2_jac", "x, y, z", "bn254snarks_fp2") - header &= '\n' - header &= genEllipticCurvePoint("bn254snarks_ec_g2_prj", "x, y, z", "bn254snarks_fp2") - header &= '\n' - header &= declNimMain("bn254snarks") - header &= '\n' - header &= cBindings - header &= '\n' - - header = genCpp(header) - header = genHeader("BN@%$SNARKS", header) - header = genHeaderLicense() & header - - writeFile(dir/"constantine_bn254_snarks.h", header) - - main() \ No newline at end of file diff --git a/bindings_generators/constantine_pasta.nim b/bindings_generators/constantine_pasta.nim deleted file mode 100644 index 1c5c937cf..000000000 --- a/bindings_generators/constantine_pasta.nim +++ /dev/null @@ -1,92 +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. - -import ./gen_bindings, ./gen_header - -type - pallas_fr = Fr[Pallas] - pallas_fp = Fp[Pallas] - vesta_fr = Fr[Vesta] - vesta_fp = Fp[Vesta] - pallas_ec_aff = ECP_ShortW_Aff[Fp[Pallas], G1] - pallas_ec_jac = ECP_ShortW_Jac[Fp[Pallas], G1] - pallas_ec_prj = ECP_ShortW_Prj[Fp[Pallas], G1] - vesta_ec_aff = ECP_ShortW_Aff[Fp[Vesta], G1] - vesta_ec_jac = ECP_ShortW_Jac[Fp[Vesta], G1] - vesta_ec_prj = ECP_ShortW_Prj[Fp[Vesta], G1] - -collectBindings(cBindings): - genBindingsField(pallas_fr) - genBindingsField(pallas_fp) - genBindingsFieldSqrt(pallas_fp) - genBindingsField(vesta_fr) - genBindingsField(vesta_fp) - genBindingsFieldSqrt(vesta_fp) - genBindings_EC_ShortW_Affine(pallas_ec_aff, pallas_fp) - genBindings_EC_ShortW_NonAffine(pallas_ec_jac, pallas_ec_aff, pallas_fp) - genBindings_EC_ShortW_NonAffine(pallas_ec_prj, pallas_ec_aff, pallas_fp) - genBindings_EC_ShortW_Affine(vesta_ec_aff, pallas_fp) - genBindings_EC_ShortW_NonAffine(vesta_ec_jac, vesta_ec_aff, vesta_fp) - genBindings_EC_ShortW_NonAffine(vesta_ec_prj, vesta_ec_aff, vesta_fp) - -# Write header -when isMainModule and defined(CTT_GENERATE_HEADERS): - import std/[os, strformat] - - proc main() = - # echo "Running bindings generation for " & getAppFilename().extractFilename() - - var dir = "." - if paramCount() == 1: - dir = paramStr(1) - elif paramCount() > 1: - let exeName = getAppFilename().extractFilename() - echo &"Usage: {exeName} " - echo "Found more than one parameter" - quit 1 - - - var header: string - header = genBuiltinsTypes() - header &= '\n' - header &= genCttBaseTypedef() - header &= '\n' - header &= genWordsRequired() - header &= '\n' - header &= genField("pallas_fr", Pallas.getCurveOrderBitWidth()) - header &= '\n' - header &= genField("pallas_fp", Pallas.getCurveBitWidth()) - header &= '\n' - header &= genField("vesta_fr", Vesta.getCurveOrderBitWidth()) - header &= '\n' - header &= genField("vesta_fp", Vesta.getCurveBitWidth()) - header &= '\n' - header &= genEllipticCurvePoint("pallas_ec_aff", "x, y", "pallas_fp") - header &= '\n' - header &= genEllipticCurvePoint("pallas_ec_jac", "x, y, z", "pallas_fp") - header &= '\n' - header &= genEllipticCurvePoint("pallas_ec_prj", "x, y, z", "pallas_fp") - header &= '\n' - header &= genEllipticCurvePoint("vesta_ec_aff", "x, y", "vesta_fp") - header &= '\n' - header &= genEllipticCurvePoint("vesta_ec_jac", "x, y, z", "vesta_fp") - header &= '\n' - header &= genEllipticCurvePoint("vesta_ec_prj", "x, y, z", "vesta_fp") - header &= '\n' - header &= declNimMain("pasta") - header &= '\n' - header &= cBindings - header &= '\n' - - header = genCpp(header) - header = genHeader("PASTA", header) - header = genHeaderLicense() & header - - writeFile(dir/"constantine_pasta.h", header) - - main() \ No newline at end of file diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 000000000..ec5adbad7 --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1 @@ +-Iinclude \ No newline at end of file diff --git a/constantine-rust/constantine-sys/Cargo.toml b/constantine-rust/constantine-sys/Cargo.toml new file mode 100644 index 000000000..6355fe555 --- /dev/null +++ b/constantine-rust/constantine-sys/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "constantine-sys" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/constantine-rust/constantine-sys/build.rs b/constantine-rust/constantine-sys/build.rs new file mode 100644 index 000000000..25b706c46 --- /dev/null +++ b/constantine-rust/constantine-sys/build.rs @@ -0,0 +1,36 @@ +use std::env; +use std::path::PathBuf; +use std::process::{Command, Stdio}; + +fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + let cargo_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); + let root_dir = cargo_dir + .parent() + .expect("constantine-sys is nested") + .parent() + .expect("constantine-rust is nested"); + + // Avoid full recompilation + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=Cargo.toml"); + println!("cargo:rerun-if-changed={}", cargo_dir.join(".cargo").join("config.toml").display()); + println!("cargo:rerun-if-changed={}", root_dir.join("Cargo.toml").display()); + println!("cargo:rerun-if-changed={}", root_dir.join("constantine").display()); + println!("cargo:rerun-if-changed={}", root_dir.join("bindings").display()); + println!("cargo:rerun-if-changed={}", root_dir.join("constantine.nimble").display()); + + println!("Building Constantine library ..."); + + Command::new("nimble") + .arg("make_lib_rust") + .current_dir(root_dir) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) + .status() + .expect("failed to execute process"); + + println!("cargo:rustc-link-search=native={}", out_dir.display()); + println!("cargo:rustc-link-lib=static=constantine"); + +} \ No newline at end of file diff --git a/constantine-rust/constantine-sys/src/bindings.rs b/constantine-rust/constantine-sys/src/bindings.rs new file mode 100644 index 000000000..bc85c68fb --- /dev/null +++ b/constantine-rust/constantine-sys/src/bindings.rs @@ -0,0 +1,3875 @@ +/* automatically generated by rust-bindgen 0.68.1 */ + +pub type secret_word = usize; +pub type secret_bool = usize; +pub type byte = u8; +#[repr(C)] +#[repr(align(64))] +#[derive(Copy, Clone)] +pub struct ctt_sha256_context { + message_schedule: [u32; 16usize], + buf: [byte; 64usize], + msgLen: u64, +} +#[test] +fn bindgen_test_layout_ctt_sha256_context() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 192usize, + concat!("Size of: ", stringify!(ctt_sha256_context)) + ); + assert_eq!( + ::core::mem::align_of::(), + 64usize, + concat!("Alignment of ", stringify!(ctt_sha256_context)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).message_schedule) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ctt_sha256_context), + "::", + stringify!(message_schedule) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).buf) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(ctt_sha256_context), + "::", + stringify!(buf) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).msgLen) as usize - ptr as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(ctt_sha256_context), + "::", + stringify!(msgLen) + ) + ); +} +extern "C" { + #[doc = " Initialize or reinitialize a Sha256 context."] + pub fn ctt_sha256_init(ctx: *mut ctt_sha256_context); +} +extern "C" { + #[doc = " Append a message to a SHA256 context\n for incremental SHA256 computation\n\n Security note: the tail of your message might be stored\n in an internal buffer.\n if sensitive content is used, ensure that\n `ctx.finish(...)` and `ctx.clear()` are called as soon as possible.\n Additionally ensure that the message(s) passed were stored\n in memory considered secure for your threat model.\n\n For passwords and secret keys, you MUST NOT use raw SHA-256\n use a Key Derivation Function instead (KDF)"] + pub fn ctt_sha256_update( + ctx: *mut ctt_sha256_context, + message: *const byte, + message_len: isize, + ); +} +extern "C" { + #[doc = " Finalize a SHA256 computation and output the\n message digest to the `digest` buffer.\n\n Security note: this does not clear the internal buffer.\n if sensitive content is used, use \"ctx.clear()\"\n and also make sure that the message(s) passed were stored\n in memory considered secure for your threat model.\n\n For passwords and secret keys, you MUST NOT use raw SHA-256\n use a Key Derivation Function instead (KDF)"] + pub fn ctt_sha256_finish(ctx: *mut ctt_sha256_context, digest: *mut byte); +} +extern "C" { + #[doc = " Clear the context internal buffers\n Security note:\n For passwords and secret keys, you MUST NOT use raw SHA-256\n use a Key Derivation Function instead (KDF)"] + pub fn ctt_sha256_clear(ctx: *mut ctt_sha256_context); +} +extern "C" { + #[doc = " Compute the SHA-256 hash of message\n and store the result in digest.\n Optionally, clear the memory buffer used."] + pub fn ctt_sha256_hash( + digest: *mut byte, + message: *const byte, + message_len: isize, + clear_memory: bool, + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_fr { + limbs: [secret_word; 4usize], +} +#[test] +fn bindgen_test_layout_bls12_381_fr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(bls12_381_fr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_fr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_fr), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_fp { + limbs: [secret_word; 6usize], +} +#[test] +fn bindgen_test_layout_bls12_381_fp() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(bls12_381_fp)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_fp)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_fp), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_fp2 { + c: [bls12_381_fp; 2usize], +} +#[test] +fn bindgen_test_layout_bls12_381_fp2() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(bls12_381_fp2)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_fp2)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_fp2), + "::", + stringify!(c) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_ec_g1_aff { + x: bls12_381_fp, + y: bls12_381_fp, +} +#[test] +fn bindgen_test_layout_bls12_381_ec_g1_aff() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(bls12_381_ec_g1_aff)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_ec_g1_aff)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_aff), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_aff), + "::", + stringify!(y) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_ec_g1_jac { + x: bls12_381_fp, + y: bls12_381_fp, + z: bls12_381_fp, +} +#[test] +fn bindgen_test_layout_bls12_381_ec_g1_jac() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 144usize, + concat!("Size of: ", stringify!(bls12_381_ec_g1_jac)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_ec_g1_jac)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_jac), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_jac), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_jac), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_ec_g1_prj { + x: bls12_381_fp, + y: bls12_381_fp, + z: bls12_381_fp, +} +#[test] +fn bindgen_test_layout_bls12_381_ec_g1_prj() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 144usize, + concat!("Size of: ", stringify!(bls12_381_ec_g1_prj)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_ec_g1_prj)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_prj), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_prj), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g1_prj), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_ec_g2_aff { + x: bls12_381_fp2, + y: bls12_381_fp2, +} +#[test] +fn bindgen_test_layout_bls12_381_ec_g2_aff() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 192usize, + concat!("Size of: ", stringify!(bls12_381_ec_g2_aff)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_ec_g2_aff)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_aff), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_aff), + "::", + stringify!(y) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_ec_g2_jac { + x: bls12_381_fp2, + y: bls12_381_fp2, + z: bls12_381_fp2, +} +#[test] +fn bindgen_test_layout_bls12_381_ec_g2_jac() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 288usize, + concat!("Size of: ", stringify!(bls12_381_ec_g2_jac)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_ec_g2_jac)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_jac), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_jac), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 192usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_jac), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bls12_381_ec_g2_prj { + x: bls12_381_fp2, + y: bls12_381_fp2, + z: bls12_381_fp2, +} +#[test] +fn bindgen_test_layout_bls12_381_ec_g2_prj() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 288usize, + concat!("Size of: ", stringify!(bls12_381_ec_g2_prj)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bls12_381_ec_g2_prj)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_prj), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_prj), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 192usize, + concat!( + "Offset of field: ", + stringify!(bls12_381_ec_g2_prj), + "::", + stringify!(z) + ) + ); +} +extern "C" { + #[must_use] + pub fn ctt_bls12_381_fr_unmarshalBE( + dst: *mut bls12_381_fr, + src: *const byte, + src_len: isize, + ) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_bls12_381_fr_marshalBE( + dst: *mut byte, + dst_len: isize, + src: *const bls12_381_fr, + ) -> bool; +} +extern "C" { + pub fn ctt_bls12_381_fr_is_eq(a: *const bls12_381_fr, b: *const bls12_381_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fr_is_zero(a: *const bls12_381_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fr_is_one(a: *const bls12_381_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fr_is_minus_one(a: *const bls12_381_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fr_set_zero(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_set_one(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_set_minus_one(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_neg(r: *mut bls12_381_fr, a: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_neg_in_place(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_sum( + r: *mut bls12_381_fr, + a: *const bls12_381_fr, + b: *const bls12_381_fr, + ); +} +extern "C" { + pub fn ctt_bls12_381_fr_add_in_place(a: *mut bls12_381_fr, b: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_diff( + r: *mut bls12_381_fr, + a: *const bls12_381_fr, + b: *const bls12_381_fr, + ); +} +extern "C" { + pub fn ctt_bls12_381_fr_sub_in_place(a: *mut bls12_381_fr, b: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_double(r: *mut bls12_381_fr, a: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_double_in_place(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_prod( + r: *mut bls12_381_fr, + a: *const bls12_381_fr, + b: *const bls12_381_fr, + ); +} +extern "C" { + pub fn ctt_bls12_381_fr_mul_in_place(a: *mut bls12_381_fr, b: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_square(r: *mut bls12_381_fr, a: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_square_in_place(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_div2(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_inv(r: *mut bls12_381_fr, a: *const bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_inv_in_place(a: *mut bls12_381_fr); +} +extern "C" { + pub fn ctt_bls12_381_fr_ccopy(a: *mut bls12_381_fr, b: *const bls12_381_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fr_cswap(a: *mut bls12_381_fr, b: *mut bls12_381_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fr_cset_zero(a: *mut bls12_381_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fr_cset_one(a: *mut bls12_381_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fr_cneg_in_place(a: *mut bls12_381_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fr_cadd_in_place( + a: *mut bls12_381_fr, + b: *const bls12_381_fr, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_fr_csub_in_place( + a: *mut bls12_381_fr, + b: *const bls12_381_fr, + ctl: secret_bool, + ); +} +extern "C" { + #[must_use] + pub fn ctt_bls12_381_fp_unmarshalBE( + dst: *mut bls12_381_fp, + src: *const byte, + src_len: isize, + ) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_bls12_381_fp_marshalBE( + dst: *mut byte, + dst_len: isize, + src: *const bls12_381_fp, + ) -> bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_is_eq(a: *const bls12_381_fp, b: *const bls12_381_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_is_zero(a: *const bls12_381_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_is_one(a: *const bls12_381_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_is_minus_one(a: *const bls12_381_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_set_zero(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_set_one(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_set_minus_one(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_neg(r: *mut bls12_381_fp, a: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_neg_in_place(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_sum( + r: *mut bls12_381_fp, + a: *const bls12_381_fp, + b: *const bls12_381_fp, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp_add_in_place(a: *mut bls12_381_fp, b: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_diff( + r: *mut bls12_381_fp, + a: *const bls12_381_fp, + b: *const bls12_381_fp, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp_sub_in_place(a: *mut bls12_381_fp, b: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_double(r: *mut bls12_381_fp, a: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_double_in_place(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_prod( + r: *mut bls12_381_fp, + a: *const bls12_381_fp, + b: *const bls12_381_fp, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp_mul_in_place(a: *mut bls12_381_fp, b: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_square(r: *mut bls12_381_fp, a: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_square_in_place(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_div2(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_inv(r: *mut bls12_381_fp, a: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_inv_in_place(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_ccopy(a: *mut bls12_381_fp, b: *const bls12_381_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp_cswap(a: *mut bls12_381_fp, b: *mut bls12_381_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp_cset_zero(a: *mut bls12_381_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp_cset_one(a: *mut bls12_381_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp_cneg_in_place(a: *mut bls12_381_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp_cadd_in_place( + a: *mut bls12_381_fp, + b: *const bls12_381_fp, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp_csub_in_place( + a: *mut bls12_381_fp, + b: *const bls12_381_fp, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp_is_square(a: *const bls12_381_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_invsqrt(r: *mut bls12_381_fp, a: *const bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_invsqrt_in_place( + r: *mut bls12_381_fp, + a: *const bls12_381_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_sqrt_in_place(a: *mut bls12_381_fp); +} +extern "C" { + pub fn ctt_bls12_381_fp_sqrt_if_square_in_place(a: *mut bls12_381_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_sqrt_invsqrt( + sqrt: *mut bls12_381_fp, + invsqrt: *mut bls12_381_fp, + a: *const bls12_381_fp, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp_sqrt_invsqrt_if_square( + sqrt: *mut bls12_381_fp, + invsqrt: *mut bls12_381_fp, + a: *const bls12_381_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp_sqrt_ratio_if_square( + r: *mut bls12_381_fp, + u: *const bls12_381_fp, + v: *const bls12_381_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp2_is_eq(a: *const bls12_381_fp2, b: *const bls12_381_fp2) + -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp2_is_zero(a: *const bls12_381_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp2_is_one(a: *const bls12_381_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp2_is_minus_one(a: *const bls12_381_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp2_set_zero(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_set_one(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_set_minus_one(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_neg(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_sum( + r: *mut bls12_381_fp2, + a: *const bls12_381_fp2, + b: *const bls12_381_fp2, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp2_add_in_place(a: *mut bls12_381_fp2, b: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_diff( + r: *mut bls12_381_fp2, + a: *const bls12_381_fp2, + b: *const bls12_381_fp2, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp2_sub_in_place(a: *mut bls12_381_fp2, b: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_double(r: *mut bls12_381_fp2, a: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_double_in_place(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_conj(r: *mut bls12_381_fp2, a: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_conj_in_place(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_conjneg(r: *mut bls12_381_fp2, a: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_conjneg_in_place(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_prod( + r: *mut bls12_381_fp2, + a: *const bls12_381_fp2, + b: *const bls12_381_fp2, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp2_mul_in_place(a: *mut bls12_381_fp2, b: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_square(r: *mut bls12_381_fp2, a: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_square_in_place(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_div2(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_inv(r: *mut bls12_381_fp2, a: *const bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_inv_in_place(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_ccopy( + a: *mut bls12_381_fp2, + b: *const bls12_381_fp2, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp2_cset_zero(a: *mut bls12_381_fp2, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp2_cset_one(a: *mut bls12_381_fp2, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp2_cneg_in_place(a: *mut bls12_381_fp2, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_fp2_cadd_in_place( + a: *mut bls12_381_fp2, + b: *const bls12_381_fp2, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp2_csub_in_place( + a: *mut bls12_381_fp2, + b: *const bls12_381_fp2, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_fp2_is_square(a: *const bls12_381_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_fp2_sqrt_in_place(a: *mut bls12_381_fp2); +} +extern "C" { + pub fn ctt_bls12_381_fp2_sqrt_if_square_in_place(a: *mut bls12_381_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_aff_is_eq( + P: *const bls12_381_ec_g1_aff, + Q: *const bls12_381_ec_g1_aff, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_aff_is_inf(P: *const bls12_381_ec_g1_aff) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_aff_set_inf(P: *mut bls12_381_ec_g1_aff); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_aff_ccopy( + P: *mut bls12_381_ec_g1_aff, + Q: *const bls12_381_ec_g1_aff, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_aff_is_on_curve( + x: *const bls12_381_fp, + y: *const bls12_381_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_aff_neg(P: *mut bls12_381_ec_g1_aff, Q: *const bls12_381_ec_g1_aff); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_aff_neg_in_place(P: *mut bls12_381_ec_g1_aff); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_is_eq( + P: *const bls12_381_ec_g1_jac, + Q: *const bls12_381_ec_g1_jac, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_is_inf(P: *const bls12_381_ec_g1_jac) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_set_inf(P: *mut bls12_381_ec_g1_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_ccopy( + P: *mut bls12_381_ec_g1_jac, + Q: *const bls12_381_ec_g1_jac, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_neg(P: *mut bls12_381_ec_g1_jac, Q: *const bls12_381_ec_g1_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_neg_in_place(P: *mut bls12_381_ec_g1_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_cneg_in_place(P: *mut bls12_381_ec_g1_jac, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_sum( + r: *mut bls12_381_ec_g1_jac, + P: *const bls12_381_ec_g1_jac, + Q: *const bls12_381_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_add_in_place( + P: *mut bls12_381_ec_g1_jac, + Q: *const bls12_381_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_diff( + r: *mut bls12_381_ec_g1_jac, + P: *const bls12_381_ec_g1_jac, + Q: *const bls12_381_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_double( + r: *mut bls12_381_ec_g1_jac, + P: *const bls12_381_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_double_in_place(P: *mut bls12_381_ec_g1_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_affine( + dst: *mut bls12_381_ec_g1_aff, + src: *const bls12_381_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_jac_from_affine( + dst: *mut bls12_381_ec_g1_jac, + src: *const bls12_381_ec_g1_aff, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_is_eq( + P: *const bls12_381_ec_g1_prj, + Q: *const bls12_381_ec_g1_prj, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_is_inf(P: *const bls12_381_ec_g1_prj) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_set_inf(P: *mut bls12_381_ec_g1_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_ccopy( + P: *mut bls12_381_ec_g1_prj, + Q: *const bls12_381_ec_g1_prj, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_neg(P: *mut bls12_381_ec_g1_prj, Q: *const bls12_381_ec_g1_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_neg_in_place(P: *mut bls12_381_ec_g1_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_cneg_in_place(P: *mut bls12_381_ec_g1_prj, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_sum( + r: *mut bls12_381_ec_g1_prj, + P: *const bls12_381_ec_g1_prj, + Q: *const bls12_381_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_add_in_place( + P: *mut bls12_381_ec_g1_prj, + Q: *const bls12_381_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_diff( + r: *mut bls12_381_ec_g1_prj, + P: *const bls12_381_ec_g1_prj, + Q: *const bls12_381_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_double( + r: *mut bls12_381_ec_g1_prj, + P: *const bls12_381_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_double_in_place(P: *mut bls12_381_ec_g1_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_affine( + dst: *mut bls12_381_ec_g1_aff, + src: *const bls12_381_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g1_prj_from_affine( + dst: *mut bls12_381_ec_g1_prj, + src: *const bls12_381_ec_g1_aff, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_aff_is_eq( + P: *const bls12_381_ec_g2_aff, + Q: *const bls12_381_ec_g2_aff, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_aff_is_inf(P: *const bls12_381_ec_g2_aff) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_aff_set_inf(P: *mut bls12_381_ec_g2_aff); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_aff_ccopy( + P: *mut bls12_381_ec_g2_aff, + Q: *const bls12_381_ec_g2_aff, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_aff_is_on_curve( + x: *const bls12_381_fp2, + y: *const bls12_381_fp2, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_aff_neg(P: *mut bls12_381_ec_g2_aff, Q: *const bls12_381_ec_g2_aff); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_aff_neg_in_place(P: *mut bls12_381_ec_g2_aff); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_is_eq( + P: *const bls12_381_ec_g2_jac, + Q: *const bls12_381_ec_g2_jac, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_is_inf(P: *const bls12_381_ec_g2_jac) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_set_inf(P: *mut bls12_381_ec_g2_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_ccopy( + P: *mut bls12_381_ec_g2_jac, + Q: *const bls12_381_ec_g2_jac, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_neg(P: *mut bls12_381_ec_g2_jac, Q: *const bls12_381_ec_g2_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_neg_in_place(P: *mut bls12_381_ec_g2_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_cneg_in_place(P: *mut bls12_381_ec_g2_jac, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_sum( + r: *mut bls12_381_ec_g2_jac, + P: *const bls12_381_ec_g2_jac, + Q: *const bls12_381_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_add_in_place( + P: *mut bls12_381_ec_g2_jac, + Q: *const bls12_381_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_diff( + r: *mut bls12_381_ec_g2_jac, + P: *const bls12_381_ec_g2_jac, + Q: *const bls12_381_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_double( + r: *mut bls12_381_ec_g2_jac, + P: *const bls12_381_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_double_in_place(P: *mut bls12_381_ec_g2_jac); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_affine( + dst: *mut bls12_381_ec_g2_aff, + src: *const bls12_381_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_jac_from_affine( + dst: *mut bls12_381_ec_g2_jac, + src: *const bls12_381_ec_g2_aff, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_is_eq( + P: *const bls12_381_ec_g2_prj, + Q: *const bls12_381_ec_g2_prj, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_is_inf(P: *const bls12_381_ec_g2_prj) -> secret_bool; +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_set_inf(P: *mut bls12_381_ec_g2_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_ccopy( + P: *mut bls12_381_ec_g2_prj, + Q: *const bls12_381_ec_g2_prj, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_neg(P: *mut bls12_381_ec_g2_prj, Q: *const bls12_381_ec_g2_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_neg_in_place(P: *mut bls12_381_ec_g2_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_cneg_in_place(P: *mut bls12_381_ec_g2_prj, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_sum( + r: *mut bls12_381_ec_g2_prj, + P: *const bls12_381_ec_g2_prj, + Q: *const bls12_381_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_add_in_place( + P: *mut bls12_381_ec_g2_prj, + Q: *const bls12_381_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_diff( + r: *mut bls12_381_ec_g2_prj, + P: *const bls12_381_ec_g2_prj, + Q: *const bls12_381_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_double( + r: *mut bls12_381_ec_g2_prj, + P: *const bls12_381_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_double_in_place(P: *mut bls12_381_ec_g2_prj); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_affine( + dst: *mut bls12_381_ec_g2_aff, + src: *const bls12_381_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bls12_381_ec_g2_prj_from_affine( + dst: *mut bls12_381_ec_g2_prj, + src: *const bls12_381_ec_g2_aff, + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_fr { + limbs: [secret_word; 4usize], +} +#[test] +fn bindgen_test_layout_bn254_snarks_fr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(bn254_snarks_fr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_fr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_fr), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_fp { + limbs: [secret_word; 4usize], +} +#[test] +fn bindgen_test_layout_bn254_snarks_fp() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(bn254_snarks_fp)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_fp)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_fp), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_fp2 { + c: [bn254_snarks_fp; 2usize], +} +#[test] +fn bindgen_test_layout_bn254_snarks_fp2() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(bn254_snarks_fp2)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_fp2)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).c) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_fp2), + "::", + stringify!(c) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_ec_g1_aff { + x: bn254_snarks_fp, + y: bn254_snarks_fp, +} +#[test] +fn bindgen_test_layout_bn254_snarks_ec_g1_aff() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(bn254_snarks_ec_g1_aff)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_ec_g1_aff)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_aff), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_aff), + "::", + stringify!(y) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_ec_g1_jac { + x: bn254_snarks_fp, + y: bn254_snarks_fp, + z: bn254_snarks_fp, +} +#[test] +fn bindgen_test_layout_bn254_snarks_ec_g1_jac() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(bn254_snarks_ec_g1_jac)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_ec_g1_jac)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_jac), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_jac), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_jac), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_ec_g1_prj { + x: bn254_snarks_fp, + y: bn254_snarks_fp, + z: bn254_snarks_fp, +} +#[test] +fn bindgen_test_layout_bn254_snarks_ec_g1_prj() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(bn254_snarks_ec_g1_prj)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_ec_g1_prj)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_prj), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_prj), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g1_prj), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_ec_g2_aff { + x: bn254_snarks_fp2, + y: bn254_snarks_fp2, +} +#[test] +fn bindgen_test_layout_bn254_snarks_ec_g2_aff() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 128usize, + concat!("Size of: ", stringify!(bn254_snarks_ec_g2_aff)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_ec_g2_aff)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_aff), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_aff), + "::", + stringify!(y) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_ec_g2_jac { + x: bn254_snarks_fp2, + y: bn254_snarks_fp2, + z: bn254_snarks_fp2, +} +#[test] +fn bindgen_test_layout_bn254_snarks_ec_g2_jac() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 192usize, + concat!("Size of: ", stringify!(bn254_snarks_ec_g2_jac)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_ec_g2_jac)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_jac), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_jac), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_jac), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct bn254_snarks_ec_g2_prj { + x: bn254_snarks_fp2, + y: bn254_snarks_fp2, + z: bn254_snarks_fp2, +} +#[test] +fn bindgen_test_layout_bn254_snarks_ec_g2_prj() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 192usize, + concat!("Size of: ", stringify!(bn254_snarks_ec_g2_prj)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bn254_snarks_ec_g2_prj)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_prj), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_prj), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 128usize, + concat!( + "Offset of field: ", + stringify!(bn254_snarks_ec_g2_prj), + "::", + stringify!(z) + ) + ); +} +extern "C" { + #[must_use] + pub fn ctt_bn254_snarks_fr_unmarshalBE( + dst: *mut bn254_snarks_fr, + src: *const byte, + src_len: isize, + ) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_bn254_snarks_fr_marshalBE( + dst: *mut byte, + dst_len: isize, + src: *const bn254_snarks_fr, + ) -> bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fr_is_eq( + a: *const bn254_snarks_fr, + b: *const bn254_snarks_fr, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fr_is_zero(a: *const bn254_snarks_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fr_is_one(a: *const bn254_snarks_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fr_is_minus_one(a: *const bn254_snarks_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fr_set_zero(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_set_one(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_set_minus_one(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_neg(r: *mut bn254_snarks_fr, a: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_neg_in_place(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_sum( + r: *mut bn254_snarks_fr, + a: *const bn254_snarks_fr, + b: *const bn254_snarks_fr, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_add_in_place(a: *mut bn254_snarks_fr, b: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_diff( + r: *mut bn254_snarks_fr, + a: *const bn254_snarks_fr, + b: *const bn254_snarks_fr, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_sub_in_place(a: *mut bn254_snarks_fr, b: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_double(r: *mut bn254_snarks_fr, a: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_double_in_place(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_prod( + r: *mut bn254_snarks_fr, + a: *const bn254_snarks_fr, + b: *const bn254_snarks_fr, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_mul_in_place(a: *mut bn254_snarks_fr, b: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_square(r: *mut bn254_snarks_fr, a: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_square_in_place(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_div2(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_inv(r: *mut bn254_snarks_fr, a: *const bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_inv_in_place(a: *mut bn254_snarks_fr); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_ccopy( + a: *mut bn254_snarks_fr, + b: *const bn254_snarks_fr, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_cswap( + a: *mut bn254_snarks_fr, + b: *mut bn254_snarks_fr, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_cset_zero(a: *mut bn254_snarks_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_cset_one(a: *mut bn254_snarks_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_cneg_in_place(a: *mut bn254_snarks_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_cadd_in_place( + a: *mut bn254_snarks_fr, + b: *const bn254_snarks_fr, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fr_csub_in_place( + a: *mut bn254_snarks_fr, + b: *const bn254_snarks_fr, + ctl: secret_bool, + ); +} +extern "C" { + #[must_use] + pub fn ctt_bn254_snarks_fp_unmarshalBE( + dst: *mut bn254_snarks_fp, + src: *const byte, + src_len: isize, + ) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_bn254_snarks_fp_marshalBE( + dst: *mut byte, + dst_len: isize, + src: *const bn254_snarks_fp, + ) -> bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_is_eq( + a: *const bn254_snarks_fp, + b: *const bn254_snarks_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_is_zero(a: *const bn254_snarks_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_is_one(a: *const bn254_snarks_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_is_minus_one(a: *const bn254_snarks_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_set_zero(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_set_one(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_set_minus_one(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_neg(r: *mut bn254_snarks_fp, a: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_neg_in_place(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_sum( + r: *mut bn254_snarks_fp, + a: *const bn254_snarks_fp, + b: *const bn254_snarks_fp, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_add_in_place(a: *mut bn254_snarks_fp, b: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_diff( + r: *mut bn254_snarks_fp, + a: *const bn254_snarks_fp, + b: *const bn254_snarks_fp, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_sub_in_place(a: *mut bn254_snarks_fp, b: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_double(r: *mut bn254_snarks_fp, a: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_double_in_place(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_prod( + r: *mut bn254_snarks_fp, + a: *const bn254_snarks_fp, + b: *const bn254_snarks_fp, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_mul_in_place(a: *mut bn254_snarks_fp, b: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_square(r: *mut bn254_snarks_fp, a: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_square_in_place(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_div2(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_inv(r: *mut bn254_snarks_fp, a: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_inv_in_place(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_ccopy( + a: *mut bn254_snarks_fp, + b: *const bn254_snarks_fp, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_cswap( + a: *mut bn254_snarks_fp, + b: *mut bn254_snarks_fp, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_cset_zero(a: *mut bn254_snarks_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_cset_one(a: *mut bn254_snarks_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_cneg_in_place(a: *mut bn254_snarks_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_cadd_in_place( + a: *mut bn254_snarks_fp, + b: *const bn254_snarks_fp, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_csub_in_place( + a: *mut bn254_snarks_fp, + b: *const bn254_snarks_fp, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_is_square(a: *const bn254_snarks_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_invsqrt(r: *mut bn254_snarks_fp, a: *const bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_invsqrt_in_place( + r: *mut bn254_snarks_fp, + a: *const bn254_snarks_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_sqrt_in_place(a: *mut bn254_snarks_fp); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_sqrt_if_square_in_place(a: *mut bn254_snarks_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_sqrt_invsqrt( + sqrt: *mut bn254_snarks_fp, + invsqrt: *mut bn254_snarks_fp, + a: *const bn254_snarks_fp, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp_sqrt_invsqrt_if_square( + sqrt: *mut bn254_snarks_fp, + invsqrt: *mut bn254_snarks_fp, + a: *const bn254_snarks_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp_sqrt_ratio_if_square( + r: *mut bn254_snarks_fp, + u: *const bn254_snarks_fp, + v: *const bn254_snarks_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_is_eq( + a: *const bn254_snarks_fp2, + b: *const bn254_snarks_fp2, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_is_zero(a: *const bn254_snarks_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_is_one(a: *const bn254_snarks_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_is_minus_one(a: *const bn254_snarks_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_set_zero(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_set_one(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_set_minus_one(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_neg(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_sum( + r: *mut bn254_snarks_fp2, + a: *const bn254_snarks_fp2, + b: *const bn254_snarks_fp2, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_add_in_place(a: *mut bn254_snarks_fp2, b: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_diff( + r: *mut bn254_snarks_fp2, + a: *const bn254_snarks_fp2, + b: *const bn254_snarks_fp2, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_sub_in_place(a: *mut bn254_snarks_fp2, b: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_double(r: *mut bn254_snarks_fp2, a: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_double_in_place(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_conj(r: *mut bn254_snarks_fp2, a: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_conj_in_place(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_conjneg(r: *mut bn254_snarks_fp2, a: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_conjneg_in_place(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_prod( + r: *mut bn254_snarks_fp2, + a: *const bn254_snarks_fp2, + b: *const bn254_snarks_fp2, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_mul_in_place(a: *mut bn254_snarks_fp2, b: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_square(r: *mut bn254_snarks_fp2, a: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_square_in_place(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_div2(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_inv(r: *mut bn254_snarks_fp2, a: *const bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_inv_in_place(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_ccopy( + a: *mut bn254_snarks_fp2, + b: *const bn254_snarks_fp2, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_cset_zero(a: *mut bn254_snarks_fp2, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_cset_one(a: *mut bn254_snarks_fp2, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_cneg_in_place(a: *mut bn254_snarks_fp2, ctl: secret_bool); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_cadd_in_place( + a: *mut bn254_snarks_fp2, + b: *const bn254_snarks_fp2, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_csub_in_place( + a: *mut bn254_snarks_fp2, + b: *const bn254_snarks_fp2, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_is_square(a: *const bn254_snarks_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_sqrt_in_place(a: *mut bn254_snarks_fp2); +} +extern "C" { + pub fn ctt_bn254_snarks_fp2_sqrt_if_square_in_place(a: *mut bn254_snarks_fp2) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_aff_is_eq( + P: *const bn254_snarks_ec_g1_aff, + Q: *const bn254_snarks_ec_g1_aff, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_aff_is_inf(P: *const bn254_snarks_ec_g1_aff) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_aff_set_inf(P: *mut bn254_snarks_ec_g1_aff); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_aff_ccopy( + P: *mut bn254_snarks_ec_g1_aff, + Q: *const bn254_snarks_ec_g1_aff, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_aff_is_on_curve( + x: *const bn254_snarks_fp, + y: *const bn254_snarks_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_aff_neg( + P: *mut bn254_snarks_ec_g1_aff, + Q: *const bn254_snarks_ec_g1_aff, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_aff_neg_in_place(P: *mut bn254_snarks_ec_g1_aff); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_is_eq( + P: *const bn254_snarks_ec_g1_jac, + Q: *const bn254_snarks_ec_g1_jac, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_is_inf(P: *const bn254_snarks_ec_g1_jac) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_set_inf(P: *mut bn254_snarks_ec_g1_jac); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_ccopy( + P: *mut bn254_snarks_ec_g1_jac, + Q: *const bn254_snarks_ec_g1_jac, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_neg( + P: *mut bn254_snarks_ec_g1_jac, + Q: *const bn254_snarks_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_neg_in_place(P: *mut bn254_snarks_ec_g1_jac); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_cneg_in_place( + P: *mut bn254_snarks_ec_g1_jac, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_sum( + r: *mut bn254_snarks_ec_g1_jac, + P: *const bn254_snarks_ec_g1_jac, + Q: *const bn254_snarks_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_add_in_place( + P: *mut bn254_snarks_ec_g1_jac, + Q: *const bn254_snarks_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_diff( + r: *mut bn254_snarks_ec_g1_jac, + P: *const bn254_snarks_ec_g1_jac, + Q: *const bn254_snarks_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_double( + r: *mut bn254_snarks_ec_g1_jac, + P: *const bn254_snarks_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_double_in_place(P: *mut bn254_snarks_ec_g1_jac); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_affine( + dst: *mut bn254_snarks_ec_g1_aff, + src: *const bn254_snarks_ec_g1_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_jac_from_affine( + dst: *mut bn254_snarks_ec_g1_jac, + src: *const bn254_snarks_ec_g1_aff, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_is_eq( + P: *const bn254_snarks_ec_g1_prj, + Q: *const bn254_snarks_ec_g1_prj, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_is_inf(P: *const bn254_snarks_ec_g1_prj) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_set_inf(P: *mut bn254_snarks_ec_g1_prj); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_ccopy( + P: *mut bn254_snarks_ec_g1_prj, + Q: *const bn254_snarks_ec_g1_prj, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_neg( + P: *mut bn254_snarks_ec_g1_prj, + Q: *const bn254_snarks_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_neg_in_place(P: *mut bn254_snarks_ec_g1_prj); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_cneg_in_place( + P: *mut bn254_snarks_ec_g1_prj, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_sum( + r: *mut bn254_snarks_ec_g1_prj, + P: *const bn254_snarks_ec_g1_prj, + Q: *const bn254_snarks_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_add_in_place( + P: *mut bn254_snarks_ec_g1_prj, + Q: *const bn254_snarks_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_diff( + r: *mut bn254_snarks_ec_g1_prj, + P: *const bn254_snarks_ec_g1_prj, + Q: *const bn254_snarks_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_double( + r: *mut bn254_snarks_ec_g1_prj, + P: *const bn254_snarks_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_double_in_place(P: *mut bn254_snarks_ec_g1_prj); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_affine( + dst: *mut bn254_snarks_ec_g1_aff, + src: *const bn254_snarks_ec_g1_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g1_prj_from_affine( + dst: *mut bn254_snarks_ec_g1_prj, + src: *const bn254_snarks_ec_g1_aff, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_aff_is_eq( + P: *const bn254_snarks_ec_g2_aff, + Q: *const bn254_snarks_ec_g2_aff, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_aff_is_inf(P: *const bn254_snarks_ec_g2_aff) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_aff_set_inf(P: *mut bn254_snarks_ec_g2_aff); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_aff_ccopy( + P: *mut bn254_snarks_ec_g2_aff, + Q: *const bn254_snarks_ec_g2_aff, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_aff_is_on_curve( + x: *const bn254_snarks_fp2, + y: *const bn254_snarks_fp2, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_aff_neg( + P: *mut bn254_snarks_ec_g2_aff, + Q: *const bn254_snarks_ec_g2_aff, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_aff_neg_in_place(P: *mut bn254_snarks_ec_g2_aff); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_is_eq( + P: *const bn254_snarks_ec_g2_jac, + Q: *const bn254_snarks_ec_g2_jac, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_is_inf(P: *const bn254_snarks_ec_g2_jac) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_set_inf(P: *mut bn254_snarks_ec_g2_jac); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_ccopy( + P: *mut bn254_snarks_ec_g2_jac, + Q: *const bn254_snarks_ec_g2_jac, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_neg( + P: *mut bn254_snarks_ec_g2_jac, + Q: *const bn254_snarks_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_neg_in_place(P: *mut bn254_snarks_ec_g2_jac); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_cneg_in_place( + P: *mut bn254_snarks_ec_g2_jac, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_sum( + r: *mut bn254_snarks_ec_g2_jac, + P: *const bn254_snarks_ec_g2_jac, + Q: *const bn254_snarks_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_add_in_place( + P: *mut bn254_snarks_ec_g2_jac, + Q: *const bn254_snarks_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_diff( + r: *mut bn254_snarks_ec_g2_jac, + P: *const bn254_snarks_ec_g2_jac, + Q: *const bn254_snarks_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_double( + r: *mut bn254_snarks_ec_g2_jac, + P: *const bn254_snarks_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_double_in_place(P: *mut bn254_snarks_ec_g2_jac); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_affine( + dst: *mut bn254_snarks_ec_g2_aff, + src: *const bn254_snarks_ec_g2_jac, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_jac_from_affine( + dst: *mut bn254_snarks_ec_g2_jac, + src: *const bn254_snarks_ec_g2_aff, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_is_eq( + P: *const bn254_snarks_ec_g2_prj, + Q: *const bn254_snarks_ec_g2_prj, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_is_inf(P: *const bn254_snarks_ec_g2_prj) -> secret_bool; +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_set_inf(P: *mut bn254_snarks_ec_g2_prj); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_ccopy( + P: *mut bn254_snarks_ec_g2_prj, + Q: *const bn254_snarks_ec_g2_prj, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_neg( + P: *mut bn254_snarks_ec_g2_prj, + Q: *const bn254_snarks_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_neg_in_place(P: *mut bn254_snarks_ec_g2_prj); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_cneg_in_place( + P: *mut bn254_snarks_ec_g2_prj, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_sum( + r: *mut bn254_snarks_ec_g2_prj, + P: *const bn254_snarks_ec_g2_prj, + Q: *const bn254_snarks_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_add_in_place( + P: *mut bn254_snarks_ec_g2_prj, + Q: *const bn254_snarks_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_diff( + r: *mut bn254_snarks_ec_g2_prj, + P: *const bn254_snarks_ec_g2_prj, + Q: *const bn254_snarks_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_double( + r: *mut bn254_snarks_ec_g2_prj, + P: *const bn254_snarks_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_double_in_place(P: *mut bn254_snarks_ec_g2_prj); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_affine( + dst: *mut bn254_snarks_ec_g2_aff, + src: *const bn254_snarks_ec_g2_prj, + ); +} +extern "C" { + pub fn ctt_bn254_snarks_ec_g2_prj_from_affine( + dst: *mut bn254_snarks_ec_g2_prj, + src: *const bn254_snarks_ec_g2_aff, + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct pallas_fr { + limbs: [secret_word; 4usize], +} +#[test] +fn bindgen_test_layout_pallas_fr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(pallas_fr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pallas_fr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pallas_fr), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct pallas_fp { + limbs: [secret_word; 4usize], +} +#[test] +fn bindgen_test_layout_pallas_fp() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(pallas_fp)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pallas_fp)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pallas_fp), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct pallas_ec_aff { + x: pallas_fp, + y: pallas_fp, +} +#[test] +fn bindgen_test_layout_pallas_ec_aff() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(pallas_ec_aff)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pallas_ec_aff)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_aff), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_aff), + "::", + stringify!(y) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct pallas_ec_jac { + x: pallas_fp, + y: pallas_fp, + z: pallas_fp, +} +#[test] +fn bindgen_test_layout_pallas_ec_jac() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(pallas_ec_jac)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pallas_ec_jac)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_jac), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_jac), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_jac), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct pallas_ec_prj { + x: pallas_fp, + y: pallas_fp, + z: pallas_fp, +} +#[test] +fn bindgen_test_layout_pallas_ec_prj() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(pallas_ec_prj)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(pallas_ec_prj)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_prj), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_prj), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(pallas_ec_prj), + "::", + stringify!(z) + ) + ); +} +extern "C" { + #[must_use] + pub fn ctt_pallas_fr_unmarshalBE(dst: *mut pallas_fr, src: *const byte, src_len: isize) + -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_pallas_fr_marshalBE(dst: *mut byte, dst_len: isize, src: *const pallas_fr) -> bool; +} +extern "C" { + pub fn ctt_pallas_fr_is_eq(a: *const pallas_fr, b: *const pallas_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fr_is_zero(a: *const pallas_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fr_is_one(a: *const pallas_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fr_is_minus_one(a: *const pallas_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fr_set_zero(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_set_one(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_set_minus_one(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_neg(r: *mut pallas_fr, a: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_neg_in_place(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_sum(r: *mut pallas_fr, a: *const pallas_fr, b: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_add_in_place(a: *mut pallas_fr, b: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_diff(r: *mut pallas_fr, a: *const pallas_fr, b: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_sub_in_place(a: *mut pallas_fr, b: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_double(r: *mut pallas_fr, a: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_double_in_place(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_prod(r: *mut pallas_fr, a: *const pallas_fr, b: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_mul_in_place(a: *mut pallas_fr, b: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_square(r: *mut pallas_fr, a: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_square_in_place(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_div2(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_inv(r: *mut pallas_fr, a: *const pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_inv_in_place(a: *mut pallas_fr); +} +extern "C" { + pub fn ctt_pallas_fr_ccopy(a: *mut pallas_fr, b: *const pallas_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fr_cswap(a: *mut pallas_fr, b: *mut pallas_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fr_cset_zero(a: *mut pallas_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fr_cset_one(a: *mut pallas_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fr_cneg_in_place(a: *mut pallas_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fr_cadd_in_place(a: *mut pallas_fr, b: *const pallas_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fr_csub_in_place(a: *mut pallas_fr, b: *const pallas_fr, ctl: secret_bool); +} +extern "C" { + #[must_use] + pub fn ctt_pallas_fp_unmarshalBE(dst: *mut pallas_fp, src: *const byte, src_len: isize) + -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_pallas_fp_marshalBE(dst: *mut byte, dst_len: isize, src: *const pallas_fp) -> bool; +} +extern "C" { + pub fn ctt_pallas_fp_is_eq(a: *const pallas_fp, b: *const pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_is_zero(a: *const pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_is_one(a: *const pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_is_minus_one(a: *const pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_set_zero(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_set_one(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_set_minus_one(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_neg(r: *mut pallas_fp, a: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_neg_in_place(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_sum(r: *mut pallas_fp, a: *const pallas_fp, b: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_add_in_place(a: *mut pallas_fp, b: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_diff(r: *mut pallas_fp, a: *const pallas_fp, b: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_sub_in_place(a: *mut pallas_fp, b: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_double(r: *mut pallas_fp, a: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_double_in_place(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_prod(r: *mut pallas_fp, a: *const pallas_fp, b: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_mul_in_place(a: *mut pallas_fp, b: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_square(r: *mut pallas_fp, a: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_square_in_place(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_div2(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_inv(r: *mut pallas_fp, a: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_inv_in_place(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_ccopy(a: *mut pallas_fp, b: *const pallas_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fp_cswap(a: *mut pallas_fp, b: *mut pallas_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fp_cset_zero(a: *mut pallas_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fp_cset_one(a: *mut pallas_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fp_cneg_in_place(a: *mut pallas_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fp_cadd_in_place(a: *mut pallas_fp, b: *const pallas_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fp_csub_in_place(a: *mut pallas_fp, b: *const pallas_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_fp_is_square(a: *const pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_invsqrt(r: *mut pallas_fp, a: *const pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_invsqrt_in_place(r: *mut pallas_fp, a: *const pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_sqrt_in_place(a: *mut pallas_fp); +} +extern "C" { + pub fn ctt_pallas_fp_sqrt_if_square_in_place(a: *mut pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_sqrt_invsqrt( + sqrt: *mut pallas_fp, + invsqrt: *mut pallas_fp, + a: *const pallas_fp, + ); +} +extern "C" { + pub fn ctt_pallas_fp_sqrt_invsqrt_if_square( + sqrt: *mut pallas_fp, + invsqrt: *mut pallas_fp, + a: *const pallas_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_fp_sqrt_ratio_if_square( + r: *mut pallas_fp, + u: *const pallas_fp, + v: *const pallas_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_aff_is_eq(P: *const pallas_ec_aff, Q: *const pallas_ec_aff) + -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_aff_is_inf(P: *const pallas_ec_aff) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_aff_set_inf(P: *mut pallas_ec_aff); +} +extern "C" { + pub fn ctt_pallas_ec_aff_ccopy( + P: *mut pallas_ec_aff, + Q: *const pallas_ec_aff, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_pallas_ec_aff_is_on_curve(x: *const pallas_fp, y: *const pallas_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_aff_neg(P: *mut pallas_ec_aff, Q: *const pallas_ec_aff); +} +extern "C" { + pub fn ctt_pallas_ec_aff_neg_in_place(P: *mut pallas_ec_aff); +} +extern "C" { + pub fn ctt_pallas_ec_jac_is_eq(P: *const pallas_ec_jac, Q: *const pallas_ec_jac) + -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_jac_is_inf(P: *const pallas_ec_jac) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_jac_set_inf(P: *mut pallas_ec_jac); +} +extern "C" { + pub fn ctt_pallas_ec_jac_ccopy( + P: *mut pallas_ec_jac, + Q: *const pallas_ec_jac, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_pallas_ec_jac_neg(P: *mut pallas_ec_jac, Q: *const pallas_ec_jac); +} +extern "C" { + pub fn ctt_pallas_ec_jac_neg_in_place(P: *mut pallas_ec_jac); +} +extern "C" { + pub fn ctt_pallas_ec_jac_cneg_in_place(P: *mut pallas_ec_jac, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_ec_jac_sum( + r: *mut pallas_ec_jac, + P: *const pallas_ec_jac, + Q: *const pallas_ec_jac, + ); +} +extern "C" { + pub fn ctt_pallas_ec_jac_add_in_place(P: *mut pallas_ec_jac, Q: *const pallas_ec_jac); +} +extern "C" { + pub fn ctt_pallas_ec_jac_diff( + r: *mut pallas_ec_jac, + P: *const pallas_ec_jac, + Q: *const pallas_ec_jac, + ); +} +extern "C" { + pub fn ctt_pallas_ec_jac_double(r: *mut pallas_ec_jac, P: *const pallas_ec_jac); +} +extern "C" { + pub fn ctt_pallas_ec_jac_double_in_place(P: *mut pallas_ec_jac); +} +extern "C" { + pub fn ctt_pallas_ec_jac_affine(dst: *mut pallas_ec_aff, src: *const pallas_ec_jac); +} +extern "C" { + pub fn ctt_pallas_ec_jac_from_affine(dst: *mut pallas_ec_jac, src: *const pallas_ec_aff); +} +extern "C" { + pub fn ctt_pallas_ec_prj_is_eq(P: *const pallas_ec_prj, Q: *const pallas_ec_prj) + -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_prj_is_inf(P: *const pallas_ec_prj) -> secret_bool; +} +extern "C" { + pub fn ctt_pallas_ec_prj_set_inf(P: *mut pallas_ec_prj); +} +extern "C" { + pub fn ctt_pallas_ec_prj_ccopy( + P: *mut pallas_ec_prj, + Q: *const pallas_ec_prj, + ctl: secret_bool, + ); +} +extern "C" { + pub fn ctt_pallas_ec_prj_neg(P: *mut pallas_ec_prj, Q: *const pallas_ec_prj); +} +extern "C" { + pub fn ctt_pallas_ec_prj_neg_in_place(P: *mut pallas_ec_prj); +} +extern "C" { + pub fn ctt_pallas_ec_prj_cneg_in_place(P: *mut pallas_ec_prj, ctl: secret_bool); +} +extern "C" { + pub fn ctt_pallas_ec_prj_sum( + r: *mut pallas_ec_prj, + P: *const pallas_ec_prj, + Q: *const pallas_ec_prj, + ); +} +extern "C" { + pub fn ctt_pallas_ec_prj_add_in_place(P: *mut pallas_ec_prj, Q: *const pallas_ec_prj); +} +extern "C" { + pub fn ctt_pallas_ec_prj_diff( + r: *mut pallas_ec_prj, + P: *const pallas_ec_prj, + Q: *const pallas_ec_prj, + ); +} +extern "C" { + pub fn ctt_pallas_ec_prj_double(r: *mut pallas_ec_prj, P: *const pallas_ec_prj); +} +extern "C" { + pub fn ctt_pallas_ec_prj_double_in_place(P: *mut pallas_ec_prj); +} +extern "C" { + pub fn ctt_pallas_ec_prj_affine(dst: *mut pallas_ec_aff, src: *const pallas_ec_prj); +} +extern "C" { + pub fn ctt_pallas_ec_prj_from_affine(dst: *mut pallas_ec_prj, src: *const pallas_ec_aff); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct vesta_fr { + limbs: [secret_word; 4usize], +} +#[test] +fn bindgen_test_layout_vesta_fr() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(vesta_fr)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(vesta_fr)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(vesta_fr), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct vesta_fp { + limbs: [secret_word; 4usize], +} +#[test] +fn bindgen_test_layout_vesta_fp() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(vesta_fp)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(vesta_fp)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).limbs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(vesta_fp), + "::", + stringify!(limbs) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct vesta_ec_aff { + x: vesta_fp, + y: vesta_fp, +} +#[test] +fn bindgen_test_layout_vesta_ec_aff() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 64usize, + concat!("Size of: ", stringify!(vesta_ec_aff)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(vesta_ec_aff)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_aff), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_aff), + "::", + stringify!(y) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct vesta_ec_jac { + x: vesta_fp, + y: vesta_fp, + z: vesta_fp, +} +#[test] +fn bindgen_test_layout_vesta_ec_jac() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(vesta_ec_jac)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(vesta_ec_jac)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_jac), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_jac), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_jac), + "::", + stringify!(z) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct vesta_ec_prj { + x: vesta_fp, + y: vesta_fp, + z: vesta_fp, +} +#[test] +fn bindgen_test_layout_vesta_ec_prj() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(vesta_ec_prj)) + ); + assert_eq!( + ::core::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(vesta_ec_prj)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_prj), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 32usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_prj), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).z) as usize - ptr as usize }, + 64usize, + concat!( + "Offset of field: ", + stringify!(vesta_ec_prj), + "::", + stringify!(z) + ) + ); +} +extern "C" { + #[must_use] + pub fn ctt_vesta_fr_unmarshalBE(dst: *mut vesta_fr, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_vesta_fr_marshalBE(dst: *mut byte, dst_len: isize, src: *const vesta_fr) -> bool; +} +extern "C" { + pub fn ctt_vesta_fr_is_eq(a: *const vesta_fr, b: *const vesta_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fr_is_zero(a: *const vesta_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fr_is_one(a: *const vesta_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fr_is_minus_one(a: *const vesta_fr) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fr_set_zero(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_set_one(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_set_minus_one(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_neg(r: *mut vesta_fr, a: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_neg_in_place(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_sum(r: *mut vesta_fr, a: *const vesta_fr, b: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_add_in_place(a: *mut vesta_fr, b: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_diff(r: *mut vesta_fr, a: *const vesta_fr, b: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_sub_in_place(a: *mut vesta_fr, b: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_double(r: *mut vesta_fr, a: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_double_in_place(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_prod(r: *mut vesta_fr, a: *const vesta_fr, b: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_mul_in_place(a: *mut vesta_fr, b: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_square(r: *mut vesta_fr, a: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_square_in_place(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_div2(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_inv(r: *mut vesta_fr, a: *const vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_inv_in_place(a: *mut vesta_fr); +} +extern "C" { + pub fn ctt_vesta_fr_ccopy(a: *mut vesta_fr, b: *const vesta_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fr_cswap(a: *mut vesta_fr, b: *mut vesta_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fr_cset_zero(a: *mut vesta_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fr_cset_one(a: *mut vesta_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fr_cneg_in_place(a: *mut vesta_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fr_cadd_in_place(a: *mut vesta_fr, b: *const vesta_fr, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fr_csub_in_place(a: *mut vesta_fr, b: *const vesta_fr, ctl: secret_bool); +} +extern "C" { + #[must_use] + pub fn ctt_vesta_fp_unmarshalBE(dst: *mut vesta_fp, src: *const byte, src_len: isize) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_vesta_fp_marshalBE(dst: *mut byte, dst_len: isize, src: *const vesta_fp) -> bool; +} +extern "C" { + pub fn ctt_vesta_fp_is_eq(a: *const vesta_fp, b: *const vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_is_zero(a: *const vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_is_one(a: *const vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_is_minus_one(a: *const vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_set_zero(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_set_one(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_set_minus_one(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_neg(r: *mut vesta_fp, a: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_neg_in_place(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_sum(r: *mut vesta_fp, a: *const vesta_fp, b: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_add_in_place(a: *mut vesta_fp, b: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_diff(r: *mut vesta_fp, a: *const vesta_fp, b: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_sub_in_place(a: *mut vesta_fp, b: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_double(r: *mut vesta_fp, a: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_double_in_place(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_prod(r: *mut vesta_fp, a: *const vesta_fp, b: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_mul_in_place(a: *mut vesta_fp, b: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_square(r: *mut vesta_fp, a: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_square_in_place(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_div2(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_inv(r: *mut vesta_fp, a: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_inv_in_place(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_ccopy(a: *mut vesta_fp, b: *const vesta_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fp_cswap(a: *mut vesta_fp, b: *mut vesta_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fp_cset_zero(a: *mut vesta_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fp_cset_one(a: *mut vesta_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fp_cneg_in_place(a: *mut vesta_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fp_cadd_in_place(a: *mut vesta_fp, b: *const vesta_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fp_csub_in_place(a: *mut vesta_fp, b: *const vesta_fp, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_fp_is_square(a: *const vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_invsqrt(r: *mut vesta_fp, a: *const vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_invsqrt_in_place(r: *mut vesta_fp, a: *const vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_sqrt_in_place(a: *mut vesta_fp); +} +extern "C" { + pub fn ctt_vesta_fp_sqrt_if_square_in_place(a: *mut vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_sqrt_invsqrt( + sqrt: *mut vesta_fp, + invsqrt: *mut vesta_fp, + a: *const vesta_fp, + ); +} +extern "C" { + pub fn ctt_vesta_fp_sqrt_invsqrt_if_square( + sqrt: *mut vesta_fp, + invsqrt: *mut vesta_fp, + a: *const vesta_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_fp_sqrt_ratio_if_square( + r: *mut vesta_fp, + u: *const vesta_fp, + v: *const vesta_fp, + ) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_aff_is_eq(P: *const vesta_ec_aff, Q: *const vesta_ec_aff) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_aff_is_inf(P: *const vesta_ec_aff) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_aff_set_inf(P: *mut vesta_ec_aff); +} +extern "C" { + pub fn ctt_vesta_ec_aff_ccopy(P: *mut vesta_ec_aff, Q: *const vesta_ec_aff, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_ec_aff_is_on_curve(x: *const vesta_fp, y: *const vesta_fp) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_aff_neg(P: *mut vesta_ec_aff, Q: *const vesta_ec_aff); +} +extern "C" { + pub fn ctt_vesta_ec_aff_neg_in_place(P: *mut vesta_ec_aff); +} +extern "C" { + pub fn ctt_vesta_ec_jac_is_eq(P: *const vesta_ec_jac, Q: *const vesta_ec_jac) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_jac_is_inf(P: *const vesta_ec_jac) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_jac_set_inf(P: *mut vesta_ec_jac); +} +extern "C" { + pub fn ctt_vesta_ec_jac_ccopy(P: *mut vesta_ec_jac, Q: *const vesta_ec_jac, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_ec_jac_neg(P: *mut vesta_ec_jac, Q: *const vesta_ec_jac); +} +extern "C" { + pub fn ctt_vesta_ec_jac_neg_in_place(P: *mut vesta_ec_jac); +} +extern "C" { + pub fn ctt_vesta_ec_jac_cneg_in_place(P: *mut vesta_ec_jac, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_ec_jac_sum( + r: *mut vesta_ec_jac, + P: *const vesta_ec_jac, + Q: *const vesta_ec_jac, + ); +} +extern "C" { + pub fn ctt_vesta_ec_jac_add_in_place(P: *mut vesta_ec_jac, Q: *const vesta_ec_jac); +} +extern "C" { + pub fn ctt_vesta_ec_jac_diff( + r: *mut vesta_ec_jac, + P: *const vesta_ec_jac, + Q: *const vesta_ec_jac, + ); +} +extern "C" { + pub fn ctt_vesta_ec_jac_double(r: *mut vesta_ec_jac, P: *const vesta_ec_jac); +} +extern "C" { + pub fn ctt_vesta_ec_jac_double_in_place(P: *mut vesta_ec_jac); +} +extern "C" { + pub fn ctt_vesta_ec_jac_affine(dst: *mut vesta_ec_aff, src: *const vesta_ec_jac); +} +extern "C" { + pub fn ctt_vesta_ec_jac_from_affine(dst: *mut vesta_ec_jac, src: *const vesta_ec_aff); +} +extern "C" { + pub fn ctt_vesta_ec_prj_is_eq(P: *const vesta_ec_prj, Q: *const vesta_ec_prj) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_prj_is_inf(P: *const vesta_ec_prj) -> secret_bool; +} +extern "C" { + pub fn ctt_vesta_ec_prj_set_inf(P: *mut vesta_ec_prj); +} +extern "C" { + pub fn ctt_vesta_ec_prj_ccopy(P: *mut vesta_ec_prj, Q: *const vesta_ec_prj, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_ec_prj_neg(P: *mut vesta_ec_prj, Q: *const vesta_ec_prj); +} +extern "C" { + pub fn ctt_vesta_ec_prj_neg_in_place(P: *mut vesta_ec_prj); +} +extern "C" { + pub fn ctt_vesta_ec_prj_cneg_in_place(P: *mut vesta_ec_prj, ctl: secret_bool); +} +extern "C" { + pub fn ctt_vesta_ec_prj_sum( + r: *mut vesta_ec_prj, + P: *const vesta_ec_prj, + Q: *const vesta_ec_prj, + ); +} +extern "C" { + pub fn ctt_vesta_ec_prj_add_in_place(P: *mut vesta_ec_prj, Q: *const vesta_ec_prj); +} +extern "C" { + pub fn ctt_vesta_ec_prj_diff( + r: *mut vesta_ec_prj, + P: *const vesta_ec_prj, + Q: *const vesta_ec_prj, + ); +} +extern "C" { + pub fn ctt_vesta_ec_prj_double(r: *mut vesta_ec_prj, P: *const vesta_ec_prj); +} +extern "C" { + pub fn ctt_vesta_ec_prj_double_in_place(P: *mut vesta_ec_prj); +} +extern "C" { + pub fn ctt_vesta_ec_prj_affine(dst: *mut vesta_ec_aff, src: *const vesta_ec_prj); +} +extern "C" { + pub fn ctt_vesta_ec_prj_from_affine(dst: *mut vesta_ec_prj, src: *const vesta_ec_aff); +} +#[repr(u8)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum ctt_codec_scalar_status { + cttCodecScalar_Success = 0, + cttCodecScalar_Zero = 1, + cttCodecScalar_ScalarLargerThanCurveOrder = 2, +} +#[repr(u8)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum ctt_codec_ecc_status { + cttCodecEcc_Success = 0, + cttCodecEcc_InvalidEncoding = 1, + cttCodecEcc_CoordinateGreaterThanOrEqualModulus = 2, + cttCodecEcc_PointNotOnCurve = 3, + cttCodecEcc_PointNotInSubgroup = 4, + cttCodecEcc_PointAtInfinity = 5, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ctt_eth_bls_fp { + raw: [byte; 48usize], +} +#[test] +fn bindgen_test_layout_ctt_eth_bls_fp() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 48usize, + concat!("Size of: ", stringify!(ctt_eth_bls_fp)) + ); + assert_eq!( + ::core::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(ctt_eth_bls_fp)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).raw) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ctt_eth_bls_fp), + "::", + stringify!(raw) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ctt_eth_bls_fp2 { + coords: [ctt_eth_bls_fp; 2usize], +} +#[test] +fn bindgen_test_layout_ctt_eth_bls_fp2() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(ctt_eth_bls_fp2)) + ); + assert_eq!( + ::core::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(ctt_eth_bls_fp2)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).coords) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ctt_eth_bls_fp2), + "::", + stringify!(coords) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ctt_eth_bls_seckey { + raw: [byte; 32usize], +} +#[test] +fn bindgen_test_layout_ctt_eth_bls_seckey() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(ctt_eth_bls_seckey)) + ); + assert_eq!( + ::core::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(ctt_eth_bls_seckey)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).raw) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ctt_eth_bls_seckey), + "::", + stringify!(raw) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ctt_eth_bls_pubkey { + x: ctt_eth_bls_fp, + y: ctt_eth_bls_fp, +} +#[test] +fn bindgen_test_layout_ctt_eth_bls_pubkey() { + const UNINIT: ::core::mem::MaybeUninit = ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 96usize, + concat!("Size of: ", stringify!(ctt_eth_bls_pubkey)) + ); + assert_eq!( + ::core::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(ctt_eth_bls_pubkey)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ctt_eth_bls_pubkey), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 48usize, + concat!( + "Offset of field: ", + stringify!(ctt_eth_bls_pubkey), + "::", + stringify!(y) + ) + ); +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct ctt_eth_bls_signature { + x: ctt_eth_bls_fp2, + y: ctt_eth_bls_fp2, +} +#[test] +fn bindgen_test_layout_ctt_eth_bls_signature() { + const UNINIT: ::core::mem::MaybeUninit = + ::core::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::core::mem::size_of::(), + 192usize, + concat!("Size of: ", stringify!(ctt_eth_bls_signature)) + ); + assert_eq!( + ::core::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(ctt_eth_bls_signature)) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).x) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(ctt_eth_bls_signature), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { ::core::ptr::addr_of!((*ptr).y) as usize - ptr as usize }, + 96usize, + concat!( + "Offset of field: ", + stringify!(ctt_eth_bls_signature), + "::", + stringify!(y) + ) + ); +} +#[repr(u8)] +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub enum ctt_eth_bls_status { + cttBLS_Success = 0, + cttBLS_VerificationFailure = 1, + cttBLS_PointAtInfinity = 2, + cttBLS_ZeroLengthAggregation = 3, + cttBLS_InconsistentLengthsOfInputs = 4, +} +extern "C" { + #[must_use] + pub fn ctt_eth_bls_pubkey_is_zero(pubkey: *const ctt_eth_bls_pubkey) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_eth_bls_signature_is_zero(sig: *const ctt_eth_bls_signature) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_eth_bls_pubkeys_are_equal( + a: *const ctt_eth_bls_pubkey, + b: *const ctt_eth_bls_pubkey, + ) -> bool; +} +extern "C" { + #[must_use] + pub fn ctt_eth_bls_signatures_are_equal( + a: *const ctt_eth_bls_signature, + b: *const ctt_eth_bls_signature, + ) -> bool; +} +extern "C" { + #[must_use] + #[doc = " Validate the secret key.\n\n Regarding timing attacks, this will leak timing information only if the key is invalid.\n Namely, the secret key is 0 or the secret key is too large."] + pub fn ctt_eth_bls_validate_seckey( + seckey: *const ctt_eth_bls_seckey, + ) -> ctt_codec_scalar_status; +} +extern "C" { + #[must_use] + #[doc = " Validate the public key.\n\n This is an expensive operation that can be cached."] + pub fn ctt_eth_bls_validate_pubkey(pubkey: *const ctt_eth_bls_pubkey) -> ctt_codec_ecc_status; +} +extern "C" { + #[must_use] + #[doc = " Validate the signature.\n\n This is an expensive operation that can be cached."] + pub fn ctt_eth_bls_validate_signature( + pubkey: *const ctt_eth_bls_signature, + ) -> ctt_codec_ecc_status; +} +extern "C" { + #[must_use] + #[doc = " Serialize a secret key\n\n Returns cttCodecScalar_Success if successful"] + pub fn ctt_eth_bls_serialize_seckey( + dst: *mut byte, + seckey: *const ctt_eth_bls_seckey, + ) -> ctt_codec_scalar_status; +} +extern "C" { + #[must_use] + #[doc = " Serialize a public key in compressed (Zcash) format\n\n Returns cttCodecEcc_Success if successful"] + pub fn ctt_eth_bls_serialize_pubkey_compressed( + dst: *mut byte, + pubkey: *const ctt_eth_bls_pubkey, + ) -> ctt_codec_ecc_status; +} +extern "C" { + #[must_use] + #[doc = " Serialize a signature in compressed (Zcash) format\n\n Returns cttCodecEcc_Success if successful"] + pub fn ctt_eth_bls_serialize_signature_compressed( + dst: *mut byte, + sig: *const ctt_eth_bls_signature, + ) -> ctt_codec_ecc_status; +} +extern "C" { + #[must_use] + #[doc = " Deserialize a secret key\n This also validates the secret key.\n\n This is protected against side-channel unless your key is invalid.\n In that case it will like whether it's all zeros or larger than the curve order."] + pub fn ctt_eth_bls_deserialize_seckey( + seckey: *mut ctt_eth_bls_seckey, + src: *const byte, + ) -> ctt_codec_scalar_status; +} +extern "C" { + #[must_use] + #[doc = " Deserialize a public key in compressed (Zcash) format.\n This does not validate the public key.\n It is intended for cases where public keys are stored in a trusted location\n and validation can be cached.\n\n Warning ⚠:\n This procedure skips the very expensive subgroup checks.\n Not checking subgroup exposes a protocol to small subgroup attacks.\n\n Returns cttCodecEcc_Success if successful"] + pub fn ctt_eth_bls_deserialize_pubkey_compressed_unchecked( + pubkey: *mut ctt_eth_bls_pubkey, + src: *const byte, + ) -> ctt_codec_ecc_status; +} +extern "C" { + #[must_use] + #[doc = " Deserialize a public_key in compressed (Zcash) format.\n This also validates the public key.\n\n Returns cttCodecEcc_Success if successful"] + pub fn ctt_eth_bls_deserialize_pubkey_compressed( + pubkey: *mut ctt_eth_bls_pubkey, + src: *const byte, + ) -> ctt_codec_ecc_status; +} +extern "C" { + #[must_use] + #[doc = " Deserialize a signature in compressed (Zcash) format.\n This does not validate the signature.\n It is intended for cases where public keys are stored in a trusted location\n and validation can be cached.\n\n Warning ⚠:\n This procedure skips the very expensive subgroup checks.\n Not checking subgroup exposes a protocol to small subgroup attacks.\n\n Returns cttCodecEcc_Success if successful"] + pub fn ctt_eth_bls_deserialize_signature_compressed_unchecked( + sig: *mut ctt_eth_bls_signature, + src: *const byte, + ) -> ctt_codec_ecc_status; +} +extern "C" { + #[must_use] + #[doc = " Deserialize a signature in compressed (Zcash) format.\n This also validates the signature.\n\n Returns cttCodecEcc_Success if successful"] + pub fn ctt_eth_bls_deserialize_signature_compressed( + sig: *mut ctt_eth_bls_signature, + src: *const byte, + ) -> ctt_codec_ecc_status; +} +extern "C" { + #[doc = " Derive the public key matching with a secret key\n\n Secret protection:\n - A valid secret key will only leak that it is valid.\n - An invalid secret key will leak whether it's all zero or larger than the curve order."] + pub fn ctt_eth_bls_derive_pubkey( + pubkey: *mut ctt_eth_bls_pubkey, + seckey: *const ctt_eth_bls_seckey, + ); +} +extern "C" { + #[doc = " Produce a signature for the message under the specified secret key\n Signature is on BLS12-381 G2 (and public key on G1)\n\n For message domain separation purpose, the tag is `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_`\n\n Input:\n - A secret key\n - A message\n\n Output:\n - `signature` is overwritten with `message` signed with `secretKey`\n with the scheme\n - A status code indicating success or if the secret key is invalid.\n\n Secret protection:\n - A valid secret key will only leak that it is valid.\n - An invalid secret key will leak whether it's all zero or larger than the curve order."] + pub fn ctt_eth_bls_sign( + sig: *mut ctt_eth_bls_signature, + seckey: *const ctt_eth_bls_seckey, + message: *const byte, + message_len: isize, + ); +} +extern "C" { + #[must_use] + #[doc = " Check that a signature is valid for a message\n under the provided public key.\n returns `true` if the signature is valid, `false` otherwise.\n\n For message domain separation purpose, the tag is `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_`\n\n Input:\n - A public key initialized by one of the key derivation or deserialization procedure.\n Or validated via validate_pubkey\n - A message\n - A signature initialized by one of the key derivation or deserialization procedure.\n Or validated via validate_signature\n\n Output:\n - a status code with verification success if signature is valid\n or indicating verification failure\n\n In particular, the public key and signature are assumed to be on curve and subgroup-checked."] + pub fn ctt_eth_bls_verify( + pubkey: *const ctt_eth_bls_pubkey, + message: *const byte, + message_len: isize, + sig: *const ctt_eth_bls_signature, + ) -> ctt_eth_bls_status; +} +extern "C" { + #[must_use] + #[doc = " Check that a signature is valid for a message\n under the aggregate of provided public keys.\n returns `true` if the signature is valid, `false` otherwise.\n\n For message domain separation purpose, the tag is `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_`\n\n Input:\n - Public keys initialized by one of the key derivation or deserialization procedure.\n Or validated via validate_pubkey\n - A message\n - A signature initialized by one of the key derivation or deserialization procedure.\n Or validated via validate_signature\n\n In particular, the public keys and signature are assumed to be on curve subgroup checked."] + pub fn ctt_eth_bls_fast_aggregate_verify( + pubkeys: *const ctt_eth_bls_pubkey, + pubkeys_len: isize, + message: *const byte, + message_len: isize, + aggregate_sig: *const ctt_eth_bls_signature, + ) -> ctt_eth_bls_status; +} diff --git a/constantine-rust/constantine-sys/src/lib.rs b/constantine-rust/constantine-sys/src/lib.rs new file mode 100644 index 000000000..5e6c92150 --- /dev/null +++ b/constantine-rust/constantine-sys/src/lib.rs @@ -0,0 +1,5 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] + +include!("bindings.rs"); \ No newline at end of file diff --git a/constantine-rust/ctt-curve-bls12-381/Cargo.toml b/constantine-rust/ctt-curve-bls12-381/Cargo.toml new file mode 100644 index 000000000..47385063b --- /dev/null +++ b/constantine-rust/ctt-curve-bls12-381/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ctt-curve-bls12-381" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +constantine-sys = { path = "../constantine-sys" } \ No newline at end of file diff --git a/constantine-rust/ctt-curve-bls12-381/src/lib.rs b/constantine-rust/ctt-curve-bls12-381/src/lib.rs new file mode 100644 index 000000000..7d12d9af8 --- /dev/null +++ b/constantine-rust/ctt-curve-bls12-381/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/constantine-rust/ctt-curve-bn254-snarks/Cargo.toml b/constantine-rust/ctt-curve-bn254-snarks/Cargo.toml new file mode 100644 index 000000000..3f3821c40 --- /dev/null +++ b/constantine-rust/ctt-curve-bn254-snarks/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ctt-curve-bn254-snarks" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +constantine-sys = { path = "../constantine-sys" } \ No newline at end of file diff --git a/constantine-rust/ctt-curve-bn254-snarks/src/lib.rs b/constantine-rust/ctt-curve-bn254-snarks/src/lib.rs new file mode 100644 index 000000000..7d12d9af8 --- /dev/null +++ b/constantine-rust/ctt-curve-bn254-snarks/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/constantine-rust/ctt-curve-pasta/Cargo.toml b/constantine-rust/ctt-curve-pasta/Cargo.toml new file mode 100644 index 000000000..032b50b0c --- /dev/null +++ b/constantine-rust/ctt-curve-pasta/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ctt-curve-pasta" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +constantine-sys = { path = "../constantine-sys" } diff --git a/constantine-rust/ctt-curve-pasta/src/lib.rs b/constantine-rust/ctt-curve-pasta/src/lib.rs new file mode 100644 index 000000000..7d12d9af8 --- /dev/null +++ b/constantine-rust/ctt-curve-pasta/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/constantine-rust/ctt-proto-ethereum-bls-signatures/Cargo.toml b/constantine-rust/ctt-proto-ethereum-bls-signatures/Cargo.toml new file mode 100644 index 000000000..04bcf7a01 --- /dev/null +++ b/constantine-rust/ctt-proto-ethereum-bls-signatures/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "ctt-proto-ethereum-bls-signatures" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +constantine-sys = { path = "../constantine-sys" } \ No newline at end of file diff --git a/constantine-rust/ctt-proto-ethereum-bls-signatures/src/lib.rs b/constantine-rust/ctt-proto-ethereum-bls-signatures/src/lib.rs new file mode 100644 index 000000000..7d12d9af8 --- /dev/null +++ b/constantine-rust/ctt-proto-ethereum-bls-signatures/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/constantine.nimble b/constantine.nimble index 86d4fb92c..147dee710 100644 --- a/constantine.nimble +++ b/constantine.nimble @@ -12,7 +12,7 @@ requires "nim >= 1.6.12" # Nimscript imports # ---------------------------------------------------------------- -import std/[strformat, strutils] +import std/[strformat, strutils, os] # Environment variables # ---------------------------------------------------------------- @@ -65,7 +65,7 @@ proc getEnvVars(): tuple[useAsmIfAble, force32: bool] = # Library compilation # ---------------------------------------------------------------- -proc releaseBuildOptions(useLTO = true): string = +func compilerFlags(): string = # -d:danger --opt:size # to avoid boundsCheck and overflowChecks that would trigger exceptions or allocations in a crypto library. # Those are internally guaranteed at compile-time by fixed-sized array @@ -80,7 +80,7 @@ proc releaseBuildOptions(useLTO = true): string = # --panics:on -d:noSignalHandler # Even with `raises: []`, Nim still has an exception path # for defects, for example array out-of-bound accesses (though deactivated with -d:danger) - # This turns them into panics, removing exceptiosn from the library. + # This turns them into panics, removing exceptions from the library. # We also remove signal handlers as it's not our business. # # -mm:arc -d:useMalloc @@ -98,12 +98,28 @@ proc releaseBuildOptions(useLTO = true): string = # Reduce instructions cache misses. # https://lkml.org/lkml/2015/5/21/443 # Our non-inlined functions are large so size cost is minimal. + # + # -fmerge-all-constants + # Merge identical constants and variables, in particular + # field and curve arithmetic constant arrays. + + " -d:danger " & + # " --opt:size " & + " --panics:on -d:noSignalHandler " & + " --mm:arc -d:useMalloc " & + " --verbosity:0 --hints:off --warnings:off " & + " --passC:-fno-semantic-interposition " & + " --passC:-falign-functions=64 " & + " --passC:-fmerge-all-constants" + +proc releaseBuildOptions(useLTO = true): string = + let compiler = if existsEnv"CC": " --cc:" & getEnv"CC" else: "" let (useAsmIfAble, force32) = getEnvVars() let envASM = if not useAsmIfAble: " -d:CTT_ASM=false " - else: "" + else: "" let env32 = if force32: " -d:CTT_32 " else: "" @@ -113,158 +129,127 @@ proc releaseBuildOptions(useLTO = true): string = compiler & envASM & env32 & lto & - " -d:danger " & - # " --opt:size " & - " --panics:on -d:noSignalHandler " & - " --mm:arc -d:useMalloc " & - " --verbosity:0 --hints:off --warnings:off " & - " --passC:-fno-semantic-interposition " & - " --passC:-falign-functions=64 " + compilerFlags() -type BindingsKind = enum - kCurve - kProtocol +proc rustBuild(): string = + # Force Rust compilation, we force Clang compiler + # and use it's LTO-thin capabilities fro Nim<->Rust cross-language LTO + # - https://blog.llvm.org/2019/09/closing-gap-cross-language-lto-between.html + # - https://github.com/rust-lang/rust/pull/58057 + # - https://doc.rust-lang.org/rustc/linker-plugin-lto.html + + let compiler = " --cc:clang " + let lto = " --passC:-flto=thin --passL:-flto=thin " + + compiler & + lto & + compilerFlags() -proc genDynamicBindings(bindingsKind: BindingsKind, bindingsName, prefixNimMain: string) = +proc genDynamicLib(outdir, nimcache: string) = proc compile(libName: string, flags = "") = - echo "Compiling dynamic library: lib/" & libName + echo &"Compiling dynamic library: {outdir}/" & libName exec "nim c " & flags & releaseBuildOptions(useLTO = true) & " --noMain --app:lib " & - &" --nimMainPrefix:{prefixNimMain} " & - &" --out:{libName} --outdir:lib " & - (block: - case bindingsKind - of kCurve: - &" --nimcache:nimcache/bindings_curves/{bindingsName}" & - &" bindings_generators/{bindingsName}.nim" - of kProtocol: - &" --nimcache:nimcache/bindings_protocols/{bindingsName}" & - &" constantine/{bindingsName}.nim") - - let bindingsName = block: - case bindingsKind - of kCurve: bindingsName - of kProtocol: "constantine_" & bindingsName + &" --nimMainPrefix:ctt_init_ " & # Constantine is designed so that NimMain isn't needed, provided --mm:arc -d:useMalloc --panics:on -d:noSignalHandler + &" --out:{libName} --outdir:{outdir} " & + &" --nimcache:{nimcache}/libconstantine_dynamic" & + &" bindings/lib_constantine.nim" when defined(windows): - compile bindingsName & ".dll" + compile "constantine.dll" elif defined(macosx): - compile "lib" & bindingsName & ".dylib.arm", "--cpu:arm64 -l:'-target arm64-apple-macos11' -t:'-target arm64-apple-macos11'" - compile "lib" & bindingsName & ".dylib.x64", "--cpu:amd64 -l:'-target x86_64-apple-macos10.12' -t:'-target x86_64-apple-macos10.12'" - exec "lipo lib/lib" & bindingsName & ".dylib.arm " & - " lib/lib" & bindingsName & ".dylib.x64 " & - " -output lib/lib" & bindingsName & ".dylib -create" + compile "libconstantine.dylib.arm", "--cpu:arm64 -l:'-target arm64-apple-macos11' -t:'-target arm64-apple-macos11'" + compile "libconstantine.dylib.x64", "--cpu:amd64 -l:'-target x86_64-apple-macos10.12' -t:'-target x86_64-apple-macos10.12'" + exec &"lipo {outdir}/libconstantine.dylib.arm " & + &" {outdir}/libconstantine.dylib.x64 " & + &" -output {outdir}/libconstantine.dylib -create" else: - compile "lib" & bindingsName & ".so" + compile "libconstantine.so" -proc genStaticBindings(bindingsKind: BindingsKind, bindingsName, prefixNimMain: string) = +proc genStaticLib(outdir, nimcache: string, rustLib = false) = proc compile(libName: string, flags = "") = - echo "Compiling static library: lib/" & libName + echo &"Compiling static library: {outdir}/" & libName exec "nim c " & flags & - releaseBuildOptions(useLTO = false) & + (if rustLib: rustBuild() else: releaseBuildOptions(useLTO = false)) & " --noMain --app:staticLib " & - &" --nimMainPrefix:{prefixNimMain} " & - &" --out:{libName} --outdir:lib " & - (block: - case bindingsKind - of kCurve: - &" --nimcache:nimcache/bindings_curves/{bindingsName}" & - &" bindings_generators/{bindingsName}.nim" - of kProtocol: - &" --nimcache:nimcache/bindings_protocols/{bindingsName}" & - &" constantine/{bindingsName}.nim") - - let bindingsName = block: - case bindingsKind - of kCurve: bindingsName - of kProtocol: "constantine_" & bindingsName + &" --nimMainPrefix:ctt_init_ " & # Constantine is designed so that NimMain isn't needed, provided --mm:arc -d:useMalloc --panics:on -d:noSignalHandler + &" --out:{libName} --outdir:{outdir} " & + &" --nimcache:{nimcache}/libconstantine_static" & (if rustLib: "_rust" else: "") & + &" bindings/lib_constantine.nim" when defined(windows): - compile bindingsName & ".lib" + compile "constantine.lib" elif defined(macosx): - compile "lib" & bindingsName & ".a.arm", "--cpu:arm64 -l:'-target arm64-apple-macos11' -t:'-target arm64-apple-macos11'" - compile "lib" & bindingsName & ".a.x64", "--cpu:amd64 -l:'-target x86_64-apple-macos10.12' -t:'-target x86_64-apple-macos10.12'" - exec "lipo lib/lib" & bindingsName & ".a.arm " & - " lib/lib" & bindingsName & ".a.x64 " & - " -output lib/lib" & bindingsName & ".a -create" + compile "libconstantine.a.arm", "--cpu:arm64 -l:'-target arm64-apple-macos11' -t:'-target arm64-apple-macos11'" + compile "libconstantine.a.x64", "--cpu:amd64 -l:'-target x86_64-apple-macos10.12' -t:'-target x86_64-apple-macos10.12'" + exec &"lipo {outdir}/libconstantine.a.arm " & + &" {outdir}/libconstantine.a.x64 " & + &" -output {outdir}/libconstantine.a -create" else: - compile "lib" & bindingsName & ".a" + compile "libconstantine.a" -proc genHeaders(bindingsName: string) = - echo "Generating header: include/" & bindingsName & ".h" - exec "nim c -d:CTT_GENERATE_HEADERS " & +task make_headers, "Regenerate Constantine headers": + exec "nim c -r -d:CTT_MAKE_HEADERS " & " -d:release " & " --verbosity:0 --hints:off --warnings:off " & - " --out:" & bindingsName & "_gen_header.exe --outdir:build " & - " --nimcache:nimcache/bindings_curves_headers/" & bindingsName & "_header" & - " bindings_generators/" & bindingsName & ".nim" - exec "build/" & bindingsName & "_gen_header.exe include" - -task bindings, "Generate Constantine bindings": - # Curve arithmetic - genStaticBindings(kCurve, "constantine_bls12_381", "ctt_bls12381_init_") - genDynamicBindings(kCurve, "constantine_bls12_381", "ctt_bls12381_init_") - genHeaders("constantine_bls12_381") - echo "" - genStaticBindings(kCurve, "constantine_pasta", "ctt_pasta_init_") - genDynamicBindings(kCurve, "constantine_pasta", "ctt_pasta_init_") - genHeaders("constantine_pasta") - echo "" - genStaticBindings(kCurve, "constantine_bn254_snarks", "ctt_bn254snarks_init_") - genDynamicBindings(kCurve, "constantine_bn254_snarks", "ctt_bn254snarks_init_") - genHeaders("constantine_bn254_snarks") - echo "" - - # Protocols - genStaticBindings(kProtocol, "ethereum_bls_signatures", "ctt_eth_bls_init_") - genDynamicBindings(kProtocol, "ethereum_bls_signatures", "ctt_eth_bls_init_") - echo "" - -proc testLib(path, testName, libName: string, useGMP: bool) = - let dynlibName = if defined(windows): libName & ".dll" - elif defined(macosx): "lib" & libName & ".dylib" - else: "lib" & libName & ".so" - let staticlibName = if defined(windows): libName & ".lib" - else: "lib" & libName & ".a" + " --outdir:build/make " & + " --nimcache:nimcache/libcurves_headers " & + " bindings/lib_headers.nim" + +task make_lib, "Build Constantine library": + genStaticLib("lib", "nimcache") + genDynamicLib("lib", "nimcache") + +task make_lib_rust, "Build Constantine library (use within a Rust build.rs script)": + doAssert existsEnv"OUT_DIR", "Cargo needs to set the \"OUT_DIR\" environment variable" + let rustOutDir = getEnv"OUT_DIR" + genStaticLib(rustOutDir, rustOutDir/"nimcache", rustLib = true) + +proc testLib(path, testName: string, useGMP: bool) = + let dynlibName = if defined(windows): "constantine.dll" + elif defined(macosx): "libconstantine.dylib" + else: "libconstantine.so" + let staticlibName = if defined(windows): "constantine.lib" + else: "libconstantine.a" let cc = if existsEnv"CC": getEnv"CC" else: "gcc" - echo &"\n[Bindings: {path}/{testName}.c] Testing dynamically linked library {dynlibName}" - exec &"{cc} -Iinclude -Llib -o build/testbindings/{testName}_dynlink.exe {path}/{testName}.c -l{libName} " & (if useGMP: "-lgmp" else: "") + echo &"\n[Test: {path}/{testName}.c] Testing dynamic library {dynlibName}" + exec &"{cc} -Iinclude -Llib -o build/test_lib/{testName}_dynlink.exe {path}/{testName}.c -lconstantine " & (if useGMP: "-lgmp" else: "") when defined(windows): # Put DLL near the exe as LD_LIBRARY_PATH doesn't work even in a POSIX compatible shell - exec &"./build/testbindings/{testName}_dynlink.exe" + exec &"./build/test_lib/{testName}_dynlink.exe" else: - exec &"LD_LIBRARY_PATH=lib ./build/testbindings/{testName}_dynlink.exe" + exec &"LD_LIBRARY_PATH=lib ./build/test_lib/{testName}_dynlink.exe" echo "" - echo &"\n[Bindings: {path}/{testName}.c] Testing statically linked library: {staticlibName}" + echo &"\n[Test: {path}/{testName}.c] Testing static library: {staticlibName}" # Beware MacOS annoying linker with regards to static libraries # The following standard way cannot be used on MacOS - # exec "gcc -Iinclude -Llib -o build/t_libctt_bls12_381_sl.exe examples_c/t_libctt_bls12_381.c -lgmp -Wl,-Bstatic -lconstantine_bls12_381 -Wl,-Bdynamic" - exec &"{cc} -Iinclude -o build/testbindings/{testName}_staticlink.exe {path}/{testName}.c lib/{staticlibName} " & (if useGMP: "-lgmp" else: "") - exec &"./build/testbindings/{testName}_staticlink.exe" + # exec "gcc -Iinclude -Llib -o build/t_libctt_bls12_381_sl.exe examples_c/t_libctt_bls12_381.c -lgmp -Wl,-Bstatic -lconstantine -Wl,-Bdynamic" + exec &"{cc} -Iinclude -o build/test_lib/{testName}_staticlink.exe {path}/{testName}.c lib/{staticlibName} " & (if useGMP: "-lgmp" else: "") + exec &"./build/test_lib/{testName}_staticlink.exe" echo "" -task test_bindings, "Test C bindings": - exec "mkdir -p build/testbindings" - testLib("examples_c", "t_libctt_bls12_381", "constantine_bls12_381", useGMP = true) - testLib("examples_c", "ethereum_bls_signatures", "constantine_ethereum_bls_signatures", useGMP = false) +task test_lib, "Test C library": + exec "mkdir -p build/test_lib" + testLib("examples_c", "t_libctt_bls12_381", useGMP = true) + testLib("examples_c", "ethereum_bls_signatures", useGMP = false) # Test config # ---------------------------------------------------------------- -const buildParallel = "test_parallel.txt" +const buildParallel = "build/test_suite_parallel.txt" # Testing strategy: to reduce CI time we test leaf functionality # and skip testing codepath that would be exercised by leaves. @@ -630,7 +615,7 @@ proc setupTestCommand(flags, path: string): string = " -r " & flags & releaseBuildOptions() & - " --outdir:build/testsuite " & + " --outdir:build/test_suite " & &" --nimcache:nimcache/{path} " & path @@ -745,7 +730,7 @@ proc addBenchSet(cmdFile: var string) = cmdFile.buildBenchBatch(bd) proc genParallelCmdRunner() = - exec "nim c --verbosity:0 --hints:off --warnings:off -d:release --out:build/pararun --nimcache:nimcache/pararun helpers/pararun.nim" + exec "nim c --verbosity:0 --hints:off --warnings:off -d:release --out:build/test_suite/pararun --nimcache:nimcache/test_suite/pararun helpers/pararun.nim" # Tasks # ---------------------------------------------------------------- @@ -781,7 +766,7 @@ task test_parallel, "Run all tests in parallel": cmdFile.addTestSet(requireGMP = true) cmdFile.addBenchSet() # Build (but don't run) benches to ensure they stay relevant writeFile(buildParallel, cmdFile) - exec "build/pararun " & buildParallel + exec "build/test_suite/pararun " & buildParallel # Threadpool tests done serially cmdFile = "" @@ -800,7 +785,7 @@ task test_parallel_no_gmp, "Run in parallel tests that don't require GMP": cmdFile.addTestSet(requireGMP = false) cmdFile.addBenchSet() # Build (but don't run) benches to ensure they stay relevant writeFile(buildParallel, cmdFile) - exec "build/pararun " & buildParallel + exec "build/test_suite/pararun " & buildParallel # Threadpool tests done serially cmdFile = "" diff --git a/constantine/ethereum_bls_signatures.nim b/constantine/ethereum_bls_signatures.nim index 0169bc9d5..ab313492c 100644 --- a/constantine/ethereum_bls_signatures.nim +++ b/constantine/ethereum_bls_signatures.nim @@ -46,26 +46,14 @@ const prefix_ffi = "ctt_eth_bls_" import ./zoo_exports -static: - # Export SHA256 routines with a protocol specific prefix - # This exports sha256.init(), sha256.update(), sha256.finish() and sha256.clear() - prefix_sha256 = prefix_ffi & "sha256_" +# static: +# # Export SHA256 routines with a protocol specific prefix +# # This exports sha256.init(), sha256.update(), sha256.finish() and sha256.clear() +# prefix_sha256 = prefix_ffi & "sha256_" import hashes export hashes # generic sandwich on sha256 -func sha256_hash*(digest: var array[32, byte], message: openArray[byte], clearMem: bool) {.libPrefix: prefix_ffi.} = - ## Compute the SHA-256 hash of message - ## and store the result in digest. - ## Optionally, clear the memory buffer used. - - # There is an extra indirect function call as we use a generic `hash` concept but: - # - the indirection saves space (instead of duplicating `hash`) - # - minimal overhead compared to hashing time - # - Can be tail-call optimized into a goto jump instead of call/return - # - Can be LTO-optimized - sha256.hash(digest, message, clearMem) - # Imports # ------------------------------------------------------------------------------------------------ diff --git a/constantine/platforms/config.nim b/constantine/platforms/config.nim index 190c6dcc4..74129baa3 100644 --- a/constantine/platforms/config.nim +++ b/constantine/platforms/config.nim @@ -9,7 +9,7 @@ # Compiler and CPU architecture configuration # ------------------------------------------------------------ -const GCC_Compatible* = defined(gcc) or defined(clang) or defined(llvm_gcc) +const GCC_Compatible* = defined(gcc) or defined(clang) or defined(llvm_gcc) or defined(icc) const X86* = defined(amd64) or defined(i386) when sizeof(int) == 8 and GCC_Compatible: diff --git a/constantine/platforms/isa/cpuinfo_x86.nim b/constantine/platforms/isa/cpuinfo_x86.nim index 885d5d61d..5f32168e2 100644 --- a/constantine/platforms/isa/cpuinfo_x86.nim +++ b/constantine/platforms/isa/cpuinfo_x86.nim @@ -1,12 +1,32 @@ -# From awr1: https://github.com/nim-lang/Nim/pull/11816/files +# 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. -proc cpuidX86(eaxi, ecxi: int32): tuple[eax, ebx, ecx, edx: int32] {.used.}= +import ../loadtime_functions + +# CPU Query +# ---------------------------------------------------------------------- + +proc cpuidX86(eaxi, ecxi: int32): tuple[eax, ebx, ecx, edx: int32] = + ## Query the CPU + ## + ## CPUID is a very slow operation, 27-70 cycles, ~120 latency + ## - https://uops.info/table.html + ## - https://www.agner.org/optimize/instruction_tables.pdf + ## + ## and need to be cached if CPU capabilities are needed in a hot path when defined(vcc): - # limited inline asm support in vcc, so intrinsics, here we go: - proc cpuidVcc(cpuInfo: ptr int32; functionID, subFunctionID: int32) + # limited inline asm support in MSVC, so intrinsics, here we go: + proc cpuidMSVC(cpuInfo: ptr int32; functionID, subFunctionID: int32) {.noconv, importc: "__cpuidex", header: "intrin.h".} - cpuidVcc(addr result.eax, eaxi, ecxi) + cpuidMSVC(addr result.eax, eaxi, ecxi) else: + # Note: https://bugs.llvm.org/show_bug.cgi?id=17907 + # AddressSanitizer + -mstackrealign might not respect RBX clobbers. var (eaxr, ebxr, ecxr, edxr) = (0'i32, 0'i32, 0'i32, 0'i32) asm """ cpuid @@ -14,766 +34,286 @@ proc cpuidX86(eaxi, ecxi: int32): tuple[eax, ebx, ecx, edx: int32] {.used.}= :"a"(`eaxi`), "c"(`ecxi`)""" (eaxr, ebxr, ecxr, edxr) -proc cpuNameX86(): string {.used.}= - var leaves {.global.} = cast[array[48, char]]([ +# CPU Name +# ---------------------------------------------------------------------- + +proc cpuName_x86*(): string = + let leaves = cast[array[48, char]]([ cpuidX86(eaxi = 0x80000002'i32, ecxi = 0), cpuidX86(eaxi = 0x80000003'i32, ecxi = 0), cpuidX86(eaxi = 0x80000004'i32, ecxi = 0)]) - result = $cast[cstring](addr leaves[0]) - -type - X86Feature {.pure.} = enum - HypervisorPresence, Hyperthreading, NoSMT, IntelVtx, Amdv, X87fpu, Mmx, - MmxExt, F3DNow, F3DNowEnhanced, Prefetch, Sse, Sse2, Sse3, Ssse3, Sse4a, - Sse41, Sse42, Avx, Avx2, Avx512f, Avx512dq, Avx512ifma, Avx512pf, - Avx512er, Avx512cd, Avx512bw, Avx512vl, Avx512vbmi, Avx512vbmi2, - Avx512vpopcntdq, Avx512vnni, Avx512vnniw4, Avx512fmaps4, Avx512bitalg, - Avx512bfloat16, Avx512vp2intersect, Rdrand, Rdseed, MovBigEndian, Popcnt, - Fma3, Fma4, Xop, Cas8B, Cas16B, Abm, Bmi1, Bmi2, TsxHle, TsxRtm, Adx, Sgx, - Gfni, Aes, Vaes, Vpclmulqdq, Pclmulqdq, NxBit, Float16c, Sha, Clflush, - ClflushOpt, Clwb, PrefetchWT1, Mpx - -let - leaf1 = cpuidX86(eaxi = 1, ecxi = 0) - leaf7 = cpuidX86(eaxi = 7, ecxi = 0) - leaf8 = cpuidX86(eaxi = 0x80000001'i32, ecxi = 0) - -# The reason why we don't just evaluate these directly in the `let` variable -# list is so that we can internally organize features by their input (leaf) -# and output registers. -proc testX86Feature(feature: X86Feature): bool = + result = $cast[cstring](unsafeAddr leaves[0]) + +# CPU Features +# ---------------------------------------------------------------------- +# +# Design considerations +# - An enum might feel natural to organize all x86 features, +# however new features regularly come +# and this means all switches over the enum need to be updated +# and code recompiled if the enum is part of the public API. +# see also the "expression problem". +# - Caching CPUID calls +# - Dead-code elimination via LTO +# with individual bools, if none are used except at initialization +# LTO can eliminate the bools (unlike with an object) +# - If heterogenous systems have ISA differences between cores +# like PPU/SPU on IBM Cell/Playstation 3 +# or Alder Lake temporary AVX512 on Performance cores but not on Efficiency cores +# we can more easily extend procedures with a core ID (+ getCurrentCoreID()) +# and a sensible default parameter to avoid refactoring all call sites. +# - Documentation. The docgen is focused on documenting functions. +# - We keep only useful functions rather than aim for exhaustiveness +# - for example "prefetch" is covered by compiler ``builtin_prefetch()``. +# - Deprecated sets like 3DNow, SSE4a, ABM, FMA4, XOP, TSX, MPX, ... aren't listed. +# - Trusted enclave features like SGX, TDX or TEE should be managed at a higher level. +# - Xeon Phi instructions are not listed. + +var + # 1999 - Pentium 3, 2001 - Athlon XP + hasSseImpl: bool + # 2000 - Pentium 4 Willamette + hasSse2Impl: bool + # 2002 - Pentium 4 Northwood + hasSimultaneousMultithreadingImpl: bool + # 2004 - Pentium 4 Prescott + hasSse3Impl: bool + hasCas16BImpl: bool + # 2006 - Core 2 Merom + hasSsse3Impl: bool + # 2007 - Core 2 Penryn + hasSse41Impl: bool + # 2007 - Core iX-XXX Nehalem + hasSse42Impl: bool + hasPopcntImpl: bool + # 2010 - Core iX-XXX Westmere + hasAesImpl: bool + hasClMulImpl: bool # Carry-less multiplication + # 2011 - Core iX-2XXX Sandy Bridge + hasAvxImpl: bool + # 2012 - Core iX-3XXX Ivy Bridge + hasRdrandImpl: bool + # fs/gs access for thread-local memory through assembly + # 2013 - Core iX-4XXX Haswell + hasAvx2Impl: bool + hasFma3Impl: bool + hasBmi1Impl: bool # LZCNT, TZCNT + hasBmi2Impl: bool # MULX, RORX, SARX, SHRX, SHLX + # 2014 - Core iX-5XXX Broadwell + hasAdxImpl: bool # ADCX, ADOX AMD: Zen 1st gen - 2017 + hasRdseedImpl: bool + # 2017 - Core iX-7XXXX Skylake-X + hasAvx512fImpl: bool # AVX512 Foundation + hasAvx512bwImpl: bool # AVX512 Byte and Word + hasAvx512dqImpl: bool # AVX512 DoubleWord and QuadWord + hasAvx512vlImpl: bool # AVX512 Vector Length Extension (AVX512 instructions ported to SSE and AVX) + # 2019 - Ice-Lake & Core iX-10XXX Comet Lake + hasShaImpl: bool # AMD: Zen 1st gen - 2017 + hasGfniImpl: bool # Galois Field New Instruction (SSE, AVX, AVX512) + hasVectorAesImpl: bool # Vector AES + hasVectorClMulImpl: bool # Vector Carry-Less Multiplication + hasAvx512ifmaImpl: bool # AVX512 Integer Fused-Multiply-Add + hasAvx512PopcountImpl: bool # AVX512 Vector Popcount double and quadword + hasAvx512vnniImpl: bool # AVX512 Vector Neural Network Instruction (Note: They multiply-accumulate bytes or integers, https://en.wikichip.org/wiki/x86/avx512_vnni) + hasAvx512vbmiImpl: bool # AVX512 Bit Manipulation 1 + hasAvx512vbmi2Impl: bool # AVX512 Bit Manipulation 2 + hasAvx512bitalgImpl: bool # AVX512 Bit ALgorithm + +proc detectCpuFeaturesX86() {.loadTime.} = proc test(input, bit: int): bool = ((1 shl bit) and input) != 0 - # see: https://en.wikipedia.org/wiki/CPUID#Calling_CPUID - # see: Intel® Architecture Instruction Set Extensions and Future Features - # Programming Reference - result = case feature - # leaf 1, edx - of X87fpu: - leaf1.edx.test(0) - of Clflush: - leaf1.edx.test(19) - of Mmx: - leaf1.edx.test(23) - of Sse: - leaf1.edx.test(25) - of Sse2: - leaf1.edx.test(26) - of Hyperthreading: - leaf1.edx.test(28) - - # leaf 1, ecx - of Sse3: - leaf1.ecx.test(0) - of Pclmulqdq: - leaf1.ecx.test(1) - of IntelVtx: - leaf1.ecx.test(5) - of Ssse3: - leaf1.ecx.test(9) - of Fma3: - leaf1.ecx.test(12) - of Cas16B: - leaf1.ecx.test(13) - of Sse41: - leaf1.ecx.test(19) - of Sse42: - leaf1.ecx.test(20) - of MovBigEndian: - leaf1.ecx.test(22) - of Popcnt: - leaf1.ecx.test(23) - of Aes: - leaf1.ecx.test(25) - of Avx: - leaf1.ecx.test(28) - of Float16c: - leaf1.ecx.test(29) - of Rdrand: - leaf1.ecx.test(30) - of HypervisorPresence: - leaf1.ecx.test(31) - - # leaf 7, ecx - of PrefetchWT1: - leaf7.ecx.test(0) - of Avx512vbmi: - leaf7.ecx.test(1) - of Avx512vbmi2: - leaf7.ecx.test(6) - of Gfni: - leaf7.ecx.test(8) - of Vaes: - leaf7.ecx.test(9) - of Vpclmulqdq: - leaf7.ecx.test(10) - of Avx512vnni: - leaf7.ecx.test(11) - of Avx512bitalg: - leaf7.ecx.test(12) - of Avx512vpopcntdq: - leaf7.ecx.test(14) - - # lead 7, eax - of Avx512bfloat16: - leaf7.eax.test(5) - - # leaf 7, ebx - of Sgx: - leaf7.ebx.test(2) - of Bmi1: - leaf7.ebx.test(3) - of TsxHle: - leaf7.ebx.test(4) - of Avx2: - leaf7.ebx.test(5) - of Bmi2: - leaf7.ebx.test(8) - of TsxRtm: - leaf7.ebx.test(11) - of Mpx: - leaf7.ebx.test(14) - of Avx512f: - leaf7.ebx.test(16) - of Avx512dq: - leaf7.ebx.test(17) - of Rdseed: - leaf7.ebx.test(18) - of Adx: - leaf7.ebx.test(19) - of Avx512ifma: - leaf7.ebx.test(21) - of ClflushOpt: - leaf7.ebx.test(23) - of Clwb: - leaf7.ebx.test(24) - of Avx512pf: - leaf7.ebx.test(26) - of Avx512er: - leaf7.ebx.test(27) - of Avx512cd: - leaf7.ebx.test(28) - of Sha: - leaf7.ebx.test(29) - of Avx512bw: - leaf7.ebx.test(30) - of Avx512vl: - leaf7.ebx.test(31) - - # leaf 7, edx - of Avx512vnniw4: - leaf7.edx.test(2) - of Avx512fmaps4: - leaf7.edx.test(3) - of Avx512vp2intersect: - leaf7.edx.test(8) - - # leaf 8, edx - of NoSMT: - leaf8.edx.test(1) - of Cas8B: - leaf8.edx.test(8) - of NxBit: - leaf8.edx.test(20) - of MmxExt: - leaf8.edx.test(22) - of F3DNowEnhanced: - leaf8.edx.test(30) - of F3DNow: - leaf8.edx.test(31) - - # leaf 8, ecx - of Amdv: - leaf8.ecx.test(2) - of Abm: - leaf8.ecx.test(5) - of Sse4a: - leaf8.ecx.test(6) - of Prefetch: - leaf8.ecx.test(8) - of Xop: - leaf8.ecx.test(11) - of Fma4: - leaf8.ecx.test(16) - -let - isHypervisorPresentImpl = testX86Feature(HypervisorPresence) - hasSimultaneousMultithreadingImpl = - testX86Feature(Hyperthreading) or not testX86Feature(NoSMT) - hasIntelVtxImpl = testX86Feature(IntelVtx) - hasAmdvImpl = testX86Feature(Amdv) - hasX87fpuImpl = testX86Feature(X87fpu) - hasMmxImpl = testX86Feature(Mmx) - hasMmxExtImpl = testX86Feature(MmxExt) - has3DNowImpl = testX86Feature(F3DNow) - has3DNowEnhancedImpl = testX86Feature(F3DNowEnhanced) - hasPrefetchImpl = testX86Feature(Prefetch) or testX86Feature(F3DNow) - hasSseImpl = testX86Feature(Sse) - hasSse2Impl = testX86Feature(Sse2) - hasSse3Impl = testX86Feature(Sse3) - hasSsse3Impl = testX86Feature(Ssse3) - hasSse4aImpl = testX86Feature(Sse4a) - hasSse41Impl = testX86Feature(Sse41) - hasSse42Impl = testX86Feature(Sse42) - hasAvxImpl = testX86Feature(Avx) - hasAvx2Impl = testX86Feature(Avx2) - hasAvx512fImpl = testX86Feature(Avx512f) - hasAvx512dqImpl = testX86Feature(Avx512dq) - hasAvx512ifmaImpl = testX86Feature(Avx512ifma) - hasAvx512pfImpl = testX86Feature(Avx512pf) - hasAvx512erImpl = testX86Feature(Avx512er) - hasAvx512cdImpl = testX86Feature(Avx512dq) - hasAvx512bwImpl = testX86Feature(Avx512bw) - hasAvx512vlImpl = testX86Feature(Avx512vl) - hasAvx512vbmiImpl = testX86Feature(Avx512vbmi) - hasAvx512vbmi2Impl = testX86Feature(Avx512vbmi2) - hasAvx512vpopcntdqImpl = testX86Feature(Avx512vpopcntdq) - hasAvx512vnniImpl = testX86Feature(Avx512vnni) - hasAvx512vnniw4Impl = testX86Feature(Avx512vnniw4) - hasAvx512fmaps4Impl = testX86Feature(Avx512fmaps4) - hasAvx512bitalgImpl = testX86Feature(Avx512bitalg) - hasAvx512bfloat16Impl = testX86Feature(Avx512bfloat16) - hasAvx512vp2intersectImpl = testX86Feature(Avx512vp2intersect) - hasRdrandImpl = testX86Feature(Rdrand) - hasRdseedImpl = testX86Feature(Rdseed) - hasMovBigEndianImpl = testX86Feature(MovBigEndian) - hasPopcntImpl = testX86Feature(Popcnt) - hasFma3Impl = testX86Feature(Fma3) - hasFma4Impl = testX86Feature(Fma4) - hasXopImpl = testX86Feature(Xop) - hasCas8BImpl = testX86Feature(Cas8B) - hasCas16BImpl = testX86Feature(Cas16B) - hasAbmImpl = testX86Feature(Abm) - hasBmi1Impl = testX86Feature(Bmi1) - hasBmi2Impl = testX86Feature(Bmi2) - hasTsxHleImpl = testX86Feature(TsxHle) - hasTsxRtmImpl = testX86Feature(TsxRtm) - hasAdxImpl = testX86Feature(Adx) - hasSgxImpl = testX86Feature(Sgx) - hasGfniImpl = testX86Feature(Gfni) - hasAesImpl = testX86Feature(Aes) - hasVaesImpl = testX86Feature(Vaes) - hasVpclmulqdqImpl = testX86Feature(Vpclmulqdq) - hasPclmulqdqImpl = testX86Feature(Pclmulqdq) - hasNxBitImpl = testX86Feature(NxBit) - hasFloat16cImpl = testX86Feature(Float16c) - hasShaImpl = testX86Feature(Sha) - hasClflushImpl = testX86Feature(Clflush) - hasClflushOptImpl = testX86Feature(ClflushOpt) - hasClwbImpl = testX86Feature(Clwb) - hasPrefetchWT1Impl = testX86Feature(PrefetchWT1) - hasMpxImpl = testX86Feature(Mpx) - -# NOTE: We use procedures here (layered over the variables) to keep the API -# consistent and usable against possible future heterogenous systems with ISA -# differences between cores (a possibility that has historical precedents, for -# instance, the PPU/SPU relationship found on the IBM Cell). If future systems -# do end up having disparate ISA features across multiple cores, expect there to -# be a "cpuCore" argument added to the feature procs. - -proc isHypervisorPresent*(): bool {.inline.} = - return isHypervisorPresentImpl - ## **(x86 Only)** - ## - ## Reports `true` if this application is running inside of a virtual machine - ## (this is by no means foolproof). - -proc hasSimultaneousMultithreading*(): bool {.inline.} = - return hasSimultaneousMultithreadingImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware is utilizing simultaneous multithreading - ## (branded as *"hyperthreads"* on Intel processors). - -proc hasIntelVtx*(): bool {.inline.} = - return hasIntelVtxImpl - ## **(x86 Only)** - ## - ## Reports `true` if the Intel virtualization extensions (VT-x) are available. - -proc hasAmdv*(): bool {.inline.} = - return hasAmdvImpl - ## **(x86 Only)** - ## - ## Reports `true` if the AMD virtualization extensions (AMD-V) are available. - -proc hasX87fpu*(): bool {.inline.} = - return hasX87fpuImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use x87 floating-point instructions - ## (includes support for single, double, and 80-bit percision floats as per - ## IEEE 754-1985). - ## - ## By virtue of SSE2 enforced compliance on AMD64 CPUs, this should always be - ## `true` on 64-bit x86 processors. It should be noted that support of these - ## instructions is deprecated on 64-bit versions of Windows - see MSDN_. - ## - ## .. _MSDN: https://docs.microsoft.com/en-us/windows/win32/dxtecharts/sixty-four-bit-programming-for-game-developers#porting-applications-to-64-bit-platforms - -proc hasMmx*(): bool {.inline.} = - return hasMmxImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use MMX SIMD instructions. - ## - ## By virtue of SSE2 enforced compliance on AMD64 CPUs, this should always be - ## `true` on 64-bit x86 processors. It should be noted that support of these - ## instructions is deprecated on 64-bit versions of Windows (see MSDN_ for - ## more info). - ## - ## .. _MSDN: https://docs.microsoft.com/en-us/windows/win32/dxtecharts/sixty-four-bit-programming-for-game-developers#porting-applications-to-64-bit-platforms - -proc hasMmxExt*(): bool {.inline.} = - return hasMmxExtImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use "Extended MMX" SIMD instructions. - ## - ## It should be noted that support of these instructions is deprecated on - ## 64-bit versions of Windows (see MSDN_ for more info). - ## - ## .. _MSDN: https://docs.microsoft.com/en-us/windows/win32/dxtecharts/sixty-four-bit-programming-for-game-developers#porting-applications-to-64-bit-platforms - -proc has3DNow*(): bool {.inline.} = - return has3DNowImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use 3DNow! SIMD instructions. - ## - ## It should be noted that support of these instructions is deprecated on - ## 64-bit versions of Windows (see MSDN_ for more info), and that the 3DNow! - ## instructions (with an exception made for the prefetch instructions, see the - ## `hasPrefetch` procedure) have been phased out of AMD processors since 2010 - ## (see `AMD Developer Central`_ for more info). - ## - ## .. _MSDN: https://docs.microsoft.com/en-us/windows/win32/dxtecharts/sixty-four-bit-programming-for-game-developers#porting-applications-to-64-bit-platforms - ## .. _`AMD Developer Central`: https://web.archive.org/web/20131109151245/http://developer.amd.com/community/blog/2010/08/18/3dnow-deprecated/ - -proc has3DNowEnhanced*(): bool {.inline.} = - return has3DNowEnhancedImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use "Enhanced 3DNow!" SIMD instructions. - ## - ## It should be noted that support of these instructions is deprecated on - ## 64-bit versions of Windows (see MSDN_ for more info), and that the 3DNow! - ## instructions (with an exception made for the prefetch instructions, see the - ## `hasPrefetch` procedure) have been phased out of AMD processors since 2010 - ## (see `AMD Developer Central`_ for more info). - ## - ## .. _MSDN: https://docs.microsoft.com/en-us/windows/win32/dxtecharts/sixty-four-bit-programming-for-game-developers#porting-applications-to-64-bit-platforms - ## .. _`AMD Developer Central`: https://web.archive.org/web/20131109151245/http://developer.amd.com/community/blog/2010/08/18/3dnow-deprecated/ - -proc hasPrefetch*(): bool {.inline.} = - return hasPrefetchImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use the `PREFETCH` and `PREFETCHW` - ## instructions. These instructions originally included as part of 3DNow!, but - ## potentially indepdendent from the rest of it due to changes in contemporary - ## AMD processors (see above). + let + leaf1 = cpuidX86(eaxi = 1, ecxi = 0) + leaf7 = cpuidX86(eaxi = 7, ecxi = 0) + # leaf8 = cpuidX86(eaxi = 0x80000001'i32, ecxi = 0) + # see: https://en.wikipedia.org/wiki/CPUID#Calling_CPUID + # see: Intel® Architecture Instruction Set Extensions and Future Features Programming Reference + # 2023-09: https://cdrdv2-public.intel.com/790021/architecture-instruction-set-extensions-programming-reference.pdf + + # leaf 1, ecx + hasSse3Impl = leaf1.ecx.test(0) + hasSsse3Impl = leaf1.ecx.test(9) + hasFma3Impl = leaf1.ecx.test(12) + hasCas16BImpl = leaf1.ecx.test(13) + hasSse41Impl = leaf1.ecx.test(19) + hasSse42Impl = leaf1.ecx.test(20) + hasPopcntImpl = leaf1.ecx.test(23) + hasAesImpl = leaf1.ecx.test(25) + hasAvxImpl = leaf1.ecx.test(28) + hasRdrandImpl = leaf1.ecx.test(30) + + # leaf 1, EDX + hasSseImpl = leaf1.edx.test(25) + hasSse2Impl = leaf1.edx.test(26) + hasSimultaneousMultithreadingImpl = leaf1.edx.test(28) + + # leaf 7, eax + # hasSha512Impl = leaf7.eax.test(0) # SHA512 - 2024 Intel Arrow Lake and Lunar Lake processor + # hasSm3Impl = leaf7.eax.test(1) # SM3 Cryptographic hash function + # hasSm4Impl = leaf7.eax.test(2) # SM4 Cryptographic hash function + # hasAvxIfmaImpl = leaf7.eax.test(23) + + # leaf 7, ebx + # hasSgxImpl = leaf7.ebx.test(2) + hasBmi1Impl = leaf7.ebx.test(3) + hasAvx2Impl = leaf7.ebx.test(5) + hasBmi2Impl = leaf7.ebx.test(8) + hasAvx512fImpl = leaf7.ebx.test(16) + hasAvx512dqImpl = leaf7.ebx.test(17) + hasRdseedImpl = leaf7.ebx.test(18) + hasAdxImpl = leaf7.ebx.test(19) + hasAvx512ifmaImpl = leaf7.ebx.test(21) + hasShaImpl = leaf7.ebx.test(29) + hasAvx512bwImpl = leaf7.ebx.test(30) + hasAvx512vlImpl = leaf7.ebx.test(31) + + # leaf 7, ecx + hasAvx512vbmiImpl = leaf7.ecx.test(1) + hasAvx512vbmi2Impl = leaf7.ecx.test(6) + hasGfniImpl = leaf7.ecx.test(8) + hasVectorAesImpl = leaf7.ecx.test(9) + hasVectorClMulImpl = leaf7.ecx.test(10) + hasAvx512vnniImpl = leaf7.ecx.test(11) + hasAvx512bitalgImpl = leaf7.ecx.test(12) + hasAvx512PopcountImpl = leaf7.ecx.test(14) + + # leaf 7, edx + # hasAvx512vp2intersectImpl = leaf7.edx.test(8) + + # leaf 8, ecx + # AMD specific deprecated instructions + + # leaf 8, edx + # hasSimultaneousMultithreadingImpl = hasSimultaneousMultithreadingImpl and + # not leaf8.edx.test(1) # AMD core multi-processing legacy mode + + +# 1999 - Pentium 3, 2001 - Athlon XP +# ------------------------------------------ proc hasSse*(): bool {.inline.} = return hasSseImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use the SSE (Streaming SIMD Extensions) - ## 1.0 instructions, which introduced 128-bit SIMD on x86 machines. - ## - ## By virtue of SSE2 enforced compliance on AMD64 CPUs, this should always be - ## `true` on 64-bit x86 processors. +# 2000 - Pentium 4 Willamette +# ------------------------------------------ proc hasSse2*(): bool {.inline.} = return hasSse2Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use the SSE (Streaming SIMD Extensions) - ## 2.0 instructions. - ## - ## By virtue of SSE2 enforced compliance on AMD64 CPUs, this should always be - ## `true` on 64-bit x86 processors. +# 2002 - Pentium 4 Northwood +# ------------------------------------------ +proc hasSimultaneousMultithreading*(): bool {.inline.} = + return hasSimultaneousMultithreadingImpl + +# 2004 - Pentium 4 Prescott +# ------------------------------------------ proc hasSse3*(): bool {.inline.} = return hasSse3Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use SSE (Streaming SIMD Extensions) 3.0 - ## instructions. +proc hasCas16B*(): bool {.inline.} = + ## Compare-and-swap 128-bit (16 bytes) support + return hasCas16BImpl +# 2006 - Core 2 Merom +# ------------------------------------------ proc hasSsse3*(): bool {.inline.} = return hasSsse3Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use Supplemental SSE (Streaming SIMD - ## Extensions) 3.0 instructions. - -proc hasSse4a*(): bool {.inline.} = - return hasSse4aImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use Supplemental SSE (Streaming SIMD - ## Extensions) 4a instructions. +# 2007 - Core 2 Penryn +# ------------------------------------------ proc hasSse41*(): bool {.inline.} = return hasSse41Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use Supplemental SSE (Streaming SIMD - ## Extensions) 4.1 instructions. +# 2007 - Core iX-XXX Nehalem +# ------------------------------------------ proc hasSse42*(): bool {.inline.} = return hasSse42Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use Supplemental SSE (Streaming SIMD - ## Extensions) 4.2 instructions. +proc hasPopcnt*(): bool {.inline.} = + return hasPopcntImpl +# 2010 - Core iX-XXX Westmere +# ------------------------------------------ +proc hasAes*(): bool {.inline.} = + return hasAesImpl +proc hasCLMUL*(): bool {.inline.} = + ## Carry-less multiplication support + return hasClMulImpl + +# 2011 - Core iX-2XXX Sandy Bridge +# ------------------------------------------ proc hasAvx*(): bool {.inline.} = return hasAvxImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 1.0 instructions, which introduced 256-bit SIMD on x86 machines along with - ## addded reencoded versions of prior 128-bit SSE instructions into the more - ## code-dense and non-backward compatible VEX (Vector Extensions) format. - -proc hasAvx2*(): bool {.inline.} = - return hasAvx2Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) 2.0 - ## instructions. - -proc hasAvx512f*(): bool {.inline.} = - return hasAvx512fImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit F (Foundation) instructions. - -proc hasAvx512dq*(): bool {.inline.} = - return hasAvx512dqImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit DQ (Doubleword + Quadword) instructions. - -proc hasAvx512ifma*(): bool {.inline.} = - return hasAvx512ifmaImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit IFMA (Integer Fused Multiply Accumulation) instructions. - -proc hasAvx512pf*(): bool {.inline.} = - return hasAvx512pfImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit PF (Prefetch) instructions. - -proc hasAvx512er*(): bool {.inline.} = - return hasAvx512erImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit ER (Exponential and Reciprocal) instructions. - -proc hasAvx512cd*(): bool {.inline.} = - return hasAvx512cdImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit CD (Conflict Detection) instructions. - -proc hasAvx512bw*(): bool {.inline.} = - return hasAvx512bwImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit BW (Byte and Word) instructions. - -proc hasAvx512vl*(): bool {.inline.} = - return hasAvx512vlImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit VL (Vector Length) instructions. - -proc hasAvx512vbmi*(): bool {.inline.} = - return hasAvx512vbmiImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit VBMI (Vector Byte Manipulation) 1.0 instructions. - -proc hasAvx512vbmi2*(): bool {.inline.} = - return hasAvx512vbmi2Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit VBMI (Vector Byte Manipulation) 2.0 instructions. - -proc hasAvx512vpopcntdq*(): bool {.inline.} = - return hasAvx512vpopcntdqImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use the AVX (Advanced Vector Extensions) - ## 512-bit `VPOPCNTDQ` (population count, i.e. determine number of flipped - ## bits) instruction. - -proc hasAvx512vnni*(): bool {.inline.} = - return hasAvx512vnniImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit VNNI (Vector Neural Network) instructions. - -proc hasAvx512vnniw4*(): bool {.inline.} = - return hasAvx512vnniw4Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit 4VNNIW (Vector Neural Network Word Variable Percision) - ## instructions. - -proc hasAvx512fmaps4*(): bool {.inline.} = - return hasAvx512fmaps4Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit 4FMAPS (Fused-Multiply-Accumulation Single-percision) instructions. - -proc hasAvx512bitalg*(): bool {.inline.} = - return hasAvx512bitalgImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit BITALG (Bit Algorithms) instructions. - -proc hasAvx512bfloat16*(): bool {.inline.} = - return hasAvx512bfloat16Impl - ## **(x86 Only)** - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit BFLOAT16 (8-bit exponent, 7-bit mantissa) instructions used by - ## Intel DL (Deep Learning) Boost. - -proc hasAvx512vp2intersect*(): bool {.inline.} = - return hasAvx512vp2intersectImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware can use AVX (Advanced Vector Extensions) - ## 512-bit VP2INTERSECT (Compute Intersections between Dualwords + Quadwords) - ## instructions. +# 2012 - Core iX-3XXX Ivy Bridge +# ------------------------------------------ +# fs/gs access for thread-local memory through assembly proc hasRdrand*(): bool {.inline.} = return hasRdrandImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `RDRAND` instruction, - ## i.e. Intel on-CPU hardware random number generation. - -proc hasRdseed*(): bool {.inline.} = - return hasRdseedImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `RDSEED` instruction, - ## i.e. Intel on-CPU hardware random number generation (used for seeding other - ## PRNGs). - -proc hasMovBigEndian*(): bool {.inline.} = - return hasMovBigEndianImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `MOVBE` instruction for - ## endianness/byte-order switching. - -proc hasPopcnt*(): bool {.inline.} = - return hasPopcntImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `POPCNT` (population - ## count, i.e. determine number of flipped bits) instruction. +# 2013 - Core iX-4XXX Haswell +# ------------------------------------------ +proc hasAvx2*(): bool {.inline.} = + return hasAvx2Impl proc hasFma3*(): bool {.inline.} = return hasFma3Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the FMA3 (Fused Multiply - ## Accumulation 3-operand) SIMD instructions. - -proc hasFma4*(): bool {.inline.} = - return hasFma4Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the FMA4 (Fused Multiply - ## Accumulation 4-operand) SIMD instructions. - -proc hasXop*(): bool {.inline.} = - return hasXopImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the XOP (eXtended - ## Operations) SIMD instructions. These instructions are exclusive to the - ## Bulldozer AMD microarchitecture family (i.e. Bulldozer, Piledriver, - ## Steamroller, and Excavator) and were phased out with the release of the Zen - ## design. - -proc hasCas8B*(): bool {.inline.} = - return hasCas8BImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the (`LOCK`-able) - ## `CMPXCHG8B` 64-bit compare-and-swap instruction. - -proc hasCas16B*(): bool {.inline.} = - return hasCas16BImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the (`LOCK`-able) - ## `CMPXCHG16B` 128-bit compare-and-swap instruction. - -proc hasAbm*(): bool {.inline.} = - return hasAbmImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for ABM (Advanced Bit - ## Manipulation) insturctions (i.e. `POPCNT` and `LZCNT` for counting leading - ## zeroes). - proc hasBmi1*(): bool {.inline.} = + ## LZCNT, TZCNT support return hasBmi1Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for BMI (Bit Manipulation) 1.0 - ## instructions. - proc hasBmi2*(): bool {.inline.} = + ## MULX, RORX, SARX, SHRX, SHLX return hasBmi2Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for BMI (Bit Manipulation) 2.0 - ## instructions. - -proc hasTsxHle*(): bool {.inline.} = - return hasTsxHleImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for HLE (Hardware Lock Elision) - ## as part of Intel's TSX (Transactional Synchronization Extensions). - -proc hasTsxRtm*(): bool {.inline.} = - return hasTsxRtmImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for RTM (Restricted - ## Transactional Memory) as part of Intel's TSX (Transactional Synchronization - ## Extensions). +# 2014 - Core iX-5XXX Broadwell +# ------------------------------------------ proc hasAdx*(): bool {.inline.} = + ## ADCX, ADOX support + # 2017 for AMD Zen 1st Gen return hasAdxImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for ADX (Multi-percision - ## Add-Carry Extensions) insructions. - -proc hasSgx*(): bool {.inline.} = - return hasSgxImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for SGX (Software Guard - ## eXtensions) memory encryption technology. - -proc hasGfni*(): bool {.inline.} = - return hasGfniImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for GFNI (Galois Field Affine - ## Transformation) instructions. - -proc hasAes*(): bool {.inline.} = - return hasAesImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for AESNI (Advanced Encryption - ## Standard) instructions. - -proc hasVaes*(): bool {.inline.} = - return hasVaesImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for VAES (Vectorized Advanced - ## Encryption Standard) instructions. - -proc hasVpclmulqdq*(): bool {.inline.} = - return hasVpclmulqdqImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for `VCLMULQDQ` (512 and 256-bit - ## Carryless Multiplication) instructions. - -proc hasPclmulqdq*(): bool {.inline.} = - return hasPclmulqdqImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for `PCLMULQDQ` (128-bit - ## Carryless Multiplication) instructions. - -proc hasNxBit*(): bool {.inline.} = - return hasNxBitImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for NX-bit (No-eXecute) - ## technology for marking pages of memory as non-executable. +proc hasRdseed*(): bool {.inline.} = + return hasRdseedImpl -proc hasFloat16c*(): bool {.inline.} = - return hasFloat16cImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for F16C instructions, used for - ## converting 16-bit "half-percision" floating-point values to and from - ## single-percision floating-point values. +# 2017 - Core iX-7XXXX Skylake-X +# ------------------------------------------ +proc hasAvx512f*(): bool {.inline.} = + ## AVX512 Foundation support + return hasAvx512fImpl +proc hasAvx512bw*(): bool {.inline.} = + ## AVX512 Byte-and-Word support + return hasAvx512bwImpl +proc hasAvx512dq*(): bool {.inline.} = + ## AVX512 DoubleWord and QuadWord support + return hasAvx512dqImpl +proc hasAvx512vl*(): bool {.inline.} = + ## AVX512 Vector Length Extension (AVX512 instructions ported to SSE and AVX) + return hasAvx512dqImpl +# 2019 - Ice-Lake & Core iX-10XXX Comet Lake +# ------------------------------------------ proc hasSha*(): bool {.inline.} = + ## SHA hash function primitive + # 2017 for AMD Zen 1st Gen return hasShaImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for SHA (Secure Hash Algorithm) - ## instructions. - -proc hasClflush*(): bool {.inline.} = - return hasClflushImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `CLFLUSH` (Cache-line - ## Flush) instruction. - -proc hasClflushOpt*(): bool {.inline.} = - return hasClflushOptImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `CLFLUSHOPT` (Cache-line - ## Flush Optimized) instruction. - -proc hasClwb*(): bool {.inline.} = - return hasClwbImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `CLWB` (Cache-line Write - ## Back) instruction. - -proc hasPrefetchWT1*(): bool {.inline.} = - return hasPrefetchWT1Impl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for the `PREFECTHWT1` - ## instruction. - -proc hasMpx*(): bool {.inline.} = - return hasMpxImpl - ## **(x86 Only)** - ## - ## Reports `true` if the hardware has support for MPX (Memory Protection - ## eXtensions). +proc hasGfni*(): bool {.inline.} = + ## Galois Field New Instruction support + return hasGfniImpl +proc hasVectorAes*(): bool {.inline.} = + return hasVectorAesImpl +proc hasVectorClMul*(): bool {.inline.} = + ## Vector Carry-Less Multiplication support + return hasVectorClMulImpl +proc hasAvx512Ifma*(): bool {.inline.} = + ## AVX512 Integer Fused-Multiply-Add support + return hasAvx512ifmaImpl +proc hasAvx512Popcount*(): bool {.inline.} = + return hasAvx512PopcountImpl +proc hasAvx512vnni*(): bool {.inline.} = + ## AVX512 Vector Neural Network Instruction + ## Note: They multiply-accumulate bytes or integers + ## https://en.wikichip.org/wiki/x86/avx512_vnni + return hasAvx512vnniImpl +proc hasAvx512vbmi*(): bool {.inline.} = + return hasAvx512vbmiImpl +proc hasAvx512vbmi2*(): bool {.inline.} = + return hasAvx512vbmi2Impl +proc hasAvx512bitalg*(): bool {.inline.} = + ## AVX512 Bit ALgorithm + return hasAvx512bitalgImpl diff --git a/constantine/platforms/loadtime_functions.nim b/constantine/platforms/loadtime_functions.nim new file mode 100644 index 000000000..39175afdb --- /dev/null +++ b/constantine/platforms/loadtime_functions.nim @@ -0,0 +1,51 @@ +# 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. + +# ############################################################ +# +# Load-time functions +# +# ############################################################ +# +# Implement functions that are automatically called at program/library load time. +# Note: They cannot use {.global.} variables as {.global.} are initialized by Nim routines + +import std/macros, ./config + +macro loadTime*(procAst: untyped): untyped = + ## This allows a function to be called at program or library load time + ## Note: such a function cannot be dead-code eliminated. + + procAst.addPragma(ident"used") # Remove unused warning + procAst.addPragma(ident"exportc") # Prevent the proc from being dead-code eliminated + + if GCC_Compatible: + # {.pragma: gcc_constructor, codegenDecl: "__attribute__((constructor)) $# $#$#".} + let gcc_constructor = + nnkExprColonExpr.newTree( + ident"codegenDecl", + newLit"__attribute__((constructor)) $# $#$#" + ) + procAst.addPragma(gcc_constructor) # Implement load-time functionality + + result = procAst + + elif defined(vcc): + warning "CPU feature autodetection at Constantine load time has not been tested with MSVC" + + template msvcInitSection(procDef: untyped): untyped = + let procName = astToStr(def) + procDef + {.emit:[""" + #pragma section(".CRT$XCU",read) + __declspec(allocate(".CRT$XCU")) static int (*p)(void) = """, procName, ";"].} + + result = getAst(msvcInitSection(procAst)) + + else: + error "Compiler not supported." \ No newline at end of file diff --git a/constantine/platforms/metering/benchmarking.nim b/constantine/platforms/metering/benchmarking.nim index 097afe56b..9f781d0ab 100644 --- a/constantine/platforms/metering/benchmarking.nim +++ b/constantine/platforms/metering/benchmarking.nim @@ -7,15 +7,74 @@ # at your option. This file may not be copied, modified, or distributed except according to those terms. when defined(amd64): # TODO defined(i386) but it seems like RDTSC call is misconfigured - import cycle_count/x86 - export getTicks, cpuName + from ../isa/cpuinfo_x86 import cpuName_x86 const SupportsCPUName* = true const SupportsGetTicks* = true + + template cpuName*: untyped = cpuName_x86() + + # From Linux + # + # The RDTSC instruction is not ordered relative to memory + # access. The Intel SDM and the AMD APM are both vague on this + # point, but empirically an RDTSC instruction can be + # speculatively executed before prior loads. An RDTSC + # immediately after an appropriate barrier appears to be + # ordered as a normal load, that is, it provides the same + # ordering guarantees as reading from a global memory location + # that some other imaginary CPU is updating continuously with a + # time stamp. + # + # From Intel SDM + # https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf + + proc getTicks*(): int64 {.inline.} = + when defined(vcc): + proc rdtsc(): int64 {.sideeffect, importc: "__rdtsc", header: "".} + proc lfence() {.importc: "__mm_lfence", header: "".} + + lfence() + return rdtsc() + + else: + when defined(amd64): + var lo, hi: int64 + # TODO: Provide a compile-time flag for RDTSCP support + # and use it instead of lfence + RDTSC + {.emit: """asm volatile( + "lfence\n" + "rdtsc\n" + : "=a"(`lo`), "=d"(`hi`) + : + : "memory" + );""".} + return (hi shl 32) or lo + else: # 32-bit x86 + # TODO: Provide a compile-time flag for RDTSCP support + # and use it instead of lfence + RDTSC + {.emit: """asm volatile( + "lfence\n" + "rdtsc\n" + : "=a"(`result`) + : + : "memory" + );""".} + else: const SupportsCPUName* = false const SupportsGetTicks* = false + # TODO cycle counting on ARM + # + # - see writeup: http://zhiyisun.github.io/2016/03/02/How-to-Use-Performance-Monitor-Unit-(PMU)-of-64-bit-ARMv8-A-in-Linux.html + # + # Otherwise Google or FFTW approach might work but might require perf_counter privilege (`kernel.perf_event_paranoid=0` ?) + # - https://github.com/google/benchmark/blob/0ab2c290/src/cycleclock.h#L127-L151 + # - https://github.com/FFTW/fftw3/blob/ef15637f/kernel/cycle.h#L518-L564 + # - https://github.com/vesperix/FFTW-for-ARMv7/blob/22ec5c0b/kernel/cycle.h#L404-L457 + + # Prevent compiler optimizing benchmark away # ----------------------------------------------- # This doesn't always work unfortunately ... diff --git a/constantine/platforms/metering/cycle_count/arm.nim b/constantine/platforms/metering/cycle_count/arm.nim deleted file mode 100644 index 076fd19a0..000000000 --- a/constantine/platforms/metering/cycle_count/arm.nim +++ /dev/null @@ -1,16 +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. - -# TODO cycle counting on ARM -# -# - see writeup: http://zhiyisun.github.io/2016/03/02/How-to-Use-Performance-Monitor-Unit-(PMU)-of-64-bit-ARMv8-A-in-Linux.html -# -# Otherwise Google or FFTW approach might work but might require perf_counter privilege (`kernel.perf_event_paranoid=0` ?) -# - https://github.com/google/benchmark/blob/0ab2c290/src/cycleclock.h#L127-L151 -# - https://github.com/FFTW/fftw3/blob/ef15637f/kernel/cycle.h#L518-L564 -# - https://github.com/vesperix/FFTW-for-ARMv7/blob/22ec5c0b/kernel/cycle.h#L404-L457 diff --git a/constantine/platforms/metering/cycle_count/x86.nim b/constantine/platforms/metering/cycle_count/x86.nim deleted file mode 100644 index ad3c3842d..000000000 --- a/constantine/platforms/metering/cycle_count/x86.nim +++ /dev/null @@ -1,82 +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. - -# Cpu Name -# ------------------------------------------------------- - -{.passC:"-std=gnu99".} # TODO may conflict with milagro "-std=c99" - -proc cpuID(eaxi, ecxi: int32): tuple[eax, ebx, ecx, edx: int32] = - when defined(vcc): - proc cpuidVcc(cpuInfo: ptr int32; functionID: int32) - {.importc: "__cpuidex", header: "intrin.h".} - cpuidVcc(addr result.eax, eaxi, ecxi) - else: - var (eaxr, ebxr, ecxr, edxr) = (0'i32, 0'i32, 0'i32, 0'i32) - asm """ - cpuid - :"=a"(`eaxr`), "=b"(`ebxr`), "=c"(`ecxr`), "=d"(`edxr`) - :"a"(`eaxi`), "c"(`ecxi`)""" - (eaxr, ebxr, ecxr, edxr) - -proc cpuName*(): string = - var leaves {.global.} = cast[array[48, char]]([ - cpuID(eaxi = 0x80000002'i32, ecxi = 0), - cpuID(eaxi = 0x80000003'i32, ecxi = 0), - cpuID(eaxi = 0x80000004'i32, ecxi = 0)]) - result = $cast[cstring](addr leaves[0]) - -# Counting cycles -# ------------------------------------------------------- - -# From Linux -# -# The RDTSC instruction is not ordered relative to memory -# access. The Intel SDM and the AMD APM are both vague on this -# point, but empirically an RDTSC instruction can be -# speculatively executed before prior loads. An RDTSC -# immediately after an appropriate barrier appears to be -# ordered as a normal load, that is, it provides the same -# ordering guarantees as reading from a global memory location -# that some other imaginary CPU is updating continuously with a -# time stamp. -# -# From Intel SDM -# https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf - -proc getTicks*(): int64 {.inline.} = - when defined(vcc): - proc rdtsc(): int64 {.sideeffect, importc: "__rdtsc", header: "".} - proc lfence() {.importc: "__mm_lfence", header: "".} - - lfence() - return rdtsc() - - else: - when defined(amd64): - var lo, hi: int64 - # TODO: Provide a compile-time flag for RDTSCP support - # and use it instead of lfence + RDTSC - {.emit: """asm volatile( - "lfence\n" - "rdtsc\n" - : "=a"(`lo`), "=d"(`hi`) - : - : "memory" - );""".} - return (hi shl 32) or lo - else: # 32-bit x86 - # TODO: Provide a compile-time flag for RDTSCP support - # and use it instead of lfence + RDTSC - {.emit: """asm volatile( - "lfence\n" - "rdtsc\n" - : "=a"(`result`) - : - : "memory" - );""".} diff --git a/constantine/platforms/primitives.nim b/constantine/platforms/primitives.nim index 56de579c5..9f40b16b2 100644 --- a/constantine/platforms/primitives.nim +++ b/constantine/platforms/primitives.nim @@ -16,8 +16,7 @@ import ], intrinsics/[ addcarry_subborrow, - extended_precision, - compiler_optim_hints + extended_precision ], ./bithacks, ./static_for, @@ -33,8 +32,7 @@ export ct_division, bithacks, staticFor, - allocs, - compiler_optim_hints + allocs # Note: # - cpuinfo_x86 initialize globals with following CPU features detection. @@ -160,6 +158,44 @@ func `+%=`*(p: var (ptr or pointer), offset: SomeInteger){.inline.}= ## Pointer increment p = p +% offset +# ############################################################ +# +# Prefetching +# +# ############################################################ + +type + PrefetchRW* {.size: cint.sizeof.} = enum + Read = 0 + Write = 1 + PrefetchLocality* {.size: cint.sizeof.} = enum + NoTemporalLocality = 0 # Data can be discarded from CPU cache after access + LowTemporalLocality = 1 + ModerateTemporalLocality = 2 + HighTemporalLocality = 3 # Data should be left in all levels of cache possible + # Translation + # 0 - use no cache eviction level + # 1 - L1 cache eviction level + # 2 - L2 cache eviction level + # 3 - L1 and L2 cache eviction level + +when GCC_Compatible: + proc builtin_prefetch(data: pointer, rw: PrefetchRW, locality: PrefetchLocality) {.importc: "__builtin_prefetch", noDecl.} + +template prefetch*( + data: ptr or pointer, + rw: static PrefetchRW = Read, + locality: static PrefetchLocality = HighTemporalLocality) = + ## Prefetch examples: + ## - https://scripts.mit.edu/~birge/blog/accelerating-code-using-gccs-prefetch-extension/ + ## - https://stackoverflow.com/questions/7327994/prefetching-examples + ## - https://lemire.me/blog/2018/04/30/is-software-prefetching-__builtin_prefetch-useful-for-performance/ + ## - https://www.naftaliharris.com/blog/2x-speedup-with-one-line-of-code/ + when GCC_Compatible: + builtin_prefetch(data, rw, locality) + else: + discard + func prefetchLarge*[T]( data: ptr T, rw: static PrefetchRW = Read, diff --git a/constantine/trusted_setups/ethereum_kzg_srs.nim b/constantine/trusted_setups/ethereum_kzg_srs.nim index 54e7b61c2..929df2baa 100644 --- a/constantine/trusted_setups/ethereum_kzg_srs.nim +++ b/constantine/trusted_setups/ethereum_kzg_srs.nim @@ -15,7 +15,7 @@ import ../math/polynomials/polynomials, ../math/io/io_fields, - std/streams + std/streams # TODO: use the C streams which do not allocate, are exception-free and are guaranteed not to bring unremovable runtime procs. # Ensure all exceptions are converted to error codes {.push raises: [], checks: off.} diff --git a/constantine/zoo_exports.nim b/constantine/zoo_exports.nim index 1dada53b5..6ddf18b46 100644 --- a/constantine/zoo_exports.nim +++ b/constantine/zoo_exports.nim @@ -21,8 +21,10 @@ # Exportable functions # ---------------------------------------------------------------------------------------------- +# A module that import these functions can modify their C prefix, if needed. +# By assigning to the prefix, in a static block **before** importing the module. -var prefix_sha256* {.compileTime.} = "" +var prefix_sha256* {.compileTime.} = "ctt_sha256_" # Conditional exports # ---------------------------------------------------------------------------------------------- diff --git a/examples_c/ethereum_bls_signatures.c b/examples_c/ethereum_bls_signatures.c index fcd3a12a4..f52ff24f5 100644 --- a/examples_c/ethereum_bls_signatures.c +++ b/examples_c/ethereum_bls_signatures.c @@ -11,13 +11,9 @@ #include #include -#include +#include int main(){ - - // Initialize the runtime. For Constantine, it populates the CPU runtime detection dispatch. - ctt_eth_bls_init_NimMain(); - // Protocol and deserialization statuses ctt_eth_bls_status bls_status; ctt_codec_scalar_status scalar_status; @@ -44,7 +40,7 @@ int main(){ // Sign a message byte message[32]; ctt_eth_bls_signature sig; - ctt_eth_bls_sha256_hash(message, "Mr F was here", 13, /* clear_memory = */ 0); + ctt_sha256_hash(message, "Mr F was here", 13, /* clear_memory = */ 0); ctt_eth_bls_sign(&sig, &seckey, message, 32); // Verify that a signature is valid for a message under the provided public key diff --git a/examples_c/t_libctt_bls12_381.c b/examples_c/t_libctt_bls12_381.c index dd1969e29..612c1cc15 100644 --- a/examples_c/t_libctt_bls12_381.c +++ b/examples_c/t_libctt_bls12_381.c @@ -15,7 +15,7 @@ #include #include -#include +#include // https://gmplib.org/manual/Integer-Import-and-Export.html const int GMP_WordLittleEndian = -1; @@ -31,20 +31,36 @@ const int GMP_LeastSignificantWordFirst = -1; #define Modulus "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab" #define Iter 24 -void prologue( + +// Beware of convention, Constantine serialization returns true/'1' for success +// but top-level program status code returns 0 for success +#define CHECK(fn_call) \ + do { \ + int status = fn_call; \ + /* printf("status %d for '%s'\n", status, #fn_call); */ \ + if (status != 0) { \ + return 1; \ + } \ + } while (0) + +int prologue( gmp_randstate_t gmp_rng, mpz_ptr a, mpz_ptr b, mpz_ptr p, - bls12381_fp* a_ctt, bls12381_fp* b_ctt, + bls12_381_fp* a_ctt, bls12_381_fp* b_ctt, byte a_buf[ByteLength], byte b_buf[ByteLength]) { - // Generate random value in the range 0 ..< 2^(bits-1) + // Generate random value in the range [0, 2^(bits-1)) mpz_urandomb(a, gmp_rng, BitLength); mpz_urandomb(b, gmp_rng, BitLength); // Set modulus to curve modulus mpz_set_str(p, Modulus, 0); + // Restrict to [0, p) + mpz_mod(a, a, p); + mpz_mod(b, b, p); + // GMP -> Constantine size_t aW, bW; mpz_export(a_buf, &aW, GMP_MostSignificantWordFirst, 1, GMP_WordNativeEndian, 0, a); @@ -53,8 +69,10 @@ void prologue( assert(ByteLength >= aW); assert(ByteLength >= bW); - ctt_bls12381_fp_unmarshalBE(a_ctt, a_buf, aW); - ctt_bls12381_fp_unmarshalBE(b_ctt, b_buf, bW); + CHECK(!ctt_bls12_381_fp_unmarshalBE(a_ctt, a_buf, aW)); + CHECK(!ctt_bls12_381_fp_unmarshalBE(b_ctt, b_buf, bW)); + + return 0; } void dump_hex(byte a[ByteLength]){ @@ -64,9 +82,9 @@ void dump_hex(byte a[ByteLength]){ } } -void epilogue( +int epilogue( mpz_ptr r, mpz_ptr a, mpz_ptr b, - bls12381_fp* r_ctt, bls12381_fp* a_ctt, bls12381_fp* b_ctt, + bls12_381_fp* r_ctt, bls12_381_fp* a_ctt, bls12_381_fp* b_ctt, char* operation) { byte r_raw_gmp[ByteLength]; @@ -77,7 +95,7 @@ void epilogue( mpz_export(r_raw_gmp, &rW, GMP_MostSignificantWordFirst, 1, GMP_WordNativeEndian, 0, r); // Constantine -> Raw - ctt_bls12381_fp_marshalBE(r_raw_ctt, ByteLength, r_ctt); + CHECK(!ctt_bls12_381_fp_marshalBE(r_raw_ctt, ByteLength, r_ctt)); // Check for (int g = 0, c = ByteLength-rW; g < rW; g+=1, c+=1) { @@ -98,13 +116,10 @@ void epilogue( } } printf("."); + return 0; } int main(){ - - // Initialize the runtime. For Constantine, it populates CPU runtime detection dispatch. - ctt_bls12381_init_NimMain(); - gmp_randstate_t gmpRng; gmp_randinit_mt(gmpRng); // The GMP seed varies between run so that @@ -121,111 +136,111 @@ int main(){ mpz_init(p); mpz_init(r); - bls12381_fp a_ctt, b_ctt, r_ctt; + bls12_381_fp a_ctt, b_ctt, r_ctt; byte a_buf[ByteLength], b_buf[ByteLength]; for (int i = 0; i < Iter; ++i){ - prologue( + CHECK(prologue( gmpRng, a, b, p, &a_ctt, &b_ctt, a_buf, b_buf - ); + )); mpz_neg(r, a); mpz_mod(r, r, p); - ctt_bls12381_fp_neg(&r_ctt, &a_ctt); + ctt_bls12_381_fp_neg(&r_ctt, &a_ctt); - epilogue( + CHECK(epilogue( r, a, b, &r_ctt, &a_ctt, &b_ctt, "negation" - ); + )); } printf(" SUCCESS negation\n"); for (int i = 0; i < Iter; ++i){ - prologue( + CHECK(prologue( gmpRng, a, b, p, &a_ctt, &b_ctt, a_buf, b_buf - ); + )); mpz_add(r, a, b); mpz_mod(r, r, p); - ctt_bls12381_fp_sum(&r_ctt, &a_ctt, &b_ctt); + ctt_bls12_381_fp_sum(&r_ctt, &a_ctt, &b_ctt); - epilogue( + CHECK(epilogue( r, a, b, &r_ctt, &a_ctt, &b_ctt, "addition" - ); + )); } printf(" SUCCESS addition\n"); for (int i = 0; i < Iter; ++i){ - prologue( + CHECK(prologue( gmpRng, a, b, p, &a_ctt, &b_ctt, a_buf, b_buf - ); + )); mpz_mul(r, a, b); mpz_mod(r, r, p); - ctt_bls12381_fp_prod(&r_ctt, &a_ctt, &b_ctt); + ctt_bls12_381_fp_prod(&r_ctt, &a_ctt, &b_ctt); - epilogue( + CHECK(epilogue( r, a, b, &r_ctt, &a_ctt, &b_ctt, "multiplication" - ); + )); } printf(" SUCCESS multiplication\n"); for (int i = 0; i < Iter; ++i){ - prologue( + CHECK(prologue( gmpRng, a, b, p, &a_ctt, &b_ctt, a_buf, b_buf - ); + )); mpz_invert(r, a, p); - ctt_bls12381_fp_inv(&r_ctt, &a_ctt); + ctt_bls12_381_fp_inv(&r_ctt, &a_ctt); - epilogue( + CHECK(epilogue( r, a, b, &r_ctt, &a_ctt, &b_ctt, "inversion" - ); + )); } printf(" SUCCESS inversion\n"); for (int i = 0; i < Iter; ++i){ - prologue( + CHECK(prologue( gmpRng, a, b, p, &a_ctt, &b_ctt, a_buf, b_buf - ); + )); int is_square_gmp = mpz_legendre(a, p) == -1 ? 0:1; - int is_square_ctt = ctt_bls12381_fp_is_square(&a_ctt); + int is_square_ctt = ctt_bls12_381_fp_is_square(&a_ctt); assert(is_square_gmp == is_square_ctt); } printf(" SUCCESS Legendre symbol / is_square\n"); - // TODO: THere are a "positive" and "negative" square roots + // TODO: There are a "positive" and "negative" square roots // for (int i = 0; i < Iter; ++i){ - // prologue( + // CHECK(prologue( // gmpRng, // a, b, p, // &a_ctt, &b_ctt, // a_buf, b_buf - // ); + // )); // if (mpz_congruent_ui_p(p, 3, 4)) { // // a^((p+1)/4) (mod p) @@ -235,13 +250,13 @@ int main(){ // } else { // assert(0); // } - // ctt_bls12381_fp_prod(&r_ctt, &a_ctt, &b_ctt); + // ctt_bls12_381_fp_prod(&r_ctt, &a_ctt, &b_ctt); - // epilogue( + // CHECK(epilogue( // r, a, b, // &r_ctt, &a_ctt, &b_ctt, // "square root" - // ); + // )); // } // printf(" SUCCESS square root\n"); diff --git a/include/README.md b/include/README.md deleted file mode 100644 index 6c7f44ed3..000000000 --- a/include/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Headers - -This folder holds the generated C headers for Constantine. - -To create a new build, download install the [Nim programming language](https://nim-lang.org/install.html), navigate to Constantine's root folder and call `nimble bindings`. \ No newline at end of file diff --git a/include/constantine.h b/include/constantine.h new file mode 100644 index 000000000..6ca80d87e --- /dev/null +++ b/include/constantine.h @@ -0,0 +1,24 @@ +/** 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_CONSTANTINE__ +#define __CTT_H_CONSTANTINE__ + +// Hash functions +#include "constantine/hashes/sha256.h" + +// Curves +#include "constantine/curves/bls12_381.h" +#include "constantine/curves/bn254_snarks.h" +#include "constantine/curves/pallas.h" +#include "constantine/curves/vesta.h" + +// Protocols +#include "constantine/protocols/ethereum_bls_signatures.h" + +#endif \ No newline at end of file diff --git a/include/constantine/core/datatypes.h b/include/constantine/core/datatypes.h new file mode 100644 index 000000000..492e3863c --- /dev/null +++ b/include/constantine/core/datatypes.h @@ -0,0 +1,67 @@ +/** 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_DATATYPES__ +#define __CTT_H_DATATYPES__ + +#ifdef __cplusplus +extern "C" { +#endif + +// Basic Types +// ------------------------------------------------------------------------------------------------ +// If we can, we want zero dependencies + +#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) +typedef __SIZE_TYPE__ size_t; +typedef __PTRDIFF_TYPE__ ptrdiff_t; +#else +#include +#endif + +#if defined(__UINT8_TYPE__) && defined(__UINT32_TYPE__) && defined(__UINT64_TYPE__) +typedef __UINT8_TYPE__ uint8_t; +typedef __UINT32_TYPE__ uint32_t; +typedef __UINT64_TYPE__ uint64_t; +#else +#include +#endif + +// https://github.com/nim-lang/Nim/blob/v1.6.12/lib/nimbase.h#L318 +#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901 +# define ctt_bool _Bool +#else +# define ctt_bool unsigned char +#endif + +typedef size_t secret_word; +typedef size_t secret_bool; +typedef uint8_t byte; + +// Sizes +// ------------------------------------------------------------------------------------------------ + +#define CTT_WORD_BITWIDTH (sizeof(secret_word)*8) +#define CTT_WORDS_REQUIRED(bits) ((bits+CTT_WORD_BITWIDTH-1)/CTT_WORD_BITWIDTH) + +// Attributes +// ------------------------------------------------------------------------------------------------ + +#if defined(_MSC_VER) +# define ctt_align(x) __declspec(align(x)) +#else +# define ctt_align(x) __attribute__((aligned(x))) +#endif + +// ------------------------------------------------------------------------------------------------ + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/constantine/core/serialization.h b/include/constantine/core/serialization.h new file mode 100644 index 000000000..c93c671d6 --- /dev/null +++ b/include/constantine/core/serialization.h @@ -0,0 +1,66 @@ +/** 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_SERIALIZATION__ +#define __CTT_H_SERIALIZATION__ + +#include "constantine/core/datatypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum __attribute__((__packed__)) { + cttCodecScalar_Success, + cttCodecScalar_Zero, + cttCodecScalar_ScalarLargerThanCurveOrder, +} ctt_codec_scalar_status; + +static const char* ctt_codec_scalar_status_to_string(ctt_codec_scalar_status status) { + static const char* const statuses[] = { + "cttCodecScalar_Success", + "cttCodecScalar_Zero", + "cttCodecScalar_ScalarLargerThanCurveOrder", + }; + size_t length = sizeof statuses / sizeof *statuses; + if (0 <= status && status < length) { + return statuses[status]; + } + return "cttCodecScalar_InvalidStatusCode"; +} + +typedef enum __attribute__((__packed__)) { + cttCodecEcc_Success, + cttCodecEcc_InvalidEncoding, + cttCodecEcc_CoordinateGreaterThanOrEqualModulus, + cttCodecEcc_PointNotOnCurve, + cttCodecEcc_PointNotInSubgroup, + cttCodecEcc_PointAtInfinity, +} ctt_codec_ecc_status; + +static const char* ctt_codec_ecc_status_to_string(ctt_codec_ecc_status status) { + static const char* const statuses[] = { + "cttCodecEcc_Success", + "cttCodecEcc_InvalidEncoding", + "cttCodecEcc_CoordinateGreaterThanOrEqualModulus", + "cttCodecEcc_PointNotOnCurve", + "cttCodecEcc_PointNotInSubgroup", + "cttCodecEcc_PointAtInfinity", + }; + size_t length = sizeof statuses / sizeof *statuses; + if (0 <= status && status < length) { + return statuses[status]; + } + return "cttCodecEcc_InvalidStatusCode"; +} + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/constantine/curves/bls12_381.h b/include/constantine/curves/bls12_381.h new file mode 100644 index 000000000..ffb255ed6 --- /dev/null +++ b/include/constantine/curves/bls12_381.h @@ -0,0 +1,209 @@ +/** 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_BLS12_381__ +#define __CTT_H_BLS12_381__ + +#include "constantine/core/datatypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } bls12_381_fr; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(381)]; } bls12_381_fp; +typedef struct { bls12_381_fp c[2]; } bls12_381_fp2; +typedef struct { bls12_381_fp x, y; } bls12_381_ec_g1_aff; +typedef struct { bls12_381_fp x, y, z; } bls12_381_ec_g1_jac; +typedef struct { bls12_381_fp x, y, z; } bls12_381_ec_g1_prj; +typedef struct { bls12_381_fp2 x, y; } bls12_381_ec_g2_aff; +typedef struct { bls12_381_fp2 x, y, z; } bls12_381_ec_g2_jac; +typedef struct { bls12_381_fp2 x, y, z; } bls12_381_ec_g2_prj; + +ctt_bool ctt_bls12_381_fr_unmarshalBE(bls12_381_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_bls12_381_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12_381_fr* src) __attribute__((warn_unused_result)); +secret_bool ctt_bls12_381_fr_is_eq(const bls12_381_fr* a, const bls12_381_fr* b); +secret_bool ctt_bls12_381_fr_is_zero(const bls12_381_fr* a); +secret_bool ctt_bls12_381_fr_is_one(const bls12_381_fr* a); +secret_bool ctt_bls12_381_fr_is_minus_one(const bls12_381_fr* a); +void ctt_bls12_381_fr_set_zero(bls12_381_fr* a); +void ctt_bls12_381_fr_set_one(bls12_381_fr* a); +void ctt_bls12_381_fr_set_minus_one(bls12_381_fr* a); +void ctt_bls12_381_fr_neg(bls12_381_fr* r, const bls12_381_fr* a); +void ctt_bls12_381_fr_neg_in_place(bls12_381_fr* a); +void ctt_bls12_381_fr_sum(bls12_381_fr* r, const bls12_381_fr* a, const bls12_381_fr* b); +void ctt_bls12_381_fr_add_in_place(bls12_381_fr* a, const bls12_381_fr* b); +void ctt_bls12_381_fr_diff(bls12_381_fr* r, const bls12_381_fr* a, const bls12_381_fr* b); +void ctt_bls12_381_fr_sub_in_place(bls12_381_fr* a, const bls12_381_fr* b); +void ctt_bls12_381_fr_double(bls12_381_fr* r, const bls12_381_fr* a); +void ctt_bls12_381_fr_double_in_place(bls12_381_fr* a); +void ctt_bls12_381_fr_prod(bls12_381_fr* r, const bls12_381_fr* a, const bls12_381_fr* b); +void ctt_bls12_381_fr_mul_in_place(bls12_381_fr* a, const bls12_381_fr* b); +void ctt_bls12_381_fr_square(bls12_381_fr* r, const bls12_381_fr* a); +void ctt_bls12_381_fr_square_in_place(bls12_381_fr* a); +void ctt_bls12_381_fr_div2(bls12_381_fr* a); +void ctt_bls12_381_fr_inv(bls12_381_fr* r, const bls12_381_fr* a); +void ctt_bls12_381_fr_inv_in_place(bls12_381_fr* a); +void ctt_bls12_381_fr_ccopy(bls12_381_fr* a, const bls12_381_fr* b, const secret_bool ctl); +void ctt_bls12_381_fr_cswap(bls12_381_fr* a, bls12_381_fr* b, const secret_bool ctl); +void ctt_bls12_381_fr_cset_zero(bls12_381_fr* a, const secret_bool ctl); +void ctt_bls12_381_fr_cset_one(bls12_381_fr* a, const secret_bool ctl); +void ctt_bls12_381_fr_cneg_in_place(bls12_381_fr* a, const secret_bool ctl); +void ctt_bls12_381_fr_cadd_in_place(bls12_381_fr* a, const bls12_381_fr* b, const secret_bool ctl); +void ctt_bls12_381_fr_csub_in_place(bls12_381_fr* a, const bls12_381_fr* b, const secret_bool ctl); +ctt_bool ctt_bls12_381_fp_unmarshalBE(bls12_381_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_bls12_381_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12_381_fp* src) __attribute__((warn_unused_result)); +secret_bool ctt_bls12_381_fp_is_eq(const bls12_381_fp* a, const bls12_381_fp* b); +secret_bool ctt_bls12_381_fp_is_zero(const bls12_381_fp* a); +secret_bool ctt_bls12_381_fp_is_one(const bls12_381_fp* a); +secret_bool ctt_bls12_381_fp_is_minus_one(const bls12_381_fp* a); +void ctt_bls12_381_fp_set_zero(bls12_381_fp* a); +void ctt_bls12_381_fp_set_one(bls12_381_fp* a); +void ctt_bls12_381_fp_set_minus_one(bls12_381_fp* a); +void ctt_bls12_381_fp_neg(bls12_381_fp* r, const bls12_381_fp* a); +void ctt_bls12_381_fp_neg_in_place(bls12_381_fp* a); +void ctt_bls12_381_fp_sum(bls12_381_fp* r, const bls12_381_fp* a, const bls12_381_fp* b); +void ctt_bls12_381_fp_add_in_place(bls12_381_fp* a, const bls12_381_fp* b); +void ctt_bls12_381_fp_diff(bls12_381_fp* r, const bls12_381_fp* a, const bls12_381_fp* b); +void ctt_bls12_381_fp_sub_in_place(bls12_381_fp* a, const bls12_381_fp* b); +void ctt_bls12_381_fp_double(bls12_381_fp* r, const bls12_381_fp* a); +void ctt_bls12_381_fp_double_in_place(bls12_381_fp* a); +void ctt_bls12_381_fp_prod(bls12_381_fp* r, const bls12_381_fp* a, const bls12_381_fp* b); +void ctt_bls12_381_fp_mul_in_place(bls12_381_fp* a, const bls12_381_fp* b); +void ctt_bls12_381_fp_square(bls12_381_fp* r, const bls12_381_fp* a); +void ctt_bls12_381_fp_square_in_place(bls12_381_fp* a); +void ctt_bls12_381_fp_div2(bls12_381_fp* a); +void ctt_bls12_381_fp_inv(bls12_381_fp* r, const bls12_381_fp* a); +void ctt_bls12_381_fp_inv_in_place(bls12_381_fp* a); +void ctt_bls12_381_fp_ccopy(bls12_381_fp* a, const bls12_381_fp* b, const secret_bool ctl); +void ctt_bls12_381_fp_cswap(bls12_381_fp* a, bls12_381_fp* b, const secret_bool ctl); +void ctt_bls12_381_fp_cset_zero(bls12_381_fp* a, const secret_bool ctl); +void ctt_bls12_381_fp_cset_one(bls12_381_fp* a, const secret_bool ctl); +void ctt_bls12_381_fp_cneg_in_place(bls12_381_fp* a, const secret_bool ctl); +void ctt_bls12_381_fp_cadd_in_place(bls12_381_fp* a, const bls12_381_fp* b, const secret_bool ctl); +void ctt_bls12_381_fp_csub_in_place(bls12_381_fp* a, const bls12_381_fp* b, const secret_bool ctl); +secret_bool ctt_bls12_381_fp_is_square(const bls12_381_fp* a); +void ctt_bls12_381_fp_invsqrt(bls12_381_fp* r, const bls12_381_fp* a); +secret_bool ctt_bls12_381_fp_invsqrt_in_place(bls12_381_fp* r, const bls12_381_fp* a); +void ctt_bls12_381_fp_sqrt_in_place(bls12_381_fp* a); +secret_bool ctt_bls12_381_fp_sqrt_if_square_in_place(bls12_381_fp* a); +void ctt_bls12_381_fp_sqrt_invsqrt(bls12_381_fp* sqrt, bls12_381_fp* invsqrt, const bls12_381_fp* a); +secret_bool ctt_bls12_381_fp_sqrt_invsqrt_if_square(bls12_381_fp* sqrt, bls12_381_fp* invsqrt, const bls12_381_fp* a); +secret_bool ctt_bls12_381_fp_sqrt_ratio_if_square(bls12_381_fp* r, const bls12_381_fp* u, const bls12_381_fp* v); +secret_bool ctt_bls12_381_fp2_is_eq(const bls12_381_fp2* a, const bls12_381_fp2* b); +secret_bool ctt_bls12_381_fp2_is_zero(const bls12_381_fp2* a); +secret_bool ctt_bls12_381_fp2_is_one(const bls12_381_fp2* a); +secret_bool ctt_bls12_381_fp2_is_minus_one(const bls12_381_fp2* a); +void ctt_bls12_381_fp2_set_zero(bls12_381_fp2* a); +void ctt_bls12_381_fp2_set_one(bls12_381_fp2* a); +void ctt_bls12_381_fp2_set_minus_one(bls12_381_fp2* a); +void ctt_bls12_381_fp2_neg(bls12_381_fp2* a); +void ctt_bls12_381_fp2_sum(bls12_381_fp2* r, const bls12_381_fp2* a, const bls12_381_fp2* b); +void ctt_bls12_381_fp2_add_in_place(bls12_381_fp2* a, const bls12_381_fp2* b); +void ctt_bls12_381_fp2_diff(bls12_381_fp2* r, const bls12_381_fp2* a, const bls12_381_fp2* b); +void ctt_bls12_381_fp2_sub_in_place(bls12_381_fp2* a, const bls12_381_fp2* b); +void ctt_bls12_381_fp2_double(bls12_381_fp2* r, const bls12_381_fp2* a); +void ctt_bls12_381_fp2_double_in_place(bls12_381_fp2* a); +void ctt_bls12_381_fp2_conj(bls12_381_fp2* r, const bls12_381_fp2* a); +void ctt_bls12_381_fp2_conj_in_place(bls12_381_fp2* a); +void ctt_bls12_381_fp2_conjneg(bls12_381_fp2* r, const bls12_381_fp2* a); +void ctt_bls12_381_fp2_conjneg_in_place(bls12_381_fp2* a); +void ctt_bls12_381_fp2_prod(bls12_381_fp2* r, const bls12_381_fp2* a, const bls12_381_fp2* b); +void ctt_bls12_381_fp2_mul_in_place(bls12_381_fp2* a, const bls12_381_fp2* b); +void ctt_bls12_381_fp2_square(bls12_381_fp2* r, const bls12_381_fp2* a); +void ctt_bls12_381_fp2_square_in_place(bls12_381_fp2* a); +void ctt_bls12_381_fp2_div2(bls12_381_fp2* a); +void ctt_bls12_381_fp2_inv(bls12_381_fp2* r, const bls12_381_fp2* a); +void ctt_bls12_381_fp2_inv_in_place(bls12_381_fp2* a); +void ctt_bls12_381_fp2_ccopy(bls12_381_fp2* a, const bls12_381_fp2* b, const secret_bool ctl); +void ctt_bls12_381_fp2_cset_zero(bls12_381_fp2* a, const secret_bool ctl); +void ctt_bls12_381_fp2_cset_one(bls12_381_fp2* a, const secret_bool ctl); +void ctt_bls12_381_fp2_cneg_in_place(bls12_381_fp2* a, const secret_bool ctl); +void ctt_bls12_381_fp2_cadd_in_place(bls12_381_fp2* a, const bls12_381_fp2* b, const secret_bool ctl); +void ctt_bls12_381_fp2_csub_in_place(bls12_381_fp2* a, const bls12_381_fp2* b, const secret_bool ctl); +secret_bool ctt_bls12_381_fp2_is_square(const bls12_381_fp2* a); +void ctt_bls12_381_fp2_sqrt_in_place(bls12_381_fp2* a); +secret_bool ctt_bls12_381_fp2_sqrt_if_square_in_place(bls12_381_fp2* a); +secret_bool ctt_bls12_381_ec_g1_aff_is_eq(const bls12_381_ec_g1_aff* P, const bls12_381_ec_g1_aff* Q); +secret_bool ctt_bls12_381_ec_g1_aff_is_inf(const bls12_381_ec_g1_aff* P); +void ctt_bls12_381_ec_g1_aff_set_inf(bls12_381_ec_g1_aff* P); +void ctt_bls12_381_ec_g1_aff_ccopy(bls12_381_ec_g1_aff* P, const bls12_381_ec_g1_aff* Q, const secret_bool ctl); +secret_bool ctt_bls12_381_ec_g1_aff_is_on_curve(const bls12_381_fp* x, const bls12_381_fp* y); +void ctt_bls12_381_ec_g1_aff_neg(bls12_381_ec_g1_aff* P, const bls12_381_ec_g1_aff* Q); +void ctt_bls12_381_ec_g1_aff_neg_in_place(bls12_381_ec_g1_aff* P); +secret_bool ctt_bls12_381_ec_g1_jac_is_eq(const bls12_381_ec_g1_jac* P, const bls12_381_ec_g1_jac* Q); +secret_bool ctt_bls12_381_ec_g1_jac_is_inf(const bls12_381_ec_g1_jac* P); +void ctt_bls12_381_ec_g1_jac_set_inf(bls12_381_ec_g1_jac* P); +void ctt_bls12_381_ec_g1_jac_ccopy(bls12_381_ec_g1_jac* P, const bls12_381_ec_g1_jac* Q, const secret_bool ctl); +void ctt_bls12_381_ec_g1_jac_neg(bls12_381_ec_g1_jac* P, const bls12_381_ec_g1_jac* Q); +void ctt_bls12_381_ec_g1_jac_neg_in_place(bls12_381_ec_g1_jac* P); +void ctt_bls12_381_ec_g1_jac_cneg_in_place(bls12_381_ec_g1_jac* P, const secret_bool ctl); +void ctt_bls12_381_ec_g1_jac_sum(bls12_381_ec_g1_jac* r, const bls12_381_ec_g1_jac* P, const bls12_381_ec_g1_jac* Q); +void ctt_bls12_381_ec_g1_jac_add_in_place(bls12_381_ec_g1_jac* P, const bls12_381_ec_g1_jac* Q); +void ctt_bls12_381_ec_g1_jac_diff(bls12_381_ec_g1_jac* r, const bls12_381_ec_g1_jac* P, const bls12_381_ec_g1_jac* Q); +void ctt_bls12_381_ec_g1_jac_double(bls12_381_ec_g1_jac* r, const bls12_381_ec_g1_jac* P); +void ctt_bls12_381_ec_g1_jac_double_in_place(bls12_381_ec_g1_jac* P); +void ctt_bls12_381_ec_g1_jac_affine(bls12_381_ec_g1_aff* dst, const bls12_381_ec_g1_jac* src); +void ctt_bls12_381_ec_g1_jac_from_affine(bls12_381_ec_g1_jac* dst, const bls12_381_ec_g1_aff* src); +secret_bool ctt_bls12_381_ec_g1_prj_is_eq(const bls12_381_ec_g1_prj* P, const bls12_381_ec_g1_prj* Q); +secret_bool ctt_bls12_381_ec_g1_prj_is_inf(const bls12_381_ec_g1_prj* P); +void ctt_bls12_381_ec_g1_prj_set_inf(bls12_381_ec_g1_prj* P); +void ctt_bls12_381_ec_g1_prj_ccopy(bls12_381_ec_g1_prj* P, const bls12_381_ec_g1_prj* Q, const secret_bool ctl); +void ctt_bls12_381_ec_g1_prj_neg(bls12_381_ec_g1_prj* P, const bls12_381_ec_g1_prj* Q); +void ctt_bls12_381_ec_g1_prj_neg_in_place(bls12_381_ec_g1_prj* P); +void ctt_bls12_381_ec_g1_prj_cneg_in_place(bls12_381_ec_g1_prj* P, const secret_bool ctl); +void ctt_bls12_381_ec_g1_prj_sum(bls12_381_ec_g1_prj* r, const bls12_381_ec_g1_prj* P, const bls12_381_ec_g1_prj* Q); +void ctt_bls12_381_ec_g1_prj_add_in_place(bls12_381_ec_g1_prj* P, const bls12_381_ec_g1_prj* Q); +void ctt_bls12_381_ec_g1_prj_diff(bls12_381_ec_g1_prj* r, const bls12_381_ec_g1_prj* P, const bls12_381_ec_g1_prj* Q); +void ctt_bls12_381_ec_g1_prj_double(bls12_381_ec_g1_prj* r, const bls12_381_ec_g1_prj* P); +void ctt_bls12_381_ec_g1_prj_double_in_place(bls12_381_ec_g1_prj* P); +void ctt_bls12_381_ec_g1_prj_affine(bls12_381_ec_g1_aff* dst, const bls12_381_ec_g1_prj* src); +void ctt_bls12_381_ec_g1_prj_from_affine(bls12_381_ec_g1_prj* dst, const bls12_381_ec_g1_aff* src); +secret_bool ctt_bls12_381_ec_g2_aff_is_eq(const bls12_381_ec_g2_aff* P, const bls12_381_ec_g2_aff* Q); +secret_bool ctt_bls12_381_ec_g2_aff_is_inf(const bls12_381_ec_g2_aff* P); +void ctt_bls12_381_ec_g2_aff_set_inf(bls12_381_ec_g2_aff* P); +void ctt_bls12_381_ec_g2_aff_ccopy(bls12_381_ec_g2_aff* P, const bls12_381_ec_g2_aff* Q, const secret_bool ctl); +secret_bool ctt_bls12_381_ec_g2_aff_is_on_curve(const bls12_381_fp2* x, const bls12_381_fp2* y); +void ctt_bls12_381_ec_g2_aff_neg(bls12_381_ec_g2_aff* P, const bls12_381_ec_g2_aff* Q); +void ctt_bls12_381_ec_g2_aff_neg_in_place(bls12_381_ec_g2_aff* P); +secret_bool ctt_bls12_381_ec_g2_jac_is_eq(const bls12_381_ec_g2_jac* P, const bls12_381_ec_g2_jac* Q); +secret_bool ctt_bls12_381_ec_g2_jac_is_inf(const bls12_381_ec_g2_jac* P); +void ctt_bls12_381_ec_g2_jac_set_inf(bls12_381_ec_g2_jac* P); +void ctt_bls12_381_ec_g2_jac_ccopy(bls12_381_ec_g2_jac* P, const bls12_381_ec_g2_jac* Q, const secret_bool ctl); +void ctt_bls12_381_ec_g2_jac_neg(bls12_381_ec_g2_jac* P, const bls12_381_ec_g2_jac* Q); +void ctt_bls12_381_ec_g2_jac_neg_in_place(bls12_381_ec_g2_jac* P); +void ctt_bls12_381_ec_g2_jac_cneg_in_place(bls12_381_ec_g2_jac* P, const secret_bool ctl); +void ctt_bls12_381_ec_g2_jac_sum(bls12_381_ec_g2_jac* r, const bls12_381_ec_g2_jac* P, const bls12_381_ec_g2_jac* Q); +void ctt_bls12_381_ec_g2_jac_add_in_place(bls12_381_ec_g2_jac* P, const bls12_381_ec_g2_jac* Q); +void ctt_bls12_381_ec_g2_jac_diff(bls12_381_ec_g2_jac* r, const bls12_381_ec_g2_jac* P, const bls12_381_ec_g2_jac* Q); +void ctt_bls12_381_ec_g2_jac_double(bls12_381_ec_g2_jac* r, const bls12_381_ec_g2_jac* P); +void ctt_bls12_381_ec_g2_jac_double_in_place(bls12_381_ec_g2_jac* P); +void ctt_bls12_381_ec_g2_jac_affine(bls12_381_ec_g2_aff* dst, const bls12_381_ec_g2_jac* src); +void ctt_bls12_381_ec_g2_jac_from_affine(bls12_381_ec_g2_jac* dst, const bls12_381_ec_g2_aff* src); +secret_bool ctt_bls12_381_ec_g2_prj_is_eq(const bls12_381_ec_g2_prj* P, const bls12_381_ec_g2_prj* Q); +secret_bool ctt_bls12_381_ec_g2_prj_is_inf(const bls12_381_ec_g2_prj* P); +void ctt_bls12_381_ec_g2_prj_set_inf(bls12_381_ec_g2_prj* P); +void ctt_bls12_381_ec_g2_prj_ccopy(bls12_381_ec_g2_prj* P, const bls12_381_ec_g2_prj* Q, const secret_bool ctl); +void ctt_bls12_381_ec_g2_prj_neg(bls12_381_ec_g2_prj* P, const bls12_381_ec_g2_prj* Q); +void ctt_bls12_381_ec_g2_prj_neg_in_place(bls12_381_ec_g2_prj* P); +void ctt_bls12_381_ec_g2_prj_cneg_in_place(bls12_381_ec_g2_prj* P, const secret_bool ctl); +void ctt_bls12_381_ec_g2_prj_sum(bls12_381_ec_g2_prj* r, const bls12_381_ec_g2_prj* P, const bls12_381_ec_g2_prj* Q); +void ctt_bls12_381_ec_g2_prj_add_in_place(bls12_381_ec_g2_prj* P, const bls12_381_ec_g2_prj* Q); +void ctt_bls12_381_ec_g2_prj_diff(bls12_381_ec_g2_prj* r, const bls12_381_ec_g2_prj* P, const bls12_381_ec_g2_prj* Q); +void ctt_bls12_381_ec_g2_prj_double(bls12_381_ec_g2_prj* r, const bls12_381_ec_g2_prj* P); +void ctt_bls12_381_ec_g2_prj_double_in_place(bls12_381_ec_g2_prj* P); +void ctt_bls12_381_ec_g2_prj_affine(bls12_381_ec_g2_aff* dst, const bls12_381_ec_g2_prj* src); +void ctt_bls12_381_ec_g2_prj_from_affine(bls12_381_ec_g2_prj* dst, const bls12_381_ec_g2_aff* src); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/constantine/curves/bn254_snarks.h b/include/constantine/curves/bn254_snarks.h new file mode 100644 index 000000000..9e0b7acd9 --- /dev/null +++ b/include/constantine/curves/bn254_snarks.h @@ -0,0 +1,209 @@ +/** 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_BN254_SNARKS__ +#define __CTT_H_BN254_SNARKS__ + +#include "constantine/core/datatypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(254)]; } bn254_snarks_fr; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(254)]; } bn254_snarks_fp; +typedef struct { bn254_snarks_fp c[2]; } bn254_snarks_fp2; +typedef struct { bn254_snarks_fp x, y; } bn254_snarks_ec_g1_aff; +typedef struct { bn254_snarks_fp x, y, z; } bn254_snarks_ec_g1_jac; +typedef struct { bn254_snarks_fp x, y, z; } bn254_snarks_ec_g1_prj; +typedef struct { bn254_snarks_fp2 x, y; } bn254_snarks_ec_g2_aff; +typedef struct { bn254_snarks_fp2 x, y, z; } bn254_snarks_ec_g2_jac; +typedef struct { bn254_snarks_fp2 x, y, z; } bn254_snarks_ec_g2_prj; + +ctt_bool ctt_bn254_snarks_fr_unmarshalBE(bn254_snarks_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_bn254_snarks_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const bn254_snarks_fr* src) __attribute__((warn_unused_result)); +secret_bool ctt_bn254_snarks_fr_is_eq(const bn254_snarks_fr* a, const bn254_snarks_fr* b); +secret_bool ctt_bn254_snarks_fr_is_zero(const bn254_snarks_fr* a); +secret_bool ctt_bn254_snarks_fr_is_one(const bn254_snarks_fr* a); +secret_bool ctt_bn254_snarks_fr_is_minus_one(const bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_set_zero(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_set_one(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_set_minus_one(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_neg(bn254_snarks_fr* r, const bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_neg_in_place(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_sum(bn254_snarks_fr* r, const bn254_snarks_fr* a, const bn254_snarks_fr* b); +void ctt_bn254_snarks_fr_add_in_place(bn254_snarks_fr* a, const bn254_snarks_fr* b); +void ctt_bn254_snarks_fr_diff(bn254_snarks_fr* r, const bn254_snarks_fr* a, const bn254_snarks_fr* b); +void ctt_bn254_snarks_fr_sub_in_place(bn254_snarks_fr* a, const bn254_snarks_fr* b); +void ctt_bn254_snarks_fr_double(bn254_snarks_fr* r, const bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_double_in_place(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_prod(bn254_snarks_fr* r, const bn254_snarks_fr* a, const bn254_snarks_fr* b); +void ctt_bn254_snarks_fr_mul_in_place(bn254_snarks_fr* a, const bn254_snarks_fr* b); +void ctt_bn254_snarks_fr_square(bn254_snarks_fr* r, const bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_square_in_place(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_div2(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_inv(bn254_snarks_fr* r, const bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_inv_in_place(bn254_snarks_fr* a); +void ctt_bn254_snarks_fr_ccopy(bn254_snarks_fr* a, const bn254_snarks_fr* b, const secret_bool ctl); +void ctt_bn254_snarks_fr_cswap(bn254_snarks_fr* a, bn254_snarks_fr* b, const secret_bool ctl); +void ctt_bn254_snarks_fr_cset_zero(bn254_snarks_fr* a, const secret_bool ctl); +void ctt_bn254_snarks_fr_cset_one(bn254_snarks_fr* a, const secret_bool ctl); +void ctt_bn254_snarks_fr_cneg_in_place(bn254_snarks_fr* a, const secret_bool ctl); +void ctt_bn254_snarks_fr_cadd_in_place(bn254_snarks_fr* a, const bn254_snarks_fr* b, const secret_bool ctl); +void ctt_bn254_snarks_fr_csub_in_place(bn254_snarks_fr* a, const bn254_snarks_fr* b, const secret_bool ctl); +ctt_bool ctt_bn254_snarks_fp_unmarshalBE(bn254_snarks_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_bn254_snarks_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const bn254_snarks_fp* src) __attribute__((warn_unused_result)); +secret_bool ctt_bn254_snarks_fp_is_eq(const bn254_snarks_fp* a, const bn254_snarks_fp* b); +secret_bool ctt_bn254_snarks_fp_is_zero(const bn254_snarks_fp* a); +secret_bool ctt_bn254_snarks_fp_is_one(const bn254_snarks_fp* a); +secret_bool ctt_bn254_snarks_fp_is_minus_one(const bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_set_zero(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_set_one(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_set_minus_one(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_neg(bn254_snarks_fp* r, const bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_neg_in_place(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_sum(bn254_snarks_fp* r, const bn254_snarks_fp* a, const bn254_snarks_fp* b); +void ctt_bn254_snarks_fp_add_in_place(bn254_snarks_fp* a, const bn254_snarks_fp* b); +void ctt_bn254_snarks_fp_diff(bn254_snarks_fp* r, const bn254_snarks_fp* a, const bn254_snarks_fp* b); +void ctt_bn254_snarks_fp_sub_in_place(bn254_snarks_fp* a, const bn254_snarks_fp* b); +void ctt_bn254_snarks_fp_double(bn254_snarks_fp* r, const bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_double_in_place(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_prod(bn254_snarks_fp* r, const bn254_snarks_fp* a, const bn254_snarks_fp* b); +void ctt_bn254_snarks_fp_mul_in_place(bn254_snarks_fp* a, const bn254_snarks_fp* b); +void ctt_bn254_snarks_fp_square(bn254_snarks_fp* r, const bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_square_in_place(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_div2(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_inv(bn254_snarks_fp* r, const bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_inv_in_place(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_ccopy(bn254_snarks_fp* a, const bn254_snarks_fp* b, const secret_bool ctl); +void ctt_bn254_snarks_fp_cswap(bn254_snarks_fp* a, bn254_snarks_fp* b, const secret_bool ctl); +void ctt_bn254_snarks_fp_cset_zero(bn254_snarks_fp* a, const secret_bool ctl); +void ctt_bn254_snarks_fp_cset_one(bn254_snarks_fp* a, const secret_bool ctl); +void ctt_bn254_snarks_fp_cneg_in_place(bn254_snarks_fp* a, const secret_bool ctl); +void ctt_bn254_snarks_fp_cadd_in_place(bn254_snarks_fp* a, const bn254_snarks_fp* b, const secret_bool ctl); +void ctt_bn254_snarks_fp_csub_in_place(bn254_snarks_fp* a, const bn254_snarks_fp* b, const secret_bool ctl); +secret_bool ctt_bn254_snarks_fp_is_square(const bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_invsqrt(bn254_snarks_fp* r, const bn254_snarks_fp* a); +secret_bool ctt_bn254_snarks_fp_invsqrt_in_place(bn254_snarks_fp* r, const bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_sqrt_in_place(bn254_snarks_fp* a); +secret_bool ctt_bn254_snarks_fp_sqrt_if_square_in_place(bn254_snarks_fp* a); +void ctt_bn254_snarks_fp_sqrt_invsqrt(bn254_snarks_fp* sqrt, bn254_snarks_fp* invsqrt, const bn254_snarks_fp* a); +secret_bool ctt_bn254_snarks_fp_sqrt_invsqrt_if_square(bn254_snarks_fp* sqrt, bn254_snarks_fp* invsqrt, const bn254_snarks_fp* a); +secret_bool ctt_bn254_snarks_fp_sqrt_ratio_if_square(bn254_snarks_fp* r, const bn254_snarks_fp* u, const bn254_snarks_fp* v); +secret_bool ctt_bn254_snarks_fp2_is_eq(const bn254_snarks_fp2* a, const bn254_snarks_fp2* b); +secret_bool ctt_bn254_snarks_fp2_is_zero(const bn254_snarks_fp2* a); +secret_bool ctt_bn254_snarks_fp2_is_one(const bn254_snarks_fp2* a); +secret_bool ctt_bn254_snarks_fp2_is_minus_one(const bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_set_zero(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_set_one(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_set_minus_one(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_neg(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_sum(bn254_snarks_fp2* r, const bn254_snarks_fp2* a, const bn254_snarks_fp2* b); +void ctt_bn254_snarks_fp2_add_in_place(bn254_snarks_fp2* a, const bn254_snarks_fp2* b); +void ctt_bn254_snarks_fp2_diff(bn254_snarks_fp2* r, const bn254_snarks_fp2* a, const bn254_snarks_fp2* b); +void ctt_bn254_snarks_fp2_sub_in_place(bn254_snarks_fp2* a, const bn254_snarks_fp2* b); +void ctt_bn254_snarks_fp2_double(bn254_snarks_fp2* r, const bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_double_in_place(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_conj(bn254_snarks_fp2* r, const bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_conj_in_place(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_conjneg(bn254_snarks_fp2* r, const bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_conjneg_in_place(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_prod(bn254_snarks_fp2* r, const bn254_snarks_fp2* a, const bn254_snarks_fp2* b); +void ctt_bn254_snarks_fp2_mul_in_place(bn254_snarks_fp2* a, const bn254_snarks_fp2* b); +void ctt_bn254_snarks_fp2_square(bn254_snarks_fp2* r, const bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_square_in_place(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_div2(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_inv(bn254_snarks_fp2* r, const bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_inv_in_place(bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_ccopy(bn254_snarks_fp2* a, const bn254_snarks_fp2* b, const secret_bool ctl); +void ctt_bn254_snarks_fp2_cset_zero(bn254_snarks_fp2* a, const secret_bool ctl); +void ctt_bn254_snarks_fp2_cset_one(bn254_snarks_fp2* a, const secret_bool ctl); +void ctt_bn254_snarks_fp2_cneg_in_place(bn254_snarks_fp2* a, const secret_bool ctl); +void ctt_bn254_snarks_fp2_cadd_in_place(bn254_snarks_fp2* a, const bn254_snarks_fp2* b, const secret_bool ctl); +void ctt_bn254_snarks_fp2_csub_in_place(bn254_snarks_fp2* a, const bn254_snarks_fp2* b, const secret_bool ctl); +secret_bool ctt_bn254_snarks_fp2_is_square(const bn254_snarks_fp2* a); +void ctt_bn254_snarks_fp2_sqrt_in_place(bn254_snarks_fp2* a); +secret_bool ctt_bn254_snarks_fp2_sqrt_if_square_in_place(bn254_snarks_fp2* a); +secret_bool ctt_bn254_snarks_ec_g1_aff_is_eq(const bn254_snarks_ec_g1_aff* P, const bn254_snarks_ec_g1_aff* Q); +secret_bool ctt_bn254_snarks_ec_g1_aff_is_inf(const bn254_snarks_ec_g1_aff* P); +void ctt_bn254_snarks_ec_g1_aff_set_inf(bn254_snarks_ec_g1_aff* P); +void ctt_bn254_snarks_ec_g1_aff_ccopy(bn254_snarks_ec_g1_aff* P, const bn254_snarks_ec_g1_aff* Q, const secret_bool ctl); +secret_bool ctt_bn254_snarks_ec_g1_aff_is_on_curve(const bn254_snarks_fp* x, const bn254_snarks_fp* y); +void ctt_bn254_snarks_ec_g1_aff_neg(bn254_snarks_ec_g1_aff* P, const bn254_snarks_ec_g1_aff* Q); +void ctt_bn254_snarks_ec_g1_aff_neg_in_place(bn254_snarks_ec_g1_aff* P); +secret_bool ctt_bn254_snarks_ec_g1_jac_is_eq(const bn254_snarks_ec_g1_jac* P, const bn254_snarks_ec_g1_jac* Q); +secret_bool ctt_bn254_snarks_ec_g1_jac_is_inf(const bn254_snarks_ec_g1_jac* P); +void ctt_bn254_snarks_ec_g1_jac_set_inf(bn254_snarks_ec_g1_jac* P); +void ctt_bn254_snarks_ec_g1_jac_ccopy(bn254_snarks_ec_g1_jac* P, const bn254_snarks_ec_g1_jac* Q, const secret_bool ctl); +void ctt_bn254_snarks_ec_g1_jac_neg(bn254_snarks_ec_g1_jac* P, const bn254_snarks_ec_g1_jac* Q); +void ctt_bn254_snarks_ec_g1_jac_neg_in_place(bn254_snarks_ec_g1_jac* P); +void ctt_bn254_snarks_ec_g1_jac_cneg_in_place(bn254_snarks_ec_g1_jac* P, const secret_bool ctl); +void ctt_bn254_snarks_ec_g1_jac_sum(bn254_snarks_ec_g1_jac* r, const bn254_snarks_ec_g1_jac* P, const bn254_snarks_ec_g1_jac* Q); +void ctt_bn254_snarks_ec_g1_jac_add_in_place(bn254_snarks_ec_g1_jac* P, const bn254_snarks_ec_g1_jac* Q); +void ctt_bn254_snarks_ec_g1_jac_diff(bn254_snarks_ec_g1_jac* r, const bn254_snarks_ec_g1_jac* P, const bn254_snarks_ec_g1_jac* Q); +void ctt_bn254_snarks_ec_g1_jac_double(bn254_snarks_ec_g1_jac* r, const bn254_snarks_ec_g1_jac* P); +void ctt_bn254_snarks_ec_g1_jac_double_in_place(bn254_snarks_ec_g1_jac* P); +void ctt_bn254_snarks_ec_g1_jac_affine(bn254_snarks_ec_g1_aff* dst, const bn254_snarks_ec_g1_jac* src); +void ctt_bn254_snarks_ec_g1_jac_from_affine(bn254_snarks_ec_g1_jac* dst, const bn254_snarks_ec_g1_aff* src); +secret_bool ctt_bn254_snarks_ec_g1_prj_is_eq(const bn254_snarks_ec_g1_prj* P, const bn254_snarks_ec_g1_prj* Q); +secret_bool ctt_bn254_snarks_ec_g1_prj_is_inf(const bn254_snarks_ec_g1_prj* P); +void ctt_bn254_snarks_ec_g1_prj_set_inf(bn254_snarks_ec_g1_prj* P); +void ctt_bn254_snarks_ec_g1_prj_ccopy(bn254_snarks_ec_g1_prj* P, const bn254_snarks_ec_g1_prj* Q, const secret_bool ctl); +void ctt_bn254_snarks_ec_g1_prj_neg(bn254_snarks_ec_g1_prj* P, const bn254_snarks_ec_g1_prj* Q); +void ctt_bn254_snarks_ec_g1_prj_neg_in_place(bn254_snarks_ec_g1_prj* P); +void ctt_bn254_snarks_ec_g1_prj_cneg_in_place(bn254_snarks_ec_g1_prj* P, const secret_bool ctl); +void ctt_bn254_snarks_ec_g1_prj_sum(bn254_snarks_ec_g1_prj* r, const bn254_snarks_ec_g1_prj* P, const bn254_snarks_ec_g1_prj* Q); +void ctt_bn254_snarks_ec_g1_prj_add_in_place(bn254_snarks_ec_g1_prj* P, const bn254_snarks_ec_g1_prj* Q); +void ctt_bn254_snarks_ec_g1_prj_diff(bn254_snarks_ec_g1_prj* r, const bn254_snarks_ec_g1_prj* P, const bn254_snarks_ec_g1_prj* Q); +void ctt_bn254_snarks_ec_g1_prj_double(bn254_snarks_ec_g1_prj* r, const bn254_snarks_ec_g1_prj* P); +void ctt_bn254_snarks_ec_g1_prj_double_in_place(bn254_snarks_ec_g1_prj* P); +void ctt_bn254_snarks_ec_g1_prj_affine(bn254_snarks_ec_g1_aff* dst, const bn254_snarks_ec_g1_prj* src); +void ctt_bn254_snarks_ec_g1_prj_from_affine(bn254_snarks_ec_g1_prj* dst, const bn254_snarks_ec_g1_aff* src); +secret_bool ctt_bn254_snarks_ec_g2_aff_is_eq(const bn254_snarks_ec_g2_aff* P, const bn254_snarks_ec_g2_aff* Q); +secret_bool ctt_bn254_snarks_ec_g2_aff_is_inf(const bn254_snarks_ec_g2_aff* P); +void ctt_bn254_snarks_ec_g2_aff_set_inf(bn254_snarks_ec_g2_aff* P); +void ctt_bn254_snarks_ec_g2_aff_ccopy(bn254_snarks_ec_g2_aff* P, const bn254_snarks_ec_g2_aff* Q, const secret_bool ctl); +secret_bool ctt_bn254_snarks_ec_g2_aff_is_on_curve(const bn254_snarks_fp2* x, const bn254_snarks_fp2* y); +void ctt_bn254_snarks_ec_g2_aff_neg(bn254_snarks_ec_g2_aff* P, const bn254_snarks_ec_g2_aff* Q); +void ctt_bn254_snarks_ec_g2_aff_neg_in_place(bn254_snarks_ec_g2_aff* P); +secret_bool ctt_bn254_snarks_ec_g2_jac_is_eq(const bn254_snarks_ec_g2_jac* P, const bn254_snarks_ec_g2_jac* Q); +secret_bool ctt_bn254_snarks_ec_g2_jac_is_inf(const bn254_snarks_ec_g2_jac* P); +void ctt_bn254_snarks_ec_g2_jac_set_inf(bn254_snarks_ec_g2_jac* P); +void ctt_bn254_snarks_ec_g2_jac_ccopy(bn254_snarks_ec_g2_jac* P, const bn254_snarks_ec_g2_jac* Q, const secret_bool ctl); +void ctt_bn254_snarks_ec_g2_jac_neg(bn254_snarks_ec_g2_jac* P, const bn254_snarks_ec_g2_jac* Q); +void ctt_bn254_snarks_ec_g2_jac_neg_in_place(bn254_snarks_ec_g2_jac* P); +void ctt_bn254_snarks_ec_g2_jac_cneg_in_place(bn254_snarks_ec_g2_jac* P, const secret_bool ctl); +void ctt_bn254_snarks_ec_g2_jac_sum(bn254_snarks_ec_g2_jac* r, const bn254_snarks_ec_g2_jac* P, const bn254_snarks_ec_g2_jac* Q); +void ctt_bn254_snarks_ec_g2_jac_add_in_place(bn254_snarks_ec_g2_jac* P, const bn254_snarks_ec_g2_jac* Q); +void ctt_bn254_snarks_ec_g2_jac_diff(bn254_snarks_ec_g2_jac* r, const bn254_snarks_ec_g2_jac* P, const bn254_snarks_ec_g2_jac* Q); +void ctt_bn254_snarks_ec_g2_jac_double(bn254_snarks_ec_g2_jac* r, const bn254_snarks_ec_g2_jac* P); +void ctt_bn254_snarks_ec_g2_jac_double_in_place(bn254_snarks_ec_g2_jac* P); +void ctt_bn254_snarks_ec_g2_jac_affine(bn254_snarks_ec_g2_aff* dst, const bn254_snarks_ec_g2_jac* src); +void ctt_bn254_snarks_ec_g2_jac_from_affine(bn254_snarks_ec_g2_jac* dst, const bn254_snarks_ec_g2_aff* src); +secret_bool ctt_bn254_snarks_ec_g2_prj_is_eq(const bn254_snarks_ec_g2_prj* P, const bn254_snarks_ec_g2_prj* Q); +secret_bool ctt_bn254_snarks_ec_g2_prj_is_inf(const bn254_snarks_ec_g2_prj* P); +void ctt_bn254_snarks_ec_g2_prj_set_inf(bn254_snarks_ec_g2_prj* P); +void ctt_bn254_snarks_ec_g2_prj_ccopy(bn254_snarks_ec_g2_prj* P, const bn254_snarks_ec_g2_prj* Q, const secret_bool ctl); +void ctt_bn254_snarks_ec_g2_prj_neg(bn254_snarks_ec_g2_prj* P, const bn254_snarks_ec_g2_prj* Q); +void ctt_bn254_snarks_ec_g2_prj_neg_in_place(bn254_snarks_ec_g2_prj* P); +void ctt_bn254_snarks_ec_g2_prj_cneg_in_place(bn254_snarks_ec_g2_prj* P, const secret_bool ctl); +void ctt_bn254_snarks_ec_g2_prj_sum(bn254_snarks_ec_g2_prj* r, const bn254_snarks_ec_g2_prj* P, const bn254_snarks_ec_g2_prj* Q); +void ctt_bn254_snarks_ec_g2_prj_add_in_place(bn254_snarks_ec_g2_prj* P, const bn254_snarks_ec_g2_prj* Q); +void ctt_bn254_snarks_ec_g2_prj_diff(bn254_snarks_ec_g2_prj* r, const bn254_snarks_ec_g2_prj* P, const bn254_snarks_ec_g2_prj* Q); +void ctt_bn254_snarks_ec_g2_prj_double(bn254_snarks_ec_g2_prj* r, const bn254_snarks_ec_g2_prj* P); +void ctt_bn254_snarks_ec_g2_prj_double_in_place(bn254_snarks_ec_g2_prj* P); +void ctt_bn254_snarks_ec_g2_prj_affine(bn254_snarks_ec_g2_aff* dst, const bn254_snarks_ec_g2_prj* src); +void ctt_bn254_snarks_ec_g2_prj_from_affine(bn254_snarks_ec_g2_prj* dst, const bn254_snarks_ec_g2_aff* src); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/constantine/curves/pallas.h b/include/constantine/curves/pallas.h new file mode 100644 index 000000000..5ebee7836 --- /dev/null +++ b/include/constantine/curves/pallas.h @@ -0,0 +1,136 @@ +/** 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_PALLAS__ +#define __CTT_H_PALLAS__ + +#include "constantine/core/datatypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } pallas_fr; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } pallas_fp; +typedef struct { pallas_fp x, y; } pallas_ec_aff; +typedef struct { pallas_fp x, y, z; } pallas_ec_jac; +typedef struct { pallas_fp x, y, z; } pallas_ec_prj; + +ctt_bool ctt_pallas_fr_unmarshalBE(pallas_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_pallas_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fr* src) __attribute__((warn_unused_result)); +secret_bool ctt_pallas_fr_is_eq(const pallas_fr* a, const pallas_fr* b); +secret_bool ctt_pallas_fr_is_zero(const pallas_fr* a); +secret_bool ctt_pallas_fr_is_one(const pallas_fr* a); +secret_bool ctt_pallas_fr_is_minus_one(const pallas_fr* a); +void ctt_pallas_fr_set_zero(pallas_fr* a); +void ctt_pallas_fr_set_one(pallas_fr* a); +void ctt_pallas_fr_set_minus_one(pallas_fr* a); +void ctt_pallas_fr_neg(pallas_fr* r, const pallas_fr* a); +void ctt_pallas_fr_neg_in_place(pallas_fr* a); +void ctt_pallas_fr_sum(pallas_fr* r, const pallas_fr* a, const pallas_fr* b); +void ctt_pallas_fr_add_in_place(pallas_fr* a, const pallas_fr* b); +void ctt_pallas_fr_diff(pallas_fr* r, const pallas_fr* a, const pallas_fr* b); +void ctt_pallas_fr_sub_in_place(pallas_fr* a, const pallas_fr* b); +void ctt_pallas_fr_double(pallas_fr* r, const pallas_fr* a); +void ctt_pallas_fr_double_in_place(pallas_fr* a); +void ctt_pallas_fr_prod(pallas_fr* r, const pallas_fr* a, const pallas_fr* b); +void ctt_pallas_fr_mul_in_place(pallas_fr* a, const pallas_fr* b); +void ctt_pallas_fr_square(pallas_fr* r, const pallas_fr* a); +void ctt_pallas_fr_square_in_place(pallas_fr* a); +void ctt_pallas_fr_div2(pallas_fr* a); +void ctt_pallas_fr_inv(pallas_fr* r, const pallas_fr* a); +void ctt_pallas_fr_inv_in_place(pallas_fr* a); +void ctt_pallas_fr_ccopy(pallas_fr* a, const pallas_fr* b, const secret_bool ctl); +void ctt_pallas_fr_cswap(pallas_fr* a, pallas_fr* b, const secret_bool ctl); +void ctt_pallas_fr_cset_zero(pallas_fr* a, const secret_bool ctl); +void ctt_pallas_fr_cset_one(pallas_fr* a, const secret_bool ctl); +void ctt_pallas_fr_cneg_in_place(pallas_fr* a, const secret_bool ctl); +void ctt_pallas_fr_cadd_in_place(pallas_fr* a, const pallas_fr* b, const secret_bool ctl); +void ctt_pallas_fr_csub_in_place(pallas_fr* a, const pallas_fr* b, const secret_bool ctl); +ctt_bool ctt_pallas_fp_unmarshalBE(pallas_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_pallas_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fp* src) __attribute__((warn_unused_result)); +secret_bool ctt_pallas_fp_is_eq(const pallas_fp* a, const pallas_fp* b); +secret_bool ctt_pallas_fp_is_zero(const pallas_fp* a); +secret_bool ctt_pallas_fp_is_one(const pallas_fp* a); +secret_bool ctt_pallas_fp_is_minus_one(const pallas_fp* a); +void ctt_pallas_fp_set_zero(pallas_fp* a); +void ctt_pallas_fp_set_one(pallas_fp* a); +void ctt_pallas_fp_set_minus_one(pallas_fp* a); +void ctt_pallas_fp_neg(pallas_fp* r, const pallas_fp* a); +void ctt_pallas_fp_neg_in_place(pallas_fp* a); +void ctt_pallas_fp_sum(pallas_fp* r, const pallas_fp* a, const pallas_fp* b); +void ctt_pallas_fp_add_in_place(pallas_fp* a, const pallas_fp* b); +void ctt_pallas_fp_diff(pallas_fp* r, const pallas_fp* a, const pallas_fp* b); +void ctt_pallas_fp_sub_in_place(pallas_fp* a, const pallas_fp* b); +void ctt_pallas_fp_double(pallas_fp* r, const pallas_fp* a); +void ctt_pallas_fp_double_in_place(pallas_fp* a); +void ctt_pallas_fp_prod(pallas_fp* r, const pallas_fp* a, const pallas_fp* b); +void ctt_pallas_fp_mul_in_place(pallas_fp* a, const pallas_fp* b); +void ctt_pallas_fp_square(pallas_fp* r, const pallas_fp* a); +void ctt_pallas_fp_square_in_place(pallas_fp* a); +void ctt_pallas_fp_div2(pallas_fp* a); +void ctt_pallas_fp_inv(pallas_fp* r, const pallas_fp* a); +void ctt_pallas_fp_inv_in_place(pallas_fp* a); +void ctt_pallas_fp_ccopy(pallas_fp* a, const pallas_fp* b, const secret_bool ctl); +void ctt_pallas_fp_cswap(pallas_fp* a, pallas_fp* b, const secret_bool ctl); +void ctt_pallas_fp_cset_zero(pallas_fp* a, const secret_bool ctl); +void ctt_pallas_fp_cset_one(pallas_fp* a, const secret_bool ctl); +void ctt_pallas_fp_cneg_in_place(pallas_fp* a, const secret_bool ctl); +void ctt_pallas_fp_cadd_in_place(pallas_fp* a, const pallas_fp* b, const secret_bool ctl); +void ctt_pallas_fp_csub_in_place(pallas_fp* a, const pallas_fp* b, const secret_bool ctl); +secret_bool ctt_pallas_fp_is_square(const pallas_fp* a); +void ctt_pallas_fp_invsqrt(pallas_fp* r, const pallas_fp* a); +secret_bool ctt_pallas_fp_invsqrt_in_place(pallas_fp* r, const pallas_fp* a); +void ctt_pallas_fp_sqrt_in_place(pallas_fp* a); +secret_bool ctt_pallas_fp_sqrt_if_square_in_place(pallas_fp* a); +void ctt_pallas_fp_sqrt_invsqrt(pallas_fp* sqrt, pallas_fp* invsqrt, const pallas_fp* a); +secret_bool ctt_pallas_fp_sqrt_invsqrt_if_square(pallas_fp* sqrt, pallas_fp* invsqrt, const pallas_fp* a); +secret_bool ctt_pallas_fp_sqrt_ratio_if_square(pallas_fp* r, const pallas_fp* u, const pallas_fp* v); +secret_bool ctt_pallas_ec_aff_is_eq(const pallas_ec_aff* P, const pallas_ec_aff* Q); +secret_bool ctt_pallas_ec_aff_is_inf(const pallas_ec_aff* P); +void ctt_pallas_ec_aff_set_inf(pallas_ec_aff* P); +void ctt_pallas_ec_aff_ccopy(pallas_ec_aff* P, const pallas_ec_aff* Q, const secret_bool ctl); +secret_bool ctt_pallas_ec_aff_is_on_curve(const pallas_fp* x, const pallas_fp* y); +void ctt_pallas_ec_aff_neg(pallas_ec_aff* P, const pallas_ec_aff* Q); +void ctt_pallas_ec_aff_neg_in_place(pallas_ec_aff* P); +secret_bool ctt_pallas_ec_jac_is_eq(const pallas_ec_jac* P, const pallas_ec_jac* Q); +secret_bool ctt_pallas_ec_jac_is_inf(const pallas_ec_jac* P); +void ctt_pallas_ec_jac_set_inf(pallas_ec_jac* P); +void ctt_pallas_ec_jac_ccopy(pallas_ec_jac* P, const pallas_ec_jac* Q, const secret_bool ctl); +void ctt_pallas_ec_jac_neg(pallas_ec_jac* P, const pallas_ec_jac* Q); +void ctt_pallas_ec_jac_neg_in_place(pallas_ec_jac* P); +void ctt_pallas_ec_jac_cneg_in_place(pallas_ec_jac* P, const secret_bool ctl); +void ctt_pallas_ec_jac_sum(pallas_ec_jac* r, const pallas_ec_jac* P, const pallas_ec_jac* Q); +void ctt_pallas_ec_jac_add_in_place(pallas_ec_jac* P, const pallas_ec_jac* Q); +void ctt_pallas_ec_jac_diff(pallas_ec_jac* r, const pallas_ec_jac* P, const pallas_ec_jac* Q); +void ctt_pallas_ec_jac_double(pallas_ec_jac* r, const pallas_ec_jac* P); +void ctt_pallas_ec_jac_double_in_place(pallas_ec_jac* P); +void ctt_pallas_ec_jac_affine(pallas_ec_aff* dst, const pallas_ec_jac* src); +void ctt_pallas_ec_jac_from_affine(pallas_ec_jac* dst, const pallas_ec_aff* src); +secret_bool ctt_pallas_ec_prj_is_eq(const pallas_ec_prj* P, const pallas_ec_prj* Q); +secret_bool ctt_pallas_ec_prj_is_inf(const pallas_ec_prj* P); +void ctt_pallas_ec_prj_set_inf(pallas_ec_prj* P); +void ctt_pallas_ec_prj_ccopy(pallas_ec_prj* P, const pallas_ec_prj* Q, const secret_bool ctl); +void ctt_pallas_ec_prj_neg(pallas_ec_prj* P, const pallas_ec_prj* Q); +void ctt_pallas_ec_prj_neg_in_place(pallas_ec_prj* P); +void ctt_pallas_ec_prj_cneg_in_place(pallas_ec_prj* P, const secret_bool ctl); +void ctt_pallas_ec_prj_sum(pallas_ec_prj* r, const pallas_ec_prj* P, const pallas_ec_prj* Q); +void ctt_pallas_ec_prj_add_in_place(pallas_ec_prj* P, const pallas_ec_prj* Q); +void ctt_pallas_ec_prj_diff(pallas_ec_prj* r, const pallas_ec_prj* P, const pallas_ec_prj* Q); +void ctt_pallas_ec_prj_double(pallas_ec_prj* r, const pallas_ec_prj* P); +void ctt_pallas_ec_prj_double_in_place(pallas_ec_prj* P); +void ctt_pallas_ec_prj_affine(pallas_ec_aff* dst, const pallas_ec_prj* src); +void ctt_pallas_ec_prj_from_affine(pallas_ec_prj* dst, const pallas_ec_aff* src); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/constantine/curves/vesta.h b/include/constantine/curves/vesta.h new file mode 100644 index 000000000..4051173d8 --- /dev/null +++ b/include/constantine/curves/vesta.h @@ -0,0 +1,136 @@ +/** 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_VESTA__ +#define __CTT_H_VESTA__ + +#include "constantine/core/datatypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } vesta_fr; +typedef struct { secret_word limbs[CTT_WORDS_REQUIRED(255)]; } vesta_fp; +typedef struct { vesta_fp x, y; } vesta_ec_aff; +typedef struct { vesta_fp x, y, z; } vesta_ec_jac; +typedef struct { vesta_fp x, y, z; } vesta_ec_prj; + +ctt_bool ctt_vesta_fr_unmarshalBE(vesta_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_vesta_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fr* src) __attribute__((warn_unused_result)); +secret_bool ctt_vesta_fr_is_eq(const vesta_fr* a, const vesta_fr* b); +secret_bool ctt_vesta_fr_is_zero(const vesta_fr* a); +secret_bool ctt_vesta_fr_is_one(const vesta_fr* a); +secret_bool ctt_vesta_fr_is_minus_one(const vesta_fr* a); +void ctt_vesta_fr_set_zero(vesta_fr* a); +void ctt_vesta_fr_set_one(vesta_fr* a); +void ctt_vesta_fr_set_minus_one(vesta_fr* a); +void ctt_vesta_fr_neg(vesta_fr* r, const vesta_fr* a); +void ctt_vesta_fr_neg_in_place(vesta_fr* a); +void ctt_vesta_fr_sum(vesta_fr* r, const vesta_fr* a, const vesta_fr* b); +void ctt_vesta_fr_add_in_place(vesta_fr* a, const vesta_fr* b); +void ctt_vesta_fr_diff(vesta_fr* r, const vesta_fr* a, const vesta_fr* b); +void ctt_vesta_fr_sub_in_place(vesta_fr* a, const vesta_fr* b); +void ctt_vesta_fr_double(vesta_fr* r, const vesta_fr* a); +void ctt_vesta_fr_double_in_place(vesta_fr* a); +void ctt_vesta_fr_prod(vesta_fr* r, const vesta_fr* a, const vesta_fr* b); +void ctt_vesta_fr_mul_in_place(vesta_fr* a, const vesta_fr* b); +void ctt_vesta_fr_square(vesta_fr* r, const vesta_fr* a); +void ctt_vesta_fr_square_in_place(vesta_fr* a); +void ctt_vesta_fr_div2(vesta_fr* a); +void ctt_vesta_fr_inv(vesta_fr* r, const vesta_fr* a); +void ctt_vesta_fr_inv_in_place(vesta_fr* a); +void ctt_vesta_fr_ccopy(vesta_fr* a, const vesta_fr* b, const secret_bool ctl); +void ctt_vesta_fr_cswap(vesta_fr* a, vesta_fr* b, const secret_bool ctl); +void ctt_vesta_fr_cset_zero(vesta_fr* a, const secret_bool ctl); +void ctt_vesta_fr_cset_one(vesta_fr* a, const secret_bool ctl); +void ctt_vesta_fr_cneg_in_place(vesta_fr* a, const secret_bool ctl); +void ctt_vesta_fr_cadd_in_place(vesta_fr* a, const vesta_fr* b, const secret_bool ctl); +void ctt_vesta_fr_csub_in_place(vesta_fr* a, const vesta_fr* b, const secret_bool ctl); +ctt_bool ctt_vesta_fp_unmarshalBE(vesta_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); +ctt_bool ctt_vesta_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fp* src) __attribute__((warn_unused_result)); +secret_bool ctt_vesta_fp_is_eq(const vesta_fp* a, const vesta_fp* b); +secret_bool ctt_vesta_fp_is_zero(const vesta_fp* a); +secret_bool ctt_vesta_fp_is_one(const vesta_fp* a); +secret_bool ctt_vesta_fp_is_minus_one(const vesta_fp* a); +void ctt_vesta_fp_set_zero(vesta_fp* a); +void ctt_vesta_fp_set_one(vesta_fp* a); +void ctt_vesta_fp_set_minus_one(vesta_fp* a); +void ctt_vesta_fp_neg(vesta_fp* r, const vesta_fp* a); +void ctt_vesta_fp_neg_in_place(vesta_fp* a); +void ctt_vesta_fp_sum(vesta_fp* r, const vesta_fp* a, const vesta_fp* b); +void ctt_vesta_fp_add_in_place(vesta_fp* a, const vesta_fp* b); +void ctt_vesta_fp_diff(vesta_fp* r, const vesta_fp* a, const vesta_fp* b); +void ctt_vesta_fp_sub_in_place(vesta_fp* a, const vesta_fp* b); +void ctt_vesta_fp_double(vesta_fp* r, const vesta_fp* a); +void ctt_vesta_fp_double_in_place(vesta_fp* a); +void ctt_vesta_fp_prod(vesta_fp* r, const vesta_fp* a, const vesta_fp* b); +void ctt_vesta_fp_mul_in_place(vesta_fp* a, const vesta_fp* b); +void ctt_vesta_fp_square(vesta_fp* r, const vesta_fp* a); +void ctt_vesta_fp_square_in_place(vesta_fp* a); +void ctt_vesta_fp_div2(vesta_fp* a); +void ctt_vesta_fp_inv(vesta_fp* r, const vesta_fp* a); +void ctt_vesta_fp_inv_in_place(vesta_fp* a); +void ctt_vesta_fp_ccopy(vesta_fp* a, const vesta_fp* b, const secret_bool ctl); +void ctt_vesta_fp_cswap(vesta_fp* a, vesta_fp* b, const secret_bool ctl); +void ctt_vesta_fp_cset_zero(vesta_fp* a, const secret_bool ctl); +void ctt_vesta_fp_cset_one(vesta_fp* a, const secret_bool ctl); +void ctt_vesta_fp_cneg_in_place(vesta_fp* a, const secret_bool ctl); +void ctt_vesta_fp_cadd_in_place(vesta_fp* a, const vesta_fp* b, const secret_bool ctl); +void ctt_vesta_fp_csub_in_place(vesta_fp* a, const vesta_fp* b, const secret_bool ctl); +secret_bool ctt_vesta_fp_is_square(const vesta_fp* a); +void ctt_vesta_fp_invsqrt(vesta_fp* r, const vesta_fp* a); +secret_bool ctt_vesta_fp_invsqrt_in_place(vesta_fp* r, const vesta_fp* a); +void ctt_vesta_fp_sqrt_in_place(vesta_fp* a); +secret_bool ctt_vesta_fp_sqrt_if_square_in_place(vesta_fp* a); +void ctt_vesta_fp_sqrt_invsqrt(vesta_fp* sqrt, vesta_fp* invsqrt, const vesta_fp* a); +secret_bool ctt_vesta_fp_sqrt_invsqrt_if_square(vesta_fp* sqrt, vesta_fp* invsqrt, const vesta_fp* a); +secret_bool ctt_vesta_fp_sqrt_ratio_if_square(vesta_fp* r, const vesta_fp* u, const vesta_fp* v); +secret_bool ctt_vesta_ec_aff_is_eq(const vesta_ec_aff* P, const vesta_ec_aff* Q); +secret_bool ctt_vesta_ec_aff_is_inf(const vesta_ec_aff* P); +void ctt_vesta_ec_aff_set_inf(vesta_ec_aff* P); +void ctt_vesta_ec_aff_ccopy(vesta_ec_aff* P, const vesta_ec_aff* Q, const secret_bool ctl); +secret_bool ctt_vesta_ec_aff_is_on_curve(const vesta_fp* x, const vesta_fp* y); +void ctt_vesta_ec_aff_neg(vesta_ec_aff* P, const vesta_ec_aff* Q); +void ctt_vesta_ec_aff_neg_in_place(vesta_ec_aff* P); +secret_bool ctt_vesta_ec_jac_is_eq(const vesta_ec_jac* P, const vesta_ec_jac* Q); +secret_bool ctt_vesta_ec_jac_is_inf(const vesta_ec_jac* P); +void ctt_vesta_ec_jac_set_inf(vesta_ec_jac* P); +void ctt_vesta_ec_jac_ccopy(vesta_ec_jac* P, const vesta_ec_jac* Q, const secret_bool ctl); +void ctt_vesta_ec_jac_neg(vesta_ec_jac* P, const vesta_ec_jac* Q); +void ctt_vesta_ec_jac_neg_in_place(vesta_ec_jac* P); +void ctt_vesta_ec_jac_cneg_in_place(vesta_ec_jac* P, const secret_bool ctl); +void ctt_vesta_ec_jac_sum(vesta_ec_jac* r, const vesta_ec_jac* P, const vesta_ec_jac* Q); +void ctt_vesta_ec_jac_add_in_place(vesta_ec_jac* P, const vesta_ec_jac* Q); +void ctt_vesta_ec_jac_diff(vesta_ec_jac* r, const vesta_ec_jac* P, const vesta_ec_jac* Q); +void ctt_vesta_ec_jac_double(vesta_ec_jac* r, const vesta_ec_jac* P); +void ctt_vesta_ec_jac_double_in_place(vesta_ec_jac* P); +void ctt_vesta_ec_jac_affine(vesta_ec_aff* dst, const vesta_ec_jac* src); +void ctt_vesta_ec_jac_from_affine(vesta_ec_jac* dst, const vesta_ec_aff* src); +secret_bool ctt_vesta_ec_prj_is_eq(const vesta_ec_prj* P, const vesta_ec_prj* Q); +secret_bool ctt_vesta_ec_prj_is_inf(const vesta_ec_prj* P); +void ctt_vesta_ec_prj_set_inf(vesta_ec_prj* P); +void ctt_vesta_ec_prj_ccopy(vesta_ec_prj* P, const vesta_ec_prj* Q, const secret_bool ctl); +void ctt_vesta_ec_prj_neg(vesta_ec_prj* P, const vesta_ec_prj* Q); +void ctt_vesta_ec_prj_neg_in_place(vesta_ec_prj* P); +void ctt_vesta_ec_prj_cneg_in_place(vesta_ec_prj* P, const secret_bool ctl); +void ctt_vesta_ec_prj_sum(vesta_ec_prj* r, const vesta_ec_prj* P, const vesta_ec_prj* Q); +void ctt_vesta_ec_prj_add_in_place(vesta_ec_prj* P, const vesta_ec_prj* Q); +void ctt_vesta_ec_prj_diff(vesta_ec_prj* r, const vesta_ec_prj* P, const vesta_ec_prj* Q); +void ctt_vesta_ec_prj_double(vesta_ec_prj* r, const vesta_ec_prj* P); +void ctt_vesta_ec_prj_double_in_place(vesta_ec_prj* P); +void ctt_vesta_ec_prj_affine(vesta_ec_aff* dst, const vesta_ec_prj* src); +void ctt_vesta_ec_prj_from_affine(vesta_ec_prj* dst, const vesta_ec_aff* src); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/constantine/hashes/sha256.h b/include/constantine/hashes/sha256.h new file mode 100644 index 000000000..a920528a8 --- /dev/null +++ b/include/constantine/hashes/sha256.h @@ -0,0 +1,73 @@ +/** 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_SHA256__ +#define __CTT_H_SHA256__ + +#include "constantine/core/datatypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + ctt_align(64) uint32_t message_schedule[16]; + ctt_align(64) byte buf[64]; + uint64_t msgLen; +} ctt_sha256_context; + +/** Initialize or reinitialize a Sha256 context. + */ +void ctt_sha256_init(ctt_sha256_context* ctx); + +/** Append a message to a SHA256 context + * for incremental SHA256 computation + * + * Security note: the tail of your message might be stored + * in an internal buffer. + * if sensitive content is used, ensure that + * `ctx.finish(...)` and `ctx.clear()` are called as soon as possible. + * Additionally ensure that the message(s) passed were stored + * in memory considered secure for your threat model. + * + * For passwords and secret keys, you MUST NOT use raw SHA-256 + * use a Key Derivation Function instead (KDF) + */ +void ctt_sha256_update(ctt_sha256_context* ctx, const byte* message, ptrdiff_t message_len); + +/** Finalize a SHA256 computation and output the + * message digest to the `digest` buffer. + * + * Security note: this does not clear the internal buffer. + * if sensitive content is used, use "ctx.clear()" + * and also make sure that the message(s) passed were stored + * in memory considered secure for your threat model. + * + * For passwords and secret keys, you MUST NOT use raw SHA-256 + * use a Key Derivation Function instead (KDF) + */ +void ctt_sha256_finish(ctt_sha256_context* ctx, byte digest[32]); + +/** Clear the context internal buffers + * Security note: + * For passwords and secret keys, you MUST NOT use raw SHA-256 + * use a Key Derivation Function instead (KDF) + */ +void ctt_sha256_clear(ctt_sha256_context* ctx); + +/** Compute the SHA-256 hash of message + * and store the result in digest. + * Optionally, clear the memory buffer used. + */ +void ctt_sha256_hash(byte digest[32], const byte* message, ptrdiff_t message_len, ctt_bool clear_memory); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/constantine_ethereum_bls_signatures.h b/include/constantine/protocols/ethereum_bls_signatures.h similarity index 54% rename from include/constantine_ethereum_bls_signatures.h rename to include/constantine/protocols/ethereum_bls_signatures.h index 035d6e725..6bd32d404 100644 --- a/include/constantine_ethereum_bls_signatures.h +++ b/include/constantine/protocols/ethereum_bls_signatures.h @@ -9,65 +9,21 @@ #ifndef __CTT_H_ETHEREUM_BLS_SIGNATURES__ #define __CTT_H_ETHEREUM_BLS_SIGNATURES__ +#include "constantine/core/datatypes.h" +#include "constantine/core/serialization.h" +#include "constantine/hashes/sha256.h" + #ifdef __cplusplus extern "C" { #endif -// Basic Types -// ------------------------------------------------------------------------------------------------ - -#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) -typedef __SIZE_TYPE__ size_t; -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#else -#include -#endif - -#if defined(__UINT8_TYPE__) && defined(__UINT32_TYPE__) && defined(__UINT64_TYPE__) -typedef __UINT8_TYPE__ uint8_t; -typedef __UINT32_TYPE__ uint32_t; -typedef __UINT64_TYPE__ uint64_t; -#else -#include -#endif - -// https://github.com/nim-lang/Nim/blob/v1.6.12/lib/nimbase.h#L318 -#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901 -# define bool _Bool -#else -# define bool unsigned char -#endif - -typedef uint8_t byte; - -// Attributes -// ------------------------------------------------------------------------------------------------ - -#if defined(_MSC_VER) -# define ctt_pure __declspec(noalias) -#elif defined(__GNUC__) -# define ctt_pure __attribute__((pure)) -#else -# define ctt_pure -#endif - -#if defined(_MSC_VER) -# define align(x) __declspec(align(x)) -#else -# define align(x) __attribute__((aligned(x))) -#endif - // BLS signature types // ------------------------------------------------------------------------------------------------ -#define FIELD_BITS 381 -#define ORDER_BITS 255 -#define BYTES(bits) ((int) ((bits) + 8 - 1) / 8) - -struct ctt_eth_bls_fp { byte raw[BYTES(FIELD_BITS)]; }; +struct ctt_eth_bls_fp { byte raw[48]; }; struct ctt_eth_bls_fp2 { struct ctt_eth_bls_fp coords[2]; }; -typedef struct { byte raw[BYTES(ORDER_BITS)]; } ctt_eth_bls_seckey; +typedef struct { byte raw[32]; } ctt_eth_bls_seckey; typedef struct { struct ctt_eth_bls_fp x, y; } ctt_eth_bls_pubkey; typedef struct { struct ctt_eth_bls_fp2 x, y; } ctt_eth_bls_signature; @@ -94,122 +50,16 @@ static const char* ctt_eth_bls_status_to_string(ctt_eth_bls_status status) { return "cttBLS_InvalidStatusCode"; } -typedef enum __attribute__((__packed__)) { - cttCodecScalar_Success, - cttCodecScalar_Zero, - cttCodecScalar_ScalarLargerThanCurveOrder, -} ctt_codec_scalar_status; - -static const char* ctt_codec_scalar_status_to_string(ctt_codec_scalar_status status) { - static const char* const statuses[] = { - "cttCodecScalar_Success", - "cttCodecScalar_Zero", - "cttCodecScalar_ScalarLargerThanCurveOrder", - }; - size_t length = sizeof statuses / sizeof *statuses; - if (0 <= status && status < length) { - return statuses[status]; - } - return "cttCodecScalar_InvalidStatusCode"; -} - -typedef enum __attribute__((__packed__)) { - cttCodecEcc_Success, - cttCodecEcc_InvalidEncoding, - cttCodecEcc_CoordinateGreaterThanOrEqualModulus, - cttCodecEcc_PointNotOnCurve, - cttCodecEcc_PointNotInSubgroup, - cttCodecEcc_PointAtInfinity, -} ctt_codec_ecc_status; - -static const char* ctt_codec_ecc_status_to_string(ctt_eth_bls_status status) { - static const char* const statuses[] = { - "cttCodecEcc_Success", - "cttCodecEcc_InvalidEncoding", - "cttCodecEcc_CoordinateGreaterThanOrEqualModulus", - "cttCodecEcc_PointNotOnCurve", - "cttCodecEcc_PointNotInSubgroup", - "cttCodecEcc_PointAtInfinity", - }; - size_t length = sizeof statuses / sizeof *statuses; - if (0 <= status && status < length) { - return statuses[status]; - } - return "cttCodecEcc_InvalidStatusCode"; -} - -// Initialization -// ------------------------------------------------------------------------------------------------ - -/** Initializes the library: - * - detect CPU features like ADX instructions support (MULX, ADCX, ADOX) - */ -void ctt_eth_bls_init_NimMain(void); - -// SHA-256 -// ------------------------------------------------------------------------------------------------ - -typedef struct { - align(64) uint32_t message_schedule[16]; - align(64) byte buf[64]; - uint64_t msgLen; -} ctt_eth_bls_sha256_context; - -/** Initialize or reinitialize a Sha256 context. - */ -void ctt_eth_bls_sha256_init(ctt_eth_bls_sha256_context* ctx); - -/** Append a message to a SHA256 context - * for incremental SHA256 computation - * - * Security note: the tail of your message might be stored - * in an internal buffer. - * if sensitive content is used, ensure that - * `ctx.finish(...)` and `ctx.clear()` are called as soon as possible. - * Additionally ensure that the message(s) passed were stored - * in memory considered secure for your threat model. - * - * For passwords and secret keys, you MUST NOT use raw SHA-256 - * use a Key Derivation Function instead (KDF) - */ -void ctt_eth_bls_sha256_update(ctt_eth_bls_sha256_context* ctx, const byte* message, ptrdiff_t message_len); - -/** Finalize a SHA256 computation and output the - * message digest to the `digest` buffer. - * - * Security note: this does not clear the internal buffer. - * if sensitive content is used, use "ctx.clear()" - * and also make sure that the message(s) passed were stored - * in memory considered secure for your threat model. - * - * For passwords and secret keys, you MUST NOT use raw SHA-256 - * use a Key Derivation Function instead (KDF) - */ -void ctt_eth_bls_sha256_finish(ctt_eth_bls_sha256_context* ctx, byte digest[32]); - -/** Clear the context internal buffers - * Security note: - * For passwords and secret keys, you MUST NOT use raw SHA-256 - * use a Key Derivation Function instead (KDF) - */ -void ctt_eth_bls_sha256_clear(ctt_eth_bls_sha256_context* ctx); - -/** Compute the SHA-256 hash of message - * and store the result in digest. - * Optionally, clear the memory buffer used. - */ -void ctt_eth_bls_sha256_hash(byte digest[32], const byte* message, ptrdiff_t message_len, bool clear_memory); - // Comparisons // ------------------------------------------------------------------------------------------------ -ctt_pure bool ctt_eth_bls_pubkey_is_zero(const ctt_eth_bls_pubkey* pubkey) __attribute__((warn_unused_result)); -ctt_pure bool ctt_eth_bls_signature_is_zero(const ctt_eth_bls_signature* sig) __attribute__((warn_unused_result)); +ctt_bool ctt_eth_bls_pubkey_is_zero(const ctt_eth_bls_pubkey* pubkey) __attribute__((warn_unused_result)); +ctt_bool ctt_eth_bls_signature_is_zero(const ctt_eth_bls_signature* sig) __attribute__((warn_unused_result)); -ctt_pure bool ctt_eth_bls_pubkeys_are_equal(const ctt_eth_bls_pubkey* a, - const ctt_eth_bls_pubkey* b) __attribute__((warn_unused_result)); -ctt_pure bool ctt_eth_bls_signatures_are_equal(const ctt_eth_bls_signature* a, - const ctt_eth_bls_signature* b) __attribute__((warn_unused_result)); +ctt_bool ctt_eth_bls_pubkeys_are_equal(const ctt_eth_bls_pubkey* a, + const ctt_eth_bls_pubkey* b) __attribute__((warn_unused_result)); +ctt_bool ctt_eth_bls_signatures_are_equal(const ctt_eth_bls_signature* a, + const ctt_eth_bls_signature* b) __attribute__((warn_unused_result)); // Input validation // ------------------------------------------------------------------------------------------------ @@ -219,19 +69,19 @@ ctt_pure bool ctt_eth_bls_signatures_are_equal(const ctt_eth_bls_signature* a, * Regarding timing attacks, this will leak timing information only if the key is invalid. * Namely, the secret key is 0 or the secret key is too large. */ -ctt_pure ctt_codec_scalar_status ctt_eth_bls_validate_seckey(const ctt_eth_bls_seckey* seckey) __attribute__((warn_unused_result)); +ctt_codec_scalar_status ctt_eth_bls_validate_seckey(const ctt_eth_bls_seckey* seckey) __attribute__((warn_unused_result)); /** Validate the public key. * * This is an expensive operation that can be cached. */ -ctt_pure ctt_codec_ecc_status ctt_eth_bls_validate_pubkey(const ctt_eth_bls_pubkey* pubkey) __attribute__((warn_unused_result)); +ctt_codec_ecc_status ctt_eth_bls_validate_pubkey(const ctt_eth_bls_pubkey* pubkey) __attribute__((warn_unused_result)); /** Validate the signature. * * This is an expensive operation that can be cached. */ -ctt_pure ctt_codec_ecc_status ctt_eth_bls_validate_signature(const ctt_eth_bls_signature* pubkey) __attribute__((warn_unused_result)); +ctt_codec_ecc_status ctt_eth_bls_validate_signature(const ctt_eth_bls_signature* pubkey) __attribute__((warn_unused_result)); // Codecs // ------------------------------------------------------------------------------------------------ @@ -353,9 +203,9 @@ void ctt_eth_bls_sign(ctt_eth_bls_signature* sig, * * In particular, the public key and signature are assumed to be on curve and subgroup-checked. */ -ctt_pure ctt_eth_bls_status ctt_eth_bls_verify(const ctt_eth_bls_pubkey* pubkey, - const byte* message, ptrdiff_t message_len, - const ctt_eth_bls_signature* sig) __attribute__((warn_unused_result)); +ctt_eth_bls_status ctt_eth_bls_verify(const ctt_eth_bls_pubkey* pubkey, + const byte* message, ptrdiff_t message_len, + const ctt_eth_bls_signature* sig) __attribute__((warn_unused_result)); // TODO: API for pubkeys and signature aggregation. Return a bool or a status code or nothing? @@ -374,12 +224,12 @@ ctt_pure ctt_eth_bls_status ctt_eth_bls_verify(const ctt_eth_bls_pubkey* pubkey, * * In particular, the public keys and signature are assumed to be on curve subgroup checked. */ -ctt_pure ctt_eth_bls_status ctt_eth_bls_fast_aggregate_verify(const ctt_eth_bls_pubkey pubkeys[], ptrdiff_t pubkeys_len, - const byte* message, ptrdiff_t message_len, - const ctt_eth_bls_signature* aggregate_sig) __attribute__((warn_unused_result)); +ctt_eth_bls_status ctt_eth_bls_fast_aggregate_verify(const ctt_eth_bls_pubkey pubkeys[], ptrdiff_t pubkeys_len, + const byte* message, ptrdiff_t message_len, + const ctt_eth_bls_signature* aggregate_sig) __attribute__((warn_unused_result)); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/include/constantine_bls12_381.h b/include/constantine_bls12_381.h deleted file mode 100644 index 585fc8823..000000000 --- a/include/constantine_bls12_381.h +++ /dev/null @@ -1,241 +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_BLS12381__ -#define __CTT_H_BLS12381__ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) -typedef __SIZE_TYPE__ size_t; -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#else -#include -#endif - -#if defined(__UINT8_TYPE__) && defined(__UINT32_TYPE__) && defined(__UINT64_TYPE__) -typedef __UINT8_TYPE__ uint8_t; -typedef __UINT32_TYPE__ uint32_t; -typedef __UINT64_TYPE__ uint64_t; -#else -#include -#endif - -#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901 -# define bool _Bool -#else -# define bool unsigned char -#endif - -typedef size_t secret_word; -typedef size_t secret_bool; -typedef uint8_t byte; - -#define WordBitWidth (sizeof(secret_word)*8) -#define words_required(bits) ((bits+WordBitWidth-1)/WordBitWidth) - -typedef struct { secret_word limbs[words_required(255)]; } bls12381_fr; -typedef struct { secret_word limbs[words_required(381)]; } bls12381_fp; -typedef struct { bls12381_fp c[2]; } bls12381_fp2; -typedef struct { bls12381_fp x, y; } bls12381_ec_g1_aff; -typedef struct { bls12381_fp x, y, z; } bls12381_ec_g1_jac; -typedef struct { bls12381_fp x, y, z; } bls12381_ec_g1_prj; -typedef struct { bls12381_fp2 x, y; } bls12381_ec_g2_aff; -typedef struct { bls12381_fp2 x, y, z; } bls12381_ec_g2_jac; -typedef struct { bls12381_fp2 x, y, z; } bls12381_ec_g2_prj; - -/* - * Initializes the library: - * - detect CPU features like ADX instructions support (MULX, ADCX, ADOX) - */ -void ctt_bls12381_init_NimMain(void); - -bool ctt_bls12381_fr_unmarshalBE(bls12381_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); -bool ctt_bls12381_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12381_fr* src) __attribute__((warn_unused_result)); -secret_bool ctt_bls12381_fr_is_eq(const bls12381_fr* a, const bls12381_fr* b); -secret_bool ctt_bls12381_fr_is_zero(const bls12381_fr* a); -secret_bool ctt_bls12381_fr_is_one(const bls12381_fr* a); -secret_bool ctt_bls12381_fr_is_minus_one(const bls12381_fr* a); -void ctt_bls12381_fr_set_zero(bls12381_fr* a); -void ctt_bls12381_fr_set_one(bls12381_fr* a); -void ctt_bls12381_fr_set_minus_one(bls12381_fr* a); -void ctt_bls12381_fr_neg(bls12381_fr* r, const bls12381_fr* a); -void ctt_bls12381_fr_neg_in_place(bls12381_fr* a); -void ctt_bls12381_fr_sum(bls12381_fr* r, const bls12381_fr* a, const bls12381_fr* b); -void ctt_bls12381_fr_add_in_place(bls12381_fr* a, const bls12381_fr* b); -void ctt_bls12381_fr_diff(bls12381_fr* r, const bls12381_fr* a, const bls12381_fr* b); -void ctt_bls12381_fr_sub_in_place(bls12381_fr* a, const bls12381_fr* b); -void ctt_bls12381_fr_double(bls12381_fr* r, const bls12381_fr* a); -void ctt_bls12381_fr_double_in_place(bls12381_fr* a); -void ctt_bls12381_fr_prod(bls12381_fr* r, const bls12381_fr* a, const bls12381_fr* b); -void ctt_bls12381_fr_mul_in_place(bls12381_fr* a, const bls12381_fr* b); -void ctt_bls12381_fr_square(bls12381_fr* r, const bls12381_fr* a); -void ctt_bls12381_fr_square_in_place(bls12381_fr* a); -void ctt_bls12381_fr_div2(bls12381_fr* a); -void ctt_bls12381_fr_inv(bls12381_fr* r, const bls12381_fr* a); -void ctt_bls12381_fr_inv_in_place(bls12381_fr* a); -void ctt_bls12381_fr_ccopy(bls12381_fr* a, const bls12381_fr* b, const secret_bool ctl); -void ctt_bls12381_fr_cswap(bls12381_fr* a, bls12381_fr* b, const secret_bool ctl); -void ctt_bls12381_fr_cset_zero(bls12381_fr* a, const secret_bool ctl); -void ctt_bls12381_fr_cset_one(bls12381_fr* a, const secret_bool ctl); -void ctt_bls12381_fr_cneg_in_place(bls12381_fr* a, const secret_bool ctl); -void ctt_bls12381_fr_cadd_in_place(bls12381_fr* a, const bls12381_fr* b, const secret_bool ctl); -void ctt_bls12381_fr_csub_in_place(bls12381_fr* a, const bls12381_fr* b, const secret_bool ctl); -bool ctt_bls12381_fp_unmarshalBE(bls12381_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); -bool ctt_bls12381_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const bls12381_fp* src) __attribute__((warn_unused_result)); -secret_bool ctt_bls12381_fp_is_eq(const bls12381_fp* a, const bls12381_fp* b); -secret_bool ctt_bls12381_fp_is_zero(const bls12381_fp* a); -secret_bool ctt_bls12381_fp_is_one(const bls12381_fp* a); -secret_bool ctt_bls12381_fp_is_minus_one(const bls12381_fp* a); -void ctt_bls12381_fp_set_zero(bls12381_fp* a); -void ctt_bls12381_fp_set_one(bls12381_fp* a); -void ctt_bls12381_fp_set_minus_one(bls12381_fp* a); -void ctt_bls12381_fp_neg(bls12381_fp* r, const bls12381_fp* a); -void ctt_bls12381_fp_neg_in_place(bls12381_fp* a); -void ctt_bls12381_fp_sum(bls12381_fp* r, const bls12381_fp* a, const bls12381_fp* b); -void ctt_bls12381_fp_add_in_place(bls12381_fp* a, const bls12381_fp* b); -void ctt_bls12381_fp_diff(bls12381_fp* r, const bls12381_fp* a, const bls12381_fp* b); -void ctt_bls12381_fp_sub_in_place(bls12381_fp* a, const bls12381_fp* b); -void ctt_bls12381_fp_double(bls12381_fp* r, const bls12381_fp* a); -void ctt_bls12381_fp_double_in_place(bls12381_fp* a); -void ctt_bls12381_fp_prod(bls12381_fp* r, const bls12381_fp* a, const bls12381_fp* b); -void ctt_bls12381_fp_mul_in_place(bls12381_fp* a, const bls12381_fp* b); -void ctt_bls12381_fp_square(bls12381_fp* r, const bls12381_fp* a); -void ctt_bls12381_fp_square_in_place(bls12381_fp* a); -void ctt_bls12381_fp_div2(bls12381_fp* a); -void ctt_bls12381_fp_inv(bls12381_fp* r, const bls12381_fp* a); -void ctt_bls12381_fp_inv_in_place(bls12381_fp* a); -void ctt_bls12381_fp_ccopy(bls12381_fp* a, const bls12381_fp* b, const secret_bool ctl); -void ctt_bls12381_fp_cswap(bls12381_fp* a, bls12381_fp* b, const secret_bool ctl); -void ctt_bls12381_fp_cset_zero(bls12381_fp* a, const secret_bool ctl); -void ctt_bls12381_fp_cset_one(bls12381_fp* a, const secret_bool ctl); -void ctt_bls12381_fp_cneg_in_place(bls12381_fp* a, const secret_bool ctl); -void ctt_bls12381_fp_cadd_in_place(bls12381_fp* a, const bls12381_fp* b, const secret_bool ctl); -void ctt_bls12381_fp_csub_in_place(bls12381_fp* a, const bls12381_fp* b, const secret_bool ctl); -secret_bool ctt_bls12381_fp_is_square(const bls12381_fp* a); -void ctt_bls12381_fp_invsqrt(bls12381_fp* r, const bls12381_fp* a); -secret_bool ctt_bls12381_fp_invsqrt_in_place(bls12381_fp* r, const bls12381_fp* a); -void ctt_bls12381_fp_sqrt_in_place(bls12381_fp* a); -secret_bool ctt_bls12381_fp_sqrt_if_square_in_place(bls12381_fp* a); -void ctt_bls12381_fp_sqrt_invsqrt(bls12381_fp* sqrt, bls12381_fp* invsqrt, const bls12381_fp* a); -secret_bool ctt_bls12381_fp_sqrt_invsqrt_if_square(bls12381_fp* sqrt, bls12381_fp* invsqrt, const bls12381_fp* a); -secret_bool ctt_bls12381_fp_sqrt_ratio_if_square(bls12381_fp* r, const bls12381_fp* u, const bls12381_fp* v); -secret_bool ctt_bls12381_fp2_is_eq(const bls12381_fp2* a, const bls12381_fp2* b); -secret_bool ctt_bls12381_fp2_is_zero(const bls12381_fp2* a); -secret_bool ctt_bls12381_fp2_is_one(const bls12381_fp2* a); -secret_bool ctt_bls12381_fp2_is_minus_one(const bls12381_fp2* a); -void ctt_bls12381_fp2_set_zero(bls12381_fp2* a); -void ctt_bls12381_fp2_set_one(bls12381_fp2* a); -void ctt_bls12381_fp2_set_minus_one(bls12381_fp2* a); -void ctt_bls12381_fp2_neg(bls12381_fp2* a); -void ctt_bls12381_fp2_sum(bls12381_fp2* r, const bls12381_fp2* a, const bls12381_fp2* b); -void ctt_bls12381_fp2_add_in_place(bls12381_fp2* a, const bls12381_fp2* b); -void ctt_bls12381_fp2_diff(bls12381_fp2* r, const bls12381_fp2* a, const bls12381_fp2* b); -void ctt_bls12381_fp2_sub_in_place(bls12381_fp2* a, const bls12381_fp2* b); -void ctt_bls12381_fp2_double(bls12381_fp2* r, const bls12381_fp2* a); -void ctt_bls12381_fp2_double_in_place(bls12381_fp2* a); -void ctt_bls12381_fp2_conj(bls12381_fp2* r, const bls12381_fp2* a); -void ctt_bls12381_fp2_conj_in_place(bls12381_fp2* a); -void ctt_bls12381_fp2_conjneg(bls12381_fp2* r, const bls12381_fp2* a); -void ctt_bls12381_fp2_conjneg_in_place(bls12381_fp2* a); -void ctt_bls12381_fp2_prod(bls12381_fp2* r, const bls12381_fp2* a, const bls12381_fp2* b); -void ctt_bls12381_fp2_mul_in_place(bls12381_fp2* a, const bls12381_fp2* b); -void ctt_bls12381_fp2_square(bls12381_fp2* r, const bls12381_fp2* a); -void ctt_bls12381_fp2_square_in_place(bls12381_fp2* a); -void ctt_bls12381_fp2_div2(bls12381_fp2* a); -void ctt_bls12381_fp2_inv(bls12381_fp2* r, const bls12381_fp2* a); -void ctt_bls12381_fp2_inv_in_place(bls12381_fp2* a); -void ctt_bls12381_fp2_ccopy(bls12381_fp2* a, const bls12381_fp2* b, const secret_bool ctl); -void ctt_bls12381_fp2_cset_zero(bls12381_fp2* a, const secret_bool ctl); -void ctt_bls12381_fp2_cset_one(bls12381_fp2* a, const secret_bool ctl); -void ctt_bls12381_fp2_cneg_in_place(bls12381_fp2* a, const secret_bool ctl); -void ctt_bls12381_fp2_cadd_in_place(bls12381_fp2* a, const bls12381_fp2* b, const secret_bool ctl); -void ctt_bls12381_fp2_csub_in_place(bls12381_fp2* a, const bls12381_fp2* b, const secret_bool ctl); -secret_bool ctt_bls12381_fp2_is_square(const bls12381_fp2* a); -void ctt_bls12381_fp2_sqrt_in_place(bls12381_fp2* a); -secret_bool ctt_bls12381_fp2_sqrt_if_square_in_place(bls12381_fp2* a); -secret_bool ctt_bls12381_ec_g1_aff_is_eq(const bls12381_ec_g1_aff* P, const bls12381_ec_g1_aff* Q); -secret_bool ctt_bls12381_ec_g1_aff_is_inf(const bls12381_ec_g1_aff* P); -void ctt_bls12381_ec_g1_aff_set_inf(bls12381_ec_g1_aff* P); -void ctt_bls12381_ec_g1_aff_ccopy(bls12381_ec_g1_aff* P, const bls12381_ec_g1_aff* Q, const secret_bool ctl); -secret_bool ctt_bls12381_ec_g1_aff_is_on_curve(const bls12381_fp* x, const bls12381_fp* y); -void ctt_bls12381_ec_g1_aff_neg(bls12381_ec_g1_aff* P, const bls12381_ec_g1_aff* Q); -void ctt_bls12381_ec_g1_aff_neg_in_place(bls12381_ec_g1_aff* P); -secret_bool ctt_bls12381_ec_g1_jac_is_eq(const bls12381_ec_g1_jac* P, const bls12381_ec_g1_jac* Q); -secret_bool ctt_bls12381_ec_g1_jac_is_inf(const bls12381_ec_g1_jac* P); -void ctt_bls12381_ec_g1_jac_set_inf(bls12381_ec_g1_jac* P); -void ctt_bls12381_ec_g1_jac_ccopy(bls12381_ec_g1_jac* P, const bls12381_ec_g1_jac* Q, const secret_bool ctl); -void ctt_bls12381_ec_g1_jac_neg(bls12381_ec_g1_jac* P, const bls12381_ec_g1_jac* Q); -void ctt_bls12381_ec_g1_jac_neg_in_place(bls12381_ec_g1_jac* P); -void ctt_bls12381_ec_g1_jac_cneg_in_place(bls12381_ec_g1_jac* P, const secret_bool ctl); -void ctt_bls12381_ec_g1_jac_sum(bls12381_ec_g1_jac* r, const bls12381_ec_g1_jac* P, const bls12381_ec_g1_jac* Q); -void ctt_bls12381_ec_g1_jac_add_in_place(bls12381_ec_g1_jac* P, const bls12381_ec_g1_jac* Q); -void ctt_bls12381_ec_g1_jac_diff(bls12381_ec_g1_jac* r, const bls12381_ec_g1_jac* P, const bls12381_ec_g1_jac* Q); -void ctt_bls12381_ec_g1_jac_double(bls12381_ec_g1_jac* r, const bls12381_ec_g1_jac* P); -void ctt_bls12381_ec_g1_jac_double_in_place(bls12381_ec_g1_jac* P); -void ctt_bls12381_ec_g1_jac_affine(bls12381_ec_g1_aff* dst, const bls12381_ec_g1_jac* src); -void ctt_bls12381_ec_g1_jac_from_affine(bls12381_ec_g1_jac* dst, const bls12381_ec_g1_aff* src); -secret_bool ctt_bls12381_ec_g1_prj_is_eq(const bls12381_ec_g1_prj* P, const bls12381_ec_g1_prj* Q); -secret_bool ctt_bls12381_ec_g1_prj_is_inf(const bls12381_ec_g1_prj* P); -void ctt_bls12381_ec_g1_prj_set_inf(bls12381_ec_g1_prj* P); -void ctt_bls12381_ec_g1_prj_ccopy(bls12381_ec_g1_prj* P, const bls12381_ec_g1_prj* Q, const secret_bool ctl); -void ctt_bls12381_ec_g1_prj_neg(bls12381_ec_g1_prj* P, const bls12381_ec_g1_prj* Q); -void ctt_bls12381_ec_g1_prj_neg_in_place(bls12381_ec_g1_prj* P); -void ctt_bls12381_ec_g1_prj_cneg_in_place(bls12381_ec_g1_prj* P, const secret_bool ctl); -void ctt_bls12381_ec_g1_prj_sum(bls12381_ec_g1_prj* r, const bls12381_ec_g1_prj* P, const bls12381_ec_g1_prj* Q); -void ctt_bls12381_ec_g1_prj_add_in_place(bls12381_ec_g1_prj* P, const bls12381_ec_g1_prj* Q); -void ctt_bls12381_ec_g1_prj_diff(bls12381_ec_g1_prj* r, const bls12381_ec_g1_prj* P, const bls12381_ec_g1_prj* Q); -void ctt_bls12381_ec_g1_prj_double(bls12381_ec_g1_prj* r, const bls12381_ec_g1_prj* P); -void ctt_bls12381_ec_g1_prj_double_in_place(bls12381_ec_g1_prj* P); -void ctt_bls12381_ec_g1_prj_affine(bls12381_ec_g1_aff* dst, const bls12381_ec_g1_prj* src); -void ctt_bls12381_ec_g1_prj_from_affine(bls12381_ec_g1_prj* dst, const bls12381_ec_g1_aff* src); -secret_bool ctt_bls12381_ec_g2_aff_is_eq(const bls12381_ec_g2_aff* P, const bls12381_ec_g2_aff* Q); -secret_bool ctt_bls12381_ec_g2_aff_is_inf(const bls12381_ec_g2_aff* P); -void ctt_bls12381_ec_g2_aff_set_inf(bls12381_ec_g2_aff* P); -void ctt_bls12381_ec_g2_aff_ccopy(bls12381_ec_g2_aff* P, const bls12381_ec_g2_aff* Q, const secret_bool ctl); -secret_bool ctt_bls12381_ec_g2_aff_is_on_curve(const bls12381_fp2* x, const bls12381_fp2* y); -void ctt_bls12381_ec_g2_aff_neg(bls12381_ec_g2_aff* P, const bls12381_ec_g2_aff* Q); -void ctt_bls12381_ec_g2_aff_neg_in_place(bls12381_ec_g2_aff* P); -secret_bool ctt_bls12381_ec_g2_jac_is_eq(const bls12381_ec_g2_jac* P, const bls12381_ec_g2_jac* Q); -secret_bool ctt_bls12381_ec_g2_jac_is_inf(const bls12381_ec_g2_jac* P); -void ctt_bls12381_ec_g2_jac_set_inf(bls12381_ec_g2_jac* P); -void ctt_bls12381_ec_g2_jac_ccopy(bls12381_ec_g2_jac* P, const bls12381_ec_g2_jac* Q, const secret_bool ctl); -void ctt_bls12381_ec_g2_jac_neg(bls12381_ec_g2_jac* P, const bls12381_ec_g2_jac* Q); -void ctt_bls12381_ec_g2_jac_neg_in_place(bls12381_ec_g2_jac* P); -void ctt_bls12381_ec_g2_jac_cneg_in_place(bls12381_ec_g2_jac* P, const secret_bool ctl); -void ctt_bls12381_ec_g2_jac_sum(bls12381_ec_g2_jac* r, const bls12381_ec_g2_jac* P, const bls12381_ec_g2_jac* Q); -void ctt_bls12381_ec_g2_jac_add_in_place(bls12381_ec_g2_jac* P, const bls12381_ec_g2_jac* Q); -void ctt_bls12381_ec_g2_jac_diff(bls12381_ec_g2_jac* r, const bls12381_ec_g2_jac* P, const bls12381_ec_g2_jac* Q); -void ctt_bls12381_ec_g2_jac_double(bls12381_ec_g2_jac* r, const bls12381_ec_g2_jac* P); -void ctt_bls12381_ec_g2_jac_double_in_place(bls12381_ec_g2_jac* P); -void ctt_bls12381_ec_g2_jac_affine(bls12381_ec_g2_aff* dst, const bls12381_ec_g2_jac* src); -void ctt_bls12381_ec_g2_jac_from_affine(bls12381_ec_g2_jac* dst, const bls12381_ec_g2_aff* src); -secret_bool ctt_bls12381_ec_g2_prj_is_eq(const bls12381_ec_g2_prj* P, const bls12381_ec_g2_prj* Q); -secret_bool ctt_bls12381_ec_g2_prj_is_inf(const bls12381_ec_g2_prj* P); -void ctt_bls12381_ec_g2_prj_set_inf(bls12381_ec_g2_prj* P); -void ctt_bls12381_ec_g2_prj_ccopy(bls12381_ec_g2_prj* P, const bls12381_ec_g2_prj* Q, const secret_bool ctl); -void ctt_bls12381_ec_g2_prj_neg(bls12381_ec_g2_prj* P, const bls12381_ec_g2_prj* Q); -void ctt_bls12381_ec_g2_prj_neg_in_place(bls12381_ec_g2_prj* P); -void ctt_bls12381_ec_g2_prj_cneg_in_place(bls12381_ec_g2_prj* P, const secret_bool ctl); -void ctt_bls12381_ec_g2_prj_sum(bls12381_ec_g2_prj* r, const bls12381_ec_g2_prj* P, const bls12381_ec_g2_prj* Q); -void ctt_bls12381_ec_g2_prj_add_in_place(bls12381_ec_g2_prj* P, const bls12381_ec_g2_prj* Q); -void ctt_bls12381_ec_g2_prj_diff(bls12381_ec_g2_prj* r, const bls12381_ec_g2_prj* P, const bls12381_ec_g2_prj* Q); -void ctt_bls12381_ec_g2_prj_double(bls12381_ec_g2_prj* r, const bls12381_ec_g2_prj* P); -void ctt_bls12381_ec_g2_prj_double_in_place(bls12381_ec_g2_prj* P); -void ctt_bls12381_ec_g2_prj_affine(bls12381_ec_g2_aff* dst, const bls12381_ec_g2_prj* src); -void ctt_bls12381_ec_g2_prj_from_affine(bls12381_ec_g2_prj* dst, const bls12381_ec_g2_aff* src); - - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/include/constantine_bn254_snarks.h b/include/constantine_bn254_snarks.h deleted file mode 100644 index 94f35b264..000000000 --- a/include/constantine_bn254_snarks.h +++ /dev/null @@ -1,235 +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_BN@%$SNARKS__ -#define __CTT_H_BN@%$SNARKS__ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) -typedef __SIZE_TYPE__ size_t; -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#else -#include -#endif - -#if defined(__UINT8_TYPE__) && defined(__UINT32_TYPE__) && defined(__UINT64_TYPE__) -typedef __UINT8_TYPE__ uint8_t; -typedef __UINT32_TYPE__ uint32_t; -typedef __UINT64_TYPE__ uint64_t; -#else -#include -#endif - -typedef size_t secret_word; -typedef size_t secret_bool; -typedef uint8_t byte; - -#define WordBitWidth (sizeof(secret_word)*8) -#define words_required(bits) ((bits+WordBitWidth-1)/WordBitWidth) - -typedef struct { secret_word limbs[words_required(254)]; } bn254snarks_fr; -typedef struct { secret_word limbs[words_required(254)]; } bn254snarks_fp; -typedef struct { bn254snarks_fp c[2]; } bn254snarks_fp2; -typedef struct { bn254snarks_fp x, y; } bn254snarks_ec_g1_aff; -typedef struct { bn254snarks_fp x, y, z; } bn254snarks_ec_g1_jac; -typedef struct { bn254snarks_fp x, y, z; } bn254snarks_ec_g1_prj; -typedef struct { bn254snarks_fp2 x, y; } bn254snarks_ec_g2_aff; -typedef struct { bn254snarks_fp2 x, y, z; } bn254snarks_ec_g2_jac; -typedef struct { bn254snarks_fp2 x, y, z; } bn254snarks_ec_g2_prj; - -/* - * Initializes the library: - * - detect CPU features like ADX instructions support (MULX, ADCX, ADOX) - */ -void ctt_bn254snarks_init_NimMain(void); - -void ctt_bn254snarks_fr_unmarshalBE(bn254snarks_fr* dst, const byte src[], ptrdiff_t src_len); -void ctt_bn254snarks_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const bn254snarks_fr* src); -secret_bool ctt_bn254snarks_fr_is_eq(const bn254snarks_fr* a, const bn254snarks_fr* b); -secret_bool ctt_bn254snarks_fr_is_zero(const bn254snarks_fr* a); -secret_bool ctt_bn254snarks_fr_is_one(const bn254snarks_fr* a); -secret_bool ctt_bn254snarks_fr_is_minus_one(const bn254snarks_fr* a); -void ctt_bn254snarks_fr_set_zero(bn254snarks_fr* a); -void ctt_bn254snarks_fr_set_one(bn254snarks_fr* a); -void ctt_bn254snarks_fr_set_minus_one(bn254snarks_fr* a); -void ctt_bn254snarks_fr_neg(bn254snarks_fr* r, const bn254snarks_fr* a); -void ctt_bn254snarks_fr_neg_in_place(bn254snarks_fr* a); -void ctt_bn254snarks_fr_sum(bn254snarks_fr* r, const bn254snarks_fr* a, const bn254snarks_fr* b); -void ctt_bn254snarks_fr_add_in_place(bn254snarks_fr* a, const bn254snarks_fr* b); -void ctt_bn254snarks_fr_diff(bn254snarks_fr* r, const bn254snarks_fr* a, const bn254snarks_fr* b); -void ctt_bn254snarks_fr_sub_in_place(bn254snarks_fr* a, const bn254snarks_fr* b); -void ctt_bn254snarks_fr_double(bn254snarks_fr* r, const bn254snarks_fr* a); -void ctt_bn254snarks_fr_double_in_place(bn254snarks_fr* a); -void ctt_bn254snarks_fr_prod(bn254snarks_fr* r, const bn254snarks_fr* a, const bn254snarks_fr* b); -void ctt_bn254snarks_fr_mul_in_place(bn254snarks_fr* a, const bn254snarks_fr* b); -void ctt_bn254snarks_fr_square(bn254snarks_fr* r, const bn254snarks_fr* a); -void ctt_bn254snarks_fr_square_in_place(bn254snarks_fr* a); -void ctt_bn254snarks_fr_div2(bn254snarks_fr* a); -void ctt_bn254snarks_fr_inv(bn254snarks_fr* r, const bn254snarks_fr* a); -void ctt_bn254snarks_fr_inv_in_place(bn254snarks_fr* a); -void ctt_bn254snarks_fr_ccopy(bn254snarks_fr* a, const bn254snarks_fr* b, const secret_bool ctl); -void ctt_bn254snarks_fr_cswap(bn254snarks_fr* a, bn254snarks_fr* b, const secret_bool ctl); -void ctt_bn254snarks_fr_cset_zero(bn254snarks_fr* a, const secret_bool ctl); -void ctt_bn254snarks_fr_cset_one(bn254snarks_fr* a, const secret_bool ctl); -void ctt_bn254snarks_fr_cneg_in_place(bn254snarks_fr* a, const secret_bool ctl); -void ctt_bn254snarks_fr_cadd_in_place(bn254snarks_fr* a, const bn254snarks_fr* b, const secret_bool ctl); -void ctt_bn254snarks_fr_csub_in_place(bn254snarks_fr* a, const bn254snarks_fr* b, const secret_bool ctl); -void ctt_bn254snarks_fp_unmarshalBE(bn254snarks_fp* dst, const byte src[], ptrdiff_t src_len); -void ctt_bn254snarks_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const bn254snarks_fp* src); -secret_bool ctt_bn254snarks_fp_is_eq(const bn254snarks_fp* a, const bn254snarks_fp* b); -secret_bool ctt_bn254snarks_fp_is_zero(const bn254snarks_fp* a); -secret_bool ctt_bn254snarks_fp_is_one(const bn254snarks_fp* a); -secret_bool ctt_bn254snarks_fp_is_minus_one(const bn254snarks_fp* a); -void ctt_bn254snarks_fp_set_zero(bn254snarks_fp* a); -void ctt_bn254snarks_fp_set_one(bn254snarks_fp* a); -void ctt_bn254snarks_fp_set_minus_one(bn254snarks_fp* a); -void ctt_bn254snarks_fp_neg(bn254snarks_fp* r, const bn254snarks_fp* a); -void ctt_bn254snarks_fp_neg_in_place(bn254snarks_fp* a); -void ctt_bn254snarks_fp_sum(bn254snarks_fp* r, const bn254snarks_fp* a, const bn254snarks_fp* b); -void ctt_bn254snarks_fp_add_in_place(bn254snarks_fp* a, const bn254snarks_fp* b); -void ctt_bn254snarks_fp_diff(bn254snarks_fp* r, const bn254snarks_fp* a, const bn254snarks_fp* b); -void ctt_bn254snarks_fp_sub_in_place(bn254snarks_fp* a, const bn254snarks_fp* b); -void ctt_bn254snarks_fp_double(bn254snarks_fp* r, const bn254snarks_fp* a); -void ctt_bn254snarks_fp_double_in_place(bn254snarks_fp* a); -void ctt_bn254snarks_fp_prod(bn254snarks_fp* r, const bn254snarks_fp* a, const bn254snarks_fp* b); -void ctt_bn254snarks_fp_mul_in_place(bn254snarks_fp* a, const bn254snarks_fp* b); -void ctt_bn254snarks_fp_square(bn254snarks_fp* r, const bn254snarks_fp* a); -void ctt_bn254snarks_fp_square_in_place(bn254snarks_fp* a); -void ctt_bn254snarks_fp_div2(bn254snarks_fp* a); -void ctt_bn254snarks_fp_inv(bn254snarks_fp* r, const bn254snarks_fp* a); -void ctt_bn254snarks_fp_inv_in_place(bn254snarks_fp* a); -void ctt_bn254snarks_fp_ccopy(bn254snarks_fp* a, const bn254snarks_fp* b, const secret_bool ctl); -void ctt_bn254snarks_fp_cswap(bn254snarks_fp* a, bn254snarks_fp* b, const secret_bool ctl); -void ctt_bn254snarks_fp_cset_zero(bn254snarks_fp* a, const secret_bool ctl); -void ctt_bn254snarks_fp_cset_one(bn254snarks_fp* a, const secret_bool ctl); -void ctt_bn254snarks_fp_cneg_in_place(bn254snarks_fp* a, const secret_bool ctl); -void ctt_bn254snarks_fp_cadd_in_place(bn254snarks_fp* a, const bn254snarks_fp* b, const secret_bool ctl); -void ctt_bn254snarks_fp_csub_in_place(bn254snarks_fp* a, const bn254snarks_fp* b, const secret_bool ctl); -secret_bool ctt_bn254snarks_fp_is_square(const bn254snarks_fp* a); -void ctt_bn254snarks_fp_invsqrt(bn254snarks_fp* r, const bn254snarks_fp* a); -secret_bool ctt_bn254snarks_fp_invsqrt_in_place(bn254snarks_fp* r, const bn254snarks_fp* a); -void ctt_bn254snarks_fp_sqrt_in_place(bn254snarks_fp* a); -secret_bool ctt_bn254snarks_fp_sqrt_if_square_in_place(bn254snarks_fp* a); -void ctt_bn254snarks_fp_sqrt_invsqrt(bn254snarks_fp* sqrt, bn254snarks_fp* invsqrt, const bn254snarks_fp* a); -secret_bool ctt_bn254snarks_fp_sqrt_invsqrt_if_square(bn254snarks_fp* sqrt, bn254snarks_fp* invsqrt, const bn254snarks_fp* a); -secret_bool ctt_bn254snarks_fp_sqrt_ratio_if_square(bn254snarks_fp* r, const bn254snarks_fp* u, const bn254snarks_fp* v); -secret_bool ctt_bn254snarks_fp2_is_eq(const bn254snarks_fp2* a, const bn254snarks_fp2* b); -secret_bool ctt_bn254snarks_fp2_is_zero(const bn254snarks_fp2* a); -secret_bool ctt_bn254snarks_fp2_is_one(const bn254snarks_fp2* a); -secret_bool ctt_bn254snarks_fp2_is_minus_one(const bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_set_zero(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_set_one(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_set_minus_one(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_neg(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_sum(bn254snarks_fp2* r, const bn254snarks_fp2* a, const bn254snarks_fp2* b); -void ctt_bn254snarks_fp2_add_in_place(bn254snarks_fp2* a, const bn254snarks_fp2* b); -void ctt_bn254snarks_fp2_diff(bn254snarks_fp2* r, const bn254snarks_fp2* a, const bn254snarks_fp2* b); -void ctt_bn254snarks_fp2_sub_in_place(bn254snarks_fp2* a, const bn254snarks_fp2* b); -void ctt_bn254snarks_fp2_double(bn254snarks_fp2* r, const bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_double_in_place(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_conj(bn254snarks_fp2* r, const bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_conj_in_place(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_conjneg(bn254snarks_fp2* r, const bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_conjneg_in_place(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_prod(bn254snarks_fp2* r, const bn254snarks_fp2* a, const bn254snarks_fp2* b); -void ctt_bn254snarks_fp2_mul_in_place(bn254snarks_fp2* a, const bn254snarks_fp2* b); -void ctt_bn254snarks_fp2_square(bn254snarks_fp2* r, const bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_square_in_place(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_div2(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_inv(bn254snarks_fp2* r, const bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_inv_in_place(bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_ccopy(bn254snarks_fp2* a, const bn254snarks_fp2* b, const secret_bool ctl); -void ctt_bn254snarks_fp2_cset_zero(bn254snarks_fp2* a, const secret_bool ctl); -void ctt_bn254snarks_fp2_cset_one(bn254snarks_fp2* a, const secret_bool ctl); -void ctt_bn254snarks_fp2_cneg_in_place(bn254snarks_fp2* a, const secret_bool ctl); -void ctt_bn254snarks_fp2_cadd_in_place(bn254snarks_fp2* a, const bn254snarks_fp2* b, const secret_bool ctl); -void ctt_bn254snarks_fp2_csub_in_place(bn254snarks_fp2* a, const bn254snarks_fp2* b, const secret_bool ctl); -secret_bool ctt_bn254snarks_fp2_is_square(const bn254snarks_fp2* a); -void ctt_bn254snarks_fp2_sqrt_in_place(bn254snarks_fp2* a); -secret_bool ctt_bn254snarks_fp2_sqrt_if_square_in_place(bn254snarks_fp2* a); -secret_bool ctt_bn254snarks_ec_g1_aff_is_eq(const bn254snarks_ec_g1_aff* P, const bn254snarks_ec_g1_aff* Q); -secret_bool ctt_bn254snarks_ec_g1_aff_is_inf(const bn254snarks_ec_g1_aff* P); -void ctt_bn254snarks_ec_g1_aff_set_inf(bn254snarks_ec_g1_aff* P); -void ctt_bn254snarks_ec_g1_aff_ccopy(bn254snarks_ec_g1_aff* P, const bn254snarks_ec_g1_aff* Q, const secret_bool ctl); -secret_bool ctt_bn254snarks_ec_g1_aff_is_on_curve(const bn254snarks_fp* x, const bn254snarks_fp* y); -void ctt_bn254snarks_ec_g1_aff_neg(bn254snarks_ec_g1_aff* P, const bn254snarks_ec_g1_aff* Q); -void ctt_bn254snarks_ec_g1_aff_neg_in_place(bn254snarks_ec_g1_aff* P); -secret_bool ctt_bn254snarks_ec_g1_jac_is_eq(const bn254snarks_ec_g1_jac* P, const bn254snarks_ec_g1_jac* Q); -secret_bool ctt_bn254snarks_ec_g1_jac_is_inf(const bn254snarks_ec_g1_jac* P); -void ctt_bn254snarks_ec_g1_jac_set_inf(bn254snarks_ec_g1_jac* P); -void ctt_bn254snarks_ec_g1_jac_ccopy(bn254snarks_ec_g1_jac* P, const bn254snarks_ec_g1_jac* Q, const secret_bool ctl); -void ctt_bn254snarks_ec_g1_jac_neg(bn254snarks_ec_g1_jac* P, const bn254snarks_ec_g1_jac* Q); -void ctt_bn254snarks_ec_g1_jac_neg_in_place(bn254snarks_ec_g1_jac* P); -void ctt_bn254snarks_ec_g1_jac_cneg_in_place(bn254snarks_ec_g1_jac* P, const secret_bool ctl); -void ctt_bn254snarks_ec_g1_jac_sum(bn254snarks_ec_g1_jac* r, const bn254snarks_ec_g1_jac* P, const bn254snarks_ec_g1_jac* Q); -void ctt_bn254snarks_ec_g1_jac_add_in_place(bn254snarks_ec_g1_jac* P, const bn254snarks_ec_g1_jac* Q); -void ctt_bn254snarks_ec_g1_jac_diff(bn254snarks_ec_g1_jac* r, const bn254snarks_ec_g1_jac* P, const bn254snarks_ec_g1_jac* Q); -void ctt_bn254snarks_ec_g1_jac_double(bn254snarks_ec_g1_jac* r, const bn254snarks_ec_g1_jac* P); -void ctt_bn254snarks_ec_g1_jac_double_in_place(bn254snarks_ec_g1_jac* P); -void ctt_bn254snarks_ec_g1_jac_affine(bn254snarks_ec_g1_aff* dst, const bn254snarks_ec_g1_jac* src); -void ctt_bn254snarks_ec_g1_jac_from_affine(bn254snarks_ec_g1_jac* dst, const bn254snarks_ec_g1_aff* src); -secret_bool ctt_bn254snarks_ec_g1_prj_is_eq(const bn254snarks_ec_g1_prj* P, const bn254snarks_ec_g1_prj* Q); -secret_bool ctt_bn254snarks_ec_g1_prj_is_inf(const bn254snarks_ec_g1_prj* P); -void ctt_bn254snarks_ec_g1_prj_set_inf(bn254snarks_ec_g1_prj* P); -void ctt_bn254snarks_ec_g1_prj_ccopy(bn254snarks_ec_g1_prj* P, const bn254snarks_ec_g1_prj* Q, const secret_bool ctl); -void ctt_bn254snarks_ec_g1_prj_neg(bn254snarks_ec_g1_prj* P, const bn254snarks_ec_g1_prj* Q); -void ctt_bn254snarks_ec_g1_prj_neg_in_place(bn254snarks_ec_g1_prj* P); -void ctt_bn254snarks_ec_g1_prj_cneg_in_place(bn254snarks_ec_g1_prj* P, const secret_bool ctl); -void ctt_bn254snarks_ec_g1_prj_sum(bn254snarks_ec_g1_prj* r, const bn254snarks_ec_g1_prj* P, const bn254snarks_ec_g1_prj* Q); -void ctt_bn254snarks_ec_g1_prj_add_in_place(bn254snarks_ec_g1_prj* P, const bn254snarks_ec_g1_prj* Q); -void ctt_bn254snarks_ec_g1_prj_diff(bn254snarks_ec_g1_prj* r, const bn254snarks_ec_g1_prj* P, const bn254snarks_ec_g1_prj* Q); -void ctt_bn254snarks_ec_g1_prj_double(bn254snarks_ec_g1_prj* r, const bn254snarks_ec_g1_prj* P); -void ctt_bn254snarks_ec_g1_prj_double_in_place(bn254snarks_ec_g1_prj* P); -void ctt_bn254snarks_ec_g1_prj_affine(bn254snarks_ec_g1_aff* dst, const bn254snarks_ec_g1_prj* src); -void ctt_bn254snarks_ec_g1_prj_from_affine(bn254snarks_ec_g1_prj* dst, const bn254snarks_ec_g1_aff* src); -secret_bool ctt_bn254snarks_ec_g2_aff_is_eq(const bn254snarks_ec_g2_aff* P, const bn254snarks_ec_g2_aff* Q); -secret_bool ctt_bn254snarks_ec_g2_aff_is_inf(const bn254snarks_ec_g2_aff* P); -void ctt_bn254snarks_ec_g2_aff_set_inf(bn254snarks_ec_g2_aff* P); -void ctt_bn254snarks_ec_g2_aff_ccopy(bn254snarks_ec_g2_aff* P, const bn254snarks_ec_g2_aff* Q, const secret_bool ctl); -secret_bool ctt_bn254snarks_ec_g2_aff_is_on_curve(const bn254snarks_fp2* x, const bn254snarks_fp2* y); -void ctt_bn254snarks_ec_g2_aff_neg(bn254snarks_ec_g2_aff* P, const bn254snarks_ec_g2_aff* Q); -void ctt_bn254snarks_ec_g2_aff_neg_in_place(bn254snarks_ec_g2_aff* P); -secret_bool ctt_bn254snarks_ec_g2_jac_is_eq(const bn254snarks_ec_g2_jac* P, const bn254snarks_ec_g2_jac* Q); -secret_bool ctt_bn254snarks_ec_g2_jac_is_inf(const bn254snarks_ec_g2_jac* P); -void ctt_bn254snarks_ec_g2_jac_set_inf(bn254snarks_ec_g2_jac* P); -void ctt_bn254snarks_ec_g2_jac_ccopy(bn254snarks_ec_g2_jac* P, const bn254snarks_ec_g2_jac* Q, const secret_bool ctl); -void ctt_bn254snarks_ec_g2_jac_neg(bn254snarks_ec_g2_jac* P, const bn254snarks_ec_g2_jac* Q); -void ctt_bn254snarks_ec_g2_jac_neg_in_place(bn254snarks_ec_g2_jac* P); -void ctt_bn254snarks_ec_g2_jac_cneg_in_place(bn254snarks_ec_g2_jac* P, const secret_bool ctl); -void ctt_bn254snarks_ec_g2_jac_sum(bn254snarks_ec_g2_jac* r, const bn254snarks_ec_g2_jac* P, const bn254snarks_ec_g2_jac* Q); -void ctt_bn254snarks_ec_g2_jac_add_in_place(bn254snarks_ec_g2_jac* P, const bn254snarks_ec_g2_jac* Q); -void ctt_bn254snarks_ec_g2_jac_diff(bn254snarks_ec_g2_jac* r, const bn254snarks_ec_g2_jac* P, const bn254snarks_ec_g2_jac* Q); -void ctt_bn254snarks_ec_g2_jac_double(bn254snarks_ec_g2_jac* r, const bn254snarks_ec_g2_jac* P); -void ctt_bn254snarks_ec_g2_jac_double_in_place(bn254snarks_ec_g2_jac* P); -void ctt_bn254snarks_ec_g2_jac_affine(bn254snarks_ec_g2_aff* dst, const bn254snarks_ec_g2_jac* src); -void ctt_bn254snarks_ec_g2_jac_from_affine(bn254snarks_ec_g2_jac* dst, const bn254snarks_ec_g2_aff* src); -secret_bool ctt_bn254snarks_ec_g2_prj_is_eq(const bn254snarks_ec_g2_prj* P, const bn254snarks_ec_g2_prj* Q); -secret_bool ctt_bn254snarks_ec_g2_prj_is_inf(const bn254snarks_ec_g2_prj* P); -void ctt_bn254snarks_ec_g2_prj_set_inf(bn254snarks_ec_g2_prj* P); -void ctt_bn254snarks_ec_g2_prj_ccopy(bn254snarks_ec_g2_prj* P, const bn254snarks_ec_g2_prj* Q, const secret_bool ctl); -void ctt_bn254snarks_ec_g2_prj_neg(bn254snarks_ec_g2_prj* P, const bn254snarks_ec_g2_prj* Q); -void ctt_bn254snarks_ec_g2_prj_neg_in_place(bn254snarks_ec_g2_prj* P); -void ctt_bn254snarks_ec_g2_prj_cneg_in_place(bn254snarks_ec_g2_prj* P, const secret_bool ctl); -void ctt_bn254snarks_ec_g2_prj_sum(bn254snarks_ec_g2_prj* r, const bn254snarks_ec_g2_prj* P, const bn254snarks_ec_g2_prj* Q); -void ctt_bn254snarks_ec_g2_prj_add_in_place(bn254snarks_ec_g2_prj* P, const bn254snarks_ec_g2_prj* Q); -void ctt_bn254snarks_ec_g2_prj_diff(bn254snarks_ec_g2_prj* r, const bn254snarks_ec_g2_prj* P, const bn254snarks_ec_g2_prj* Q); -void ctt_bn254snarks_ec_g2_prj_double(bn254snarks_ec_g2_prj* r, const bn254snarks_ec_g2_prj* P); -void ctt_bn254snarks_ec_g2_prj_double_in_place(bn254snarks_ec_g2_prj* P); -void ctt_bn254snarks_ec_g2_prj_affine(bn254snarks_ec_g2_aff* dst, const bn254snarks_ec_g2_prj* src); -void ctt_bn254snarks_ec_g2_prj_from_affine(bn254snarks_ec_g2_prj* dst, const bn254snarks_ec_g2_aff* src); - - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/include/constantine_pasta.h b/include/constantine_pasta.h deleted file mode 100644 index 40a464c51..000000000 --- a/include/constantine_pasta.h +++ /dev/null @@ -1,278 +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_PASTA__ -#define __CTT_H_PASTA__ - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) -typedef __SIZE_TYPE__ size_t; -typedef __PTRDIFF_TYPE__ ptrdiff_t; -#else -#include -#endif - -#if defined(__UINT8_TYPE__) && defined(__UINT32_TYPE__) && defined(__UINT64_TYPE__) -typedef __UINT8_TYPE__ uint8_t; -typedef __UINT32_TYPE__ uint32_t; -typedef __UINT64_TYPE__ uint64_t; -#else -#include -#endif - -#if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901 -# define bool _Bool -#else -# define bool unsigned char -#endif - -typedef size_t secret_word; -typedef size_t secret_bool; -typedef uint8_t byte; - -#define WordBitWidth (sizeof(secret_word)*8) -#define words_required(bits) ((bits+WordBitWidth-1)/WordBitWidth) - -typedef struct { secret_word limbs[words_required(255)]; } pallas_fr; -typedef struct { secret_word limbs[words_required(255)]; } pallas_fp; -typedef struct { secret_word limbs[words_required(255)]; } vesta_fr; -typedef struct { secret_word limbs[words_required(255)]; } vesta_fp; -typedef struct { pallas_fp x, y; } pallas_ec_aff; -typedef struct { pallas_fp x, y, z; } pallas_ec_jac; -typedef struct { pallas_fp x, y, z; } pallas_ec_prj; -typedef struct { vesta_fp x, y; } vesta_ec_aff; -typedef struct { vesta_fp x, y, z; } vesta_ec_jac; -typedef struct { vesta_fp x, y, z; } vesta_ec_prj; - -/* - * Initializes the library: - * - detect CPU features like ADX instructions support (MULX, ADCX, ADOX) - */ -void ctt_pasta_init_NimMain(void); - -bool ctt_pallas_fr_unmarshalBE(pallas_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); -bool ctt_pallas_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fr* src) __attribute__((warn_unused_result)); -secret_bool ctt_pallas_fr_is_eq(const pallas_fr* a, const pallas_fr* b); -secret_bool ctt_pallas_fr_is_zero(const pallas_fr* a); -secret_bool ctt_pallas_fr_is_one(const pallas_fr* a); -secret_bool ctt_pallas_fr_is_minus_one(const pallas_fr* a); -void ctt_pallas_fr_set_zero(pallas_fr* a); -void ctt_pallas_fr_set_one(pallas_fr* a); -void ctt_pallas_fr_set_minus_one(pallas_fr* a); -void ctt_pallas_fr_neg(pallas_fr* r, const pallas_fr* a); -void ctt_pallas_fr_neg_in_place(pallas_fr* a); -void ctt_pallas_fr_sum(pallas_fr* r, const pallas_fr* a, const pallas_fr* b); -void ctt_pallas_fr_add_in_place(pallas_fr* a, const pallas_fr* b); -void ctt_pallas_fr_diff(pallas_fr* r, const pallas_fr* a, const pallas_fr* b); -void ctt_pallas_fr_sub_in_place(pallas_fr* a, const pallas_fr* b); -void ctt_pallas_fr_double(pallas_fr* r, const pallas_fr* a); -void ctt_pallas_fr_double_in_place(pallas_fr* a); -void ctt_pallas_fr_prod(pallas_fr* r, const pallas_fr* a, const pallas_fr* b); -void ctt_pallas_fr_mul_in_place(pallas_fr* a, const pallas_fr* b); -void ctt_pallas_fr_square(pallas_fr* r, const pallas_fr* a); -void ctt_pallas_fr_square_in_place(pallas_fr* a); -void ctt_pallas_fr_div2(pallas_fr* a); -void ctt_pallas_fr_inv(pallas_fr* r, const pallas_fr* a); -void ctt_pallas_fr_inv_in_place(pallas_fr* a); -void ctt_pallas_fr_ccopy(pallas_fr* a, const pallas_fr* b, const secret_bool ctl); -void ctt_pallas_fr_cswap(pallas_fr* a, pallas_fr* b, const secret_bool ctl); -void ctt_pallas_fr_cset_zero(pallas_fr* a, const secret_bool ctl); -void ctt_pallas_fr_cset_one(pallas_fr* a, const secret_bool ctl); -void ctt_pallas_fr_cneg_in_place(pallas_fr* a, const secret_bool ctl); -void ctt_pallas_fr_cadd_in_place(pallas_fr* a, const pallas_fr* b, const secret_bool ctl); -void ctt_pallas_fr_csub_in_place(pallas_fr* a, const pallas_fr* b, const secret_bool ctl); -bool ctt_pallas_fp_unmarshalBE(pallas_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); -bool ctt_pallas_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const pallas_fp* src) __attribute__((warn_unused_result)); -secret_bool ctt_pallas_fp_is_eq(const pallas_fp* a, const pallas_fp* b); -secret_bool ctt_pallas_fp_is_zero(const pallas_fp* a); -secret_bool ctt_pallas_fp_is_one(const pallas_fp* a); -secret_bool ctt_pallas_fp_is_minus_one(const pallas_fp* a); -void ctt_pallas_fp_set_zero(pallas_fp* a); -void ctt_pallas_fp_set_one(pallas_fp* a); -void ctt_pallas_fp_set_minus_one(pallas_fp* a); -void ctt_pallas_fp_neg(pallas_fp* r, const pallas_fp* a); -void ctt_pallas_fp_neg_in_place(pallas_fp* a); -void ctt_pallas_fp_sum(pallas_fp* r, const pallas_fp* a, const pallas_fp* b); -void ctt_pallas_fp_add_in_place(pallas_fp* a, const pallas_fp* b); -void ctt_pallas_fp_diff(pallas_fp* r, const pallas_fp* a, const pallas_fp* b); -void ctt_pallas_fp_sub_in_place(pallas_fp* a, const pallas_fp* b); -void ctt_pallas_fp_double(pallas_fp* r, const pallas_fp* a); -void ctt_pallas_fp_double_in_place(pallas_fp* a); -void ctt_pallas_fp_prod(pallas_fp* r, const pallas_fp* a, const pallas_fp* b); -void ctt_pallas_fp_mul_in_place(pallas_fp* a, const pallas_fp* b); -void ctt_pallas_fp_square(pallas_fp* r, const pallas_fp* a); -void ctt_pallas_fp_square_in_place(pallas_fp* a); -void ctt_pallas_fp_div2(pallas_fp* a); -void ctt_pallas_fp_inv(pallas_fp* r, const pallas_fp* a); -void ctt_pallas_fp_inv_in_place(pallas_fp* a); -void ctt_pallas_fp_ccopy(pallas_fp* a, const pallas_fp* b, const secret_bool ctl); -void ctt_pallas_fp_cswap(pallas_fp* a, pallas_fp* b, const secret_bool ctl); -void ctt_pallas_fp_cset_zero(pallas_fp* a, const secret_bool ctl); -void ctt_pallas_fp_cset_one(pallas_fp* a, const secret_bool ctl); -void ctt_pallas_fp_cneg_in_place(pallas_fp* a, const secret_bool ctl); -void ctt_pallas_fp_cadd_in_place(pallas_fp* a, const pallas_fp* b, const secret_bool ctl); -void ctt_pallas_fp_csub_in_place(pallas_fp* a, const pallas_fp* b, const secret_bool ctl); -secret_bool ctt_pallas_fp_is_square(const pallas_fp* a); -void ctt_pallas_fp_invsqrt(pallas_fp* r, const pallas_fp* a); -secret_bool ctt_pallas_fp_invsqrt_in_place(pallas_fp* r, const pallas_fp* a); -void ctt_pallas_fp_sqrt_in_place(pallas_fp* a); -secret_bool ctt_pallas_fp_sqrt_if_square_in_place(pallas_fp* a); -void ctt_pallas_fp_sqrt_invsqrt(pallas_fp* sqrt, pallas_fp* invsqrt, const pallas_fp* a); -secret_bool ctt_pallas_fp_sqrt_invsqrt_if_square(pallas_fp* sqrt, pallas_fp* invsqrt, const pallas_fp* a); -secret_bool ctt_pallas_fp_sqrt_ratio_if_square(pallas_fp* r, const pallas_fp* u, const pallas_fp* v); -bool ctt_vesta_fr_unmarshalBE(vesta_fr* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); -bool ctt_vesta_fr_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fr* src) __attribute__((warn_unused_result)); -secret_bool ctt_vesta_fr_is_eq(const vesta_fr* a, const vesta_fr* b); -secret_bool ctt_vesta_fr_is_zero(const vesta_fr* a); -secret_bool ctt_vesta_fr_is_one(const vesta_fr* a); -secret_bool ctt_vesta_fr_is_minus_one(const vesta_fr* a); -void ctt_vesta_fr_set_zero(vesta_fr* a); -void ctt_vesta_fr_set_one(vesta_fr* a); -void ctt_vesta_fr_set_minus_one(vesta_fr* a); -void ctt_vesta_fr_neg(vesta_fr* r, const vesta_fr* a); -void ctt_vesta_fr_neg_in_place(vesta_fr* a); -void ctt_vesta_fr_sum(vesta_fr* r, const vesta_fr* a, const vesta_fr* b); -void ctt_vesta_fr_add_in_place(vesta_fr* a, const vesta_fr* b); -void ctt_vesta_fr_diff(vesta_fr* r, const vesta_fr* a, const vesta_fr* b); -void ctt_vesta_fr_sub_in_place(vesta_fr* a, const vesta_fr* b); -void ctt_vesta_fr_double(vesta_fr* r, const vesta_fr* a); -void ctt_vesta_fr_double_in_place(vesta_fr* a); -void ctt_vesta_fr_prod(vesta_fr* r, const vesta_fr* a, const vesta_fr* b); -void ctt_vesta_fr_mul_in_place(vesta_fr* a, const vesta_fr* b); -void ctt_vesta_fr_square(vesta_fr* r, const vesta_fr* a); -void ctt_vesta_fr_square_in_place(vesta_fr* a); -void ctt_vesta_fr_div2(vesta_fr* a); -void ctt_vesta_fr_inv(vesta_fr* r, const vesta_fr* a); -void ctt_vesta_fr_inv_in_place(vesta_fr* a); -void ctt_vesta_fr_ccopy(vesta_fr* a, const vesta_fr* b, const secret_bool ctl); -void ctt_vesta_fr_cswap(vesta_fr* a, vesta_fr* b, const secret_bool ctl); -void ctt_vesta_fr_cset_zero(vesta_fr* a, const secret_bool ctl); -void ctt_vesta_fr_cset_one(vesta_fr* a, const secret_bool ctl); -void ctt_vesta_fr_cneg_in_place(vesta_fr* a, const secret_bool ctl); -void ctt_vesta_fr_cadd_in_place(vesta_fr* a, const vesta_fr* b, const secret_bool ctl); -void ctt_vesta_fr_csub_in_place(vesta_fr* a, const vesta_fr* b, const secret_bool ctl); -bool ctt_vesta_fp_unmarshalBE(vesta_fp* dst, const byte src[], ptrdiff_t src_len) __attribute__((warn_unused_result)); -bool ctt_vesta_fp_marshalBE(byte dst[], ptrdiff_t dst_len, const vesta_fp* src) __attribute__((warn_unused_result)); -secret_bool ctt_vesta_fp_is_eq(const vesta_fp* a, const vesta_fp* b); -secret_bool ctt_vesta_fp_is_zero(const vesta_fp* a); -secret_bool ctt_vesta_fp_is_one(const vesta_fp* a); -secret_bool ctt_vesta_fp_is_minus_one(const vesta_fp* a); -void ctt_vesta_fp_set_zero(vesta_fp* a); -void ctt_vesta_fp_set_one(vesta_fp* a); -void ctt_vesta_fp_set_minus_one(vesta_fp* a); -void ctt_vesta_fp_neg(vesta_fp* r, const vesta_fp* a); -void ctt_vesta_fp_neg_in_place(vesta_fp* a); -void ctt_vesta_fp_sum(vesta_fp* r, const vesta_fp* a, const vesta_fp* b); -void ctt_vesta_fp_add_in_place(vesta_fp* a, const vesta_fp* b); -void ctt_vesta_fp_diff(vesta_fp* r, const vesta_fp* a, const vesta_fp* b); -void ctt_vesta_fp_sub_in_place(vesta_fp* a, const vesta_fp* b); -void ctt_vesta_fp_double(vesta_fp* r, const vesta_fp* a); -void ctt_vesta_fp_double_in_place(vesta_fp* a); -void ctt_vesta_fp_prod(vesta_fp* r, const vesta_fp* a, const vesta_fp* b); -void ctt_vesta_fp_mul_in_place(vesta_fp* a, const vesta_fp* b); -void ctt_vesta_fp_square(vesta_fp* r, const vesta_fp* a); -void ctt_vesta_fp_square_in_place(vesta_fp* a); -void ctt_vesta_fp_div2(vesta_fp* a); -void ctt_vesta_fp_inv(vesta_fp* r, const vesta_fp* a); -void ctt_vesta_fp_inv_in_place(vesta_fp* a); -void ctt_vesta_fp_ccopy(vesta_fp* a, const vesta_fp* b, const secret_bool ctl); -void ctt_vesta_fp_cswap(vesta_fp* a, vesta_fp* b, const secret_bool ctl); -void ctt_vesta_fp_cset_zero(vesta_fp* a, const secret_bool ctl); -void ctt_vesta_fp_cset_one(vesta_fp* a, const secret_bool ctl); -void ctt_vesta_fp_cneg_in_place(vesta_fp* a, const secret_bool ctl); -void ctt_vesta_fp_cadd_in_place(vesta_fp* a, const vesta_fp* b, const secret_bool ctl); -void ctt_vesta_fp_csub_in_place(vesta_fp* a, const vesta_fp* b, const secret_bool ctl); -secret_bool ctt_vesta_fp_is_square(const vesta_fp* a); -void ctt_vesta_fp_invsqrt(vesta_fp* r, const vesta_fp* a); -secret_bool ctt_vesta_fp_invsqrt_in_place(vesta_fp* r, const vesta_fp* a); -void ctt_vesta_fp_sqrt_in_place(vesta_fp* a); -secret_bool ctt_vesta_fp_sqrt_if_square_in_place(vesta_fp* a); -void ctt_vesta_fp_sqrt_invsqrt(vesta_fp* sqrt, vesta_fp* invsqrt, const vesta_fp* a); -secret_bool ctt_vesta_fp_sqrt_invsqrt_if_square(vesta_fp* sqrt, vesta_fp* invsqrt, const vesta_fp* a); -secret_bool ctt_vesta_fp_sqrt_ratio_if_square(vesta_fp* r, const vesta_fp* u, const vesta_fp* v); -secret_bool ctt_pallas_ec_aff_is_eq(const pallas_ec_aff* P, const pallas_ec_aff* Q); -secret_bool ctt_pallas_ec_aff_is_inf(const pallas_ec_aff* P); -void ctt_pallas_ec_aff_set_inf(pallas_ec_aff* P); -void ctt_pallas_ec_aff_ccopy(pallas_ec_aff* P, const pallas_ec_aff* Q, const secret_bool ctl); -secret_bool ctt_pallas_ec_aff_is_on_curve(const pallas_fp* x, const pallas_fp* y); -void ctt_pallas_ec_aff_neg(pallas_ec_aff* P, const pallas_ec_aff* Q); -void ctt_pallas_ec_aff_neg_in_place(pallas_ec_aff* P); -secret_bool ctt_pallas_ec_jac_is_eq(const pallas_ec_jac* P, const pallas_ec_jac* Q); -secret_bool ctt_pallas_ec_jac_is_inf(const pallas_ec_jac* P); -void ctt_pallas_ec_jac_set_inf(pallas_ec_jac* P); -void ctt_pallas_ec_jac_ccopy(pallas_ec_jac* P, const pallas_ec_jac* Q, const secret_bool ctl); -void ctt_pallas_ec_jac_neg(pallas_ec_jac* P, const pallas_ec_jac* Q); -void ctt_pallas_ec_jac_neg_in_place(pallas_ec_jac* P); -void ctt_pallas_ec_jac_cneg_in_place(pallas_ec_jac* P, const secret_bool ctl); -void ctt_pallas_ec_jac_sum(pallas_ec_jac* r, const pallas_ec_jac* P, const pallas_ec_jac* Q); -void ctt_pallas_ec_jac_add_in_place(pallas_ec_jac* P, const pallas_ec_jac* Q); -void ctt_pallas_ec_jac_diff(pallas_ec_jac* r, const pallas_ec_jac* P, const pallas_ec_jac* Q); -void ctt_pallas_ec_jac_double(pallas_ec_jac* r, const pallas_ec_jac* P); -void ctt_pallas_ec_jac_double_in_place(pallas_ec_jac* P); -void ctt_pallas_ec_jac_affine(pallas_ec_aff* dst, const pallas_ec_jac* src); -void ctt_pallas_ec_jac_from_affine(pallas_ec_jac* dst, const pallas_ec_aff* src); -secret_bool ctt_pallas_ec_prj_is_eq(const pallas_ec_prj* P, const pallas_ec_prj* Q); -secret_bool ctt_pallas_ec_prj_is_inf(const pallas_ec_prj* P); -void ctt_pallas_ec_prj_set_inf(pallas_ec_prj* P); -void ctt_pallas_ec_prj_ccopy(pallas_ec_prj* P, const pallas_ec_prj* Q, const secret_bool ctl); -void ctt_pallas_ec_prj_neg(pallas_ec_prj* P, const pallas_ec_prj* Q); -void ctt_pallas_ec_prj_neg_in_place(pallas_ec_prj* P); -void ctt_pallas_ec_prj_cneg_in_place(pallas_ec_prj* P, const secret_bool ctl); -void ctt_pallas_ec_prj_sum(pallas_ec_prj* r, const pallas_ec_prj* P, const pallas_ec_prj* Q); -void ctt_pallas_ec_prj_add_in_place(pallas_ec_prj* P, const pallas_ec_prj* Q); -void ctt_pallas_ec_prj_diff(pallas_ec_prj* r, const pallas_ec_prj* P, const pallas_ec_prj* Q); -void ctt_pallas_ec_prj_double(pallas_ec_prj* r, const pallas_ec_prj* P); -void ctt_pallas_ec_prj_double_in_place(pallas_ec_prj* P); -void ctt_pallas_ec_prj_affine(pallas_ec_aff* dst, const pallas_ec_prj* src); -void ctt_pallas_ec_prj_from_affine(pallas_ec_prj* dst, const pallas_ec_aff* src); -secret_bool ctt_vesta_ec_aff_is_eq(const vesta_ec_aff* P, const vesta_ec_aff* Q); -secret_bool ctt_vesta_ec_aff_is_inf(const vesta_ec_aff* P); -void ctt_vesta_ec_aff_set_inf(vesta_ec_aff* P); -void ctt_vesta_ec_aff_ccopy(vesta_ec_aff* P, const vesta_ec_aff* Q, const secret_bool ctl); -secret_bool ctt_vesta_ec_aff_is_on_curve(const pallas_fp* x, const pallas_fp* y); -void ctt_vesta_ec_aff_neg(vesta_ec_aff* P, const vesta_ec_aff* Q); -void ctt_vesta_ec_aff_neg_in_place(vesta_ec_aff* P); -secret_bool ctt_vesta_ec_jac_is_eq(const vesta_ec_jac* P, const vesta_ec_jac* Q); -secret_bool ctt_vesta_ec_jac_is_inf(const vesta_ec_jac* P); -void ctt_vesta_ec_jac_set_inf(vesta_ec_jac* P); -void ctt_vesta_ec_jac_ccopy(vesta_ec_jac* P, const vesta_ec_jac* Q, const secret_bool ctl); -void ctt_vesta_ec_jac_neg(vesta_ec_jac* P, const vesta_ec_jac* Q); -void ctt_vesta_ec_jac_neg_in_place(vesta_ec_jac* P); -void ctt_vesta_ec_jac_cneg_in_place(vesta_ec_jac* P, const secret_bool ctl); -void ctt_vesta_ec_jac_sum(vesta_ec_jac* r, const vesta_ec_jac* P, const vesta_ec_jac* Q); -void ctt_vesta_ec_jac_add_in_place(vesta_ec_jac* P, const vesta_ec_jac* Q); -void ctt_vesta_ec_jac_diff(vesta_ec_jac* r, const vesta_ec_jac* P, const vesta_ec_jac* Q); -void ctt_vesta_ec_jac_double(vesta_ec_jac* r, const vesta_ec_jac* P); -void ctt_vesta_ec_jac_double_in_place(vesta_ec_jac* P); -void ctt_vesta_ec_jac_affine(vesta_ec_aff* dst, const vesta_ec_jac* src); -void ctt_vesta_ec_jac_from_affine(vesta_ec_jac* dst, const vesta_ec_aff* src); -secret_bool ctt_vesta_ec_prj_is_eq(const vesta_ec_prj* P, const vesta_ec_prj* Q); -secret_bool ctt_vesta_ec_prj_is_inf(const vesta_ec_prj* P); -void ctt_vesta_ec_prj_set_inf(vesta_ec_prj* P); -void ctt_vesta_ec_prj_ccopy(vesta_ec_prj* P, const vesta_ec_prj* Q, const secret_bool ctl); -void ctt_vesta_ec_prj_neg(vesta_ec_prj* P, const vesta_ec_prj* Q); -void ctt_vesta_ec_prj_neg_in_place(vesta_ec_prj* P); -void ctt_vesta_ec_prj_cneg_in_place(vesta_ec_prj* P, const secret_bool ctl); -void ctt_vesta_ec_prj_sum(vesta_ec_prj* r, const vesta_ec_prj* P, const vesta_ec_prj* Q); -void ctt_vesta_ec_prj_add_in_place(vesta_ec_prj* P, const vesta_ec_prj* Q); -void ctt_vesta_ec_prj_diff(vesta_ec_prj* r, const vesta_ec_prj* P, const vesta_ec_prj* Q); -void ctt_vesta_ec_prj_double(vesta_ec_prj* r, const vesta_ec_prj* P); -void ctt_vesta_ec_prj_double_in_place(vesta_ec_prj* P); -void ctt_vesta_ec_prj_affine(vesta_ec_aff* dst, const vesta_ec_prj* src); -void ctt_vesta_ec_prj_from_affine(vesta_ec_prj* dst, const vesta_ec_aff* src); - - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/lib/.empty_dir b/lib/.empty_dir new file mode 100644 index 000000000..e69de29bb diff --git a/lib/.gitignore b/lib/.gitignore deleted file mode 100644 index 1cbdcaf01..000000000 --- a/lib/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Ignore everything in this directory -* -# Except this file and README -!.gitignore -!README.md \ No newline at end of file diff --git a/lib/README.md b/lib/README.md deleted file mode 100644 index 350c95505..000000000 --- a/lib/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Libraries - -This folder holds the generated dynamic libraries (.so on Linux, .dylib on MacOS, .dll on Windows) and static libraries (.a on Linux and Mac, .dll on Windows). - -To create a new build, download install the [Nim programming language](https://nim-lang.org/install.html), navigate to Constantine's root folder and call `nimble bindings`. \ No newline at end of file diff --git a/scripts/gen_rust_bindings.sh b/scripts/gen_rust_bindings.sh new file mode 100644 index 000000000..0f30aacde --- /dev/null +++ b/scripts/gen_rust_bindings.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Due to cryptographic secrets, deriving Debug is absolutely forbidden. +# Some resources are non-copyable non-clonable: +# - Threadpools +# - Contexts holding sessions +bindgen \ + include/constantine.h \ + -o constantine-rust/constantine-sys/src/bindings.rs \ + --default-enum-style rust \ + --use-core \ + --no-derive-debug \ + --default-visibility private \ + --enable-function-attribute-detection \ + -- -Iinclude + + +# --must-use-type "ctt_.*_status" is not needed with function attribute detection