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
//! Construction of a [`U384`] from a 48-byte little-endian array.
use super::U384;
impl U384 {
/// Creates a new [`U384`] from a 48-byte array in little-endian order.
///
/// Bytes `[0..8]` become limb `[0]` (least significant), bytes `[8..16]`
/// become `[1]`, and so on through bytes `[40..48]` which become `[5]`
/// (most significant).
///
/// # Examples
///
/// ```
/// use cnfy_uint::u384::U384;
///
/// let mut bytes = [0u8; 48];
/// bytes[0] = 1;
/// assert_eq!(U384::from_le_bytes(bytes), U384::from_be_limbs([0, 0, 0, 0, 0, 1]));
/// ```
#[inline]
pub const fn from_le_bytes(bytes: [u8; 48]) -> Self {
let l0 = u64::from_le_bytes([
bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
]);
let l1 = u64::from_le_bytes([
bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
]);
let l2 = u64::from_le_bytes([
bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23],
]);
let l3 = u64::from_le_bytes([
bytes[24], bytes[25], bytes[26], bytes[27], bytes[28], bytes[29], bytes[30], bytes[31],
]);
let l4 = u64::from_le_bytes([
bytes[32], bytes[33], bytes[34], bytes[35], bytes[36], bytes[37], bytes[38], bytes[39],
]);
let l5 = u64::from_le_bytes([
bytes[40], bytes[41], bytes[42], bytes[43], bytes[44], bytes[45], bytes[46], bytes[47],
]);
Self([l0, l1, l2, l3, l4, l5])
}
}
#[cfg(test)]
mod ai_tests {
use super::*;
/// All zeros produces the zero value.
#[test]
fn zero() {
assert_eq!(
U384::from_le_bytes([0; 48]),
U384::from_be_limbs([0, 0, 0, 0, 0, 0]),
);
}
/// All 0xFF produces the maximum value.
#[test]
fn max() {
assert_eq!(
U384::from_le_bytes([0xFF; 48]),
U384::MAX,
);
}
/// Byte 0 (least significant in LE) maps to the low bit of limb w5.
#[test]
fn single_lsb() {
let mut bytes = [0u8; 48];
bytes[0] = 1;
assert_eq!(
U384::from_le_bytes(bytes),
U384::from_be_limbs([0, 0, 0, 0, 0, 1]),
);
}
/// Byte 47 (most significant in LE) maps to the high byte of limb w0.
#[test]
fn single_msb() {
let mut bytes = [0u8; 48];
bytes[47] = 0x80;
assert_eq!(
U384::from_le_bytes(bytes),
U384::from_be_limbs([0x8000000000000000, 0, 0, 0, 0, 0]),
);
}
/// Round-trip with from_be_bytes using reversed bytes.
#[test]
fn le_vs_be() {
let mut be_bytes = [0u8; 48];
be_bytes[47] = 0x42;
let mut le_bytes = [0u8; 48];
le_bytes[0] = 0x42;
assert_eq!(U384::from_be_bytes(be_bytes), U384::from_le_bytes(le_bytes));
}
}