mirror of
https://github.com/codex-storage/constantine.git
synced 2025-02-06 16:05:05 +00:00
Create a specialized montgomery modular square function
This commit is contained in:
parent
c807707ee4
commit
dc46e86490
@ -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
|
||||
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](
|
||||
a: var BigInt[mBits], exponent: BigInt[eBits],
|
||||
|
@ -550,6 +550,17 @@ func montyResidue*(
|
||||
|
||||
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
|
||||
# ------------------------------------------
|
||||
# We use fixed-window based exponentiation
|
||||
@ -664,7 +675,7 @@ func montyPowSquarings(
|
||||
|
||||
# We have k bits and can do k squaring
|
||||
for i in 0 ..< k:
|
||||
tmp.montyMul(a, a, M, negInvModWord)
|
||||
tmp.montySquare(a, M, negInvModWord)
|
||||
copyMem(pointer a, pointer tmp, bigIntSize)
|
||||
|
||||
return (k, bits)
|
||||
|
@ -129,6 +129,15 @@ func `*`*(a, b: Fq): Fq {.noInit.} =
|
||||
result.mres.setInternalBitLength()
|
||||
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) =
|
||||
## Exponentiation over Fq
|
||||
## ``a``: a field element to be exponentiated
|
||||
|
Loading…
x
Reference in New Issue
Block a user