Do less in curve generator macro:
- no more monty magic "negInvModWord" - no public "matchingBigInt" Improve comment on Montgomery procedures
This commit is contained in:
parent
398b871c4f
commit
d3ad4acb3a
|
@ -32,14 +32,10 @@ import
|
||||||
# Barbulescu, R. and S. Duquesne, "Updating Key Size Estimations for Pairings",
|
# Barbulescu, R. and S. Duquesne, "Updating Key Size Estimations for Pairings",
|
||||||
# Journal of Cryptology, DOI 10.1007/s00145-018-9280-5, January 2018.
|
# Journal of Cryptology, DOI 10.1007/s00145-018-9280-5, January 2018.
|
||||||
|
|
||||||
# Generates:
|
# Generates public:
|
||||||
# - type Curve = enum
|
# - type Curve* = enum
|
||||||
# - const CurveBitSize: array[Curve, int]
|
# - proc Mod*(curve: static Curve): auto
|
||||||
# - proc Mod(curve: static Curve): auto
|
|
||||||
# which returns the field modulus of the curve
|
# which returns the field modulus of the curve
|
||||||
# - proc negInvModWord(curve: static Curve): static Word =
|
|
||||||
# which returns the Montgomery magic constant
|
|
||||||
# associated with the curve modulus
|
|
||||||
when not defined(testingCurves):
|
when not defined(testingCurves):
|
||||||
declareCurves:
|
declareCurves:
|
||||||
# Barreto-Naehrig curve, pairing-friendly, Prime 254 bit, ~100-bit security
|
# Barreto-Naehrig curve, pairing-friendly, Prime 254 bit, ~100-bit security
|
||||||
|
|
|
@ -127,7 +127,7 @@ macro declareCurves*(curves: untyped): untyped =
|
||||||
pure = false
|
pure = false
|
||||||
)
|
)
|
||||||
|
|
||||||
# const CurveBitSize*: array[Curve, int] = ...
|
# const CurveBitSize: array[Curve, int] = ...
|
||||||
let cbs = ident("CurveBitSize")
|
let cbs = ident("CurveBitSize")
|
||||||
result.add newConstStmt(
|
result.add newConstStmt(
|
||||||
cbs, CurveBitSize
|
cbs, CurveBitSize
|
||||||
|
@ -137,9 +137,9 @@ macro declareCurves*(curves: untyped): untyped =
|
||||||
# template matchingBigInt(C: static Curve): untyped =
|
# template matchingBigInt(C: static Curve): untyped =
|
||||||
# BigInt[CurveBitSize[C]]
|
# BigInt[CurveBitSize[C]]
|
||||||
let C = ident"C"
|
let C = ident"C"
|
||||||
let matchingBigInt = ident"matchingBigInt"
|
let matchingBigInt = genSym(nskTemplate, "matchingBigInt")
|
||||||
result.add newProc(
|
result.add newProc(
|
||||||
name = nnkPostFix.newTree(ident"*", matchingBigInt),
|
name = matchingBigInt,
|
||||||
params = [ident"untyped", newIdentDefs(C, nnkStaticTy.newTree(Curve))],
|
params = [ident"untyped", newIdentDefs(C, nnkStaticTy.newTree(Curve))],
|
||||||
body = nnkBracketExpr.newTree(bindSym"BigInt", nnkBracketExpr.newTree(cbs, C)),
|
body = nnkBracketExpr.newTree(bindSym"BigInt", nnkBracketExpr.newTree(cbs, C)),
|
||||||
procType = nnkTemplateDef
|
procType = nnkTemplateDef
|
||||||
|
@ -198,26 +198,4 @@ macro declareCurves*(curves: untyped): untyped =
|
||||||
procType = nnkFuncDef
|
procType = nnkFuncDef
|
||||||
)
|
)
|
||||||
|
|
||||||
# proc negInvModWord(curve: static Curve): static Word
|
|
||||||
result.add newProc(
|
|
||||||
name = nnkPostfix.newTree(ident"*", ident"negInvModWord"),
|
|
||||||
params = [
|
|
||||||
ident"auto",
|
|
||||||
newIdentDefs(
|
|
||||||
name = ident"curve",
|
|
||||||
kind = nnkStaticTy.newTree(ident"Curve")
|
|
||||||
)
|
|
||||||
],
|
|
||||||
body = newCall(
|
|
||||||
ident"negInvModWord",
|
|
||||||
# curve.Mod().nres
|
|
||||||
nnkDotExpr.newTree(
|
|
||||||
newCall(ident"Mod", ident"curve"),
|
|
||||||
ident"nres"
|
|
||||||
)
|
|
||||||
|
|
||||||
),
|
|
||||||
procType = nnkFuncDef
|
|
||||||
)
|
|
||||||
|
|
||||||
# echo result.toStrLit()
|
# echo result.toStrLit()
|
||||||
|
|
|
@ -396,8 +396,11 @@ func reduce*(r: BigIntViewMut, a: BigIntViewAny, M: BigIntViewConst) =
|
||||||
func montgomeryResidue*(a: BigIntViewMut, N: BigIntViewConst) =
|
func montgomeryResidue*(a: BigIntViewMut, N: BigIntViewConst) =
|
||||||
## Transform a bigint ``a`` from it's natural representation (mod N)
|
## Transform a bigint ``a`` from it's natural representation (mod N)
|
||||||
## to a the Montgomery n-residue representation
|
## to a the Montgomery n-residue representation
|
||||||
## i.e. Does "a * (2^LimbSize)^W (mod N), where W is the number
|
##
|
||||||
## of words needed to represent n in base 2^LimbSize
|
## with W = N.numLimbs()
|
||||||
|
## and R = (2^WordBitSize)^W
|
||||||
|
##
|
||||||
|
## Does "a * R (mod N)"
|
||||||
##
|
##
|
||||||
## `a`: The source BigInt in the natural representation. `a` in [0, N) range
|
## `a`: The source BigInt in the natural representation. `a` in [0, N) range
|
||||||
## `N`: The field modulus. N must be odd.
|
## `N`: The field modulus. N must be odd.
|
||||||
|
@ -419,8 +422,10 @@ func redc*(a: BigIntViewMut, N: BigIntViewConst, negInvModWord: Word) =
|
||||||
## Transform a bigint ``a`` from it's Montgomery N-residue representation (mod N)
|
## Transform a bigint ``a`` from it's Montgomery N-residue representation (mod N)
|
||||||
## to the regular natural representation (mod N)
|
## to the regular natural representation (mod N)
|
||||||
##
|
##
|
||||||
## i.e. Does "a * ((2^LimbSize)^W)^-1 (mod N), where W is the number
|
## with W = N.numLimbs()
|
||||||
## of words needed to represent n in base 2^LimbSize
|
## and R = (2^WordBitSize)^W
|
||||||
|
##
|
||||||
|
## Does "a * R^-1 (mod N)"
|
||||||
##
|
##
|
||||||
## This is called a Montgomery Reduction
|
## This is called a Montgomery Reduction
|
||||||
## The Montgomery Magic Constant is µ = -1/N mod N
|
## The Montgomery Magic Constant is µ = -1/N mod N
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
import
|
import
|
||||||
../primitives/constant_time,
|
../primitives/constant_time,
|
||||||
../config/[common, curves],
|
../config/[common, curves],
|
||||||
./bigints_checked
|
./bigints_checked, ./precomputed
|
||||||
|
|
||||||
# type
|
# type
|
||||||
# `Fq`*[C: static Curve] = object
|
# `Fq`*[C: static Curve] = object
|
||||||
|
@ -54,10 +54,10 @@ func fromBig*(T: type Fq, src: BigInt): T =
|
||||||
result.nres = src
|
result.nres = src
|
||||||
result.nres.unsafeMontgomeryResidue(Fq.C.Mod)
|
result.nres.unsafeMontgomeryResidue(Fq.C.Mod)
|
||||||
|
|
||||||
func toBig*[C: static Curve](src: Fq[C]): 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.nres
|
result = src.nres
|
||||||
result.unsafeRedC(C.Mod.nres, negInvModWord(C))
|
result.unsafeRedC(Fq.C.Mod.nres, Fq.C.Mod.nres.negInvModWord())
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
|
@ -88,6 +88,14 @@ template sub(a: var Fq, b: Fq, ctl: CTBool[Word]): CTBool[Word] =
|
||||||
# Field arithmetic primitives
|
# Field arithmetic primitives
|
||||||
#
|
#
|
||||||
# ############################################################
|
# ############################################################
|
||||||
|
#
|
||||||
|
# Note: the library currently implements generic routine for odd field modulus.
|
||||||
|
# Routines for special field modulus form:
|
||||||
|
# - Mersenne Prime (2^k - 1),
|
||||||
|
# - Generalized Mersenne Prime (NIST Prime P256: 2^256 - 2^224 + 2^192 + 2^96 - 1)
|
||||||
|
# - Pseudo-Mersenne Prime (2^m - k for example Curve25519: 2^255 - 19)
|
||||||
|
# - Golden Primes (φ^2 - φ - 1 with φ = 2^k for example Ed448-Goldilocks: 2^448 - 2^224 - 1)
|
||||||
|
# exist and can be implemented with compile-time specialization.
|
||||||
|
|
||||||
func `+=`*(a: var Fq, b: Fq) =
|
func `+=`*(a: var Fq, b: Fq) =
|
||||||
## Addition over Fq
|
## Addition over Fq
|
||||||
|
@ -107,4 +115,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.nres.setInternalBitLength()
|
result.nres.setInternalBitLength()
|
||||||
result.nres.montyMul(a.nres, b.nres, Fq.C.Mod.nres, negInvModWord(Fq.C))
|
result.nres.montyMul(a.nres, b.nres, Fq.C.Mod.nres, Fq.C.Mod.nres.negInvModWord())
|
||||||
|
|
|
@ -20,10 +20,11 @@ import
|
||||||
#
|
#
|
||||||
# ############################################################
|
# ############################################################
|
||||||
|
|
||||||
# Note: The declareCurve macro builds an exported negInvModWord*(C: static Curve) on top of the one below
|
|
||||||
func negInvModWord*(M: BigInt): BaseType =
|
func negInvModWord*(M: BigInt): BaseType =
|
||||||
## Returns the Montgomery domain magic constant for the input modulus:
|
## Returns the Montgomery domain magic constant for the input modulus:
|
||||||
## -1/M[0] mod LimbSize
|
##
|
||||||
|
## µ = -1/M[0] mod M
|
||||||
|
##
|
||||||
## M[0] is the least significant limb of M
|
## M[0] is the least significant limb of M
|
||||||
## M must be odd and greater than 2.
|
## M must be odd and greater than 2.
|
||||||
# We use BaseType for return value because static distinct type
|
# We use BaseType for return value because static distinct type
|
||||||
|
|
Loading…
Reference in New Issue