1use crate::{
4 Choice, CtEq, CtSelect, One, UintRef, WrappingAdd, WrappingMul, WrappingNeg, WrappingShl,
5 WrappingShr, WrappingSub, Zero,
6};
7use core::{
8 fmt,
9 ops::{Add, Mul, Neg, Shl, Shr, Sub},
10};
11
12#[cfg(feature = "rand_core")]
13use {crate::Random, rand_core::TryRng};
14
15#[cfg(feature = "serde")]
16use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer};
17
18#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)]
23pub struct Wrapping<T>(pub T);
24
25impl<T: AsRef<UintRef>> AsRef<UintRef> for Wrapping<T> {
26 fn as_ref(&self) -> &UintRef {
27 self.0.as_ref()
28 }
29}
30
31impl<T: AsMut<UintRef>> AsMut<UintRef> for Wrapping<T> {
32 fn as_mut(&mut self) -> &mut UintRef {
33 self.0.as_mut()
34 }
35}
36
37impl<T: WrappingAdd> Add<Self> for Wrapping<T> {
38 type Output = Wrapping<T>;
39
40 #[inline]
41 fn add(self, rhs: Self) -> Self::Output {
42 Wrapping(self.0.wrapping_add(&rhs.0))
43 }
44}
45
46impl<T: WrappingAdd> Add<&Self> for Wrapping<T> {
47 type Output = Wrapping<T>;
48
49 #[inline]
50 fn add(self, rhs: &Self) -> Self::Output {
51 Wrapping(self.0.wrapping_add(&rhs.0))
52 }
53}
54
55impl<T: WrappingAdd> Add<Wrapping<T>> for &Wrapping<T> {
56 type Output = Wrapping<T>;
57
58 #[inline]
59 fn add(self, rhs: Wrapping<T>) -> Self::Output {
60 Wrapping(self.0.wrapping_add(&rhs.0))
61 }
62}
63
64impl<T: WrappingAdd> Add<&Wrapping<T>> for &Wrapping<T> {
65 type Output = Wrapping<T>;
66
67 #[inline]
68 fn add(self, rhs: &Wrapping<T>) -> Self::Output {
69 Wrapping(self.0.wrapping_add(&rhs.0))
70 }
71}
72
73impl<T: WrappingSub> Sub<Self> for Wrapping<T> {
74 type Output = Wrapping<T>;
75
76 #[inline]
77 fn sub(self, rhs: Self) -> Self::Output {
78 Wrapping(self.0.wrapping_sub(&rhs.0))
79 }
80}
81
82impl<T: WrappingSub> Sub<&Self> for Wrapping<T> {
83 type Output = Wrapping<T>;
84
85 #[inline]
86 fn sub(self, rhs: &Self) -> Self::Output {
87 Wrapping(self.0.wrapping_sub(&rhs.0))
88 }
89}
90
91impl<T: WrappingSub> Sub<Wrapping<T>> for &Wrapping<T> {
92 type Output = Wrapping<T>;
93
94 #[inline]
95 fn sub(self, rhs: Wrapping<T>) -> Self::Output {
96 Wrapping(self.0.wrapping_sub(&rhs.0))
97 }
98}
99
100impl<T: WrappingSub> Sub<&Wrapping<T>> for &Wrapping<T> {
101 type Output = Wrapping<T>;
102
103 #[inline]
104 fn sub(self, rhs: &Wrapping<T>) -> Self::Output {
105 Wrapping(self.0.wrapping_sub(&rhs.0))
106 }
107}
108
109impl<T: WrappingMul> Mul<Self> for Wrapping<T> {
110 type Output = Wrapping<T>;
111
112 #[inline]
113 fn mul(self, rhs: Self) -> Self::Output {
114 Wrapping(self.0.wrapping_mul(&rhs.0))
115 }
116}
117
118impl<T: WrappingMul> Mul<&Self> for Wrapping<T> {
119 type Output = Wrapping<T>;
120
121 #[inline]
122 fn mul(self, rhs: &Self) -> Self::Output {
123 Wrapping(self.0.wrapping_mul(&rhs.0))
124 }
125}
126
127impl<T: WrappingMul> Mul<Wrapping<T>> for &Wrapping<T> {
128 type Output = Wrapping<T>;
129
130 #[inline]
131 fn mul(self, rhs: Wrapping<T>) -> Self::Output {
132 Wrapping(self.0.wrapping_mul(&rhs.0))
133 }
134}
135
136impl<T: WrappingMul> Mul<&Wrapping<T>> for &Wrapping<T> {
137 type Output = Wrapping<T>;
138
139 #[inline]
140 fn mul(self, rhs: &Wrapping<T>) -> Self::Output {
141 Wrapping(self.0.wrapping_mul(&rhs.0))
142 }
143}
144
145impl<T: WrappingNeg> Neg for Wrapping<T> {
146 type Output = Wrapping<T>;
147
148 #[inline]
149 fn neg(self) -> Self::Output {
150 Wrapping(self.0.wrapping_neg())
151 }
152}
153
154impl<T: WrappingNeg> Neg for &Wrapping<T> {
155 type Output = Wrapping<T>;
156
157 #[inline]
158 fn neg(self) -> Self::Output {
159 Wrapping(self.0.wrapping_neg())
160 }
161}
162
163impl<T: WrappingShl> Shl<u32> for Wrapping<T> {
164 type Output = Wrapping<T>;
165
166 #[inline]
167 fn shl(self, rhs: u32) -> Self::Output {
168 Wrapping(self.0.wrapping_shl(rhs))
169 }
170}
171
172impl<T: WrappingShl> Shl<u32> for &Wrapping<T> {
173 type Output = Wrapping<T>;
174
175 #[inline]
176 fn shl(self, rhs: u32) -> Self::Output {
177 Wrapping(self.0.wrapping_shl(rhs))
178 }
179}
180
181impl<T: WrappingShr> Shr<u32> for Wrapping<T> {
182 type Output = Wrapping<T>;
183
184 #[inline]
185 fn shr(self, rhs: u32) -> Self::Output {
186 Wrapping(self.0.wrapping_shr(rhs))
187 }
188}
189
190impl<T: WrappingShr> Shr<u32> for &Wrapping<T> {
191 type Output = Wrapping<T>;
192
193 #[inline]
194 fn shr(self, rhs: u32) -> Self::Output {
195 Wrapping(self.0.wrapping_shr(rhs))
196 }
197}
198
199impl<T> CtEq for Wrapping<T>
200where
201 T: CtEq,
202{
203 #[inline]
204 fn ct_eq(&self, other: &Self) -> Choice {
205 CtEq::ct_eq(&self.0, &other.0)
206 }
207}
208
209impl<T> CtSelect for Wrapping<T>
210where
211 T: CtSelect,
212{
213 #[inline]
214 fn ct_select(&self, other: &Self, choice: Choice) -> Self {
215 Self(self.0.ct_select(&other.0, choice))
216 }
217}
218
219impl<T: Zero> Zero for Wrapping<T> {
220 #[inline]
221 fn zero() -> Self {
222 Wrapping(T::zero())
223 }
224}
225
226impl<T: One> One for Wrapping<T> {
227 #[inline]
228 fn one() -> Self {
229 Wrapping(T::one())
230 }
231}
232
233impl<T: num_traits::Zero + WrappingAdd> num_traits::Zero for Wrapping<T> {
234 #[inline]
235 fn zero() -> Self {
236 Wrapping(T::zero())
237 }
238
239 #[inline]
240 fn is_zero(&self) -> bool {
241 self.0.is_zero()
242 }
243}
244
245impl<T: num_traits::One + WrappingMul + PartialEq> num_traits::One for Wrapping<T> {
246 #[inline]
247 fn one() -> Self {
248 Wrapping(T::one())
249 }
250
251 #[inline]
252 fn is_one(&self) -> bool {
253 self.0.is_one()
254 }
255}
256
257impl<T: fmt::Display> fmt::Display for Wrapping<T> {
258 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
259 self.0.fmt(f)
260 }
261}
262
263impl<T: fmt::Binary> fmt::Binary for Wrapping<T> {
264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265 self.0.fmt(f)
266 }
267}
268
269impl<T: fmt::Octal> fmt::Octal for Wrapping<T> {
270 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271 self.0.fmt(f)
272 }
273}
274
275impl<T: fmt::LowerHex> fmt::LowerHex for Wrapping<T> {
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 self.0.fmt(f)
278 }
279}
280
281impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> {
282 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
283 self.0.fmt(f)
284 }
285}
286
287#[cfg(feature = "rand_core")]
288impl<T: Random> Random for Wrapping<T> {
289 fn try_random_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
290 Ok(Wrapping(Random::try_random_from_rng(rng)?))
291 }
292}
293
294#[cfg(feature = "serde")]
295impl<'de, T: Deserialize<'de>> Deserialize<'de> for Wrapping<T> {
296 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
297 where
298 D: Deserializer<'de>,
299 {
300 Ok(Self(T::deserialize(deserializer)?))
301 }
302}
303
304#[cfg(feature = "serde")]
305impl<T: Serialize> Serialize for Wrapping<T> {
306 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307 where
308 S: Serializer,
309 {
310 self.0.serialize(serializer)
311 }
312}
313
314#[cfg(feature = "subtle")]
315impl<T> subtle::ConditionallySelectable for Wrapping<T>
316where
317 T: Copy,
318 Self: CtSelect,
319{
320 #[inline]
321 fn conditional_select(a: &Self, b: &Self, choice: subtle::Choice) -> Self {
322 a.ct_select(b, choice.into())
323 }
324}
325
326#[cfg(feature = "subtle")]
327impl<T> subtle::ConstantTimeEq for Wrapping<T>
328where
329 Self: CtEq,
330{
331 #[inline]
332 fn ct_eq(&self, other: &Self) -> subtle::Choice {
333 CtEq::ct_eq(self, other).into()
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use super::Wrapping;
340 use crate::{
341 Choice, CtEq, CtSelect, Limb, WrappingAdd, WrappingMul, WrappingNeg, WrappingShl,
342 WrappingShr, WrappingSub,
343 };
344
345 const INPUTS: &[(Limb, Limb)] = &[
347 (Limb::ZERO, Limb::ZERO),
348 (Limb::ZERO, Limb::ONE),
349 (Limb::ZERO, Limb::MAX),
350 (Limb::ONE, Limb::ZERO),
351 (Limb::ONE, Limb::ONE),
352 (Limb::ONE, Limb::MAX),
353 (Limb::MAX, Limb::ZERO),
354 (Limb::MAX, Limb::ONE),
355 (Limb::MAX, Limb::MAX),
356 ];
357
358 #[test]
359 fn wrapping_new() {
360 assert_eq!(Wrapping::<Limb>::default().0, Limb::default());
361 assert_eq!(<Wrapping<Limb> as crate::Zero>::zero().0, Limb::ZERO);
362 assert_eq!(<Wrapping<Limb> as crate::One>::one().0, Limb::ONE);
363 assert_eq!(<Wrapping<Limb> as num_traits::Zero>::zero().0, Limb::ZERO);
364 assert_eq!(<Wrapping<Limb> as num_traits::One>::one().0, Limb::ONE);
365 }
366
367 #[test]
368 #[cfg(feature = "alloc")]
369 fn wrapping_format() {
370 for a in [Limb::ZERO, Limb::ONE, Limb::MAX] {
371 assert_eq!(format!("{}", Wrapping(a)), format!("{}", a));
372 assert_eq!(format!("{:?}", Wrapping(a)), format!("Wrapping({:?})", a));
373 assert_eq!(format!("{:b}", Wrapping(a)), format!("{:b}", a));
374 assert_eq!(format!("{:o}", Wrapping(a)), format!("{:o}", a));
375 assert_eq!(format!("{:x}", Wrapping(a)), format!("{:x}", a));
376 assert_eq!(format!("{:X}", Wrapping(a)), format!("{:X}", a));
377 }
378 }
379 #[test]
380 fn wrapping_eq_select() {
381 let pairs: &[(Limb, Limb, bool)] = &[
382 (Limb::ZERO, Limb::ZERO, true),
383 (Limb::ZERO, Limb::ONE, false),
384 (Limb::ONE, Limb::ZERO, false),
385 (Limb::ONE, Limb::ONE, true),
386 ];
387
388 for (a, b, eq) in pairs {
389 assert_eq!(a.ct_eq(b).to_bool(), *eq);
390 assert!(a.ct_select(b, Choice::FALSE).ct_eq(a).to_bool());
391 assert!(a.ct_select(b, Choice::TRUE).ct_eq(b).to_bool());
392 #[cfg(feature = "subtle")]
393 assert_eq!(bool::from(subtle::ConstantTimeEq::ct_eq(a, b)), *eq);
394 #[cfg(feature = "subtle")]
395 assert!(
396 subtle::ConditionallySelectable::conditional_select(
397 a,
398 b,
399 subtle::Choice::from(0u8)
400 )
401 .ct_eq(a)
402 .to_bool()
403 );
404 #[cfg(feature = "subtle")]
405 assert!(
406 subtle::ConditionallySelectable::conditional_select(
407 a,
408 b,
409 subtle::Choice::from(1u8)
410 )
411 .ct_eq(b)
412 .to_bool()
413 );
414 }
415 }
416
417 #[allow(clippy::op_ref)]
418 #[test]
419 fn wrapping_add() {
420 for (a, b) in INPUTS {
421 let expect = WrappingAdd::wrapping_add(a, b);
422 assert_eq!((Wrapping(*a) + Wrapping(*b)).0, expect);
423 assert_eq!((&Wrapping(*a) + Wrapping(*b)).0, expect);
424 assert_eq!((Wrapping(*a) + &Wrapping(*b)).0, expect);
425 assert_eq!((&Wrapping(*a) + &Wrapping(*b)).0, expect);
426 }
427 }
428
429 #[allow(clippy::op_ref)]
430 #[test]
431 fn wrapping_sub() {
432 for (a, b) in INPUTS {
433 let expect = WrappingSub::wrapping_sub(a, b);
434 assert_eq!((Wrapping(*a) - Wrapping(*b)).0, expect);
435 assert_eq!((&Wrapping(*a) - Wrapping(*b)).0, expect);
436 assert_eq!((Wrapping(*a) - &Wrapping(*b)).0, expect);
437 assert_eq!((&Wrapping(*a) - &Wrapping(*b)).0, expect);
438 }
439 }
440
441 #[allow(clippy::op_ref)]
442 #[test]
443 fn wrapping_mul() {
444 for (a, b) in INPUTS {
445 let expect = WrappingMul::wrapping_mul(a, b);
446 assert_eq!((Wrapping(*a) * Wrapping(*b)).0, expect);
447 assert_eq!((&Wrapping(*a) * Wrapping(*b)).0, expect);
448 assert_eq!((Wrapping(*a) * &Wrapping(*b)).0, expect);
449 assert_eq!((&Wrapping(*a) * &Wrapping(*b)).0, expect);
450 }
451 }
452
453 #[allow(clippy::op_ref)]
454 #[test]
455 fn wrapping_neg() {
456 assert_eq!(
457 (-Wrapping(Limb::ZERO)).0,
458 WrappingNeg::wrapping_neg(&Limb::ZERO)
459 );
460 assert_eq!(
461 (-&Wrapping(Limb::ONE)).0,
462 WrappingNeg::wrapping_neg(&Limb::ONE)
463 );
464 assert_eq!(
465 (-Wrapping(Limb::MAX)).0,
466 WrappingNeg::wrapping_neg(&Limb::MAX)
467 );
468 }
469
470 #[allow(clippy::op_ref)]
471 #[test]
472 fn wrapping_shift() {
473 for a in [Limb::ZERO, Limb::ONE, Limb::MAX] {
474 assert_eq!((Wrapping(a) << 1).0, WrappingShl::wrapping_shl(&a, 1));
475 assert_eq!((&Wrapping(a) << 2).0, WrappingShl::wrapping_shl(&a, 2));
476 assert_eq!((Wrapping(a) >> 1).0, WrappingShr::wrapping_shr(&a, 1));
477 assert_eq!((&Wrapping(a) >> 2).0, WrappingShr::wrapping_shr(&a, 2));
478 }
479 }
480}