/rust/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-bigint-0.5.5/src/wrapping.rs
Line | Count | Source |
1 | | //! Wrapping arithmetic. |
2 | | |
3 | | use crate::Zero; |
4 | | use core::fmt; |
5 | | use subtle::{Choice, ConditionallySelectable, ConstantTimeEq}; |
6 | | |
7 | | #[cfg(feature = "rand_core")] |
8 | | use {crate::Random, rand_core::CryptoRngCore}; |
9 | | |
10 | | #[cfg(feature = "serde")] |
11 | | use serdect::serde::{Deserialize, Deserializer, Serialize, Serializer}; |
12 | | |
13 | | /// Provides intentionally-wrapped arithmetic on `T`. |
14 | | /// |
15 | | /// This is analogous to [`core::num::Wrapping`] but allows this crate to |
16 | | /// define trait impls for this type. |
17 | | #[derive(Copy, Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord)] |
18 | | pub struct Wrapping<T>(pub T); |
19 | | |
20 | | impl<T: Zero> Zero for Wrapping<T> { |
21 | | const ZERO: Self = Self(T::ZERO); |
22 | | } |
23 | | |
24 | | impl<T: fmt::Display> fmt::Display for Wrapping<T> { |
25 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
26 | 0 | self.0.fmt(f) |
27 | 0 | } |
28 | | } |
29 | | |
30 | | impl<T: fmt::Binary> fmt::Binary for Wrapping<T> { |
31 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
32 | 0 | self.0.fmt(f) |
33 | 0 | } |
34 | | } |
35 | | |
36 | | impl<T: fmt::Octal> fmt::Octal for Wrapping<T> { |
37 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
38 | 0 | self.0.fmt(f) |
39 | 0 | } |
40 | | } |
41 | | |
42 | | impl<T: fmt::LowerHex> fmt::LowerHex for Wrapping<T> { |
43 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
44 | 0 | self.0.fmt(f) |
45 | 0 | } |
46 | | } |
47 | | |
48 | | impl<T: fmt::UpperHex> fmt::UpperHex for Wrapping<T> { |
49 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
50 | 0 | self.0.fmt(f) |
51 | 0 | } |
52 | | } |
53 | | |
54 | | impl<T: ConditionallySelectable> ConditionallySelectable for Wrapping<T> { |
55 | 0 | fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self { |
56 | 0 | Wrapping(T::conditional_select(&a.0, &b.0, choice)) |
57 | 0 | } |
58 | | } |
59 | | |
60 | | impl<T: ConstantTimeEq> ConstantTimeEq for Wrapping<T> { |
61 | 0 | fn ct_eq(&self, other: &Self) -> Choice { |
62 | 0 | self.0.ct_eq(&other.0) |
63 | 0 | } |
64 | | } |
65 | | |
66 | | #[cfg(feature = "rand_core")] |
67 | | impl<T: Random> Random for Wrapping<T> { |
68 | 0 | fn random(rng: &mut impl CryptoRngCore) -> Self { |
69 | 0 | Wrapping(Random::random(rng)) |
70 | 0 | } |
71 | | } |
72 | | |
73 | | #[cfg(feature = "serde")] |
74 | | impl<'de, T: Deserialize<'de>> Deserialize<'de> for Wrapping<T> { |
75 | | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
76 | | where |
77 | | D: Deserializer<'de>, |
78 | | { |
79 | | Ok(Self(T::deserialize(deserializer)?)) |
80 | | } |
81 | | } |
82 | | |
83 | | #[cfg(feature = "serde")] |
84 | | impl<T: Serialize> Serialize for Wrapping<T> { |
85 | | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
86 | | where |
87 | | S: Serializer, |
88 | | { |
89 | | self.0.serialize(serializer) |
90 | | } |
91 | | } |
92 | | |
93 | | #[cfg(all(test, feature = "serde"))] |
94 | | #[allow(clippy::unwrap_used)] |
95 | | mod tests { |
96 | | use crate::{Wrapping, U64}; |
97 | | |
98 | | #[test] |
99 | | fn serde() { |
100 | | const TEST: Wrapping<U64> = Wrapping(U64::from_u64(0x0011223344556677)); |
101 | | |
102 | | let serialized = bincode::serialize(&TEST).unwrap(); |
103 | | let deserialized: Wrapping<U64> = bincode::deserialize(&serialized).unwrap(); |
104 | | |
105 | | assert_eq!(TEST, deserialized); |
106 | | } |
107 | | |
108 | | #[test] |
109 | | fn serde_owned() { |
110 | | const TEST: Wrapping<U64> = Wrapping(U64::from_u64(0x0011223344556677)); |
111 | | |
112 | | let serialized = bincode::serialize(&TEST).unwrap(); |
113 | | let deserialized: Wrapping<U64> = bincode::deserialize_from(serialized.as_slice()).unwrap(); |
114 | | |
115 | | assert_eq!(TEST, deserialized); |
116 | | } |
117 | | } |