Use Assembly cmov on x86
This commit is contained in:
parent
309a15ce8b
commit
ca817fcb69
|
@ -43,8 +43,8 @@ proc addBench() =
|
||||||
x += y
|
x += y
|
||||||
let stop = getMonotime()
|
let stop = getMonotime()
|
||||||
|
|
||||||
echo &"Time for {Iters} conditional additions (constant-time 381-bit): {inMilliseconds(stop-start)} ms"
|
echo &"Time for {Iters} additions in 𝔽p (constant-time 381-bit): {inMilliseconds(stop-start)} ms"
|
||||||
echo &"Time for 1 conditional addition ==> {inNanoseconds((stop-start) div Iters)} ns"
|
echo &"Time for 1 addition in 𝔽p ==> {inNanoseconds((stop-start) div Iters)} ns"
|
||||||
|
|
||||||
addBench()
|
addBench()
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ proc mulBench() =
|
||||||
r.prod(x, y)
|
r.prod(x, y)
|
||||||
let stop = getMonotime()
|
let stop = getMonotime()
|
||||||
|
|
||||||
echo &"Time for {Iters} multiplications (constant-time 381-bit): {inMilliseconds(stop-start)} ms"
|
echo &"Time for {Iters} multiplications 𝔽p (constant-time 381-bit): {inMilliseconds(stop-start)} ms"
|
||||||
echo &"Time for 1 multiplication ==> {inNanoseconds((stop-start) div Iters)} ns"
|
echo &"Time for 1 multiplication 𝔽p ==> {inNanoseconds((stop-start) div Iters)} ns"
|
||||||
|
|
||||||
mulBench()
|
mulBench()
|
||||||
|
|
|
@ -227,7 +227,7 @@ template `<=`*[T: Ct](x, y: T): CTBool[T] =
|
||||||
template `xor`*[T: Ct](x, y: CTBool[T]): CTBool[T] =
|
template `xor`*[T: Ct](x, y: CTBool[T]): CTBool[T] =
|
||||||
CTBool[T](noteq(T(x), T(y)))
|
CTBool[T](noteq(T(x), T(y)))
|
||||||
|
|
||||||
template mux*[T: Ct](ctl: CTBool[T], x, y: T): T =
|
func mux*[T](ctl: CTBool[T], x, y: T): T {.inline.}=
|
||||||
## Multiplexer / selector
|
## Multiplexer / selector
|
||||||
## Returns x if ctl is true
|
## Returns x if ctl is true
|
||||||
## else returns y
|
## else returns y
|
||||||
|
@ -237,22 +237,68 @@ template mux*[T: Ct](ctl: CTBool[T], x, y: T): T =
|
||||||
# Alternatives:
|
# Alternatives:
|
||||||
# - https://cryptocoding.net/index.php/Coding_rules
|
# - https://cryptocoding.net/index.php/Coding_rules
|
||||||
# - https://www.cl.cam.ac.uk/~rja14/Papers/whatyouc.pdf
|
# - https://www.cl.cam.ac.uk/~rja14/Papers/whatyouc.pdf
|
||||||
#
|
when defined(amd64) or defined(i386):
|
||||||
# TODO: assembly fastpath for conditional mov
|
when sizeof(T) == 8:
|
||||||
let # Templates duplicate input params code
|
var muxed = x
|
||||||
x_Mux = x
|
asm """
|
||||||
y_Mux = y
|
testq %[ctl], %[ctl]
|
||||||
y_Mux xor (-T(ctl) and (x_Mux xor y_Mux))
|
cmovzq %[y], %[muxed]
|
||||||
|
: [muxed] "+r" (`muxed`)
|
||||||
|
: [ctl] "r" (`ctl`), [y] "r" (`y`)
|
||||||
|
: "cc"
|
||||||
|
"""
|
||||||
|
muxed
|
||||||
|
elif sizeof(T) == 4:
|
||||||
|
var muxed = x
|
||||||
|
asm """
|
||||||
|
testl %[ctl], %[ctl]
|
||||||
|
cmovzl %[y], %[muxed]
|
||||||
|
: [muxed] "+r" (`muxed`)
|
||||||
|
: [ctl] "r" (`ctl`), [y] "r" (`y`)
|
||||||
|
: "cc"
|
||||||
|
"""
|
||||||
|
muxed
|
||||||
|
else:
|
||||||
|
{.error: "Unsupported word size".}
|
||||||
|
else:
|
||||||
|
let # Templates duplicate input params code
|
||||||
|
x_Mux = x
|
||||||
|
y_Mux = y
|
||||||
|
y_Mux xor (-T(ctl) and (x_Mux xor y_Mux))
|
||||||
|
|
||||||
template mux*[T: CTBool](ctl: CTBool, x, y: T): T =
|
func mux*[T: CTBool](ctl: CTBool, x, y: T): T {.inline.}=
|
||||||
## Multiplexer / selector
|
## Multiplexer / selector
|
||||||
## Returns x if ctl is true
|
## Returns x if ctl is true
|
||||||
## else returns y
|
## else returns y
|
||||||
## So equivalent to ctl? x: y
|
## So equivalent to ctl? x: y
|
||||||
let # Templates duplicate input params code
|
when defined(amd64) or defined(i386):
|
||||||
x_Mux = x
|
when sizeof(T) == 8:
|
||||||
y_Mux = y
|
var muxed = x
|
||||||
T(T.T(y_Mux) xor (-T.T(ctl) and T.T(x_Mux xor y_Mux)))
|
asm """
|
||||||
|
testq %[ctl], %[ctl]
|
||||||
|
cmovzq %[y], %[muxed]
|
||||||
|
: [muxed] "+r" (`muxed`)
|
||||||
|
: [ctl] "r" (`ctl`), [y] "r" (`y`)
|
||||||
|
: "cc"
|
||||||
|
"""
|
||||||
|
muxed
|
||||||
|
elif sizeof(T) == 4:
|
||||||
|
var muxed = x
|
||||||
|
asm """
|
||||||
|
testl %[ctl], %[ctl]
|
||||||
|
cmovzl %[y], %[muxed]
|
||||||
|
: [muxed] "+r" (`muxed`)
|
||||||
|
: [ctl] "r" (`ctl`), [y] "r" (`y`)
|
||||||
|
: "cc"
|
||||||
|
"""
|
||||||
|
muxed
|
||||||
|
else:
|
||||||
|
{.error: "Unsupported word size".}
|
||||||
|
else:
|
||||||
|
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)))
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue