bigint/
m256.rs

1//! Unsigned modulo 256-bit integer
2
3#[cfg(feature = "std")] use std::convert::{From, Into};
4#[cfg(feature = "std")] use std::str::FromStr;
5#[cfg(feature = "std")] use std::ops::{Add, Sub, Not, Mul, Div, Shr, Shl, BitAnd, BitOr, BitXor, Rem};
6#[cfg(feature = "std")] use std::cmp::Ordering;
7#[cfg(feature = "std")] use std::fmt;
8
9#[cfg(not(feature = "std"))] use core::convert::{From, Into};
10#[cfg(not(feature = "std"))] use core::str::FromStr;
11#[cfg(not(feature = "std"))] use core::ops::{Add, Sub, Not, Mul, Div, Shr, Shl, BitAnd, BitOr, BitXor, Rem};
12#[cfg(not(feature = "std"))] use core::cmp::Ordering;
13#[cfg(not(feature = "std"))] use core::fmt;
14
15#[cfg(feature = "string")]
16use hexutil::ParseHexError;
17#[cfg(feature = "rlp")]
18use rlp::{Encodable, Decodable, RlpStream, DecoderError, UntrustedRlp};
19use super::{U512, U256, H256, H160};
20
21#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
22/// Represent an unsigned modulo 256-bit integer
23pub struct M256(pub U256);
24
25impl M256 {
26    /// Zero value of M256,
27    pub fn zero() -> M256 { M256(U256::zero()) }
28    /// One value of M256,
29    pub fn one() -> M256 { M256(U256::one()) }
30    /// Maximum value of M256,
31    pub fn max_value() -> M256 { M256(U256::max_value()) }
32    /// Minimum value of M256,
33    pub fn min_value() -> M256 { M256(U256::min_value()) }
34    /// Bits required to represent this value.
35    pub fn bits(self) -> usize { self.0.bits() }
36    /// Equals `floor(log2(*))`. This is always an integer.
37    pub fn log2floor(self) -> usize { self.0.log2floor() }
38    /// Conversion to u32 with overflow checking
39    ///
40    /// # Panics
41    ///
42    /// Panics if the number is larger than 2^32.
43    pub fn as_u32(&self) -> u32 {
44        self.0.as_u32()
45    }
46    /// Conversion to u64 with overflow checking
47    ///
48    /// # Panics
49    ///
50    /// Panics if the number is larger than 2^64.
51    pub fn as_u64(&self) -> u64 {
52        self.0.as_u64()
53    }
54    /// Conversion to usize with overflow checking
55    ///
56    /// # Panics
57    ///
58    /// Panics if the number is larger than usize::max_value().
59    pub fn as_usize(&self) -> usize {
60        self.0.as_usize()
61    }
62    /// Return specific byte.
63    ///
64    /// # Panics
65    ///
66    /// Panics if `index` exceeds the byte width of the number.
67    #[inline]
68    pub fn byte(&self, index: usize) -> u8 {
69        self.0.byte(index)
70    }
71    /// Return specific byte in big-endian format.
72    ///
73	/// # Panics
74	///
75	/// Panics if `index` exceeds the byte width of the number.
76    #[inline]
77    pub fn index(&self, index: usize) -> u8 {
78        self.0.index(index)
79    }
80}
81
82impl Default for M256 { fn default() -> M256 { M256::zero() } }
83
84#[cfg(feature = "string")]
85impl FromStr for M256 {
86    type Err = ParseHexError;
87
88    fn from_str(s: &str) -> Result<M256, ParseHexError> {
89        U256::from_str(s).map(|s| M256(s))
90    }
91}
92
93#[cfg(feature = "rlp")]
94impl Encodable for M256 {
95    fn rlp_append(&self, s: &mut RlpStream) {
96        self.0.rlp_append(s);
97    }
98}
99
100#[cfg(feature = "rlp")]
101impl Decodable for M256 {
102    fn decode(rlp: &UntrustedRlp) -> Result<Self, DecoderError> {
103        Ok(M256(U256::decode(rlp)?))
104    }
105}
106
107impl From<u64> for M256 { fn from(val: u64) -> M256 { M256(U256::from(val)) } }
108impl Into<u64> for M256 { fn into(self) -> u64 { self.0.into() } }
109impl From<usize> for M256 { fn from(val: usize) -> M256 { M256(U256::from(val)) } }
110impl<'a> From<&'a [u8]> for M256 { fn from(val: &'a [u8]) -> M256 { M256(U256::from(val)) } }
111impl From<bool> for M256 {
112    fn from(val: bool) -> M256 {
113        if val {
114            M256::one()
115        } else {
116            M256::zero()
117        }
118    }
119}
120impl From<U256> for M256 { fn from(val: U256) -> M256 { M256(val) } }
121impl Into<U256> for M256 { fn into(self) -> U256 { self.0 } }
122impl From<U512> for M256 { fn from(val: U512) -> M256 { M256(val.into()) } }
123impl Into<U512> for M256 { fn into(self) -> U512 { self.0.into() } }
124impl From<i32> for M256 { fn from(val: i32) -> M256 { (val as u64).into() } }
125impl From<H256> for M256 {
126    fn from(val: H256) -> M256 {
127        let inter: U256 = val.into();
128        inter.into()
129    }
130}
131impl From<M256> for H256 {
132    fn from(val: M256) -> H256 {
133        let inter: U256 = val.into();
134        inter.into()
135    }
136}
137impl From<H160> for M256 {
138    fn from(val: H160) -> M256 {
139        let inter: H256 = val.into();
140        inter.into()
141    }
142}
143impl From<M256> for H160 {
144    fn from(val: M256) -> H160 {
145        let inter: H256 = val.into();
146        inter.into()
147    }
148}
149
150impl Ord for M256 { fn cmp(&self, other: &M256) -> Ordering { self.0.cmp(&other.0) } }
151impl PartialOrd for M256 {
152    fn partial_cmp(&self, other: &M256) -> Option<Ordering> {
153        self.0.partial_cmp(&other.0)
154    }
155}
156
157impl BitAnd<M256> for M256 {
158    type Output = M256;
159
160    fn bitand(self, other: M256) -> M256 {
161        M256(self.0.bitand(other.0))
162    }
163}
164
165impl BitOr<M256> for M256 {
166    type Output = M256;
167
168    fn bitor(self, other: M256) -> M256 {
169        M256(self.0.bitor(other.0))
170    }
171}
172
173impl BitXor<M256> for M256 {
174    type Output = M256;
175
176    fn bitxor(self, other: M256) -> M256 {
177        M256(self.0.bitxor(other.0))
178    }
179}
180
181impl Shl<usize> for M256 {
182    type Output = M256;
183
184    fn shl(self, shift: usize) -> M256 {
185        M256(self.0.shl(shift))
186    }
187}
188
189impl Shr<usize> for M256 {
190    type Output = M256;
191
192    fn shr(self, shift: usize) -> M256 {
193        M256(self.0.shr(shift))
194    }
195}
196
197impl Add<M256> for M256 {
198    type Output = M256;
199
200    fn add(self, other: M256) -> M256 {
201        let (o, _) = self.0.overflowing_add(other.0);
202        M256(o)
203    }
204}
205
206impl Sub<M256> for M256 {
207    type Output = M256;
208
209    fn sub(self, other: M256) -> M256 {
210        if self.0 >= other.0 {
211            M256(self.0 - other.0)
212        } else {
213            M256(U256::max_value() - other.0 + self.0 + U256::from(1u64))
214        }
215    }
216}
217
218impl Mul<M256> for M256 {
219    type Output = M256;
220
221    fn mul(self, other: M256) -> M256 {
222        let (o, _) = self.0.overflowing_mul(other.0);
223        M256(o)
224    }
225}
226
227impl Div for M256 {
228    type Output = M256;
229
230    fn div(self, other: M256) -> M256 {
231        if other == M256::zero() {
232            M256::zero()
233        } else {
234            M256(self.0.div(other.0))
235        }
236    }
237}
238
239impl Rem for M256 {
240    type Output = M256;
241
242    fn rem(self, other: M256) -> M256 {
243        if other == M256::zero() {
244            M256::zero()
245        } else {
246            M256(self.0.rem(other.0))
247        }
248    }
249}
250
251impl Not for M256 {
252    type Output = M256;
253
254    fn not(self) -> M256 {
255        M256(self.0.not())
256    }
257}
258
259impl fmt::LowerHex for M256 {
260    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
261        write!(f, "{:x}", self.0)
262    }
263}
264
265impl fmt::UpperHex for M256 {
266    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
267        write!(f, "{:X}", self.0)
268    }
269}
270
271#[cfg(test)]
272mod tests {
273    use super::M256;
274    use std::str::FromStr;
275
276    #[test]
277    pub fn sub() {
278        assert_eq!(M256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap() - M256::from_str("0000000000000000000000000000000100000000000000000000000000000000").unwrap(), M256::from_str("ffffffffffffffffffffffffffffffff00000000000000000000000000000000").unwrap());
279        assert_eq!(M256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap() - M256::from_str("0000000000000000000000000000000000000000000000000000000000000001").unwrap(), M256::from_str("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap());
280        assert_eq!(M256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap() - M256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap(), M256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap());
281    }
282}