// Constant-time comparison utilities for MoonVault
// These prevent timing side-channel attacks on MAC/password comparisons
pub fn constant_eq(a : Bytes, b : Bytes) -> Bool {
if a.length() != b.length() { return false }
let mut diff : UInt = 0
let mut i = 0
while i < a.length() {
diff = diff | (a[i].to_uint() ^ b[i].to_uint())
i = i + 1
}
diff == 0
}
pub fn constant_eq_bytes(a : Array[Byte], b : Array[Byte], len : Int) -> Bool {
let mut diff : UInt = 0
let mut i = 0
while i < len {
diff = diff | (a[i].to_uint() ^ b[i].to_uint())
i = i + 1
}
diff == 0
}
pub fn constant_eq_string(a : String, b : String) -> Bool {
if a.length() != b.length() { return false }
let mut diff : UInt = 0
let mut i = 0
while i < a.length() {
diff = diff | (a[i] ^ b[i]).to_uint()
i = i + 1
}
diff == 0
}
pub fn constant_select(a : Int, b : Int, cond : Bool) -> Int {
let m = if cond { 0xFF } else { 0 }
(a & m) | (b & m.lnot() & 0xFF)
}
pub fn constant_is_zero(x : UInt) -> Bool {
(x | x.lnot().lnot()) == 0
}
pub fn constant_ne(a : Bytes, b : Bytes) -> Bool {
!constant_eq(a, b)
}
pub fn constant_lt(a : Int, b : Int) -> Bool {
let d = a - b
(d >> 31) != 0
}
pub fn constant_ge(a : Int, b : Int) -> Bool {
!constant_lt(a, b)
}