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