dryoc/
utils.rs

1/// Increments `bytes` in constant time, representing a large little-endian
2/// integer; equivalent to `sodium_increment`.
3#[inline]
4pub fn increment_bytes(bytes: &mut [u8]) {
5    let mut carry: u16 = 1;
6    for b in bytes {
7        carry += *b as u16;
8        *b = (carry & 0xff) as u8;
9        carry >>= 8;
10    }
11}
12
13/// Convenience wrapper for [`increment_bytes`]. Functionally equivalent to
14/// `sodium_increment`.
15pub fn sodium_increment(bytes: &mut [u8]) {
16    increment_bytes(bytes)
17}
18
19#[inline]
20pub(crate) fn xor_buf(out: &mut [u8], in_: &[u8]) {
21    let len = std::cmp::min(out.len(), in_.len());
22    for i in 0..len {
23        out[i] ^= in_[i];
24    }
25}
26
27#[inline]
28pub(crate) fn load_u64_le(bytes: &[u8]) -> u64 {
29    (bytes[0] as u64)
30        | ((bytes[1] as u64) << 8)
31        | ((bytes[2] as u64) << 16)
32        | ((bytes[3] as u64) << 24)
33        | ((bytes[4] as u64) << 32)
34        | ((bytes[5] as u64) << 40)
35        | ((bytes[6] as u64) << 48)
36        | ((bytes[7] as u64) << 56)
37}
38
39#[inline]
40pub(crate) fn load_u32_le(bytes: &[u8]) -> u32 {
41    (bytes[0] as u32)
42        | ((bytes[1] as u32) << 8)
43        | ((bytes[2] as u32) << 16)
44        | ((bytes[3] as u32) << 24)
45}
46
47// #[inline]
48// pub(crate) fn load_i32_le(bytes: &[u8]) -> i32 {
49//     (bytes[0] as i32) | (bytes[1] as i32) << 8 | (bytes[2] as i32) << 16 |
50// (bytes[3] as i32) << 24 }
51
52#[inline]
53pub(crate) fn rotr64(x: u64, b: u64) -> u64 {
54    (x >> b) | (x << (64 - b))
55}
56
57#[inline]
58pub(crate) fn pad16(n: usize) -> usize {
59    (0x10 - (n % 16)) & 0xf
60}
61
62#[cfg(test)]
63mod tests {
64    use rand::TryRngCore;
65
66    use super::*;
67
68    #[test]
69    fn test_increment_bytes() {
70        let mut b = [0];
71
72        increment_bytes(&mut b);
73        assert_eq!(b, [1]);
74        increment_bytes(&mut b);
75        assert_eq!(b, [2]);
76
77        let mut b = [0xff];
78
79        increment_bytes(&mut b);
80        assert_eq!(b, [0]);
81        increment_bytes(&mut b);
82        assert_eq!(b, [1]);
83
84        let mut b = [0xff, 0];
85
86        increment_bytes(&mut b);
87        assert_eq!(b, [0, 1]);
88        increment_bytes(&mut b);
89        assert_eq!(b, [1, 1]);
90        increment_bytes(&mut b);
91        assert_eq!(b, [2, 1]);
92    }
93
94    #[test]
95    fn test_xor_buf() {
96        let mut a = [0];
97        let b = [0];
98
99        xor_buf(&mut a, &b);
100        assert_eq!([0], a);
101
102        let mut a = [1];
103        let b = [0];
104
105        xor_buf(&mut a, &b);
106        assert_eq!([1], a);
107
108        let mut a = [1, 1, 1];
109        let b = [0];
110
111        xor_buf(&mut a, &b);
112        assert_eq!([1, 1, 1], a);
113
114        let mut a = [1, 1, 1];
115        let b = [0];
116
117        xor_buf(&mut a, &b);
118        assert_eq!([1, 1, 1], a);
119
120        let mut a = [1, 1, 1];
121        let b = [0, 1, 1];
122
123        xor_buf(&mut a, &b);
124        assert_eq!([1, 0, 0], a);
125    }
126
127    #[test]
128    fn test_sodium_increment() {
129        use libsodium_sys::sodium_increment as so_sodium_increment;
130        use rand_core::OsRng;
131
132        use crate::rng::copy_randombytes;
133
134        for _ in 0..20 {
135            let rand_usize = (OsRng.try_next_u32().unwrap() % 1000) as usize;
136            let mut data = vec![0u8; rand_usize];
137            copy_randombytes(&mut data);
138
139            let mut data_copy = data.clone();
140
141            sodium_increment(&mut data);
142
143            unsafe { so_sodium_increment(data_copy.as_mut_ptr(), data_copy.len()) };
144
145            assert_eq!(data, data_copy);
146        }
147    }
148
149    #[test]
150    fn test_pad16() {
151        assert_eq!(pad16(0), 0);
152        assert_eq!(pad16(1), 15);
153        assert_eq!(pad16(2), 14);
154        assert_eq!(pad16(15), 1);
155        assert_eq!(pad16(16), 0);
156        assert_eq!(pad16(17), 15);
157        assert_eq!(pad16(32), 0);
158        assert_eq!(pad16(33), 15);
159    }
160}