crypto_bigint/limb/
encoding.rs

1//! Limb encoding
2
3use super::{Limb, Word};
4use crate::Encoding;
5
6impl Encoding for Limb {
7    #[cfg(target_pointer_width = "32")]
8    type Repr = [u8; 4];
9    #[cfg(target_pointer_width = "64")]
10    type Repr = [u8; 8];
11
12    #[inline]
13    fn from_be_bytes(bytes: Self::Repr) -> Self {
14        Limb(Word::from_be_bytes(bytes))
15    }
16
17    #[inline]
18    fn from_le_bytes(bytes: Self::Repr) -> Self {
19        Limb(Word::from_le_bytes(bytes))
20    }
21
22    #[inline]
23    fn to_be_bytes(&self) -> Self::Repr {
24        self.0.to_be_bytes()
25    }
26
27    #[inline]
28    fn to_le_bytes(&self) -> Self::Repr {
29        self.0.to_le_bytes()
30    }
31}
32
33#[cfg(feature = "alloc")]
34impl Limb {
35    /// Decode limb from a big endian byte slice.
36    ///
37    /// Panics if the slice is larger than [`Limb::Repr`].
38    pub(crate) fn from_be_slice(bytes: &[u8]) -> Self {
39        let mut repr = Self::ZERO.to_be_bytes();
40        let repr_len = repr.len();
41        assert!(
42            bytes.len() <= repr_len,
43            "The given slice is larger than the limb size"
44        );
45        repr[(repr_len - bytes.len())..].copy_from_slice(bytes);
46        Self::from_be_bytes(repr)
47    }
48
49    /// Decode limb from a little endian byte slice.
50    ///
51    /// Panics if the slice is not the same size as [`Limb::Repr`].
52    pub(crate) fn from_le_slice(bytes: &[u8]) -> Self {
53        let mut repr = Self::ZERO.to_le_bytes();
54        let repr_len = repr.len();
55        assert!(
56            bytes.len() <= repr_len,
57            "The given slice is larger than the limb size"
58        );
59        repr[..bytes.len()].copy_from_slice(bytes);
60        Self::from_le_bytes(repr)
61    }
62}
63
64#[cfg(test)]
65mod test {
66    use super::*;
67
68    #[cfg(target_pointer_width = "32")]
69    const LIMB: Limb = Limb(0x7654_3210);
70
71    #[cfg(target_pointer_width = "64")]
72    const LIMB: Limb = Limb(0xFEDCBA9876543210);
73
74    #[test]
75    fn roundtrip() {
76        assert_eq!(LIMB, Limb::from_be_bytes(LIMB.to_be_bytes()));
77        assert_eq!(LIMB, Limb::from_le_bytes(LIMB.to_le_bytes()));
78    }
79
80    #[test]
81    fn reverse() {
82        let mut bytes = LIMB.to_be_bytes();
83        bytes.reverse();
84        assert_eq!(LIMB, Limb::from_le_bytes(bytes));
85
86        let mut bytes = LIMB.to_le_bytes();
87        bytes.reverse();
88        assert_eq!(LIMB, Limb::from_be_bytes(bytes));
89    }
90}