diff --git a/src/uint/encoding.rs b/src/uint/encoding.rs index c15526580..b89e980bd 100644 --- a/src/uint/encoding.rs +++ b/src/uint/encoding.rs @@ -7,7 +7,10 @@ mod der; mod rlp; use super::Uint; -use crate::{Encoding, Limb, Word}; +use crate::{Limb, Word}; + +#[cfg(feature = "generic-array")] +use crate::Encoding; impl Uint { /// Create a new [`Uint`] from the provided big endian bytes. @@ -124,6 +127,7 @@ impl Uint { /// Serialize this [`Uint`] as big-endian, writing it into the provided /// byte slice. + #[cfg(feature = "generic-array")] #[inline] pub(crate) fn write_be_bytes(&self, out: &mut [u8]) { debug_assert_eq!(out.len(), Limb::BYTES * LIMBS); @@ -141,6 +145,7 @@ impl Uint { /// Serialize this [`Uint`] as little-endian, writing it into the provided /// byte slice. + #[cfg(feature = "generic-array")] #[inline] pub(crate) fn write_le_bytes(&self, out: &mut [u8]) { debug_assert_eq!(out.len(), Limb::BYTES * LIMBS); @@ -156,6 +161,58 @@ impl Uint { } } +/// Encode a [`Uint`] to a big endian byte array of the given size. +pub(crate) const fn uint_to_be_bytes( + uint: &Uint, +) -> [u8; BYTES] { + if BYTES != LIMBS * Limb::BYTES { + panic!("BYTES != LIMBS * Limb::BYTES"); + } + + let mut ret = [0u8; BYTES]; + let mut i = 0; + + while i < LIMBS { + let limb_bytes = uint.limbs[LIMBS - i - 1].0.to_be_bytes(); + let mut j = 0; + + while j < Limb::BYTES { + ret[i * Limb::BYTES + j] = limb_bytes[j]; + j += 1; + } + + i += 1; + } + + ret +} + +/// Encode a [`Uint`] to a little endian byte array of the given size. +pub(crate) const fn uint_to_le_bytes( + uint: &Uint, +) -> [u8; BYTES] { + if BYTES != LIMBS * Limb::BYTES { + panic!("BYTES != LIMBS * Limb::BYTES"); + } + + let mut ret = [0u8; BYTES]; + let mut i = 0; + + while i < LIMBS { + let limb_bytes = uint.limbs[i].0.to_le_bytes(); + let mut j = 0; + + while j < Limb::BYTES { + ret[i * Limb::BYTES + j] = limb_bytes[j]; + j += 1; + } + + i += 1; + } + + ret +} + /// Decode a single nibble of upper or lower hex #[inline(always)] const fn decode_nibble(src: u8) -> u16 { diff --git a/src/uint/macros.rs b/src/uint/macros.rs index 67af3b69b..cc03e1c5c 100644 --- a/src/uint/macros.rs +++ b/src/uint/macros.rs @@ -34,7 +34,14 @@ macro_rules! impl_uint_aliases { $( #[doc = $doc] #[doc="unsigned big integer."] - pub type $name = Uint<{nlimbs!($bits)}>; + pub type $name = Uint<{ nlimbs!($bits) }>; + + impl $name { + /// Serialize as big endian bytes. + pub const fn to_be_bytes(&self) -> [u8; $bits / 8] { + encoding::uint_to_be_bytes::<{ nlimbs!($bits) }, { $bits / 8 }>(self) + } + } impl Encoding for $name { type Repr = [u8; $bits / 8]; @@ -51,16 +58,12 @@ macro_rules! impl_uint_aliases { #[inline] fn to_be_bytes(&self) -> Self::Repr { - let mut result = [0u8; $bits / 8]; - self.write_be_bytes(&mut result); - result + encoding::uint_to_be_bytes(self) } #[inline] fn to_le_bytes(&self) -> Self::Repr { - let mut result = [0u8; $bits / 8]; - self.write_le_bytes(&mut result); - result + encoding::uint_to_le_bytes(self) } }