1#[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
13pub 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#[cfg_attr(all(feature = "simd_backend", feature = "nightly"), allow(dead_code))]
49pub(crate) fn rotr64(x: u64, b: u32) -> u64 {
50 x.rotate_right(b)
51}
52
53#[inline]
54pub(crate) fn pad16(n: usize) -> usize {
55 (0x10 - (n % 16)) & 0xf
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn test_increment_bytes() {
64 let mut b = [0];
65
66 increment_bytes(&mut b);
67 assert_eq!(b, [1]);
68 increment_bytes(&mut b);
69 assert_eq!(b, [2]);
70
71 let mut b = [0xff];
72
73 increment_bytes(&mut b);
74 assert_eq!(b, [0]);
75 increment_bytes(&mut b);
76 assert_eq!(b, [1]);
77
78 let mut b = [0xff, 0];
79
80 increment_bytes(&mut b);
81 assert_eq!(b, [0, 1]);
82 increment_bytes(&mut b);
83 assert_eq!(b, [1, 1]);
84 increment_bytes(&mut b);
85 assert_eq!(b, [2, 1]);
86 }
87
88 #[test]
89 fn test_xor_buf() {
90 let mut a = [0];
91 let b = [0];
92
93 xor_buf(&mut a, &b);
94 assert_eq!([0], a);
95
96 let mut a = [1];
97 let b = [0];
98
99 xor_buf(&mut a, &b);
100 assert_eq!([1], a);
101
102 let mut a = [1, 1, 1];
103 let b = [0];
104
105 xor_buf(&mut a, &b);
106 assert_eq!([1, 1, 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, 1, 1];
116
117 xor_buf(&mut a, &b);
118 assert_eq!([1, 0, 0], a);
119 }
120
121 #[test]
122 fn test_pad16() {
123 assert_eq!(pad16(0), 0);
124 assert_eq!(pad16(1), 15);
125 assert_eq!(pad16(2), 14);
126 assert_eq!(pad16(15), 1);
127 assert_eq!(pad16(16), 0);
128 assert_eq!(pad16(17), 15);
129 assert_eq!(pad16(32), 0);
130 assert_eq!(pad16(33), 15);
131 }
132
133 #[cfg(dryoc_native_tests)]
134 mod native_tests {
135 use super::*;
136
137 #[test]
138 fn test_sodium_increment() {
139 use libsodium_sys::sodium_increment as so_sodium_increment;
140 use rand::TryRng;
141 use rand::rngs::SysRng;
142
143 use crate::rng::copy_randombytes;
144
145 for _ in 0..20 {
146 let rand_usize = (SysRng.try_next_u32().unwrap() % 1000) as usize;
147 let mut data = vec![0u8; rand_usize];
148 copy_randombytes(&mut data);
149
150 let mut data_copy = data.clone();
151
152 sodium_increment(&mut data);
153
154 unsafe { so_sodium_increment(data_copy.as_mut_ptr(), data_copy.len()) };
155
156 assert_eq!(data, data_copy);
157 }
158 }
159 }
160}