cnfy-uint 0.2.3

Zero-dependency 256-bit unsigned integer arithmetic for cryptographic applications
Documentation
//! Construction of a [`U320`] from a 40-byte little-endian array.
use super::U320;

impl U320 {
    /// Creates a new [`U320`] from a 40-byte array in little-endian order.
    ///
    /// Byte `[0]` is the least significant and byte `[39]` is the most
    /// significant. Reverses the bytes and delegates to
    /// [`U320::from_be_bytes`].
    ///
    /// # Examples
    ///
    /// ```
    /// use cnfy_uint::u320::U320;
    ///
    /// let mut le_bytes = [0u8; 40];
    /// le_bytes[0] = 1; // LSB
    /// assert_eq!(U320::from_le_bytes(le_bytes), U320::from_be_limbs([0, 0, 0, 0, 1]));
    /// ```
    #[inline]
    pub const fn from_le_bytes(bytes: [u8; 40]) -> Self {
        Self::from_be_bytes([
            bytes[39], bytes[38], bytes[37], bytes[36],
            bytes[35], bytes[34], bytes[33], bytes[32],
            bytes[31], bytes[30], bytes[29], bytes[28],
            bytes[27], bytes[26], bytes[25], bytes[24],
            bytes[23], bytes[22], bytes[21], bytes[20],
            bytes[19], bytes[18], bytes[17], bytes[16],
            bytes[15], bytes[14], bytes[13], bytes[12],
            bytes[11], bytes[10], bytes[9], bytes[8],
            bytes[7], bytes[6], bytes[5], bytes[4],
            bytes[3], bytes[2], bytes[1], bytes[0],
        ])
    }
}

#[cfg(test)]
mod ai_tests {
    use super::*;

    /// All zeros produces the zero value.
    #[test]
    fn zero() {
        assert_eq!(U320::from_le_bytes([0; 40]), U320::ZERO);
    }

    /// All 0xFF produces the maximum value.
    #[test]
    fn max() {
        assert_eq!(U320::from_le_bytes([0xFF; 40]), U320::MAX);
    }

    /// Byte 0 (LSB in LE) maps to the lowest bit of limb w4.
    #[test]
    fn single_lsb() {
        let mut bytes = [0u8; 40];
        bytes[0] = 1;
        assert_eq!(U320::from_le_bytes(bytes), U320::from_be_limbs([0, 0, 0, 0, 1]));
    }

    /// Byte 39 (MSB in LE) maps to the high bit of limb w0.
    #[test]
    fn single_msb() {
        let mut bytes = [0u8; 40];
        bytes[39] = 0x80;
        assert_eq!(
            U320::from_le_bytes(bytes),
            U320::from_be_limbs([0x8000000000000000, 0, 0, 0, 0]),
        );
    }

    /// Round-trip: from_le_bytes reverses from_be_bytes.
    #[test]
    fn inverse_of_be() {
        let be_bytes: [u8; 40] = [
            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
            0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
            0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
        ];
        let mut le_bytes = be_bytes;
        le_bytes.reverse();
        assert_eq!(U320::from_le_bytes(le_bytes), U320::from_be_bytes(be_bytes));
    }
}