commonware_utils/
lib.rs

1//! Leverage common functionality across multiple primitives.
2
3use bytes::{BufMut, BytesMut};
4use commonware_codec::varint;
5
6pub mod array;
7pub use array::Array;
8mod time;
9pub use time::SystemTimeExt;
10mod priority_set;
11pub use priority_set::PrioritySet;
12pub mod futures;
13
14/// Converts bytes to a hexadecimal string.
15pub fn hex(bytes: &[u8]) -> String {
16    let mut hex = String::new();
17    for byte in bytes.iter() {
18        hex.push_str(&format!("{:02x}", byte));
19    }
20    hex
21}
22
23/// Converts a hexadecimal string to bytes.
24pub fn from_hex(hex: &str) -> Option<Vec<u8>> {
25    if hex.len() % 2 != 0 {
26        return None;
27    }
28
29    (0..hex.len())
30        .step_by(2)
31        .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).ok())
32        .collect()
33}
34
35/// Converts a hexadecimal string to bytes, stripping whitespace and/or a `0x` prefix. Commonly used
36/// in testing to encode external test vectors without modification.
37pub fn from_hex_formatted(hex: &str) -> Option<Vec<u8>> {
38    let hex = hex.replace(['\t', '\n', '\r', ' '], "");
39    let res = hex.strip_prefix("0x").unwrap_or(&hex);
40    from_hex(res)
41}
42
43/// Compute the maximum value of `f` (faults) that can be tolerated given `n = 3f + 1`.
44pub fn max_faults(n: u32) -> Option<u32> {
45    let f = n.checked_sub(1)? / 3;
46    if f == 0 {
47        return None;
48    }
49    Some(f)
50}
51
52/// Assuming that `n = 3f + 1`, compute the minimum size of `q` such that `q >= 2f + 1`.
53///
54/// If the value of `n` is too small to tolerate any faults, this function returns `None`.
55pub fn quorum(n: u32) -> Option<u32> {
56    let f = max_faults(n)?;
57    Some((2 * f) + 1)
58}
59
60/// Computes the union of two byte slices.
61pub fn union(a: &[u8], b: &[u8]) -> Vec<u8> {
62    let mut union = Vec::with_capacity(a.len() + b.len());
63    union.extend_from_slice(a);
64    union.extend_from_slice(b);
65    union
66}
67
68/// Concatenate a namespace and a message, prepended by a varint encoding of the namespace length.
69///
70/// This produces a unique byte sequence (i.e. no collisions) for each `(namespace, msg)` pair.
71pub fn union_unique(namespace: &[u8], msg: &[u8]) -> Vec<u8> {
72    let len = u32::try_from(namespace.len()).expect("namespace length too large");
73    let mut buf = BytesMut::with_capacity(varint::size(len) + namespace.len() + msg.len());
74    varint::write(len, &mut buf);
75    buf.put_slice(namespace);
76    buf.put_slice(msg);
77    buf.into()
78}
79
80/// Compute the modulo of bytes interpreted as a big-endian integer.
81///
82/// This function is used to select a random entry from an array
83/// when the bytes are a random seed.
84pub fn modulo(bytes: &[u8], n: u64) -> u64 {
85    let mut result = 0;
86    for &byte in bytes {
87        result = (result << 8) | (byte as u64);
88        result %= n;
89    }
90    result
91}
92
93#[cfg(test)]
94mod tests {
95    use super::*;
96    use num_bigint::BigUint;
97    use rand::{rngs::StdRng, Rng, SeedableRng};
98
99    #[test]
100    fn test_hex() {
101        // Test case 0: empty bytes
102        let b = &[];
103        let h = hex(b);
104        assert_eq!(h, "");
105        assert_eq!(from_hex(&h).unwrap(), b.to_vec());
106
107        // Test case 1: single byte
108        let b = &[0x01];
109        let h = hex(b);
110        assert_eq!(h, "01");
111        assert_eq!(from_hex(&h).unwrap(), b.to_vec());
112
113        // Test case 2: multiple bytes
114        let b = &[0x01, 0x02, 0x03];
115        let h = hex(b);
116        assert_eq!(h, "010203");
117        assert_eq!(from_hex(&h).unwrap(), b.to_vec());
118
119        // Test case 3: odd number of bytes
120        let h = "0102030";
121        assert!(from_hex(h).is_none());
122
123        // Test case 4: invalid hexadecimal character
124        let h = "01g3";
125        assert!(from_hex(h).is_none());
126    }
127
128    #[test]
129    fn test_from_hex_formatted() {
130        // Test case 0: empty bytes
131        let b = &[];
132        let h = hex(b);
133        assert_eq!(h, "");
134        assert_eq!(from_hex_formatted(&h).unwrap(), b.to_vec());
135
136        // Test case 1: single byte
137        let b = &[0x01];
138        let h = hex(b);
139        assert_eq!(h, "01");
140        assert_eq!(from_hex_formatted(&h).unwrap(), b.to_vec());
141
142        // Test case 2: multiple bytes
143        let b = &[0x01, 0x02, 0x03];
144        let h = hex(b);
145        assert_eq!(h, "010203");
146        assert_eq!(from_hex_formatted(&h).unwrap(), b.to_vec());
147
148        // Test case 3: odd number of bytes
149        let h = "0102030";
150        assert!(from_hex_formatted(h).is_none());
151
152        // Test case 4: invalid hexadecimal character
153        let h = "01g3";
154        assert!(from_hex_formatted(h).is_none());
155
156        // Test case 5: whitespace
157        let h = "01 02 03";
158        assert_eq!(from_hex_formatted(h).unwrap(), b.to_vec());
159
160        // Test case 6: 0x prefix
161        let h = "0x010203";
162        assert_eq!(from_hex_formatted(h).unwrap(), b.to_vec());
163
164        // Test case 7: 0x prefix + different whitespace chars
165        let h = "    \n\n0x\r\n01
166                            02\t03\n";
167        assert_eq!(from_hex_formatted(h).unwrap(), b.to_vec());
168    }
169
170    #[test]
171    fn test_quorum() {
172        // Test case 0: n = 3 (3*0 + 1)
173        assert_eq!(quorum(3), None);
174
175        // Test case 1: n = 4 (3*1 + 1)
176        assert_eq!(quorum(4), Some(3));
177
178        // Test case 2: n = 7 (3*2 + 1)
179        assert_eq!(quorum(7), Some(5));
180
181        // Test case 3: n = 10 (3*3 + 1)
182        assert_eq!(quorum(10), Some(7));
183    }
184
185    #[test]
186    fn test_union() {
187        // Test case 0: empty slices
188        assert_eq!(union(&[], &[]), []);
189
190        // Test case 1: empty and non-empty slices
191        assert_eq!(union(&[], &[0x01, 0x02, 0x03]), [0x01, 0x02, 0x03]);
192
193        // Test case 2: non-empty and non-empty slices
194        assert_eq!(
195            union(&[0x01, 0x02, 0x03], &[0x04, 0x05, 0x06]),
196            [0x01, 0x02, 0x03, 0x04, 0x05, 0x06]
197        );
198    }
199
200    #[test]
201    fn test_union_unique() {
202        let namespace = b"namespace";
203        let msg = b"message";
204
205        let length_encoding = vec![0b0000_1001];
206        let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
207        expected.extend_from_slice(&length_encoding);
208        expected.extend_from_slice(namespace);
209        expected.extend_from_slice(msg);
210
211        let result = union_unique(namespace, msg);
212        assert_eq!(result, expected);
213        assert_eq!(result.len(), result.capacity());
214    }
215
216    #[test]
217    fn test_union_unique_zero_length() {
218        let namespace = b"";
219        let msg = b"message";
220
221        let length_encoding = vec![0];
222        let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
223        expected.extend_from_slice(&length_encoding);
224        expected.extend_from_slice(msg);
225
226        let result = union_unique(namespace, msg);
227        assert_eq!(result, expected);
228        assert_eq!(result.len(), result.capacity());
229    }
230
231    #[test]
232    fn test_union_unique_long_length() {
233        // Use a namespace of over length 127.
234        let namespace = &b"n".repeat(256);
235        let msg = b"message";
236
237        let length_encoding = vec![0b1000_0000, 0b0000_0010];
238        let mut expected = Vec::with_capacity(length_encoding.len() + namespace.len() + msg.len());
239        expected.extend_from_slice(&length_encoding);
240        expected.extend_from_slice(namespace);
241        expected.extend_from_slice(msg);
242
243        let result = union_unique(namespace, msg);
244        assert_eq!(result, expected);
245        assert_eq!(result.len(), result.capacity());
246    }
247
248    #[test]
249    fn test_modulo() {
250        // Test case 0: empty bytes
251        assert_eq!(modulo(&[], 1), 0);
252
253        // Test case 1: single byte
254        assert_eq!(modulo(&[0x01], 1), 0);
255
256        // Test case 2: multiple bytes
257        assert_eq!(modulo(&[0x01, 0x02, 0x03], 10), 1);
258
259        // Test case 3: check equivalence with BigUint
260        let n = 11u64;
261        for i in 0..100 {
262            let mut rng = StdRng::seed_from_u64(i);
263            let bytes: [u8; 32] = rng.gen();
264            let big_modulo = BigUint::from_bytes_be(&bytes) % n;
265            let utils_modulo = modulo(&bytes, n);
266            assert_eq!(big_modulo, BigUint::from(utils_modulo));
267        }
268    }
269}