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:
Mamy André-Ratsimbazafy 2020-02-25 01:26:21 +01:00
parent 5b53ad9cf3
commit bb8dc579ea
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
4 changed files with 45 additions and 45 deletions

View File

@ -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`

View File

@ -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,

View File

@ -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

View File

@ -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: