evm_interpreter/uint/mod.rs
1//! Re-export of uint type that is currently use.
2//!
3//! Depending on the feature flag, different underlying crate may be used.
4//! * Default (no feature flag): use `primitive-types` crate.
5//! * `ruint` feature flag: use `ruint` crate.
6
7// H256 and H160 are pretty standardized, and there's no performance difference
8// in different implementations, so we always only use the one from
9// `primitive-types`.
10pub use ::primitive_types::{H160, H256};
11
12/// Extension for specialized U256 operations.
13// Note on name resolution: when trait and struct itself defines functions of
14// identical name, then Rust would by default calls the implementation on the
15// struct directly. We take advantage of this for the extension trait.
16#[doc(hidden)]
17pub trait U256Ext: Sealed + Sized + Eq + PartialEq + Ord + PartialOrd + Clone + Copy {
18 /// Zero value.
19 const ZERO: Self;
20 /// One value.
21 const ONE: Self;
22 /// Value 32.
23 const VALUE_32: Self;
24 /// Value 64.
25 const VALUE_64: Self;
26 /// Value 256.
27 const VALUE_256: Self;
28 /// Usize max.
29 const USIZE_MAX: Self;
30 /// U64 max.
31 const U64_MAX: Self;
32 /// U32 max.
33 const U32_MAX: Self;
34 /// Sign bit mask.
35 const SIGN_BIT_MASK: Self;
36
37 /// An ADDMOD operation for U256.
38 fn add_mod(self, op2: Self, op3: Self) -> Self;
39 /// An MULMOD operation for U256.
40 fn mul_mod(self, op2: Self, op3: Self) -> Self;
41
42 /// Conversion to usize with overflow checking.
43 /// Should panic if the number is larger than usize::MAX.
44 fn to_usize(&self) -> usize {
45 assert!(*self <= Self::USIZE_MAX);
46 self.low_usize()
47 }
48 /// Conversion to u64 with overflow checking.
49 /// Should panic if the number is larger than u64::MAX.
50 fn to_u64(&self) -> u64 {
51 assert!(*self <= Self::U64_MAX);
52 self.low_u64()
53 }
54 /// Conversion to u32 with overflow checking.
55 /// Should panic if the number is larger than u32::MAX.
56 fn to_u32(&self) -> u32 {
57 assert!(*self <= Self::U32_MAX);
58 self.low_u32()
59 }
60
61 /// Lower word of u64.
62 fn low_u64(&self) -> u64;
63 /// Lower word of u32.
64 fn low_u32(&self) -> u32;
65 /// Lower word of usize.
66 fn low_usize(&self) -> usize;
67
68 /// Conversion from u32.
69 fn from_u32(v: u32) -> Self;
70 /// Conversion from u64.
71 fn from_u64(v: u64) -> Self;
72 /// Conversion from usize.
73 fn from_usize(v: usize) -> Self;
74
75 /// Conversion to H256 big-endian.
76 fn to_h256(self) -> H256;
77 /// Conversion from H256 big-endian.
78 fn from_h256(v: H256) -> Self;
79 /// Conversion to H160 big-endian, discard leading bits.
80 fn to_h160(self) -> H160 {
81 self.to_h256().into()
82 }
83 /// Conversion from H160 big-endian, with leading bits as zero.
84 fn from_h160(v: H160) -> Self {
85 Self::from_h256(v.into())
86 }
87
88 /// Whether the value is zero.
89 fn is_zero(&self) -> bool {
90 *self == Self::ZERO
91 }
92 /// Whether a specific bit is set.
93 fn bit(&self, index: usize) -> bool;
94 /// Least number of bits needed to represent the number.
95 fn bits(&self) -> usize;
96 /// Log2 of the value, rounded down.
97 fn log2floor(&self) -> u64;
98 /// Append the value to RLP stream.
99 fn append_to_rlp_stream(&self, rlp: &mut rlp::RlpStream);
100}
101
102// Use default primitive-types U256 implementation.
103#[cfg(not(feature = "ruint"))]
104mod primitive_types;
105#[cfg(not(feature = "ruint"))]
106use self::primitive_types::Sealed;
107#[cfg(not(feature = "ruint"))]
108pub use self::primitive_types::U256;
109
110// Use ruint U256 implementation.
111#[cfg(feature = "ruint")]
112mod ruint;
113#[cfg(feature = "ruint")]
114use self::ruint::Sealed;
115#[cfg(feature = "ruint")]
116pub use self::ruint::U256;
117
118#[cfg(test)]
119mod tests {
120 #[allow(unused_imports)]
121 use super::{U256, U256Ext};
122
123 #[test]
124 fn shl_overflowing() {
125 assert_eq!(U256::ONE << 257, U256::ZERO);
126 }
127}