Create a specialized montgomery modular square function

This commit is contained in:
Mamy André-Ratsimbazafy 2020-02-23 01:43:42 +01:00
parent c807707ee4
commit dc46e86490
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
3 changed files with 27 additions and 2 deletions

View File

@ -158,7 +158,12 @@ func montyMul*[mBits](r: var BigInt[mBits], a, b, M: BigInt[mBits], negInvModWor
## to avoid duplicating with Nim zero-init policy ## to avoid duplicating with Nim zero-init policy
montyMul(r.view, a.view, b.view, M.view, Word(negInvModWord)) montyMul(r.view, a.view, b.view, M.view, Word(negInvModWord))
import stew/byteutils func montySquare*[mBits](r: var BigInt[mBits], a, M: BigInt[mBits], negInvModWord: static BaseType) =
## Compute r <- a^2 (mod M) in the Montgomery domain
##
## This resets r to zero before processing. Use {.noInit.}
## to avoid duplicating with Nim zero-init policy
montySquare(r.view, a.view, M.view, Word(negInvModWord))
func montyPow*[mBits, eBits: static int]( func montyPow*[mBits, eBits: static int](
a: var BigInt[mBits], exponent: BigInt[eBits], a: var BigInt[mBits], exponent: BigInt[eBits],

View File

@ -550,6 +550,17 @@ func montyResidue*(
montyMul(r, a, r2ModN, N, negInvModWord) montyMul(r, a, r2ModN, N, negInvModWord)
func montySquare(
r: BigIntViewMut, a: BigIntViewAny,
M: BigIntViewConst, negInvModWord: Word) {.inline.} =
## Compute r <- a^2 (mod M) in the Montgomery domain
## `negInvModWord` = -1/M (mod Word). Our words are 2^31 or 2^63
# TODO: specialized implementation when optimizing for speed
# and montyMul when optimizing for size
# - https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-large-integer-arithmetic-paper.pdf
montyMul(r, a, a, M, negInvModWord)
# Montgomery Modular Exponentiation # Montgomery Modular Exponentiation
# ------------------------------------------ # ------------------------------------------
# We use fixed-window based exponentiation # We use fixed-window based exponentiation
@ -664,7 +675,7 @@ func montyPowSquarings(
# We have k bits and can do k squaring # We have k bits and can do k squaring
for i in 0 ..< k: for i in 0 ..< k:
tmp.montyMul(a, a, M, negInvModWord) tmp.montySquare(a, M, negInvModWord)
copyMem(pointer a, pointer tmp, bigIntSize) copyMem(pointer a, pointer tmp, bigIntSize)
return (k, bits) return (k, bits)

View File

@ -129,6 +129,15 @@ func `*`*(a, b: Fq): Fq {.noInit.} =
result.mres.setInternalBitLength() result.mres.setInternalBitLength()
result.mres.montyMul(a.mres, b.mres, Fq.C.Mod.mres, Fq.C.getNegInvModWord()) result.mres.montyMul(a.mres, b.mres, Fq.C.Mod.mres, Fq.C.getNegInvModWord())
func square*(a: Fq): Fq {.noInit.} =
## Squaring over Fq
##
## It is recommended to assign with {.noInit.}
## as Fq elements are usually large and this
## routine will zero init internally the result.
result.mres.setInternalBitLength()
result.mres.montySquare(a.mres, Fq.C.Mod.mres, Fq.C.getNegInvModWord())
func pow*(a: var Fq, exponent: BigInt) = func pow*(a: var Fq, exponent: BigInt) =
## Exponentiation over Fq ## Exponentiation over Fq
## ``a``: a field element to be exponentiated ## ``a``: a field element to be exponentiated