mirror of
https://github.com/status-im/constantine.git
synced 2025-02-23 09:28:07 +00:00
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
|
bitsize: 254
|
||||||
modulus: "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
modulus: "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
||||||
# Equation: Y^2 = X^3 + 3
|
# Equation: Y^2 = X^3 + 3
|
||||||
|
curve BLS12_381:
|
||||||
|
bitsize: 381
|
||||||
|
modulus: "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
# Equation: y^2 = x^3 + 4
|
||||||
else:
|
else:
|
||||||
# Fake curve for testing field arithmetic
|
# Fake curve for testing field arithmetic
|
||||||
declareCurves:
|
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".}
|
{.experimental: "dynamicBindSym".}
|
||||||
|
|
||||||
macro genR2modP(T: typed): untyped =
|
macro Mod*(C: static Curve): untyped =
|
||||||
## Store the Montgomery Magic Constant "R^2 mod N" in ROM
|
## Get the Modulus associated to a curve
|
||||||
## For each curve under the private symbol "MyCurve_R2modP"
|
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.expectKind(nnkTypeDef)
|
||||||
T.getImpl[2].expectKind(nnkEnumTy)
|
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
|
# echo result.toStrLit
|
||||||
|
|
||||||
genR2modP(Curve)
|
genMontyMagics(Curve)
|
||||||
|
|
||||||
macro getR2modP*(C: static Curve): untyped =
|
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")
|
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 Curves: seq[NimNode]
|
||||||
var CurveBitSize = nnKBracket.newTree()
|
var CurveBitSize = nnKBracket.newTree()
|
||||||
var curveModStmts = newStmtList()
|
var curveModStmts = newStmtList()
|
||||||
var curveModWhenStmt = nnkIfStmt.newTree()
|
|
||||||
|
|
||||||
let Fq = ident"Fq"
|
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 ---------------------------------------------------
|
# end for ---------------------------------------------------
|
||||||
|
|
||||||
result = newStmtList()
|
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
|
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()
|
# echo result.toStrLit()
|
||||||
|
@ -22,7 +22,7 @@ func fromUint*(dst: var Fq,
|
|||||||
## Parse a regular unsigned integer
|
## Parse a regular unsigned integer
|
||||||
## and store it into a BigInt of size `bits`
|
## and store it into a BigInt of size `bits`
|
||||||
let raw = (type dst.mres).fromRawUint(cast[array[sizeof(src), byte]](src), cpuEndian)
|
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],
|
func serializeRawUint*(dst: var openarray[byte],
|
||||||
src: Fq,
|
src: Fq,
|
||||||
|
@ -51,12 +51,12 @@ debug:
|
|||||||
|
|
||||||
func fromBig*(T: type Fq, src: BigInt): T =
|
func fromBig*(T: type Fq, src: BigInt): T =
|
||||||
## Convert a BigInt to its Montgomery form
|
## 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 =
|
func toBig*(src: Fq): auto =
|
||||||
## Convert a finite-field element to a BigInt in natral representation
|
## Convert a finite-field element to a BigInt in natral representation
|
||||||
result = src.mres
|
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
|
## as Fq elements are usually large and this
|
||||||
## routine will zero init internally the result.
|
## routine will zero init internally the result.
|
||||||
result.mres.setInternalBitLength()
|
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…
x
Reference in New Issue
Block a user