conditional arithmetic prefixed with c: cadd, csub. Also use ccopy instead of cmov to avoid potential confusion like in https://github.com/cfrg/draft-irtf-cfrg-hash-to-curve/issues/210
This commit is contained in:
parent
5b53ad9cf3
commit
bb8dc579ea
|
@ -113,23 +113,23 @@ func setOne*(a: var BigInt) =
|
|||
when a.limbs.len > 1:
|
||||
zeroMem(a.limbs[1].unsafeAddr, (a.limbs.len-1) * sizeof(Word))
|
||||
|
||||
func add*[bits](a: var BigInt[bits], b: BigInt[bits], ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time big integer in-place optional addition
|
||||
func cadd*[bits](a: var BigInt[bits], b: BigInt[bits], ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time in-place conditional addition
|
||||
## The addition is only performed if ctl is "true"
|
||||
## The result carry is always computed.
|
||||
add(a.view, b.view, ctl)
|
||||
cadd(a.view, b.view, ctl)
|
||||
|
||||
func sub*[bits](a: var BigInt[bits], b: BigInt[bits], ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time big integer in-place optional addition
|
||||
func csub*[bits](a: var BigInt[bits], b: BigInt[bits], ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time in-place conditional addition
|
||||
## The addition is only performed if ctl is "true"
|
||||
## The result carry is always computed.
|
||||
sub(a.view, b.view, ctl)
|
||||
csub(a.view, b.view, ctl)
|
||||
|
||||
func double*[bits](a: var BigInt[bits], ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time big integer in-place optional doubling
|
||||
func cdouble*[bits](a: var BigInt[bits], ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time in-place conditional doubling
|
||||
## The doubling is only performed if ctl is "true"
|
||||
## The result carry is always computed.
|
||||
add(a.view, a.view, ctl)
|
||||
cadd(a.view, a.view, ctl)
|
||||
|
||||
func reduce*[aBits, mBits](r: var BigInt[mBits], a: BigInt[aBits], M: BigInt[mBits]) =
|
||||
## Reduce `a` modulo `M` and store the result in `r`
|
||||
|
|
|
@ -228,7 +228,7 @@ func setZero(a: BigIntViewMut) =
|
|||
## It's bit size is unchanged
|
||||
zeroMem(a[0].unsafeAddr, a.numLimbs() * sizeof(Word))
|
||||
|
||||
func cmov*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]) =
|
||||
func ccopy*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]) =
|
||||
## Constant-time conditional copy
|
||||
## If ctl is true: b is copied into a
|
||||
## if ctl is false: b is not copied and a is untouched
|
||||
|
@ -241,8 +241,8 @@ func cmov*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]) =
|
|||
# if it is a placebo operation. It stills performs the
|
||||
# same memory accesses to be side-channel attack resistant.
|
||||
|
||||
func add*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time big integer in-place optional addition
|
||||
func cadd*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time in-place conditional addition
|
||||
## The addition is only performed if ctl is "true"
|
||||
## The result carry is always computed.
|
||||
##
|
||||
|
@ -255,8 +255,8 @@ func add*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
|
|||
result = new_a.isMsbSet()
|
||||
a[i] = ctl.mux(new_a.mask(), a[i])
|
||||
|
||||
func sub*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time big integer in-place optional substraction
|
||||
func csub*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time in-place conditional substraction
|
||||
## The substraction is only performed if ctl is "true"
|
||||
## The result carry is always computed.
|
||||
##
|
||||
|
@ -395,8 +395,8 @@ func shlAddMod(a: BigIntViewMut, c: Word, M: BigIntViewConst) =
|
|||
let neg = carry > hi
|
||||
let tooBig = not neg and (over_p or (carry < hi))
|
||||
|
||||
discard a.add(M, ctl = neg)
|
||||
discard a.sub(M, ctl = tooBig)
|
||||
discard a.cadd(M, ctl = neg)
|
||||
discard a.csub(M, ctl = tooBig)
|
||||
return
|
||||
|
||||
func reduce*(r: BigIntViewMut, a: BigIntViewAny, M: BigIntViewConst) =
|
||||
|
@ -496,7 +496,7 @@ func montyMul*(
|
|||
|
||||
# If the extra word is not zero or if r-M does not borrow (i.e. r > M)
|
||||
# Then substract M
|
||||
discard r.sub(M, r_hi.isNonZero() or not r.sub(M, CtFalse))
|
||||
discard r.csub(M, r_hi.isNonZero() or not r.csub(M, CtFalse))
|
||||
|
||||
func redc*(r: BigIntViewMut, a: BigIntViewAny, one, N: BigIntViewConst, negInvModWord: Word) {.inline.} =
|
||||
## Transform a bigint ``a`` from it's Montgomery N-residue representation (mod N)
|
||||
|
@ -573,7 +573,7 @@ func montySquare(
|
|||
# and k the window-size
|
||||
# - we always multiply even for unused multiplications
|
||||
# - conditional copy only save a small fraction of time
|
||||
# (multiplication O(n²), cmov O(n), doing nothing i.e. non constant-time O(n))
|
||||
# (multiplication O(n²), ccopy O(n), doing nothing i.e. non constant-time O(n))
|
||||
# - Table lookup is O(kn) copy time since we need to access the whole table to
|
||||
# defeat cache attacks. Without windows, we don't have table lookups at all.
|
||||
#
|
||||
|
@ -738,12 +738,12 @@ func montyPow*(
|
|||
# just index the openarray with the bits to avoid cache attacks.
|
||||
for i in 1 ..< 1 shl k:
|
||||
let ctl = Word(i) == Word(bits)
|
||||
scratchspace[1].cmov(scratchspace[1+i], ctl)
|
||||
scratchspace[1].ccopy(scratchspace[1+i], ctl)
|
||||
|
||||
# Multiply with the looked-up value
|
||||
# we keep the product only if the exponent bits are not all zero
|
||||
scratchspace[0].montyMul(a, scratchspace[1], M, negInvModWord)
|
||||
a.cmov(scratchspace[0], Word(bits) != Zero)
|
||||
a.ccopy(scratchspace[0], Word(bits) != Zero)
|
||||
|
||||
func montyPowUnsafeExponent*(
|
||||
a: BigIntViewMut,
|
||||
|
|
|
@ -81,23 +81,23 @@ func toBig*(src: Fp): auto {.noInit.} =
|
|||
#
|
||||
# ############################################################
|
||||
|
||||
template add(a: var Fp, b: Fp, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time big integer in-place optional addition
|
||||
template cadd(a: var Fp, b: Fp, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time in-place conditional addition
|
||||
## The addition is only performed if ctl is "true"
|
||||
## The result carry is always computed.
|
||||
##
|
||||
## a and b MAY be the same buffer
|
||||
## a and b MUST have the same announced bitlength (i.e. `bits` static parameters)
|
||||
add(a.mres, b.mres, ctl)
|
||||
cadd(a.mres, b.mres, ctl)
|
||||
|
||||
template sub(a: var Fp, b: Fp, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time big integer in-place optional substraction
|
||||
template csub(a: var Fp, b: Fp, ctl: CTBool[Word]): CTBool[Word] =
|
||||
## Constant-time in-place conditional substraction
|
||||
## The substraction is only performed if ctl is "true"
|
||||
## The result carry is always computed.
|
||||
##
|
||||
## a and b MAY be the same buffer
|
||||
## a and b MUST have the same announced bitlength (i.e. `bits` static parameters)
|
||||
sub(a.mres, b.mres, ctl)
|
||||
csub(a.mres, b.mres, ctl)
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
|
@ -124,20 +124,20 @@ func setOne*(a: var Fp) =
|
|||
|
||||
func `+=`*(a: var Fp, b: Fp) =
|
||||
## Addition modulo p
|
||||
var ctl = add(a, b, CtTrue)
|
||||
ctl = ctl or not sub(a, Fp.C.Mod, CtFalse)
|
||||
discard sub(a, Fp.C.Mod, ctl)
|
||||
var ctl = cadd(a, b, CtTrue)
|
||||
ctl = ctl or not csub(a, Fp.C.Mod, CtFalse)
|
||||
discard csub(a, Fp.C.Mod, ctl)
|
||||
|
||||
func `-=`*(a: var Fp, b: Fp) =
|
||||
## Substraction modulo p
|
||||
let ctl = sub(a, b, CtTrue)
|
||||
discard add(a, Fp.C.Mod, ctl)
|
||||
let ctl = csub(a, b, CtTrue)
|
||||
discard cadd(a, Fp.C.Mod, ctl)
|
||||
|
||||
func double*(a: var Fp) =
|
||||
## Double ``a`` modulo p
|
||||
var ctl = double(a, CtTrue)
|
||||
ctl = ctl or not sub(a, Fp.C.Mod, CtFalse)
|
||||
discard sub(a, Fp.C.Mod, ctl)
|
||||
var ctl = cdouble(a, CtTrue)
|
||||
ctl = ctl or not csub(a, Fp.C.Mod, CtFalse)
|
||||
discard csub(a, Fp.C.Mod, ctl)
|
||||
|
||||
func `*`*(a, b: Fp): Fp {.noInit.} =
|
||||
## Multiplication modulo p
|
||||
|
|
|
@ -32,14 +32,14 @@ proc main() =
|
|||
test "Adding 2 zeros":
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||
let carry = a.add(b, ctrue(Word))
|
||||
let carry = a.cadd(b, ctrue(Word))
|
||||
check: a.isZero().bool
|
||||
|
||||
test "Adding 1 zero - real addition":
|
||||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let carry = a.add(b, ctrue(Word))
|
||||
let carry = a.cadd(b, ctrue(Word))
|
||||
|
||||
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
check:
|
||||
|
@ -47,7 +47,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||
let carry = a.add(b, ctrue(Word))
|
||||
let carry = a.cadd(b, ctrue(Word))
|
||||
|
||||
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
check:
|
||||
|
@ -57,7 +57,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let carry = a.add(b, cfalse(Word))
|
||||
let carry = a.cadd(b, cfalse(Word))
|
||||
|
||||
let c = a
|
||||
check:
|
||||
|
@ -65,7 +65,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||
let carry = a.add(b, cfalse(Word))
|
||||
let carry = a.cadd(b, cfalse(Word))
|
||||
|
||||
let c = a
|
||||
check:
|
||||
|
@ -75,7 +75,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let carry = a.add(b, ctrue(Word))
|
||||
let carry = a.cadd(b, ctrue(Word))
|
||||
|
||||
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
||||
check:
|
||||
|
@ -83,7 +83,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||
let carry = a.add(b, ctrue(Word))
|
||||
let carry = a.cadd(b, ctrue(Word))
|
||||
|
||||
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
||||
check:
|
||||
|
@ -93,7 +93,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let carry = a.add(b, cfalse(Word))
|
||||
let carry = a.cadd(b, cfalse(Word))
|
||||
|
||||
let c = a
|
||||
check:
|
||||
|
@ -101,7 +101,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||
let carry = a.add(b, cfalse(Word))
|
||||
let carry = a.cadd(b, cfalse(Word))
|
||||
|
||||
let c = a
|
||||
check:
|
||||
|
@ -111,7 +111,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFE")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let carry = a.add(b, ctrue(Word))
|
||||
let carry = a.cadd(b, ctrue(Word))
|
||||
|
||||
let c = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
||||
check:
|
||||
|
@ -121,7 +121,7 @@ proc main() =
|
|||
block:
|
||||
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||
let carry = a.add(b, ctrue(Word))
|
||||
let carry = a.cadd(b, ctrue(Word))
|
||||
|
||||
let c = fromHex(BigInt[128], "0x00000001_00000000_00000000_00000000")
|
||||
check:
|
||||
|
|
Loading…
Reference in New Issue