Use cmov name instead of mux to be in line with IETF spec on Hash to curve and Verifiable Random Functions

This commit is contained in:
Mamy André-Ratsimbazafy 2020-02-16 21:34:21 +01:00
parent a1801e26a0
commit 56177c0cfe
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
3 changed files with 29 additions and 22 deletions

View File

@ -233,7 +233,7 @@ func add*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
for i in 0 ..< a.numLimbs():
let new_a = a[i] + b[i] + Word(result)
result = new_a.isMsbSet()
a[i] = ctl.mux(new_a and MaxWord, a[i])
a[i] = ctl.cmov(new_a and MaxWord, a[i])
func sub*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
## Constant-time big integer in-place optional substraction
@ -247,7 +247,7 @@ func sub*(a: BigIntViewMut, b: BigIntViewAny, ctl: CTBool[Word]): CTBool[Word] =
for i in 0 ..< a.numLimbs():
let new_a = a[i] - b[i] - Word(result)
result = new_a.isMsbSet()
a[i] = ctl.mux(new_a and MaxWord, a[i])
a[i] = ctl.cmov(new_a and MaxWord, a[i])
# ############################################################
#
@ -306,9 +306,9 @@ func shlAddMod(a: BigIntViewMut, c: Word, M: BigIntViewConst) =
a_lo = (a0 shl WordBitSize) or a1
var q, r: Word
unsafeDiv2n1n(q, r, a_hi, a_lo, m0) # Estimate quotient
q = mux( # If n_hi == divisor
q = cmov( # If n_hi == divisor
a0 == m0, MaxWord, # Quotient == MaxWord (0b0111...1111)
mux(
cmov(
q.isZero, Zero, # elif q == 0, true quotient = 0
q - One # else instead of being of by 0, 1 or 2
) # we returning q-1 to be off by -1, 0 or 1
@ -332,7 +332,7 @@ func shlAddMod(a: BigIntViewMut, c: Word, M: BigIntViewConst) =
carry += Word(a[i].isMsbSet) # Adjust if borrow
a[i] = a[i] and MaxWord # Normalize to u63
over_p = mux(
over_p = cmov(
a[i] == M[i], over_p,
a[i] > M[i]
)
@ -393,6 +393,13 @@ func reduce*(r: BigIntViewMut, a: BigIntViewAny, M: BigIntViewConst) =
#
# ############################################################
# TODO: when not optimizing for code-size we can benefit from
# specialized implementations of
# - Montgomery Multiplication by 1 (redc)
# - Montgomery squaring
# - Almost Montgomery Multiplication for Modular exponentiation:
# https://eprint.iacr.org/2011/239.pdf
template wordMul(a, b: Word): Word =
(a * b) and MaxWord

View File

@ -100,7 +100,7 @@ template `$`*(x: CTBool): string =
# Note that templates duplicate their input parameters.
# If a param is used multiple times, it **must** be `let` assigned first
# to avoid duplicate computation or duplicate side-effect.
# We append a mnemonic like `mux` or `LT` to help inspecting the C code
# We append a mnemonic like `cmov` or `LT` to help inspecting the C code
template fmap[T: Ct](x: T, op: untyped, y: T): T =
## Unwrap x and y from their distinct type
@ -208,8 +208,8 @@ template `<=`*[T: Ct](x, y: T): CTBool[T] =
template `xor`*[T: Ct](x, y: CTBool[T]): CTBool[T] =
CTBool[T](noteq(T(x), T(y)))
template mux*[T: Ct](ctl: CTBool[T], x, y: T): T =
## Multiplexer / selector
template cmov*[T: Ct](ctl: CTBool[T], x, y: T): T =
## Conditional Move / Multiplexer / selector /
## Returns x if ctl is true
## else returns y
## So equivalent to ctl? x: y
@ -222,19 +222,19 @@ template mux*[T: Ct](ctl: CTBool[T], x, y: T): T =
#
# TODO: assembly fastpath for conditional mov
let # Templates duplicate input params code
x_Mux = x
y_Mux = y
y_Mux xor (-T(ctl) and (x_Mux xor y_Mux))
x_cmov = x
y_cmov = y
y_cmov xor (-T(ctl) and (x_cmov xor y_cmov))
template mux*[T: CTBool](ctl: CTBool, x, y: T): T =
template cmov*[T: CTBool](ctl: CTBool, x, y: T): T =
## Multiplexer / selector
## Returns x if ctl is true
## else returns y
## So equivalent to ctl? x: y
let # Templates duplicate input params code
x_Mux = x
y_Mux = y
T(T.T(y_Mux) xor (-T.T(ctl) and T.T(x_Mux xor y_Mux)))
x_cmov = x
y_cmov = y
T(T.T(y_cmov) xor (-T.T(ctl) and T.T(x_cmov xor y_cmov)))
# ############################################################
#

View File

@ -169,7 +169,7 @@ proc main() =
bool(ct(10'u32) >= ct(5'u32)) == true
bool(ct(10'u32) >= ct(0xFFFFFFFF'u32)) == false
test "Multiplexer/selector - mux(ctl, x, y) <=> ctl? x: y":
test "Multiplexer/selector - cmov(ctl, x, y) <=> ctl? x: y":
let u = 10'u32.ct
let v = 20'u32.ct
let w = 5'u32.ct
@ -178,13 +178,13 @@ proc main() =
let n = cfalse(uint32)
check:
bool(mux(y, u, v) == u)
bool(mux(n, u, v) == v)
bool(cmov(y, u, v) == u)
bool(cmov(n, u, v) == v)
bool(mux(y, u, w) == u)
bool(mux(n, u, w) == w)
bool(cmov(y, u, w) == u)
bool(cmov(n, u, w) == w)
bool(mux(y, v, w) == v)
bool(mux(n, v, w) == w)
bool(cmov(y, v, w) == v)
bool(cmov(n, v, w) == w)
main()