Rust bindings (#287)

* first jab at Rust bindings

* stash C library and header generation

* Create a single big library with multiple headers

* remove ctt_pure, people will not call crypto proc twice with unchanged parameter and extra noise when reading header

* fix MacOS and Windows builds

* fix cross-lang ThinLTO, require LLD

* Remove NimMain need, cleanup CPU features and detect them on library load
This commit is contained in:
Mamy Ratsimbazafy 2023-10-24 10:56:28 +02:00 committed by GitHub
parent c3b76cd420
commit 3e27f1e831
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 5941 additions and 2274 deletions

3
.cargo/config.toml Normal file
View File

@ -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"

View File

@ -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

40
.gitignore vendored
View File

@ -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

23
Cargo.toml Normal file
View File

@ -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"

View File

@ -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

View File

@ -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

152
bindings/lib_curves.nim Normal file
View File

@ -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)
# ----------------------------------------------------------

34
bindings/lib_hashes.nim Normal file
View File

@ -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)

97
bindings/lib_headers.nim Normal file
View File

@ -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()

View File

@ -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} <optional directory to save header to>"
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()

View File

@ -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} <optional directory to save header to>"
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()

View File

@ -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} <optional directory to save header to>"
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()

1
compile_flags.txt Normal file
View File

@ -0,0 +1 @@
-Iinclude

View File

@ -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]

View File

@ -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");
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!("bindings.rs");

View File

@ -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" }

View File

@ -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);
}
}

View File

@ -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" }

View File

@ -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);
}
}

View File

@ -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" }

View File

@ -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);
}
}

View File

@ -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" }

View File

@ -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);
}
}

View File

@ -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
proc genDynamicBindings(bindingsKind: BindingsKind, bindingsName, prefixNimMain: string) =
let compiler = " --cc:clang "
let lto = " --passC:-flto=thin --passL:-flto=thin "
compiler &
lto &
compilerFlags()
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"
" --outdir:build/make " &
" --nimcache:nimcache/libcurves_headers " &
" bindings/lib_headers.nim"
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 ""
task make_lib, "Build Constantine library":
genStaticLib("lib", "nimcache")
genDynamicLib("lib", "nimcache")
# Protocols
genStaticBindings(kProtocol, "ethereum_bls_signatures", "ctt_eth_bls_init_")
genDynamicBindings(kProtocol, "ethereum_bls_signatures", "ctt_eth_bls_init_")
echo ""
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, 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"
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 = ""

View File

@ -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
# ------------------------------------------------------------------------------------------------

View File

@ -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:

File diff suppressed because it is too large Load Diff

View File

@ -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."

View File

@ -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: "<intrin.h>".}
proc lfence() {.importc: "__mm_lfence", header: "<intrin.h>".}
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 ...

View File

@ -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

View File

@ -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: "<intrin.h>".}
proc lfence() {.importc: "__mm_lfence", header: "<intrin.h>".}
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"
);""".}

View File

@ -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,

View File

@ -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.}

View File

@ -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
# ----------------------------------------------------------------------------------------------

View File

@ -11,13 +11,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <constantine_ethereum_bls_signatures.h>
#include <constantine.h>
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

View File

@ -15,7 +15,7 @@
#include <stdlib.h>
#include <gmp.h>
#include <constantine_bls12_381.h>
#include <constantine.h>
// 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");

View File

@ -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`.

24
include/constantine.h Normal file
View File

@ -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

View File

@ -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 <stddef.h>
#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 <stdint.h>
#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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <stddef.h>
#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 <stdint.h>
#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,9 +224,9 @@ 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
}

View File

@ -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 <stddef.h>
#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 <stdint.h>
#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

View File

@ -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 <stddef.h>
#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 <stdint.h>
#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

View File

@ -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 <stddef.h>
#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 <stdint.h>
#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

0
lib/.empty_dir Normal file
View File

5
lib/.gitignore vendored
View File

@ -1,5 +0,0 @@
# Ignore everything in this directory
*
# Except this file and README
!.gitignore
!README.md

View File

@ -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`.

View File

@ -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