Add BLS12-381 curve:
- don't create "Mod" in curve parser: compile-time type incompatibility - don't use "Mod" in const sections: compile-time type incompat --> create a macro to get montgomery magics instead of a const array
This commit is contained in:
parent
05a2c6a34b
commit
bd1430157f
|
@ -48,6 +48,10 @@ when not defined(testingCurves):
|
|||
bitsize: 254
|
||||
modulus: "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
||||
# Equation: Y^2 = X^3 + 3
|
||||
curve BLS12_381:
|
||||
bitsize: 381
|
||||
modulus: "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||
# Equation: y^2 = x^3 + 4
|
||||
else:
|
||||
# Fake curve for testing field arithmetic
|
||||
declareCurves:
|
||||
|
@ -57,22 +61,28 @@ else:
|
|||
|
||||
# ############################################################
|
||||
#
|
||||
# Autogeneration of precomputed constants in ROM
|
||||
# Curve Modulus Accessor
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
const MontyNegInvModWord* = block:
|
||||
## Store the Montgomery Magic Constant "Negative Inverse mod 2^63" in ROM
|
||||
var buf: array[Curve, BaseType]
|
||||
for curve in Curve:
|
||||
buf[curve] = curve.Mod.mres.negInvModWord
|
||||
buf
|
||||
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
||||
macro genR2modP(T: typed): untyped =
|
||||
## Store the Montgomery Magic Constant "R^2 mod N" in ROM
|
||||
## For each curve under the private symbol "MyCurve_R2modP"
|
||||
macro Mod*(C: static Curve): untyped =
|
||||
## Get the Modulus associated to a curve
|
||||
result = bindSym($C & "_Modulus")
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Autogeneration of precomputed Montgomery constants in ROM
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
macro genMontyMagics(T: typed): untyped =
|
||||
## Store
|
||||
## - the Montgomery magic constant "R^2 mod N" in ROM
|
||||
## For each curve under the private symbol "MyCurve_R2modP"
|
||||
## - the Montgomery magic constant -1/P mod 2^WordBitSize
|
||||
## For each curve under the private symbol "MyCurve_NegInvModWord
|
||||
T.getImpl.expectKind(nnkTypeDef)
|
||||
T.getImpl[2].expectKind(nnkEnumTy)
|
||||
|
||||
|
@ -92,11 +102,26 @@ macro genR2modP(T: typed): untyped =
|
|||
)
|
||||
)
|
||||
)
|
||||
result.add newConstStmt(
|
||||
ident($curve & "_NegInvModWord"), newCall(
|
||||
bindSym"negInvModWord",
|
||||
# The curve parser creates modulus
|
||||
# under symbol "MyCurve_Modulus"
|
||||
nnkDotExpr.newTree(
|
||||
bindSym($curve & "_Modulus"),
|
||||
ident"mres"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
# echo result.toStrLit
|
||||
|
||||
genR2modP(Curve)
|
||||
genMontyMagics(Curve)
|
||||
|
||||
macro getR2modP*(C: static Curve): untyped =
|
||||
## Get the Montgomery Magic Constant Associated to a curve
|
||||
## Get the Montgomery "R^2 mod P" constant associated to a curve field modulus
|
||||
result = bindSym($C & "_R2modP")
|
||||
|
||||
macro getNegInvModWord*(C: static Curve): untyped =
|
||||
## Get the Montgomery "-1/P[0] mod 2^WordBitSize" constant associated to a curve field modulus
|
||||
result = bindSym($C & "_NegInvModWord")
|
||||
|
|
|
@ -58,7 +58,6 @@ macro declareCurves*(curves: untyped): untyped =
|
|||
var Curves: seq[NimNode]
|
||||
var CurveBitSize = nnKBracket.newTree()
|
||||
var curveModStmts = newStmtList()
|
||||
var curveModWhenStmt = nnkIfStmt.newTree()
|
||||
|
||||
let Fq = ident"Fq"
|
||||
|
||||
|
@ -105,15 +104,6 @@ macro declareCurves*(curves: untyped): untyped =
|
|||
)
|
||||
)
|
||||
|
||||
# when curve == BN254: BN254_Modulus
|
||||
curveModWhenStmt.add nnkElifBranch.newTree(
|
||||
nnkInfix.newTree(
|
||||
ident"==",
|
||||
ident"curve",
|
||||
curve
|
||||
),
|
||||
newAssignment(ident"result", modulusID)
|
||||
)
|
||||
# end for ---------------------------------------------------
|
||||
|
||||
result = newStmtList()
|
||||
|
@ -172,29 +162,6 @@ macro declareCurves*(curves: untyped): untyped =
|
|||
)
|
||||
)
|
||||
|
||||
# Add 'else: error"Unreachable" to the when statements
|
||||
curveModWhenStmt.add nnkElse.newTree(
|
||||
newCall(
|
||||
bindSym"error",
|
||||
newLit"Unreachable: the curve does not exist."
|
||||
)
|
||||
)
|
||||
|
||||
result.add curveModStmts
|
||||
|
||||
# proc Mod(curve: static Curve): auto
|
||||
result.add newProc(
|
||||
name = nnkPostfix.newTree(ident"*", ident"Mod"),
|
||||
params = [
|
||||
ident"auto",
|
||||
newIdentDefs(
|
||||
name = ident"curve",
|
||||
kind = ident"Curve"
|
||||
)
|
||||
],
|
||||
body = curveModWhenStmt,
|
||||
procType = nnkFuncDef,
|
||||
pragmas = nnkPragma.newTree(ident"compileTime")
|
||||
)
|
||||
|
||||
# echo result.toStrLit()
|
||||
|
|
|
@ -22,7 +22,7 @@ func fromUint*(dst: var Fq,
|
|||
## Parse a regular unsigned integer
|
||||
## and store it into a BigInt of size `bits`
|
||||
let raw = (type dst.mres).fromRawUint(cast[array[sizeof(src), byte]](src), cpuEndian)
|
||||
dst.mres.unsafeMontyResidue(raw, Fq.C.Mod.mres, Fq.C.getR2modP(), MontyNegInvModWord[Fq.C])
|
||||
dst.mres.unsafeMontyResidue(raw, Fq.C.Mod.mres, Fq.C.getR2modP(), Fq.C.getNegInvModWord())
|
||||
|
||||
func serializeRawUint*(dst: var openarray[byte],
|
||||
src: Fq,
|
||||
|
|
|
@ -51,12 +51,12 @@ debug:
|
|||
|
||||
func fromBig*(T: type Fq, src: BigInt): T =
|
||||
## Convert a BigInt to its Montgomery form
|
||||
result.mres.unsafeMontyResidue(src, Fq.C.Mod.mres, Fq.C.getR2modP(), MontyNegInvModWord[Fq.C])
|
||||
result.mres.unsafeMontyResidue(src, Fq.C.Mod.mres, Fq.C.getR2modP(), Fq.C.getNegInvModWord())
|
||||
|
||||
func toBig*(src: Fq): auto =
|
||||
## Convert a finite-field element to a BigInt in natral representation
|
||||
result = src.mres
|
||||
result.unsafeRedC(Fq.C.Mod.mres, MontyNegInvModWord[Fq.C])
|
||||
result.unsafeRedC(Fq.C.Mod.mres, Fq.C.getNegInvModWord())
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
|
@ -114,4 +114,4 @@ func `*`*(a, b: Fq): Fq {.noInit.} =
|
|||
## as Fq elements are usually large and this
|
||||
## routine will zero init internally the result.
|
||||
result.mres.setInternalBitLength()
|
||||
result.mres.montyMul(a.mres, b.mres, Fq.C.Mod.mres, MontyNegInvModWord[Fq.C])
|
||||
result.mres.montyMul(a.mres, b.mres, Fq.C.Mod.mres, Fq.C.getNegInvModWord())
|
||||
|
|
Loading…
Reference in New Issue