1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
//! Constant-time comparison of fixed-size vecs use ffi; /// `verify_16()` returns `true` if `x[0]`, `x[1]`, ..., `x[15]` are the /// same as `y[0]`, `y[1]`, ..., `y[15]`. Otherwise it returns `false`. /// /// This function is safe to use for secrets `x[0]`, `x[1]`, ..., `x[15]`, /// `y[0]`, `y[1]`, ..., `y[15]`. The time taken by `verify_16` is independent /// of the contents of `x[0]`, `x[1]`, ..., `x[15]`, `y[0]`, `y[1]`, ..., `y[15]`. /// In contrast, the standard C comparison function `memcmp(x,y,16)` takes time /// that depends on the longest matching prefix of `x` and `y`, often allowing easy /// timing attacks. pub fn verify_16(x: &[u8; 16], y: &[u8; 16]) -> bool { unsafe { ffi::crypto_verify_16(x, y) == 0 } } /// `verify_32()` returns true if `x[0]`, `x[1]`, ..., `x[31]` are the /// same as `y[0]`, `y[1]`, ..., `y[31]`. Otherwise it returns `false`. /// /// This function is safe to use for secrets `x[0]`, `x[1]`, ..., `x[31]`, /// `y[0]`, `y[1]`, ..., `y[31]`. The time taken by `verify_32` is independent /// of the contents of `x[0]`, `x[1]`, ..., `x[31]`, `y[0]`, `y[1]`, ..., `y[31]`. /// In contrast, the standard C comparison function `memcmp(x,y,32)` takes time /// that depends on the longest matching prefix of `x` and `y`, often allowing easy /// timing attacks. pub fn verify_32(x: &[u8; 32], y: &[u8; 32]) -> bool { unsafe { ffi::crypto_verify_32(x, y) == 0 } } /// `verify_64()` returns true if `x[0]`, `x[1]`, ..., `x[63]` are the /// same as `y[0]`, `y[1]`, ..., `y[63]`. Otherwise it returns `false`. /// /// This function is safe to use for secrets `x[0]`, `x[1]`, ..., `x[63]`, /// `y[0]`, `y[1]`, ..., `y[63]`. The time taken by `verify_64` is independent /// of the contents of `x[0]`, `x[1]`, ..., `x[63]`, `y[0]`, `y[1]`, ..., `y[63]`. /// In contrast, the standard C comparison function `memcmp(x,y,64)` takes time /// that depends on the longest matching prefix of `x` and `y`, often allowing easy /// timing attacks. pub fn verify_64(x: &[u8; 64], y: &[u8; 64]) -> bool { unsafe { ffi::crypto_verify_64(x, y) == 0 } } #[cfg(test)] mod test { use super::*; #[test] fn test_verify_16() { use randombytes::randombytes_into; for _ in 0usize..256 { let mut x = [0; 16]; let mut y = [0; 16]; assert!(verify_16(&x, &y)); randombytes_into(&mut x); randombytes_into(&mut y); if x == y { assert!(verify_16(&x, &y)) } else { assert!(!verify_16(&x, &y)) } } } #[test] fn test_verify_32() { use randombytes::randombytes_into; for _ in 0usize..256 { let mut x = [0; 32]; let mut y = [0; 32]; assert!(verify_32(&x, &y)); randombytes_into(&mut x); randombytes_into(&mut y); if x == y { assert!(verify_32(&x, &y)) } else { assert!(!verify_32(&x, &y)) } } } #[test] fn test_verify_64() { use randombytes::randombytes_into; for _ in 0usize..256 { let mut x = [0; 64]; let mut y = [0; 64]; assert!(verify_64(&x, &y)); randombytes_into(&mut x); randombytes_into(&mut y); if x[..] == y[..] { assert!(verify_64(&x, &y)) } else { assert!(!verify_64(&x, &y)) } } } }