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.}=
|
func `not`*(ctl: HardBool): HardBool {.inline.}=
|
||||||
## Negate a constant-time boolean
|
## 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
|
## Multiplexer / selector
|
||||||
## Returns x if ctl == 1
|
## Returns x if ctl == 1
|
||||||
## else returns y
|
## else returns y
|
||||||
## So equivalent to ctl? x: y
|
## So equivalent to ctl? x: y
|
||||||
|
y xor (-T(ctl) and (x xor y))
|
||||||
|
|
||||||
# TODO verify assembly generated
|
# TODO verify assembly generated
|
||||||
# as mentionned in https://cryptocoding.net/index.php/Coding_rules
|
# 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 :/
|
# 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.}=
|
func noteq[T: HardBase](x, y: T): HardBool[T] {.inline.}=
|
||||||
const msb = T.sizeof * 8 - 1
|
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.}=
|
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
|
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
|
## To avoid the compiler replacing bitwise boolean operations
|
||||||
## by conditional branches, we don't use booleans.
|
## by conditional branches, we don't use booleans.
|
||||||
## We use an int to prevent compiler "optimization" and introduction of branches
|
## 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(0'u32)).undistinct == not 0'u32
|
||||||
not(hard(1'u32)).undistinct == not 1'u32
|
not(hard(1'u32)).undistinct == not 1'u32
|
||||||
not(hard(1234'u64)).undistinct == not 1234'u64
|
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(x1)).undistinct == not x1
|
||||||
not(hard(x2)).undistinct == not x2
|
not(hard(x2)).undistinct == not x2
|
||||||
not(hard(x3)).undistinct == not x3
|
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(20'u32)) == false
|
||||||
bool(hard(10'u32) >= hard(5'u32)) == true
|
bool(hard(10'u32) >= hard(5'u32)) == true
|
||||||
bool(hard(10'u32) >= hard(0xFFFFFFFF'u32)) == false
|
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