Use distinct range for Hardened booleans + first select test
This commit is contained in:
parent
8d6e328397
commit
d545147b0b
|
@ -73,20 +73,24 @@ func isMsbSet*[T: HardBase](x: T): HardBool[T] {.inline.} =
|
|||
#
|
||||
# ############################################################
|
||||
|
||||
template undistinct[T: HardBase](x: HardBool[T]): T =
|
||||
T(x)
|
||||
|
||||
func `not`*(ctl: HardBool): HardBool {.inline.}=
|
||||
## Negate a constant-time boolean
|
||||
ctl xor 1
|
||||
(type result)(ctl.undistinct xor (type ctl.undistinct)(1))
|
||||
|
||||
func select*[T: HardBase](ctl: HardBool[T], x, y: T): T {.inline.}=
|
||||
template select*[T: HardBase](ctl: HardBool[T], x, y: T): T =
|
||||
## Multiplexer / selector
|
||||
## Returns x if ctl == 1
|
||||
## else returns y
|
||||
## So equivalent to ctl? x: y
|
||||
y xor (-T(ctl) and (x xor y))
|
||||
|
||||
# TODO verify assembly generated
|
||||
# as mentionned in https://cryptocoding.net/index.php/Coding_rules
|
||||
# the alternative `(x and ctl) or (y and -m)`
|
||||
# the alternative `(x and ctl) or (y and -ctl)`
|
||||
# is optimized into a branch by Clang :/
|
||||
y xor (-ctl.T and (x xor y))
|
||||
|
||||
func noteq[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||
const msb = T.sizeof * 8 - 1
|
||||
|
@ -104,7 +108,7 @@ func `<`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
|||
)
|
||||
|
||||
func `<=`*[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||
(y < x) xor 1
|
||||
not(y < x)
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
|
|
|
@ -10,7 +10,7 @@ type
|
|||
|
||||
HardBase*[T: BaseUint] = distinct T
|
||||
|
||||
HardBool*[T: HardBase] = range[T(0)..T(1)]
|
||||
HardBool*[T: HardBase] = distinct range[T(0)..T(1)]
|
||||
## To avoid the compiler replacing bitwise boolean operations
|
||||
## by conditional branches, we don't use booleans.
|
||||
## We use an int to prevent compiler "optimization" and introduction of branches
|
||||
|
|
|
@ -50,7 +50,7 @@ suite "Hardened unsigned integers":
|
|||
not(hard(0'u32)).undistinct == not 0'u32
|
||||
not(hard(1'u32)).undistinct == not 1'u32
|
||||
not(hard(1234'u64)).undistinct == not 1234'u64
|
||||
not(hard(5678'u64)).undistinct == not 5678'u32
|
||||
not(hard(5678'u64)).undistinct == not 5678'u64
|
||||
not(hard(x1)).undistinct == not x1
|
||||
not(hard(x2)).undistinct == not x2
|
||||
not(hard(x3)).undistinct == not x3
|
||||
|
@ -166,3 +166,15 @@ suite "Hardened booleans":
|
|||
bool(hard(10'u32) >= hard(20'u32)) == false
|
||||
bool(hard(10'u32) >= hard(5'u32)) == true
|
||||
bool(hard(10'u32) >= hard(0xFFFFFFFF'u32)) == false
|
||||
|
||||
test "Multiplexer/selector - select(ctl, x, y) <=> ctl? x: y":
|
||||
let u = 10'u32.hard
|
||||
let v = 20'u32.hard
|
||||
let w = 5'u32.hard
|
||||
|
||||
let y = htrue(uint32)
|
||||
let n = hfalse(uint32)
|
||||
|
||||
check:
|
||||
bool(select(y, u, v) == u)
|
||||
|
||||
|
|
Loading…
Reference in New Issue