Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
fn check_bytes(value: &[i64], name: &str) {
if value.iter().any(|b| !(0..=255).contains(b)) {
panic!("{} must be a list of integers from 0 to 255", name);
}
}
/// Are two byte strings equal, without stopping at the first difference?
/// Every byte is visited and the differences OR-ed together, so the time
/// taken says nothing about where a forged tag goes wrong. Different lengths
/// answer false at once: a digest's length is not a secret.
///
/// # Panics
/// Panics if any value is outside 0-255.
pub fn constant_time_equal(a: &[i64], b: &[i64]) -> bool {
check_bytes(a, "a");
check_bytes(b, "b");
if a.len() != b.len() {
return false;
}
let mut diff: i64 = 0;
for i in 0..a.len() {
diff |= a[i] ^ b[i];
}
diff == 0
}
fn bytes_from_value(value: &Value, name: &str) -> Vec<i64> {
match value {
Value::Arr(items) => items
.iter()
.map(|item| match item {
Value::Int(i) => *i,
_ => panic!("{} must be a list of integers from 0 to 255", name),
})
.collect(),
_ => panic!("{} must be a list of integers from 0 to 255", name),
}
}
pub fn fune_vector(args: &[Value]) -> Value {
let a = bytes_from_value(&args[0], "a");
let b = bytes_from_value(&args[1], "b");
Value::Bool(constant_time_equal(&a, &b))
}