From 7ac59a424971a2865d2a6838735bdf173aa2aef4 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Fri, 16 Feb 2024 08:47:25 -0700 Subject: [PATCH] Further expand array size support (#49) This adds support for sizes identified as needed for post-quantum KEM/DSA use cases, namely the ones from this comment: https://github.com/RustCrypto/KEMs/pull/2#discussion_r1491883770 These should ideally get expanded into some consistent multiples above 1024, e.g. multiples of 32, and generated in a purely automated manner (e.g. by a script that can break down the bit representation and build the generic syntax), but this should at least be sufficient to unblock these use cases. Note that `UInt, B#...` aliases expressing the explicit bits for a given number are used instead of e.g. `>::Output` because when the latter is used it causes similar errors for conflicting trait impls as we saw with `typenum::U` for whatever reason: error[E0119]: conflicting implementations of trait `traits::ArraySize` for type `UTerm` --> src/sizes.rs:82:13 | 82 | unsafe impl ArraySize for $ty { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | first implementation here | conflicting implementation for `UTerm` --- src/sizes.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/sizes.rs b/src/sizes.rs index be8588e..c8dab49 100644 --- a/src/sizes.rs +++ b/src/sizes.rs @@ -1,16 +1,43 @@ //! Macros for defining various array sizes, and their associated invocations. use super::{ArraySize, AssocArraySize}; +use typenum::consts::*; + +/// Additional typenum size aliases beyond what are normally provided. +/// +/// These are defined using their component bits rather than `Add` to avoid conflicting impls. +#[rustfmt::skip] +pub mod extra_sizes { + use typenum::{UInt, UTerm, B0, B1}; + + pub type U1088 = UInt, B0>, B0>, B0>, B1>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U1152 = UInt, B0>, B0>, B1>, B0>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U1184 = UInt, B0>, B0>, B1>, B0>, B1>, B0>, B0>, B0>, B0>, B0>; + pub type U1472 = UInt, B0>, B1>, B1>, B1>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U1536 = UInt, B1>, B0>, B0>, B0>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U1568 = UInt, B1>, B0>, B0>, B0>, B1>, B0>, B0>, B0>, B0>, B0>; + pub type U1600 = UInt, B1>, B0>, B0>, B1>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U1632 = UInt, B1>, B0>, B0>, B1>, B1>, B0>, B0>, B0>, B0>, B0>; + pub type U2336 = UInt, B0>, B0>, B1>, B0>, B0>, B1>, B0>, B0>, B0>, B0>, B0>; + pub type U2368 = UInt, B0>, B0>, B1>, B0>, B1>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U2400 = UInt, B0>, B0>, B1>, B0>, B1>, B1>, B0>, B0>, B0>, B0>, B0>; + pub type U3072 = UInt, B1>, B0>, B0>, B0>, B0>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U3104 = UInt, B1>, B0>, B0>, B0>, B0>, B1>, B0>, B0>, B0>, B0>, B0>; + pub type U3136 = UInt, B1>, B0>, B0>, B0>, B1>, B0>, B0>, B0>, B0>, B0>, B0>; + pub type U3168 = UInt, B1>, B0>, B0>, B0>, B1>, B1>, B0>, B0>, B0>, B0>, B0>; +} + +pub use extra_sizes::*; macro_rules! impl_array_size { ($($len:expr => $ty:ident),+) => { $( - unsafe impl ArraySize for typenum::consts::$ty { + unsafe impl ArraySize for $ty { type ArrayType = [T; $len]; } impl AssocArraySize for [T; $len] { - type Size = typenum::consts::$ty; + type Size = $ty; } )+ }; @@ -321,5 +348,22 @@ impl_array_size! { 976 => U976, 992 => U992, 1008 => U1008, - 1024 => U1024 + 1024 => U1024, + 1088 => U1088, + 1152 => U1152, + 1184 => U1184, + 1472 => U1472, + 1536 => U1536, + 1568 => U1568, + 1600 => U1600, + 1632 => U1632, + 2048 => U2048, + 2336 => U2336, + 2368 => U2368, + 2400 => U2400, + 3072 => U3072, + 3104 => U3104, + 3136 => U3136, + 3168 => U3168, + 4096 => U4096 }