diff --git a/CHANGELOG.md b/CHANGELOG.md index b220ec58..caf9934f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,10 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Make `as_limbs_mut` const ([#757]) +- Impl `RemMixed` for even splits as well ([#791]) - Make `Integer` be fmt::Binary, LowerHex and UpperHex ([#792]) - +- [#757]: https://github.com/RustCrypto/crypto-bigint/pull/757 [#760]: https://github.com/RustCrypto/crypto-bigint/pull/760 +[#791]: https://github.com/RustCrypto/crypto-bigint/pull/791 [#792]:https://github.com/RustCrypto/crypto-bigint/pull/792 ## 0.6.0 (2025-01-22) diff --git a/src/uint/div.rs b/src/uint/div.rs index 6ae5b4d6..add1e731 100644 --- a/src/uint/div.rs +++ b/src/uint/div.rs @@ -962,7 +962,7 @@ impl RemLimb for Uint { #[cfg(test)] mod tests { use crate::{ - DivVartime, Limb, NonZero, RemMixed, U64, U128, U256, U896, U1024, Uint, Word, Zero, + DivVartime, Limb, NonZero, RemMixed, U64, U128, U256, U896, U1024, U2048, Uint, Word, Zero, }; #[cfg(feature = "rand")] @@ -1176,6 +1176,26 @@ mod tests { ); } + #[test] + fn rem_mixed_even() { + let x = U2048::from_be_hex( + "B1EB364536A78FAAFDB3467E062072E019B764561F0B800F16A276763845A42F44A45463D1424AE28688CDF4E2E4D04E2F64A601419F13CE0C86001BCB12544A0381AEA1EEF6C45665B7B5A9298BBAE17AF5168C347039E657FBAE920FC0902B221C45E641FE43DDF2764A7CC915F079E99017B2B621320BFDB44C31096437DD47BD11DA7391671D7415EFBF72A6FBE243901A0BF9E9E1A119762DE5D5DB8E2393C3FA5EF11049E37BB6BDB2070C4371B4E550B02C806908DFF1A71B0AB1601327143F42B5C5488E7609DFE07EFF8A17B5EA8D36E9E22058489FF253D51BCBE53825A7DC63080D4298B82B0336070665149406D8FC0E8E6B67094CEA8CA40DB1", + ); + let y = U1024::from_u64(1234567890987654321); + let rem: U1024 = x.rem_mixed(&y.to_nz().unwrap()); + + let y_wide = U1024::concat_mixed(&y, &U1024::ZERO); + let rem_control: U2048 = x.rem(&NonZero::new(y_wide).unwrap()); + + assert_eq!(rem.bits(), rem_control.bits()); + assert_eq!(rem.as_words(), &rem_control.as_words()[0..U1024::LIMBS]); + assert!( + rem_control.as_words()[U1024::LIMBS..] + .iter() + .all(|w| *w == 0) + ); + } + #[test] fn rem_mixed_through_traits() { struct A { diff --git a/src/uint/macros.rs b/src/uint/macros.rs index 5c5c93cf..862de83d 100644 --- a/src/uint/macros.rs +++ b/src/uint/macros.rs @@ -135,6 +135,13 @@ macro_rules! impl_uint_concat_split_even { } } + impl $crate::traits::RemMixed::LIMBS / 2 }>> for $name + { + fn rem_mixed(&self, reductor: &NonZero::LIMBS / 2 }>>) -> Uint<{ <$name>::LIMBS / 2 }> { + self.div_rem_vartime(reductor).1 + } + } + impl $crate::traits::Split for $name { type Output = Uint<{ <$name>::LIMBS / 2 }>;