Do less in curve generator macro:

- no more monty magic "negInvModWord"
- no public "matchingBigInt"

Improve comment on Montgomery procedures
This commit is contained in:
Mamy André-Ratsimbazafy 2020-02-15 13:56:13 +01:00
parent 398b871c4f
commit d3ad4acb3a
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
5 changed files with 30 additions and 42 deletions

View File

@ -32,14 +32,10 @@ import
# Barbulescu, R. and S. Duquesne, "Updating Key Size Estimations for Pairings",
# Journal of Cryptology, DOI 10.1007/s00145-018-9280-5, January 2018.
# Generates:
# - type Curve = enum
# - const CurveBitSize: array[Curve, int]
# - proc Mod(curve: static Curve): auto
# Generates public:
# - type Curve* = enum
# - proc Mod*(curve: static Curve): auto
# 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):
declareCurves:
# Barreto-Naehrig curve, pairing-friendly, Prime 254 bit, ~100-bit security

View File

@ -127,7 +127,7 @@ macro declareCurves*(curves: untyped): untyped =
pure = false
)
# const CurveBitSize*: array[Curve, int] = ...
# const CurveBitSize: array[Curve, int] = ...
let cbs = ident("CurveBitSize")
result.add newConstStmt(
cbs, CurveBitSize
@ -137,9 +137,9 @@ macro declareCurves*(curves: untyped): untyped =
# template matchingBigInt(C: static Curve): untyped =
# BigInt[CurveBitSize[C]]
let C = ident"C"
let matchingBigInt = ident"matchingBigInt"
let matchingBigInt = genSym(nskTemplate, "matchingBigInt")
result.add newProc(
name = nnkPostFix.newTree(ident"*", matchingBigInt),
name = matchingBigInt,
params = [ident"untyped", newIdentDefs(C, nnkStaticTy.newTree(Curve))],
body = nnkBracketExpr.newTree(bindSym"BigInt", nnkBracketExpr.newTree(cbs, C)),
procType = nnkTemplateDef
@ -198,26 +198,4 @@ macro declareCurves*(curves: untyped): untyped =
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()

View File

@ -396,8 +396,11 @@ func reduce*(r: BigIntViewMut, a: BigIntViewAny, M: BigIntViewConst) =
func montgomeryResidue*(a: BigIntViewMut, N: BigIntViewConst) =
## Transform a bigint ``a`` from it's natural representation (mod N)
## 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
## `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)
## to the regular natural representation (mod N)
##
## i.e. Does "a * ((2^LimbSize)^W)^-1 (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^-1 (mod N)"
##
## This is called a Montgomery Reduction
## The Montgomery Magic Constant is µ = -1/N mod N

View File

@ -23,7 +23,7 @@
import
../primitives/constant_time,
../config/[common, curves],
./bigints_checked
./bigints_checked, ./precomputed
# type
# `Fq`*[C: static Curve] = object
@ -54,10 +54,10 @@ func fromBig*(T: type Fq, src: BigInt): T =
result.nres = src
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
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
#
# ############################################################
#
# 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) =
## Addition over Fq
@ -107,4 +115,4 @@ func `*`*(a, b: Fq): Fq {.noInit.} =
## as Fq elements are usually large and this
## routine will zero init internally the result.
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())

View File

@ -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 =
## 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 must be odd and greater than 2.
# We use BaseType for return value because static distinct type