diff --git a/src/int.rs b/src/int.rs index 6295ee255..8a2246d3a 100644 --- a/src/int.rs +++ b/src/int.rs @@ -8,11 +8,13 @@ use core::fmt; use num_traits::{ConstOne, ConstZero}; use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; -#[cfg(feature = "serde")] use crate::Encoding; #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer}; +#[macro_use] +mod macros; + mod add; mod bit_and; mod bit_not; @@ -34,7 +36,6 @@ mod shl; mod shr; mod sign; mod sub; -pub(crate) mod types; #[cfg(feature = "rand_core")] mod rand; @@ -346,6 +347,38 @@ impl fmt::UpperHex for Int { } } +impl_int_aliases! { + (I64, 64, "64-bit"), + (I128, 128, "128-bit"), + (I192, 192, "192-bit"), + (I256, 256, "256-bit"), + (I320, 320, "320-bit"), + (I384, 384, "384-bit"), + (I448, 448, "448-bit"), + (I512, 512, "512-bit"), + (I576, 576, "576-bit"), + (I640, 640, "640-bit"), + (I704, 704, "704-bit"), + (I768, 768, "768-bit"), + (I832, 832, "832-bit"), + (I896, 896, "896-bit"), + (I960, 960, "960-bit"), + (I1024, 1024, "1024-bit"), + (I1280, 1280, "1280-bit"), + (I1536, 1536, "1536-bit"), + (I1792, 1792, "1792-bit"), + (I2048, 2048, "2048-bit"), + (I3072, 3072, "3072-bit"), + (I3584, 3584, "3584-bit"), + (I4096, 4096, "4096-bit"), + (I4224, 4224, "4224-bit"), + (I4352, 4352, "4352-bit"), + (I6144, 6144, "6144-bit"), + (I8192, 8192, "8192-bit"), + (I16384, 16384, "16384-bit"), + (I32768, 32768, "32768-bit") +} + #[cfg(feature = "serde")] impl<'de, const LIMBS: usize> Deserialize<'de> for Int where diff --git a/src/int/encoding.rs b/src/int/encoding.rs index 1bbe30c88..9e66e789a 100644 --- a/src/int/encoding.rs +++ b/src/int/encoding.rs @@ -3,6 +3,13 @@ use crate::{Int, Uint}; impl Int { + /// Create a new [`Int`] from the provided big endian bytes. + /// + /// See [`Uint::from_be_slice`] for more details. + pub const fn from_be_slice(bytes: &[u8]) -> Self { + Self(Uint::from_be_slice(bytes)) + } + /// Create a new [`Int`] from the provided big endian hex string. /// /// Panics if the hex is malformed or not zero-padded accordingly for the size. @@ -11,4 +18,34 @@ impl Int { pub const fn from_be_hex(hex: &str) -> Self { Self(Uint::from_be_hex(hex)) } + + /// Create a new [`Int`] from the provided little endian bytes. + /// + /// See [`Uint::from_le_slice`] for more details. + pub const fn from_le_slice(bytes: &[u8]) -> Self { + Self(Uint::from_le_slice(bytes)) + } + + /// Create a new [`Int`] from the provided little endian hex string. + /// + /// Panics if the hex is malformed or not zero-padded accordingly for the size. + /// + /// See [`Uint::from_le_hex`] for more details. + pub const fn from_le_hex(hex: &str) -> Self { + Self(Uint::from_le_hex(hex)) + } +} + +/// Encode an [`Int`] to a big endian byte array of the given size. +pub(crate) const fn int_to_be_bytes( + int: &Int, +) -> [u8; BYTES] { + crate::uint::encoding::uint_to_be_bytes(&int.0) +} + +/// Encode an [`Int`] to a little endian byte array of the given size. +pub(crate) const fn int_to_le_bytes( + int: &Int, +) -> [u8; BYTES] { + crate::uint::encoding::uint_to_le_bytes(&int.0) } diff --git a/src/int/macros.rs b/src/int/macros.rs new file mode 100644 index 000000000..eea4527a2 --- /dev/null +++ b/src/int/macros.rs @@ -0,0 +1,48 @@ +//! Macros used to define traits on aliases of `Int`. + +// TODO(tarcieri): use `generic_const_exprs` when stable to make generic around bits. +macro_rules! impl_int_aliases { + ($(($name:ident, $bits:expr, $doc:expr)),+) => { + $( + #[doc = $doc] + #[doc="unsigned big integer."] + pub type $name = Int<{ nlimbs!($bits) }>; + + impl $name { + /// Serialize as big endian bytes. + pub const fn to_be_bytes(&self) -> [u8; $bits / 8] { + encoding::int_to_be_bytes::<{ nlimbs!($bits) }, { $bits / 8 }>(self) + } + + /// Serialize as little endian bytes. + pub const fn to_le_bytes(&self) -> [u8; $bits / 8] { + encoding::int_to_le_bytes::<{ nlimbs!($bits) }, { $bits / 8 }>(self) + } + } + + impl Encoding for $name { + type Repr = [u8; $bits / 8]; + + #[inline] + fn from_be_bytes(bytes: Self::Repr) -> Self { + Self::from_be_slice(&bytes) + } + + #[inline] + fn from_le_bytes(bytes: Self::Repr) -> Self { + Self::from_le_slice(&bytes) + } + + #[inline] + fn to_be_bytes(&self) -> Self::Repr { + encoding::int_to_be_bytes(self) + } + + #[inline] + fn to_le_bytes(&self) -> Self::Repr { + encoding::int_to_le_bytes(self) + } + } + )+ + }; +} diff --git a/src/int/types.rs b/src/int/types.rs deleted file mode 100644 index 0488dd494..000000000 --- a/src/int/types.rs +++ /dev/null @@ -1,60 +0,0 @@ -//! Selection of [`Int`] types. -//! todo: replace with macro implementation once serde is set up. - -use crate::Int; - -#[cfg(target_pointer_width = "64")] -/// Signed bit integer. -pub type I64 = Int<1>; - -#[cfg(target_pointer_width = "64")] -/// Signed bit integer. -pub type I128 = Int<2>; - -#[cfg(target_pointer_width = "64")] -/// Signed bit integer. -pub type I256 = Int<4>; - -#[cfg(target_pointer_width = "64")] -/// Signed bit integer. -pub type I512 = Int<8>; - -#[cfg(target_pointer_width = "64")] -/// Signed bit integer. -pub type I1024 = Int<16>; - -#[cfg(target_pointer_width = "64")] -/// Signed bit integer. -pub type I2048 = Int<32>; - -#[cfg(target_pointer_width = "64")] -/// Signed bit integer. -pub type I4096 = Int<64>; - -#[cfg(target_pointer_width = "32")] -/// Signed bit integer. -pub type I64 = Int<2>; - -#[cfg(target_pointer_width = "32")] -/// Signed bit integer. -pub type I128 = Int<4>; - -#[cfg(target_pointer_width = "32")] -/// Signed bit integer. -pub type I256 = Int<8>; - -#[cfg(target_pointer_width = "32")] -/// Signed bit integer. -pub type I512 = Int<16>; - -#[cfg(target_pointer_width = "32")] -/// Signed bit integer. -pub type I1024 = Int<32>; - -#[cfg(target_pointer_width = "32")] -/// Signed bit integer. -pub type I2048 = Int<64>; - -#[cfg(target_pointer_width = "32")] -/// Signed bit integer. -pub type I4096 = Int<128>; diff --git a/src/lib.rs b/src/lib.rs index d98d54b2d..fc780c08b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -186,7 +186,7 @@ pub use crate::uint::boxed::BoxedUint; pub use crate::{ checked::Checked, const_choice::{ConstChoice, ConstCtOption}, - int::{types::*, *}, + int::{*}, jacobi::JacobiSymbol, limb::{Limb, WideWord, Word}, non_zero::*,