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