Skip to main content

crypto_bigint/limb/
encoding.rs

1//! Limb encoding
2
3use super::{Limb, Word};
4use crate::Encoding;
5
6impl Encoding for Limb {
7    cpubits::cpubits! {
8        32 => { type Repr = [u8; 4]; }
9        64 => { type Repr = [u8; 8]; }
10    }
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
38    /// - if the slice is larger than [`Limb::Repr`].
39    pub(crate) fn from_be_slice(bytes: &[u8]) -> Self {
40        let mut repr = Self::ZERO.to_be_bytes();
41        let repr_len = repr.len();
42        assert!(
43            bytes.len() <= repr_len,
44            "The given slice is larger than the limb size"
45        );
46        repr[(repr_len - bytes.len())..].copy_from_slice(bytes);
47        Self::from_be_bytes(repr)
48    }
49
50    /// Decode limb from a little endian byte slice.
51    ///
52    /// # Panics
53    /// - if the slice is not the same size as [`Limb::Repr`].
54    pub(crate) fn from_le_slice(bytes: &[u8]) -> Self {
55        let mut repr = Self::ZERO.to_le_bytes();
56        let repr_len = repr.len();
57        assert!(
58            bytes.len() <= repr_len,
59            "The given slice is larger than the limb size"
60        );
61        repr[..bytes.len()].copy_from_slice(bytes);
62        Self::from_le_bytes(repr)
63    }
64}
65
66#[cfg(test)]
67mod test {
68    use super::*;
69
70    cpubits::cpubits! {
71        32 => { const LIMB: Limb = Limb(0x7654_3210); }
72        64 => { const LIMB: Limb = Limb(0xFEDCBA9876543210); }
73    }
74
75    #[test]
76    fn roundtrip() {
77        assert_eq!(LIMB, Limb::from_be_bytes(LIMB.to_be_bytes()));
78        assert_eq!(LIMB, Limb::from_le_bytes(LIMB.to_le_bytes()));
79    }
80
81    #[test]
82    fn reverse() {
83        let mut bytes = LIMB.to_be_bytes();
84        bytes.reverse();
85        assert_eq!(LIMB, Limb::from_le_bytes(bytes));
86
87        let mut bytes = LIMB.to_le_bytes();
88        bytes.reverse();
89        assert_eq!(LIMB, Limb::from_be_bytes(bytes));
90    }
91}