ref: 3e9fc44da6d6f27d911211d6b8fbced97c0b4812
dir: /lib/crypto/ct.myr/
use std
pkg crypto =
/* These functions require unsigned inputs in order to work correctly */
generic not : (a : @t -> @t) :: integral,numeric @t
generic eq : (a : @t, b : @t -> @t) :: integral,numeric @t
generic ne : (a : @t, b : @t -> @t) :: integral,numeric @t
generic gt : (a : @t, b : @t -> @t) :: integral,numeric @t
generic lt : (a : @t, b : @t -> @t) :: integral,numeric @t
generic ge : (a : @t, b : @t -> @t) :: integral,numeric @t
generic le : (a : @t, b : @t -> @t) :: integral,numeric @t
generic mux : (x : @t, a : @t, b : @t ->@t) :: integral,numeric @t
generic min : (a : @t, b : @t -> @t) :: integral,numeric @t
generic max : (a : @t, b : @t -> @t) :: integral,numeric @t
const bufeq : (a : byte[:], b : byte[:] -> bool)
;;
generic not = {a : @t :: integral,numeric @t
-> a ^ 1
}
generic eq = {a : @t, b : @t :: integral,numeric @t
const nshift = 8*sizeof(@t) - 1
var q = a ^ b
-> ((q | -q) >> nshift)^1
}
generic gt = {a : @t, b : @t :: integral,numeric @t
/*
3 cases:
- both top bits unset => check if result is -ve (top bit set)
- one top bit set: => one with top bit set is >
- both top bits set: => subtract, check if result is -ve
*/
const nshift = 8*sizeof(@t) - 1
var z = (b - a)
-> (z ^ ((a ^ b) & (a ^ z))) >> nshift;
}
generic ge = {a, b
-> lt(a, b) ^ 1
}
generic lt = {a, b
const nshift = 8*sizeof(@t) - 1
var z = (a - b)
-> (z ^ ((b ^ a) & (b ^ a))) >> nshift;
}
generic le = {a, b
-> gt(a, b) ^ 1
}
generic ne = {a, b
const nshift = 8*sizeof(@t) - 1
var q = a ^ b
-> (q | -q) >> nshift
}
generic mux = {c, a, b
-> b ^ (-c & (a ^ b))
}
generic min = {a, b
var x
x = lt(a, b)
-> mux(x, a, b)
}
generic max = {a, b
var x
x = lt(a, b)
-> mux(x, b, a)
}
const bufeq = {a, b
var r, n
r = 1
n = min(a.len, b.len)
for var i = 0; i < n; i++
r = mux(r, eq(a[i], b[i]), r)
;;
-> (r : bool)
}