pub fn memzero(x: &mut [u8]) {
unsafe {
ffi::sodium_memzero(x.as_mut_ptr(), x.len());
}
}
pub fn memcmp(x: &[u8], y: &[u8]) -> bool {
if x.len() != y.len() {
return false;
}
unsafe { ffi::sodium_memcmp(x.as_ptr(), y.as_ptr(), x.len()) == 0 }
}
pub fn increment_le(x: &mut [u8]) {
unsafe {
ffi::sodium_increment(x.as_mut_ptr(), x.len());
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_memcmp() {
use crate::randombytes::randombytes;
for i in 0usize..256 {
let x = randombytes(i);
assert!(memcmp(&x, &x));
let mut y = x.clone();
assert!(memcmp(&x, &y));
y.push(0);
assert!(!memcmp(&x, &y));
assert!(!memcmp(&y, &x));
y = randombytes(i);
if x == y {
assert!(memcmp(&x, &y))
} else {
assert!(!memcmp(&x, &y))
}
}
}
#[test]
fn test_increment_le_zero() {
for i in 1usize..256 {
let mut x = vec![0u8; i];
increment_le(&mut x);
assert!(!x.iter().all(|x| *x == 0));
let mut y = vec![0u8; i];
y[0] += 1;
assert_eq!(x, y);
}
}
#[test]
fn test_increment_le_vectors() {
let mut x = [255, 2, 3, 4, 5];
let y = [0, 3, 3, 4, 5];
increment_le(&mut x);
assert!(!x.iter().all(|x| *x == 0));
assert_eq!(x, y);
let mut x = [255, 255, 3, 4, 5];
let y = [0, 0, 4, 4, 5];
increment_le(&mut x);
assert!(!x.iter().all(|x| *x == 0));
assert_eq!(x, y);
let mut x = [255, 255, 255, 4, 5];
let y = [0, 0, 0, 5, 5];
increment_le(&mut x);
assert!(!x.iter().all(|x| *x == 0));
assert_eq!(x, y);
let mut x = [255, 255, 255, 255, 5];
let y = [0, 0, 0, 0, 6];
increment_le(&mut x);
assert!(!x.iter().all(|x| *x == 0));
assert_eq!(x, y);
let mut x = [255, 255, 255, 255, 255];
let y = [0, 0, 0, 0, 0];
increment_le(&mut x);
assert!(x.iter().all(|x| *x == 0));
assert_eq!(x, y);
}
#[test]
fn test_increment_le_overflow() {
for i in 1usize..256 {
let mut x = vec![255u8; i];
increment_le(&mut x);
assert!(x.iter().all(|xi| *xi == 0));
}
}
}