Add curve configuration + BN254 config (zkSnarks, ZCash, Ethereum 1 precompile)
This commit is contained in:
parent
f18a958d5e
commit
bd2b10817e
|
@ -0,0 +1,37 @@
|
|||
# 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
|
||||
# Internal
|
||||
./private/curves_config_parser
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Configuration of finite fields
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
# Finite fields are preconfigured in this file
|
||||
# To workaround the following limitation https://github.com/nim-lang/Nim/issues/11142
|
||||
# i.e. an object can be parametrized by a compiletime bigint
|
||||
# we instead have the fields, curve points and Montgomery objects
|
||||
# be parametrized over an enum.
|
||||
|
||||
# Note, in the past the convention was to name a curve by its conjectured security level.
|
||||
# as this might change with advances in research, the new convention is
|
||||
# to name curves according to the length of the prime bit length.
|
||||
# i.e. the BN254 was previously named BN128.
|
||||
|
||||
declareCurves:
|
||||
# Barreto-Naehrig curve, Prime 254 bit, 128-bit security, https://eprint.iacr.org/2013/879.pdf
|
||||
# Usage: Zero-Knowledge Proofs / zkSNARKs in ZCash and Ethereum 1
|
||||
# https://eips.ethereum.org/EIPS/eip-196
|
||||
curve BN254:
|
||||
bitsize: 254
|
||||
modulus: "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
||||
# Equation: Y^2 = X^3 + 3
|
|
@ -0,0 +1,150 @@
|
|||
# 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
|
||||
# Standard library
|
||||
macros,
|
||||
# Internal
|
||||
../io, ../bigints
|
||||
|
||||
# Macro to parse declarative curves configuration.
|
||||
|
||||
macro declareCurves*(curves: untyped): untyped =
|
||||
## Parse curve configuration and generates
|
||||
##
|
||||
## type Curve = enum
|
||||
## BN254
|
||||
## ...
|
||||
##
|
||||
## const CurveBitSize* = array[
|
||||
## BN254: 254,
|
||||
## ...
|
||||
## ]
|
||||
##
|
||||
## TODO: Ensure that the modulus is not inlined at runtime
|
||||
## to avoid codesize explosion.
|
||||
## const BN254_Modulus = fromHex(BigInt[254], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
|
||||
##
|
||||
## func fieldModulus*(curve: static Curve): auto =
|
||||
## when curve == BN254_Modulus: BN254_Modulus
|
||||
## ...
|
||||
curves.expectKind(nnkStmtList)
|
||||
|
||||
# curve BN254:
|
||||
# bitsize: 254
|
||||
# modulus: "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
||||
#
|
||||
# is parsed into
|
||||
#
|
||||
# StmtList
|
||||
# Command
|
||||
# Ident "curve"
|
||||
# Ident "BN254"
|
||||
# StmtList
|
||||
# Call
|
||||
# Ident "bitsize"
|
||||
# StmtList
|
||||
# IntLit 254
|
||||
# Call
|
||||
# Ident "modulus"
|
||||
# StmtList
|
||||
# StrLit "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
||||
|
||||
var Curves: seq[NimNode]
|
||||
var CurveBitSize = nnKBracket.newTree()
|
||||
var curveModStmts = newStmtList()
|
||||
var curveModWhenStmt = nnkWhenStmt.newTree()
|
||||
|
||||
for curveDesc in curves:
|
||||
curveDesc.expectKind(nnkCommand)
|
||||
doAssert curveDesc[0].eqIdent"curve"
|
||||
curveDesc[1].expectKind(nnkIdent) # Curve name
|
||||
curveDesc[2].expectKind(nnkStmtList)
|
||||
curveDesc[2][0].expectKind(nnkCall)
|
||||
curveDesc[2][1].expectKind(nnkCall)
|
||||
|
||||
let curve = curveDesc[1]
|
||||
|
||||
let sizeSection = curveDesc[2][0]
|
||||
doAssert sizeSection[0].eqIdent"bitsize"
|
||||
sizeSection[1].expectKind(nnkStmtList)
|
||||
let bitSize = sizeSection[1][0]
|
||||
|
||||
let modSection = curveDesc[2][1]
|
||||
doAssert modSection[0].eqIdent"modulus"
|
||||
modSection[1].expectKind(nnkStmtList)
|
||||
let modulus = modSection[1][0]
|
||||
|
||||
Curves.add curve
|
||||
# "BN254: 254" for array construction
|
||||
CurveBitSize.add nnkExprColonExpr.newTree(
|
||||
curve, bitSize
|
||||
)
|
||||
|
||||
# const BN254_Modulus = fromHex(BigInt[254], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47")
|
||||
let modulusID = ident($curve & "_Modulus")
|
||||
curveModStmts.add newConstStmt(
|
||||
modulusID,
|
||||
newCall(
|
||||
bindSym"fromHex",
|
||||
nnkBracketExpr.newTree(
|
||||
bindSym"BigInt",
|
||||
bitSize
|
||||
),
|
||||
modulus
|
||||
)
|
||||
)
|
||||
|
||||
# when curve == BN254: BN254_Modulus
|
||||
curveModWhenStmt.add nnkElifBranch.newTree(
|
||||
nnkInfix.newTree(
|
||||
ident"==",
|
||||
ident"curve",
|
||||
curve
|
||||
),
|
||||
modulusID
|
||||
)
|
||||
|
||||
result = newStmtList()
|
||||
|
||||
result.add newEnum(
|
||||
name = ident"Curve",
|
||||
fields = Curves,
|
||||
public = true,
|
||||
pure = false
|
||||
)
|
||||
|
||||
result.add quote do:
|
||||
const CurveBitSize: array[Curve, int] = `CurveBitSize`
|
||||
|
||||
result.add curveModStmts
|
||||
|
||||
# Add 'else: {.error: "Unreachable".}' to the when statements
|
||||
curveModWhenStmt.add nnkElse.newTree(
|
||||
nnkPragma.newTree(
|
||||
nnkExprColonExpr.newTree(
|
||||
ident"error",
|
||||
newLit"Unreachable: the curve does not exist."
|
||||
)
|
||||
)
|
||||
)
|
||||
result.add newProc(
|
||||
name = nnkPostfix.newTree(ident"*", ident"fieldModulus"),
|
||||
params = [
|
||||
ident"auto",
|
||||
newIdentDefs(
|
||||
name = ident"curve",
|
||||
kind = nnkStaticTy.newTree(ident"Curve")
|
||||
)
|
||||
],
|
||||
body = curveModWhenStmt,
|
||||
procType = nnkFuncDef,
|
||||
pragmas = nnkPragma.newTree(ident"compileTime")
|
||||
)
|
||||
|
||||
# echo result.toStrLit
|
Loading…
Reference in New Issue