commonware_utils/
lib.rs

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