esvm_bigint/
m256.rs

1//! Unsigned modulo 256-bit integer
2
3use std::convert::{From, Into};
4use std::str::FromStr;
5use std::ops::{Add, Sub, Not, Mul, Div, Shr, Shl, BitAnd, BitOr, BitXor, Rem};
6use std::cmp::Ordering;
7use std::fmt;
8
9use super::{ParseHexError, U512, U256};
10use rlp::{Encodable, RlpStream};
11
12#[derive(Eq, PartialEq, Debug, Copy, Clone, Hash)]
13/// Represent an unsigned modulo 256-bit integer
14pub struct M256(U256);
15
16impl M256 {
17    /// Zero value of M256,
18    pub fn zero() -> M256 { M256(U256::zero()) }
19    /// One value of M256,
20    pub fn one() -> M256 { M256(U256::one()) }
21    /// Maximum value of M256,
22    pub fn max_value() -> M256 { M256(U256::max_value()) }
23    /// Minimum value of M256,
24    pub fn min_value() -> M256 { M256(U256::min_value()) }
25    /// Bits required to represent this value.
26    pub fn bits(self) -> usize { self.0.bits() }
27    /// Equals `floor(log2(*))`. This is always an integer.
28    pub fn log2floor(self) -> usize { self.0.log2floor() }
29}
30
31impl Default for M256 { fn default() -> M256 { M256::zero() } }
32
33impl FromStr for M256 {
34    type Err = ParseHexError;
35
36    fn from_str(s: &str) -> Result<M256, ParseHexError> {
37        U256::from_str(s).map(|s| M256(s))
38    }
39}
40
41impl Encodable for M256 {
42    fn rlp_append(&self, s: &mut RlpStream) {
43        let leading_empty_bytes = 32 - (self.bits() + 7) / 8;
44        let buffer: [u8; 32] = self.clone().into();
45        s.encoder().encode_value(&buffer[leading_empty_bytes..]);
46    }
47}
48
49impl From<bool> for M256 { fn from(val: bool) -> M256 { M256(U256::from(val)) } }
50impl From<u64> for M256 { fn from(val: u64) -> M256 { M256(U256::from(val)) } }
51impl Into<u64> for M256 { fn into(self) -> u64 { self.0.into() } }
52impl From<usize> for M256 { fn from(val: usize) -> M256 { M256(U256::from(val)) } }
53impl Into<usize> for M256 { fn into(self) -> usize { self.0.into() } }
54impl<'a> From<&'a [u8]> for M256 { fn from(val: &'a [u8]) -> M256 { M256(U256::from(val)) } }
55impl From<[u8; 32]> for M256 { fn from(val: [u8; 32]) -> M256 { M256(U256::from(val)) } }
56impl Into<[u8; 32]> for M256 { fn into(self) -> [u8; 32] { self.0.into() } }
57impl Into<[u32; 8]> for M256 { fn into(self) -> [u32; 8] { self.0.into() } }
58impl From<[u32; 8]> for M256 { fn from(val: [u32; 8]) -> M256 { M256(U256::from(val)) } }
59impl From<U256> for M256 { fn from(val: U256) -> M256 { M256(val) } }
60impl Into<U256> for M256 { fn into(self) -> U256 { self.0 } }
61impl From<U512> for M256 { fn from(val: U512) -> M256 { M256(val.into()) } }
62impl Into<U512> for M256 { fn into(self) -> U512 { self.0.into() } }
63impl From<i32> for M256 { fn from(val: i32) -> M256 { (val as u64).into() } }
64
65impl Ord for M256 { fn cmp(&self, other: &M256) -> Ordering { self.0.cmp(&other.0) } }
66impl PartialOrd for M256 {
67    fn partial_cmp(&self, other: &M256) -> Option<Ordering> {
68        self.0.partial_cmp(&other.0)
69    }
70}
71
72impl BitAnd<M256> for M256 {
73    type Output = M256;
74
75    fn bitand(self, other: M256) -> M256 {
76        M256(self.0.bitand(other.0))
77    }
78}
79
80impl BitOr<M256> for M256 {
81    type Output = M256;
82
83    fn bitor(self, other: M256) -> M256 {
84        M256(self.0.bitor(other.0))
85    }
86}
87
88impl BitXor<M256> for M256 {
89    type Output = M256;
90
91    fn bitxor(self, other: M256) -> M256 {
92        M256(self.0.bitxor(other.0))
93    }
94}
95
96impl Shl<usize> for M256 {
97    type Output = M256;
98
99    fn shl(self, shift: usize) -> M256 {
100        M256(self.0.shl(shift))
101    }
102}
103
104impl Shr<usize> for M256 {
105    type Output = M256;
106
107    fn shr(self, shift: usize) -> M256 {
108        M256(self.0.shr(shift))
109    }
110}
111
112impl Add<M256> for M256 {
113    type Output = M256;
114
115    fn add(self, other: M256) -> M256 {
116        let (o, _) = self.0.overflowing_add(other.0);
117        M256(o)
118    }
119}
120
121impl Sub<M256> for M256 {
122    type Output = M256;
123
124    fn sub(self, other: M256) -> M256 {
125        let (o, _) = self.0.underflowing_sub(other.0);
126        M256(o)
127    }
128}
129
130impl Mul<M256> for M256 {
131    type Output = M256;
132
133    fn mul(self, other: M256) -> M256 {
134        let (o, _) = self.0.overflowing_mul(other.0);
135        M256(o)
136    }
137}
138
139impl Div for M256 {
140    type Output = M256;
141
142    fn div(self, other: M256) -> M256 {
143        if other == M256::zero() {
144            M256::zero()
145        } else {
146            M256(self.0.div(other.0))
147        }
148    }
149}
150
151impl Rem for M256 {
152    type Output = M256;
153
154    fn rem(self, other: M256) -> M256 {
155        if other == M256::zero() {
156            M256::zero()
157        } else {
158            M256(self.0.rem(other.0))
159        }
160    }
161}
162
163impl Not for M256 {
164    type Output = M256;
165
166    fn not(self) -> M256 {
167        M256(self.0.not())
168    }
169}
170
171impl fmt::LowerHex for M256 {
172    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
173        write!(f, "{:x}", self.0)
174    }
175}
176
177impl fmt::UpperHex for M256 {
178    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179        write!(f, "{:X}", self.0)
180    }
181}