Skip to main content

bobcat_maths/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3use core::{
4    cmp::{Eq, Ordering},
5    fmt::{Debug, Display, Error as FmtError, Formatter, LowerHex, UpperHex},
6    ops::{
7        Add, AddAssign, BitAnd, BitOr, BitOrAssign, BitXor, Deref, DerefMut, Div, Index, IndexMut,
8        Mul, MulAssign, Neg, Not, Rem, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
9    },
10    str::{FromStr, from_utf8_unchecked},
11};
12
13#[allow(unused)]
14use core::ptr::copy_nonoverlapping;
15
16#[cfg(feature = "std")]
17use clap::builder::TypedValueParser;
18
19use bobcat_panic::{panic_on_err_div_by_zero, panic_on_err_overflow};
20
21use num_traits::{One, Zero};
22
23#[cfg(feature = "borsh")]
24use borsh::{BorshDeserialize, BorshSerialize};
25
26#[cfg(feature = "serde")]
27use serde::{
28    Deserialize as SerdeDeserialize, Deserializer as SerdeDeserializer,
29    Serialize as SerdeSerialize, Serializer as SerdeSerializer,
30};
31
32#[cfg(feature = "proptest")]
33pub mod strategies;
34
35#[cfg(feature = "alloc")]
36extern crate alloc;
37
38#[cfg(all(
39    any(feature = "wasm-bindgen", feature = "wasm-bindgen-wasi"),
40    target_arch = "wasm32"
41))]
42use alloc::boxed::Box;
43
44type Address = [u8; 20];
45
46#[cfg(not(feature = "alloy-enabled"))]
47use bobcat_host::*;
48
49#[cfg(feature = "ruint-enabled")]
50use alloy_primitives::{U256, ruint};
51
52#[cfg(feature = "alloc")]
53use alloc::vec::Vec;
54
55#[cfg(any(
56    all(
57        feature = "wasm-bindgen-wasi",
58        target_os = "wasi",
59        any(target_env = "p1", target_env = "p2")
60    ),
61    all(feature = "wasm-bindgen", target_arch = "wasm32")
62))]
63use wasm_bindgen::{
64    convert::{FromWasmAbi, IntoWasmAbi},
65    describe::WasmDescribe,
66};
67
68#[cfg(feature = "alloy-enabled")]
69mod alloy {
70    use super::copy_nonoverlapping;
71
72    pub(crate) use alloy_primitives::U256;
73
74    #[cfg(test)]
75    pub(crate) use alloy_primitives::I256;
76
77    pub(crate) unsafe fn math_div(out: *mut u8, y: *const u8) {
78        unsafe {
79            let x = U256::from_be_slice(&*(out as *const [u8; 32]));
80            let y = U256::from_be_slice(&*(y as *const [u8; 32]));
81            let z = if y.is_zero() {
82                // TODO: I think the node returns 0 when this is the case.
83                U256::ZERO
84            } else {
85                x / y
86            };
87            copy_nonoverlapping(z.to_be_bytes::<32>().as_ptr(), out, 32);
88        }
89    }
90
91    pub(crate) unsafe fn math_mod(out: *mut u8, y: *const u8) {
92        unsafe {
93            let x = U256::from_be_slice(&*(out as *const [u8; 32]));
94            let y = U256::from_be_slice(&*(y as *const [u8; 32]));
95            let z = x % y;
96            copy_nonoverlapping(z.to_be_bytes::<32>().as_ptr(), out, 32);
97        }
98    }
99
100    pub(crate) unsafe fn math_add_mod(a: *mut u8, b: *const u8, c: *const u8) {
101        unsafe {
102            let x = U256::from_be_slice(&*(a as *const [u8; 32]));
103            let y = U256::from_be_slice(&*(b as *const [u8; 32]));
104            let z = U256::from_be_slice(&*(c as *const [u8; 32]));
105            let x = x.add_mod(y, z);
106            copy_nonoverlapping(x.to_be_bytes::<32>().as_ptr(), a, 32);
107        }
108    }
109
110    pub(crate) unsafe fn math_mul_mod(a: *mut u8, b: *const u8, c: *const u8) {
111        unsafe {
112            let x = U256::from_be_slice(&*(a as *const [u8; 32]));
113            let y = U256::from_be_slice(&*(b as *const [u8; 32]));
114            let z = U256::from_be_slice(&*(c as *const [u8; 32]));
115            let x = x.mul_mod(y, z);
116            copy_nonoverlapping(x.to_be_bytes::<32>().as_ptr(), a, 32);
117        }
118    }
119}
120
121#[cfg(feature = "alloy-enabled")]
122use alloy::*;
123
124#[derive(Copy, Clone, PartialEq, Hash)]
125#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
126#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
127#[cfg_attr(feature = "borsh", derive(BorshDeserialize, BorshSerialize))]
128#[repr(transparent)]
129pub struct U(pub [u8; 32]);
130
131#[cfg(feature = "serde")]
132impl SerdeSerialize for U {
133    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
134    where
135        S: SerdeSerializer,
136    {
137        SerdeSerialize::serialize(&self.0, s)
138    }
139}
140
141#[cfg(feature = "serde")]
142impl<'de> SerdeDeserialize<'de> for U {
143    fn deserialize<D>(d: D) -> Result<Self, D::Error>
144    where
145        D: SerdeDeserializer<'de>,
146    {
147        Ok(Self(<[u8; 32] as SerdeDeserialize>::deserialize(d)?))
148    }
149}
150
151#[derive(Copy, Clone, PartialEq, Hash, Debug)]
152#[cfg_attr(feature = "proptest", derive(proptest_derive::Arbitrary))]
153#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
154#[cfg_attr(feature = "borsh", derive(BorshDeserialize, BorshSerialize))]
155#[repr(transparent)]
156pub struct I(pub [u8; 32]);
157
158#[cfg(feature = "alloc")]
159impl From<U> for Vec<u8> {
160    fn from(x: U) -> Self {
161        x.as_vec()
162    }
163}
164
165#[cfg(feature = "std")]
166impl clap::builder::ValueParserFactory for U {
167    type Parser = UValueParser;
168
169    fn value_parser() -> Self::Parser {
170        UValueParser
171    }
172}
173
174#[derive(Clone)]
175pub struct UValueParser;
176
177#[cfg(feature = "std")]
178impl TypedValueParser for UValueParser {
179    type Value = U;
180
181    fn parse_ref(
182        &self,
183        _: &clap::Command,
184        _: Option<&clap::Arg>,
185        value: &std::ffi::OsStr,
186    ) -> Result<Self::Value, clap::Error> {
187        let s = value
188            .to_str()
189            .ok_or_else(|| clap::Error::raw(clap::error::ErrorKind::InvalidUtf8, "bad utf8"))?;
190        U::from_str(s).map_err(|e| {
191            clap::Error::raw(
192                clap::error::ErrorKind::ValueValidation,
193                format!("invalid u256: {e}\n"),
194            )
195        })
196    }
197}
198
199#[cfg(any(
200    all(
201        feature = "wasm-bindgen-wasi",
202        target_os = "wasi",
203        any(target_env = "p1", target_env = "p2")
204    ),
205    all(feature = "wasm-bindgen", target_arch = "wasm32")
206))]
207impl WasmDescribe for U {
208    fn describe() {
209        <Box<[u8]> as WasmDescribe>::describe()
210    }
211}
212
213#[cfg(any(
214    all(
215        feature = "wasm-bindgen-wasi",
216        target_os = "wasi",
217        any(target_env = "p1", target_env = "p2")
218    ),
219    all(feature = "wasm-bindgen", target_arch = "wasm32")
220))]
221impl FromWasmAbi for U {
222    type Abi = u32;
223
224    #[inline]
225    unsafe fn from_abi(js: u32) -> Self {
226        let ptr = js as *const u8;
227        let mut bytes = [0u8; 32];
228        unsafe { copy_nonoverlapping(ptr, bytes.as_mut_ptr(), 32) }
229        U(bytes)
230    }
231}
232
233#[cfg(any(
234    all(
235        feature = "wasm-bindgen-wasi",
236        target_os = "wasi",
237        any(target_env = "p1", target_env = "p2")
238    ),
239    all(feature = "wasm-bindgen", target_arch = "wasm32")
240))]
241impl IntoWasmAbi for U {
242    type Abi = u32;
243
244    #[inline]
245    fn into_abi(self) -> u32 {
246        let ptr = Box::into_raw(Box::new(self.0)) as *const u8;
247        ptr as u32
248    }
249}
250
251pub fn wrapping_div(x: &U, y: &U) -> U {
252    assert!(y.is_some(), "divide by zero");
253    let mut b = *x;
254    unsafe { math_div(b.as_mut_ptr(), y.as_ptr()) }
255    b
256}
257
258fn wrapping_div_quo_rem_b<const C: usize>(x: &[u8; C], denom: &[u8; C]) -> ([u8; C], [u8; C]) {
259    if denom == &[0u8; C] {
260        return ([0u8; C], [0u8; C]);
261    }
262    let mut q = [0u8; C];
263    let mut r = [0u8; C];
264    let mut one = [0u8; C];
265    one[C - 1] = 1;
266    let mut two = [0u8; C];
267    two[C - 1] = 2;
268    let mut i = 0;
269    while i < C * 8 {
270        let bit = (x[i / 8] >> (7 - (i % 8))) & 1;
271        r = wrapping_mul_b::<C>(&r, &two);
272        if bit == 1 {
273            r = wrapping_add_b::<C>(&r, &one);
274        }
275        if r >= *denom {
276            r = wrapping_sub_b::<C>(&r, denom);
277            q[i / 8] |= 1 << (7 - (i % 8));
278        }
279        i += 1;
280    }
281    (q, r)
282}
283
284pub fn wrapping_div_const(x: &U, y: &U) -> U {
285    U(wrapping_div_quo_rem_b::<32>(&x.0, &y.0).0)
286}
287
288#[deprecated = "Use wrapping_div_const instead"]
289pub fn const_wrapping_div(x: &U, y: &U) -> U {
290    wrapping_div_const(x, y)
291}
292
293#[cfg_attr(test, mutants::skip)]
294pub fn checked_div_opt(x: &U, y: &U) -> Option<U> {
295    if y.is_zero() {
296        None
297    } else {
298        Some(wrapping_div(x, y))
299    }
300}
301
302#[cfg_attr(test, mutants::skip)]
303pub fn checked_div(x: &U, y: &U) -> U {
304    panic_on_err_div_by_zero!(checked_div_opt(x, y); "division by zero: {x}")
305}
306
307pub fn modd(x: &U, y: &U) -> U {
308    let mut b = *x;
309    unsafe { math_mod(b.as_mut_ptr(), y.as_ptr()) }
310    b
311}
312
313pub fn mul_mod(mut x: U, y: &U, z: &U) -> U {
314    unsafe { math_mul_mod(x.as_mut_ptr(), y.as_ptr(), z.as_ptr()) }
315    x
316}
317
318const fn wrapping_add_b<const C: usize>(x: &[u8; C], y: &[u8; C]) -> [u8; C] {
319    let mut r = [0u8; C];
320    let mut c = 0;
321    let mut i = C - 1;
322    loop {
323        let s = x[i] as u16 + y[i] as u16 + c;
324        r[i] = s as u8;
325        c = s >> 8;
326        if i == 0 {
327            break;
328        }
329        i -= 1;
330    }
331    r
332}
333
334pub const fn wrapping_add(x: &U, y: &U) -> U {
335    U(wrapping_add_b(&x.0, &y.0))
336}
337
338#[cfg_attr(test, mutants::skip)]
339pub fn checked_add_opt(x: &U, y: &U) -> Option<U> {
340    if y.is_max() {
341        return if x.is_zero() { Some(U::MAX) } else { None };
342    }
343    let z = x.add_mod(y, &U::MAX);
344    if z.is_zero() {
345        return Some(if x.is_zero() { U::ZERO } else { U::MAX });
346    }
347    if z.cmp(x) == Ordering::Less {
348        return None;
349    }
350    Some(z)
351}
352
353#[cfg_attr(test, mutants::skip)]
354pub fn checked_add(x: &U, y: &U) -> U {
355    panic_on_err_overflow!(
356        checked_add_opt(x, y);
357        "checked add overflow: {x}, y: {y}"
358    )
359}
360
361#[cfg_attr(test, mutants::skip)]
362pub fn saturating_add(x: &U, y: &U) -> U {
363    checked_add_opt(x, y).unwrap_or(U::MAX)
364}
365
366const fn wrapping_sub_b<const C: usize>(x: &[u8; C], y: &[u8; C]) -> [u8; C] {
367    let mut neg_y = *y;
368    let mut i = 0;
369    while i < C {
370        neg_y[i] = !neg_y[i];
371        i += 1;
372    }
373    let mut c = 1u16;
374    let mut i = C - 1;
375    loop {
376        let sum = neg_y[i] as u16 + c;
377        neg_y[i] = sum as u8;
378        c = sum >> 8;
379        if i == 0 {
380            break;
381        }
382        i -= 1;
383    }
384    wrapping_add_b(x, &neg_y)
385}
386
387pub const fn wrapping_sub(x: &U, y: &U) -> U {
388    U(wrapping_sub_b::<32>(&x.0, &y.0))
389}
390
391pub fn saturating_sub(x: &U, y: &U) -> U {
392    checked_sub_opt(x, y).unwrap_or(U::ZERO)
393}
394
395#[cfg_attr(test, mutants::skip)]
396pub fn checked_sub_opt(x: &U, y: &U) -> Option<U> {
397    if x < y {
398        None
399    } else {
400        Some(wrapping_sub(x, y))
401    }
402}
403
404#[cfg_attr(test, mutants::skip)]
405pub fn checked_sub(x: &U, y: &U) -> U {
406    panic_on_err_overflow!(checked_sub_opt(x, y); "checked sub overflow: {x}, y: {y}")
407}
408
409pub const fn wrapping_mul_const_b<const C: usize>(x: &[u8; C], y: &[u8; C]) -> [u8; C] {
410    let mut r = [0u8; C];
411    let mut i = 0;
412    while i < C {
413        let mut c = 0u16;
414        let mut j = 0;
415        while j < C {
416            let i_r = i + j;
417            if i_r >= C {
418                break;
419            }
420            let r_idx = C - 1 - i_r;
421            let xi = x[C - 1 - i] as u16;
422            let yj = y[C - 1 - j] as u16;
423            let prod = xi * yj + r[r_idx] as u16 + c;
424            r[r_idx] = prod as u8;
425            c = prod >> 8;
426            j += 1;
427        }
428        i += 1;
429    }
430    r
431}
432
433pub const fn wrapping_mul_const(x: &U, y: &U) -> U {
434    U(wrapping_mul_const_b(&x.0, &y.0))
435}
436
437pub const fn wrapping_mul_b<const C: usize>(x: &[u8; C], y: &[u8; C]) -> [u8; C] {
438    let mut r = [0u8; C];
439    let mut i = 0;
440    while i < C {
441        let mut c = 0u16;
442        let mut j = 0;
443        while j < C {
444            let i_r = i + j;
445            if i_r >= C {
446                break;
447            }
448            let r_idx = C - 1 - i_r;
449            let xi = x[C - 1 - i] as u16;
450            let yj = y[C - 1 - j] as u16;
451            let prod = xi * yj + r[r_idx] as u16 + c;
452            r[r_idx] = prod as u8;
453            c = prod >> 8;
454            j += 1;
455        }
456        i += 1;
457    }
458    r
459}
460
461pub fn wrapping_mul(x: &U, y: &U) -> U {
462    U(wrapping_mul_b(&x.0, &y.0))
463}
464
465#[cfg_attr(test, mutants::skip)]
466#[inline(never)]
467pub fn checked_mul_opt(x: &U, y: &U) -> Option<U> {
468    if x.is_zero() | y.is_zero() {
469        return Some(U::ZERO);
470    }
471    let mut max_div_y = U::MAX;
472    unsafe { math_div(max_div_y.as_mut_ptr(), y.as_ptr()) }
473
474    if x.cmp(&max_div_y) == Ordering::Greater {
475        return None;
476    }
477    let z = mul_mod(*x, y, &U::MAX);
478    Some(if z.is_zero() { U::MAX } else { z })
479}
480
481pub fn checked_mul(x: &U, y: &U) -> U {
482    panic_on_err_overflow!(checked_mul_opt(x, y); "checked mul overflow: {x}, y: {y}")
483}
484
485pub fn saturating_mul(x: &U, y: &U) -> U {
486    checked_mul_opt(x, y).unwrap_or(U::MAX)
487}
488
489pub fn saturating_div(x: &U, y: &U) -> U {
490    checked_div_opt(x, y).unwrap_or(U::MAX)
491}
492
493pub fn widening_mul(x: &U, y: &U) -> [u8; 64] {
494    let shift_128 = &U([
495        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
496        0, 0,
497    ]);
498    let x_hi = x / shift_128;
499    let x_lo = x % shift_128;
500    let y_hi = y / shift_128;
501    let y_lo = y % shift_128;
502    let t0 = x_lo.mul_mod(&y_lo, &U::MAX);
503    let t1 = x_hi.mul_mod(&y_lo, &U::MAX);
504    let t2 = x_lo.mul_mod(&y_hi, &U::MAX);
505    let t3 = x_hi.mul_mod(&y_hi, &U::MAX);
506    let t0_hi = &t0 / shift_128;
507    let t0_lo = &t0 % shift_128;
508    let t1_hi = &t1 / shift_128;
509    let t1_lo = &t1 % shift_128;
510    let t2_hi = &t2 / shift_128;
511    let t2_lo = &t2 % shift_128;
512    let mid = (t0_hi + t1_lo) + t2_lo;
513    let mid_hi = &mid / shift_128;
514    let mid_lo = &mid % shift_128;
515    let mid_lo_shifted = mid_lo.mul_mod(shift_128, &U::MAX);
516    let out_low = t0_lo + mid_lo_shifted;
517    let out_high = t3 + t1_hi + t2_hi + mid_hi;
518    let mut o = [0u8; 64];
519    o[..32].copy_from_slice(&out_high.0);
520    o[32..].copy_from_slice(&out_low.0);
521    o
522}
523
524/// Widening then truncate mul div that's cheaper in codesize that's safe for cold
525/// operations. The most expensive in gas costs.
526pub fn widening_mul_div(x: &U, y: &U, denom: U) -> Option<(U, bool)> {
527    if denom.is_zero() {
528        return None;
529    }
530    if x.is_zero() {
531        return Some((U::ZERO, false));
532    }
533    // We use a boring method if the overflow wouldn't happen:
534    if wrapping_div(&U::MAX, x) >= *y {
535        let l = wrapping_mul(x, y);
536        let carry = x.mul_mod(y, &denom).is_some();
537        return Some((wrapping_div(&l, &denom), carry));
538    }
539    let x = widening_mul(x, y);
540    let mut d = [0u8; 64];
541    d[32..].copy_from_slice(&denom.0);
542    let (q, rem) = wrapping_div_quo_rem_b::<64>(&x, &d);
543    if q[..32] != [0u8; 32] {
544        return None;
545    }
546    let l: [u8; 32] = q[32..].try_into().unwrap();
547    let l = U::from(l);
548    let has_carry = rem[32..] != [0u8; 32];
549    Some((l, has_carry))
550}
551
552pub fn widening_mul_div_round_up(x: &U, y: &U, denom: U) -> Option<U> {
553    let (x, y) = widening_mul_div(x, y, denom)?;
554    if x.is_max() && y {
555        return None;
556    }
557    Some(if y { x + U::ONE } else { x })
558}
559
560/// Muldiv that's used in practice by Uniswap and other on-chain dapps.
561/// Middling in gas costs.
562pub fn mul_div(x: &U, y: &U, mut denom: U) -> Option<(U, bool)> {
563    // Implemented from https://xn--2-umb.com/21/muldiv/
564    if denom.is_zero() {
565        return None;
566    }
567    if x.is_zero() {
568        return Some((U::ZERO, false));
569    }
570    let mut prod0 = wrapping_mul(x, y);
571    let mm = mul_mod(*x, y, &U::MAX);
572    let mut prod1 = wrapping_sub(
573        &wrapping_sub(&mm, &prod0),
574        &if prod0 > mm { U::ONE } else { U::ZERO },
575    );
576    if prod1.is_zero() {
577        let carry = mul_mod(*x, y, &denom).is_some();
578        return Some((wrapping_div(&prod0, &denom), carry));
579    }
580    if prod1 >= denom {
581        return None;
582    }
583    let remainder = mul_mod(*x, y, &denom);
584    let carry = remainder.is_some();
585    if remainder > prod0 {
586        prod1 -= U::ONE;
587    }
588    prod0 = wrapping_sub(&prod0, &remainder);
589    let mut twos = wrapping_sub(&U::ZERO, &denom) & denom;
590    denom = wrapping_div(&denom, &twos);
591    prod0 = wrapping_div(&prod0, &twos);
592    twos = wrapping_add(
593        &wrapping_div(&wrapping_sub(&U::ZERO, &twos), &twos),
594        &U::ONE,
595    );
596    prod0 = prod0 | wrapping_mul(&prod1, &twos);
597    let mut inv = wrapping_mul(&U::from(3u32), &denom) ^ U::from(2u32);
598    for _ in 0..6 {
599        inv = wrapping_mul(
600            &inv,
601            &wrapping_sub(&U::from(2u32), &wrapping_mul(&denom, &inv)),
602        );
603    }
604    Some((wrapping_mul(&prod0, &inv), carry))
605}
606
607pub fn mul_div_round_up(x: &U, y: &U, denom_and_rem: U) -> Option<U> {
608    let (x, y) = mul_div(x, y, denom_and_rem)?;
609    if x.is_max() && y {
610        return None;
611    }
612    Some(if y { x + U::ONE } else { x })
613}
614
615/// The cheapest muldiv operation, but the most expensive in codesize muldiv.
616#[cfg(feature = "ruint-enabled")]
617pub fn ruint_mul_div(x: &U, y: &U, denom: U) -> Option<(U, bool)> {
618    if denom.is_zero() {
619        return None;
620    }
621    let x = U256::from_be_slice(x.as_slice());
622    let y = U256::from_be_slice(y.as_slice());
623    let mut denom = U256::from_be_slice(denom.as_slice());
624    let mut mul_and_quo = x.widening_mul::<256, 4, 512, 8>(y);
625    unsafe {
626        ruint::algorithms::div(mul_and_quo.as_limbs_mut(), denom.as_limbs_mut());
627    }
628    let limbs = mul_and_quo.into_limbs();
629    if limbs[4..] != [0_u64; 4] {
630        return None;
631    }
632    let has_carry = !denom.is_zero();
633    let r = U(U256::from_limbs_slice(&limbs[0..4]).to_be_bytes::<32>());
634    Some((r, has_carry))
635}
636
637#[cfg(feature = "ruint-enabled")]
638pub fn ruint_mul_div_round_up(x: &U, y: &U, denom: U) -> Option<U> {
639    let (x, y) = ruint_mul_div(x, y, denom)?;
640    if x.is_max() && y {
641        return None;
642    }
643    Some(if y { x + U::ONE } else { x })
644}
645
646/// Rooti iterative method based on the 9lives implementation. Using this
647/// operation is the equivalent of pow(x, 1/n).
648pub fn checked_rooti(x: U, n: u32) -> Option<U> {
649    if n == 0 {
650        return None;
651    }
652    if x.is_zero() {
653        return Some(U::ZERO);
654    }
655    if n == 1 {
656        return Some(x);
657    }
658    // Due to the nature of this iterative method, we hardcode some
659    // values to have consistency with the 9lives reference.
660    if x == U::from(4u32) && n == 2 {
661        return Some(U::from(2u32));
662    }
663    let n_u256 = U::from(n);
664    let n_1 = n_u256 - U::ONE;
665    // Initial guess: 2^ceil(bits(x)/n)
666    let mut b = 0;
667    let mut t = x;
668    while t.is_some() {
669        b += 1;
670        t >>= 1;
671    }
672    let shift = (b + n as usize - 1) / n as usize;
673    let mut z = U::ONE << shift;
674    let mut y = x;
675    // Newton's method:
676    while z < y {
677        y = z;
678        let p = z.checked_pow(&n_1)?;
679        z = ((x / p) + (z * n_1)) / n_u256;
680    }
681    // Correct overshoot:
682    if y.checked_pow(&n_u256)? > x {
683        y -= U::ONE;
684    }
685    Some(y)
686}
687
688pub fn wrapping_pow(x: &U, exp: &U) -> U {
689    let mut r = U::ONE;
690    let mut i = U::ZERO;
691    while &i < exp {
692        r = wrapping_mul(&r, x);
693        i += U::ONE;
694    }
695    r
696}
697
698pub fn checked_pow(x: &U, exp: &U) -> Option<U> {
699    let mut r = U::ONE;
700    let mut i = U::ZERO;
701    while &i < exp {
702        r = checked_mul_opt(&r, x)?;
703        i += U::ONE;
704    }
705    Some(r)
706}
707
708impl Add for U {
709    type Output = U;
710
711    fn add(self, rhs: U) -> U {
712        cfg_if::cfg_if! {
713            if #[cfg(debug_assertions)] {
714                checked_add_opt(&self, &rhs).expect("overflow when add")
715            } else {
716                wrapping_add(&self, &rhs)
717            }
718        }
719    }
720}
721
722impl Add for &U {
723    type Output = U;
724
725    fn add(self, rhs: &U) -> U {
726        cfg_if::cfg_if! {
727            if #[cfg(debug_assertions)] {
728                checked_add_opt(self, rhs).expect("overflow when add")
729            } else {
730                wrapping_add(self, rhs)
731            }
732        }
733    }
734}
735
736impl AddAssign for U {
737    fn add_assign(&mut self, o: Self) {
738        *self = *self + o;
739    }
740}
741
742impl Sub for U {
743    type Output = U;
744
745    fn sub(self, rhs: U) -> U {
746        cfg_if::cfg_if! {
747            if #[cfg(debug_assertions)] {
748                checked_sub_opt(&self, &rhs).expect("overflow when sub")
749            } else {
750                wrapping_sub(&self, &rhs)
751            }
752        }
753    }
754}
755
756impl Sub for &U {
757    type Output = U;
758
759    fn sub(self, rhs: &U) -> U {
760        cfg_if::cfg_if! {
761            if #[cfg(debug_assertions)] {
762                checked_sub_opt(self, rhs).expect("overflow when sub")
763            } else {
764                wrapping_sub(self, rhs)
765            }
766        }
767    }
768}
769
770impl SubAssign for U {
771    fn sub_assign(&mut self, o: Self) {
772        *self = *self - o;
773    }
774}
775
776impl Mul for U {
777    type Output = U;
778
779    fn mul(self, rhs: U) -> U {
780        cfg_if::cfg_if! {
781            if #[cfg(debug_assertions)] {
782                checked_mul_opt(&self, &rhs).expect("overflow when mul")
783            } else {
784                wrapping_mul(&self, &rhs)
785            }
786        }
787    }
788}
789
790impl Mul for &U {
791    type Output = U;
792
793    fn mul(self, rhs: &U) -> U {
794        cfg_if::cfg_if! {
795            if #[cfg(debug_assertions)] {
796                checked_mul_opt(self, rhs).expect("overflow when mul")
797            } else {
798                wrapping_mul(self, rhs)
799            }
800        }
801    }
802}
803
804impl MulAssign for U {
805    fn mul_assign(&mut self, rhs: Self) {
806        *self = *self * rhs
807    }
808}
809
810impl Div for U {
811    type Output = U;
812
813    fn div(self, rhs: U) -> U {
814        cfg_if::cfg_if! {
815            if #[cfg(debug_assertions)] {
816                checked_div_opt(&self, &rhs).expect("overflow when div")
817            } else {
818                wrapping_div(&self, &rhs)
819            }
820        }
821    }
822}
823
824impl Div for &U {
825    type Output = U;
826
827    fn div(self, rhs: &U) -> U {
828        cfg_if::cfg_if! {
829            if #[cfg(debug_assertions)] {
830                checked_div_opt(self, rhs).expect("overflow when div")
831            } else {
832                wrapping_div(self, rhs)
833            }
834        }
835    }
836}
837
838impl Rem for U {
839    type Output = U;
840
841    fn rem(self, rhs: U) -> U {
842        modd(&self, &rhs)
843    }
844}
845
846impl Rem for &U {
847    type Output = U;
848
849    fn rem(self, rhs: &U) -> U {
850        modd(self, rhs)
851    }
852}
853
854impl Shl<usize> for U {
855    type Output = Self;
856
857    fn shl(self, shift: usize) -> Self::Output {
858        if shift >= 256 {
859            return U::ZERO;
860        }
861        let mut result = [0u8; 32];
862        let byte_shift = shift / 8;
863        let bit_shift = shift % 8;
864        if bit_shift == 0 {
865            for i in 0..(32 - byte_shift) {
866                result[i] = self.0[i + byte_shift];
867            }
868        } else {
869            let mut carry = 0u8;
870            for i in (byte_shift..32).rev() {
871                let src_idx = i;
872                let dst_idx = i - byte_shift;
873                let byte = self.0[src_idx];
874                result[dst_idx] = (byte << bit_shift) | carry;
875                carry = byte >> (8 - bit_shift);
876            }
877        }
878        U(result)
879    }
880}
881
882impl ShlAssign<usize> for U {
883    fn shl_assign(&mut self, rhs: usize) {
884        *self = *self << rhs
885    }
886}
887
888impl BitAnd for U {
889    type Output = Self;
890
891    fn bitand(self, rhs: Self) -> Self::Output {
892        let mut r = U::ZERO;
893        for i in 0..32 {
894            r[i] = self[i] & rhs[i];
895        }
896        r
897    }
898}
899
900impl BitOr for U {
901    type Output = Self;
902
903    fn bitor(self, rhs: Self) -> Self::Output {
904        let mut r = U::ZERO;
905        for i in 0..32 {
906            r[i] = self[i] | rhs[i];
907        }
908        r
909    }
910}
911
912impl BitXor for U {
913    type Output = Self;
914    fn bitxor(self, rhs: Self) -> Self::Output {
915        let mut r = U::ZERO;
916        for i in 0..32 {
917            r[i] = self[i] ^ rhs[i];
918        }
919        r
920    }
921}
922
923impl BitOrAssign for U {
924    fn bitor_assign(&mut self, rhs: Self) {
925        *self = *self | rhs
926    }
927}
928
929impl Shr<usize> for U {
930    type Output = Self;
931
932    fn shr(self, shift: usize) -> Self::Output {
933        if shift >= 256 {
934            return U::ZERO;
935        }
936        let mut result = U::ZERO;
937        let byte_shift = shift / 8;
938        let bit_shift = shift % 8;
939        if bit_shift == 0 {
940            for i in byte_shift..32 {
941                result[i] = self.0[i - byte_shift];
942            }
943        } else {
944            let mut carry = 0u8;
945            for i in 0..(32 - byte_shift) {
946                let src_idx = i;
947                let dst_idx = i + byte_shift;
948                let byte = self.0[src_idx];
949                result[dst_idx] = (byte >> bit_shift) | carry;
950                carry = byte << (8 - bit_shift);
951            }
952        }
953        result
954    }
955}
956
957impl ShrAssign<usize> for U {
958    fn shr_assign(&mut self, rhs: usize) {
959        *self = *self >> rhs
960    }
961}
962
963impl Eq for U {}
964
965impl PartialOrd for U {
966    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
967        Some(self.cmp(other))
968    }
969}
970
971impl Ord for U {
972    fn cmp(&self, other: &Self) -> Ordering {
973        self.0.cmp(&other.0)
974    }
975}
976
977impl LowerHex for U {
978    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
979        let b = self.to_hex_array();
980        write!(f, "{}", unsafe { from_utf8_unchecked(&b) })
981    }
982}
983
984impl UpperHex for U {
985    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
986        let mut b = [0u8; 32 * 2];
987        const_hex::encode_to_slice_upper(self.0, &mut b).unwrap();
988        write!(f, "{}", unsafe { from_utf8_unchecked(&b) })
989    }
990}
991
992impl Debug for U {
993    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
994        write!(f, "{self:x}")
995    }
996}
997
998impl Not for U {
999    type Output = Self;
1000
1001    fn not(mut self) -> Self::Output {
1002        for i in 0..32 {
1003            self[i] = !self[i]
1004        }
1005        self
1006    }
1007}
1008
1009impl Neg for U {
1010    type Output = Self;
1011
1012    fn neg(self) -> Self {
1013        let mut r = U::ZERO;
1014        let mut carry = 1u16;
1015        for i in (0..32).rev() {
1016            let inverted = !self.0[i] as u16;
1017            let sum = inverted + carry;
1018            r[i] = sum as u8;
1019            carry = sum >> 8;
1020        }
1021        r
1022    }
1023}
1024
1025#[derive(Debug, Clone, PartialEq)]
1026pub enum UFromStrErr {
1027    InvalidChar(char),
1028    Overflow,
1029    Empty,
1030}
1031
1032impl Display for UFromStrErr {
1033    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1034        write!(f, "{self:?}")
1035    }
1036}
1037
1038impl core::error::Error for UFromStrErr {}
1039
1040impl FromStr for U {
1041    type Err = UFromStrErr;
1042
1043    fn from_str(s: &str) -> Result<Self, Self::Err> {
1044        if s.is_empty() {
1045            return Err(UFromStrErr::Empty);
1046        }
1047        let mut r = U::ZERO;
1048        for c in s.chars() {
1049            r *= U::from_u32(10);
1050            r += match c {
1051                '0'..='9' => U::from(c as u8 - b'0'),
1052                _ => return Err(UFromStrErr::InvalidChar(c)),
1053            };
1054        }
1055        Ok(r)
1056    }
1057}
1058
1059impl U {
1060    pub const ZERO: Self = U([0u8; 32]);
1061
1062    pub const MAX: Self = U([u8::MAX; 32]);
1063
1064    pub const ONE: Self = U([
1065        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1066        0, 1,
1067    ]);
1068
1069    pub fn is_true(&self) -> bool {
1070        self.0[31] == 1
1071    }
1072
1073    pub const fn is_zero(&self) -> bool {
1074        let mut i = 0;
1075        while i < 32 {
1076            if self.0[i] != 0 {
1077                return false;
1078            }
1079            i += 1;
1080        }
1081        true
1082    }
1083
1084    pub fn abs_diff(&self, y: &U) -> U {
1085        if self > y { self - y } else { y - self }
1086    }
1087
1088    pub const fn const_addr(self) -> Address {
1089        self.const_20_slice()
1090    }
1091
1092    pub const fn is_max_const(&self) -> bool {
1093        let mut i = 0;
1094        while i < 32 {
1095            if self.0[i] != u8::MAX {
1096                return false;
1097            }
1098            i += 1;
1099        }
1100        true
1101    }
1102
1103    pub fn is_max(&self) -> bool {
1104        self.0 == [0xffu8; 32]
1105    }
1106
1107    pub fn is_some(&self) -> bool {
1108        !self.is_zero()
1109    }
1110
1111    pub fn trailing_zeros(&self) -> usize {
1112        let mut count = 0;
1113        for i in (0..32).rev() {
1114            if self[i] == 0 {
1115                count += 8;
1116            } else {
1117                count += self[i].trailing_zeros() as usize;
1118                break;
1119            }
1120        }
1121        count
1122    }
1123
1124    pub fn as_slice(&self) -> &[u8; 32] {
1125        &self.0
1126    }
1127
1128    pub const fn from_slice_leftpad(x: &[u8]) -> Option<U> {
1129        if x.len() > 32 {
1130            return None;
1131        }
1132        let mut b = [0u8; 32];
1133        let mut i = 0;
1134        while i < x.len() {
1135            b[32 - x.len() + i] = x[i];
1136            i += 1;
1137        }
1138        Some(U(b))
1139    }
1140
1141    /// Write a string encoding of self to a buffer given. It can be converted
1142    /// using `from_utf8_unchecked` to a string.
1143    pub const fn str_slice_buf(&self, res: &mut [u8; 78]) -> usize {
1144        if self.is_zero() {
1145            res[0] = b'0';
1146            return 1;
1147        }
1148        let mut i = 0;
1149        let mut b = 0;
1150        while b < 32 {
1151            let mut carry = self.0[b] as u32;
1152            let mut j = 0;
1153            while j < i {
1154                let temp = (res[j] as u32) * 256 + carry;
1155                res[j] = (temp % 10) as u8;
1156                carry = temp / 10;
1157                j += 1;
1158            }
1159            while carry > 0 {
1160                res[i] = (carry % 10) as u8;
1161                i += 1;
1162                carry /= 10;
1163            }
1164            b += 1;
1165        }
1166        let mut j = 0;
1167        while j < i / 2 {
1168            let temp = res[j];
1169            res[j] = res[i - 1 - j];
1170            res[i - 1 - j] = temp;
1171            j += 1;
1172        }
1173        j = 0;
1174        while j < i {
1175            res[j] += b'0';
1176            j += 1;
1177        }
1178        i
1179    }
1180
1181    pub const fn str<'a>(&'a self, result: &'a mut [u8; 78]) -> &'a str {
1182        let i = self.str_slice_buf(result);
1183        unsafe { core::str::from_utf8_unchecked(core::slice::from_raw_parts(result.as_ptr(), i)) }
1184    }
1185
1186    /// Get a slice that can be converted to utf8 with
1187    /// `core::str::from_utf8_unchecked`. Returns the slice and the
1188    /// length that was written.
1189    pub const fn str_slice(&self) -> ([u8; 78], usize) {
1190        let mut buf = [0u8; 78];
1191        let i = self.str_slice_buf(&mut buf);
1192        (buf, i)
1193    }
1194
1195    pub fn addr(self) -> [u8; 20] {
1196        self.into()
1197    }
1198
1199    #[cfg(feature = "alloc")]
1200    pub fn as_vec(self) -> Vec<u8> {
1201        self.0.to_vec()
1202    }
1203
1204    pub fn checked_add_opt(&self, y: &Self) -> Option<Self> {
1205        checked_add_opt(self, y)
1206    }
1207
1208    pub fn checked_add(&self, y: &Self) -> Self {
1209        checked_add(self, y)
1210    }
1211
1212    pub fn checked_mul_opt(&self, y: &Self) -> Option<Self> {
1213        checked_mul_opt(self, y)
1214    }
1215
1216    pub fn checked_mul(&self, y: &Self) -> Self {
1217        checked_mul(self, y)
1218    }
1219
1220    pub fn checked_sub_opt(&self, y: &Self) -> Option<Self> {
1221        checked_sub_opt(self, y)
1222    }
1223
1224    pub fn checked_sub(&self, y: &Self) -> Self {
1225        checked_sub(self, y)
1226    }
1227
1228    pub fn checked_div_opt(&self, y: &Self) -> Option<Self> {
1229        checked_div_opt(self, y)
1230    }
1231
1232    pub fn checked_div(&self, y: &Self) -> Self {
1233        checked_div(self, y)
1234    }
1235
1236    pub fn checked_pow(&self, exp: &U) -> Option<Self> {
1237        checked_pow(self, exp)
1238    }
1239
1240    pub fn wrapping_add(&self, y: &Self) -> U {
1241        wrapping_add(self, y)
1242    }
1243
1244    pub fn wrapping_sub(&self, y: &Self) -> U {
1245        wrapping_sub(self, y)
1246    }
1247
1248    pub fn wrapping_mul(&self, y: &Self) -> U {
1249        wrapping_mul(self, y)
1250    }
1251
1252    pub fn wrapping_div(&self, y: &Self) -> U {
1253        wrapping_div(self, y)
1254    }
1255
1256    pub fn saturating_add(&self, y: &Self) -> U {
1257        saturating_add(self, y)
1258    }
1259
1260    pub fn saturating_sub(&self, y: &Self) -> U {
1261        saturating_sub(self, y)
1262    }
1263
1264    pub fn saturating_mul(&self, y: &Self) -> U {
1265        saturating_mul(self, y)
1266    }
1267
1268    pub fn saturating_div(&self, y: &Self) -> Self {
1269        saturating_div(self, y)
1270    }
1271
1272    pub fn wrapping_neg(self) -> Self {
1273        let mut x = self;
1274        let mut carry = 1u8;
1275        for b in x.iter_mut().rev() {
1276            *b = (!*b).wrapping_add(carry);
1277            carry = b.is_zero() as u8;
1278        }
1279        x
1280    }
1281
1282    pub fn mul_div(&self, y: &Self, z: Self) -> Option<(Self, bool)> {
1283        mul_div(self, y, z)
1284    }
1285
1286    pub fn mul_div_round_up(&self, y: &Self, z: Self) -> Option<Self> {
1287        mul_div_round_up(self, y, z)
1288    }
1289
1290    pub fn widening_mul_div(&self, y: &Self, z: Self) -> Option<(Self, bool)> {
1291        widening_mul_div(self, y, z)
1292    }
1293
1294    pub fn widening_mul_div_round_up(&self, y: &Self, z: Self) -> Option<Self> {
1295        widening_mul_div_round_up(self, y, z)
1296    }
1297
1298    #[cfg(feature = "ruint-enabled")]
1299    pub fn ruint_mul_div(&self, y: &Self, z: Self) -> Option<(Self, bool)> {
1300        ruint_mul_div(self, y, z)
1301    }
1302
1303    #[cfg(feature = "ruint-enabled")]
1304    pub fn ruint_mul_div_round_up(&self, y: &Self, z: Self) -> Option<Self> {
1305        ruint_mul_div_round_up(self, y, z)
1306    }
1307
1308    pub fn mul_mod(&self, y: &Self, z: &Self) -> Self {
1309        mul_mod(*self, y, z)
1310    }
1311
1312    pub fn add_mod(&self, y: &Self, z: &Self) -> Self {
1313        let mut b = self.0;
1314        unsafe { math_add_mod(b.as_mut_ptr(), y.as_ptr(), z.as_ptr()) }
1315        Self(b)
1316    }
1317
1318    pub fn checked_rooti(self, x: u32) -> Option<Self> {
1319        checked_rooti(self, x)
1320    }
1321
1322    pub fn wrapping_ceil_div(&self, y: &Self) -> Self {
1323        if self.is_zero() || y.is_zero() {
1324            return U::ZERO;
1325        }
1326        self.wrapping_sub(&U::ONE)
1327            .wrapping_div(y)
1328            .wrapping_add(&U::ONE)
1329    }
1330
1331    pub fn checked_ceil_div(&self, y: &Self) -> Self {
1332        if self.is_zero() || y.is_zero() {
1333            return U::ZERO;
1334        }
1335        let v = panic_on_err_overflow!(
1336            checked_sub_opt(self, &U::ONE);
1337            "checked ceil div checked sub overflow: {self}, y: {}",
1338            U::ONE
1339        );
1340        let v = panic_on_err_overflow!(
1341            checked_div_opt(&v, y);
1342            "checked ceil div checked div overflow: {v}, y: {y}"
1343        );
1344        panic_on_err_overflow!(
1345            checked_add_opt(&v, &U::ONE);
1346            "checked ceil div checked add overflow: {v}, y: {}",
1347            U::ONE
1348        )
1349    }
1350
1351    pub fn checked_ceil_div_opt(&self, y: &Self) -> Option<Self> {
1352        if self.is_zero() || y.is_zero() {
1353            return Some(U::ZERO);
1354        }
1355        self.checked_sub_opt(&U::ONE)?
1356            .checked_div_opt(y)?
1357            .checked_add_opt(&U::ONE)
1358    }
1359
1360    pub fn from_hex(x: &str) -> Option<U> {
1361        match const_hex::decode_to_array::<_, 32>(x) {
1362            Ok(v) => Some(U(v)),
1363            Err(_) => None,
1364        }
1365    }
1366
1367    pub const fn const_from_hex(x: &[u8]) -> Option<U> {
1368        match const_hex::const_decode_to_array::<32>(x) {
1369            Ok(v) => Some(U(v)),
1370            Err(_) => None,
1371        }
1372    }
1373
1374    /// Convert U to a lowercase hex string using a buffer.
1375    pub fn to_hex_str_buf<'a>(&'a self, buf: &'a mut [u8; 32 * 2]) -> &'a str {
1376        const_hex::encode_to_str(self.0, buf).unwrap()
1377    }
1378
1379    /// Convert U to a lowercase hex array that can be written to with `from_utf8_unchecked`.
1380    pub fn to_hex_array(&self) -> [u8; 32 * 2] {
1381        let mut buf = [0u8; 32 * 2];
1382        const_hex::encode_to_slice(self.0, &mut buf).unwrap();
1383        buf
1384    }
1385}
1386
1387impl Display for U {
1388    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1389        let mut buf = [0u8; 78];
1390        write!(f, "{}", self.str(&mut buf))
1391    }
1392}
1393
1394impl From<U> for [u8; 32] {
1395    fn from(x: U) -> Self {
1396        x.0
1397    }
1398}
1399
1400impl From<&U> for U {
1401    fn from(x: &U) -> Self {
1402        *x
1403    }
1404}
1405
1406impl From<U> for bool {
1407    fn from(x: U) -> Self {
1408        x.0[31] == 1
1409    }
1410}
1411
1412impl From<&[u8]> for U {
1413    fn from(x: &[u8]) -> Self {
1414        let x: &[u8; 32] = x.try_into().unwrap();
1415        (*x).into()
1416    }
1417}
1418
1419impl From<&[u8; 32]> for &U {
1420    fn from(x: &[u8; 32]) -> Self {
1421        unsafe { &*(x as *const [u8; 32] as *const U) }
1422    }
1423}
1424
1425impl From<[u8; 32]> for U {
1426    fn from(x: [u8; 32]) -> Self {
1427        U(x)
1428    }
1429}
1430
1431impl Deref for U {
1432    type Target = [u8; 32];
1433
1434    fn deref(&self) -> &Self::Target {
1435        &self.0
1436    }
1437}
1438
1439impl DerefMut for U {
1440    fn deref_mut(&mut self) -> &mut Self::Target {
1441        &mut self.0
1442    }
1443}
1444
1445impl From<bool> for U {
1446    fn from(x: bool) -> Self {
1447        U::from(&[x as u8])
1448    }
1449}
1450
1451impl Zero for U {
1452    fn zero() -> Self {
1453        U::ZERO
1454    }
1455
1456    fn is_zero(&self) -> bool {
1457        self.0.iter().all(|&b| b == 0)
1458    }
1459}
1460
1461impl Default for U {
1462    fn default() -> Self {
1463        U::ZERO
1464    }
1465}
1466
1467impl One for U {
1468    fn one() -> Self {
1469        U::ONE
1470    }
1471}
1472
1473impl Index<usize> for U {
1474    type Output = u8;
1475
1476    fn index(&self, index: usize) -> &Self::Output {
1477        &self.0[index]
1478    }
1479}
1480
1481impl IndexMut<usize> for U {
1482    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1483        &mut self.0[index]
1484    }
1485}
1486
1487impl I {
1488    fn is_neg(&self) -> bool {
1489        self.0[0] & 0x80 != 0
1490    }
1491
1492    pub fn is_zero(&self) -> bool {
1493        *self == Self::ZERO
1494    }
1495
1496    pub fn is_some(&self) -> bool {
1497        !self.is_zero()
1498    }
1499
1500    pub fn as_slice(&self) -> &[u8; 32] {
1501        &self.0
1502    }
1503
1504    fn neg(&self) -> Self {
1505        let x = wrapping_add(&U(self.0.map(|b| !b)), &U::ONE);
1506        I(x.0)
1507    }
1508
1509    fn abs(self) -> U {
1510        if self.is_neg() {
1511            U(self.neg().0)
1512        } else {
1513            U(self.0)
1514        }
1515    }
1516}
1517
1518macro_rules! from_slices {
1519    ($($n:expr),+ $(,)?) => {
1520        $(
1521            paste::paste! {
1522                impl From<&[u8; $n]> for U {
1523                    fn from(x: &[u8; $n]) -> Self {
1524                        let mut b = [0u8; 32];
1525                        b[32 - $n..].copy_from_slice(x);
1526                        U(b)
1527                    }
1528                }
1529
1530                impl From<[u8; $n]> for U {
1531                    fn from(x: [u8; $n]) -> Self {
1532                        U::from(&x)
1533                    }
1534                }
1535
1536                impl U {
1537                    /// Convert U to the slice, ignoring any excess amounts in the slice.
1538                    pub const fn [<const_ $n _unsafe_slice>](self) -> [u8; $n] {
1539                        let mut b = [0u8; $n];
1540                        let mut i = 0;
1541                        while i < $n {
1542                            b[i] = self.0[32-$n+i];
1543                            i += 1;
1544                        }
1545                        b
1546                    }
1547
1548                    /// Convert U to the slice, returning None on an unsafe conversion to
1549                    /// the other slice (there is leftmost data in the slice).
1550                    pub const fn [<const_ $n _safe_slice>](self) -> Option<[u8; $n]> {
1551                        let mut i = 0;
1552                        while i < 32 - $n {
1553                            if self.0[i] != 0 {
1554                                return None;
1555                            }
1556                            i += 1;
1557                        }
1558                        Some(self.[<const_ $n _unsafe_slice>]())
1559                    }
1560
1561                    /// Convert U to the slice, panicking with debug assertions if U is too
1562                    /// large to convert to the slice given.
1563                    pub const fn [<const_ $n _slice>](self) -> [u8; $n] {
1564                        cfg_if::cfg_if! {
1565                            if #[cfg(debug_assertions)] {
1566                                self.[<const_ $n _safe_slice>]().expect("Slice too large")
1567                            } else {
1568                                self.[<const_ $n _unsafe_slice>]()
1569                            }
1570                        }
1571                    }
1572                }
1573
1574                impl From<U> for [u8; $n] {
1575                    /// Convert from U into [u8; $n], panicking during debug if U is too
1576                    /// large to trim safely.
1577                    fn from(x: U) -> Self {
1578                        cfg_if::cfg_if! {
1579                            if #[cfg(debug_assertions)] {
1580                                if 32 > $n {
1581                                    for i in 0..32 - $n {
1582                                        assert_eq!(0, x.0[i], "unsafe slice conversion to slice size {} at {i}, {x:x}", $n)
1583                                    }
1584                                }
1585                            }
1586                        }
1587                        unsafe { *(x.as_ptr().add(32 - $n) as *const [u8; $n]) }
1588                    }
1589                }
1590            }
1591        )+
1592    };
1593}
1594
1595from_slices!(
1596    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
1597    27, 28, 29, 30, 31
1598);
1599
1600impl From<&U> for Address {
1601    fn from(x: &U) -> Self {
1602        (*x).into()
1603    }
1604}
1605
1606macro_rules! from_ints {
1607    ($($t:ty),+ $(,)?) => {
1608        $(
1609            paste::paste! {
1610                impl U {
1611                    pub const fn [<from_ $t>](x: $t) -> U {
1612                        U(array_concat::concat_arrays!(
1613                            [0u8; 32-core::mem::size_of::<$t>()],
1614                            x.to_be_bytes())
1615                        )
1616                    }
1617                }
1618
1619                impl From<$t> for U {
1620                    fn from(x: $t) -> Self {
1621                        U::[<from_ $t>](x)
1622                    }
1623                }
1624
1625                impl From<U> for $t {
1626                    fn from(x: U) -> Self {
1627                        Self::from_be_bytes(x.into())
1628                    }
1629                }
1630
1631                impl PartialEq<$t> for U {
1632                    fn eq(&self, rhs: &$t) -> bool {
1633                        *self == U::from(*rhs)
1634                    }
1635                }
1636
1637                impl PartialOrd<$t> for U {
1638                    fn partial_cmp(&self, rhs: &$t) -> Option<Ordering> {
1639                        let rhs = rhs.to_be_bytes();
1640                        let n = core::mem::size_of::<$t>();
1641                        let split = 32 - n;
1642                        if self.0[..split].iter().any(|&b| b != 0) {
1643                            return Some(Ordering::Greater);
1644                        }
1645                        Some(self.0[split..].cmp(&rhs))
1646                    }
1647                }
1648            }
1649        )+
1650    };
1651}
1652
1653#[macro_export]
1654macro_rules! u {
1655    ($e:expr) => {
1656        $crate::U::from_u32($e)
1657    };
1658}
1659
1660from_ints! { u8, u16, u32, u64, u128, usize }
1661
1662impl From<I> for [u8; 32] {
1663    fn from(x: I) -> Self {
1664        x.0
1665    }
1666}
1667
1668impl From<[u8; 32]> for I {
1669    fn from(x: [u8; 32]) -> Self {
1670        I(x)
1671    }
1672}
1673
1674fn i_add(x: &I, y: &I) -> I {
1675    I(wrapping_add(&U(x.0), &U(y.0)).0)
1676}
1677
1678fn i_sub(x: &I, y: &I) -> I {
1679    I(wrapping_sub(&U(x.0), &U(y.0)).0)
1680}
1681
1682fn i_mul(x: &I, y: &I) -> I {
1683    let result = wrapping_mul(&U(x.0), &U(y.0));
1684    I(result.0)
1685}
1686
1687fn i_div(x: &I, y: &I) -> I {
1688    let r = wrapping_div(&x.abs(), &y.abs());
1689    if x.is_neg() ^ y.is_neg() {
1690        I(r.0).neg()
1691    } else {
1692        I(r.0)
1693    }
1694}
1695
1696fn i_rem(x: &I, y: &I) -> I {
1697    let r = modd(&x.abs(), &y.abs());
1698    if x.is_neg() { I(r.0).neg() } else { I(r.0) }
1699}
1700
1701impl Add for I {
1702    type Output = I;
1703    fn add(self, rhs: I) -> I {
1704        i_add(&self, &rhs)
1705    }
1706}
1707
1708impl Add for &I {
1709    type Output = I;
1710    fn add(self, rhs: &I) -> I {
1711        i_add(self, rhs)
1712    }
1713}
1714
1715impl Sub for I {
1716    type Output = I;
1717    fn sub(self, rhs: I) -> I {
1718        i_sub(&self, &rhs)
1719    }
1720}
1721
1722impl Sub for &I {
1723    type Output = I;
1724    fn sub(self, rhs: &I) -> I {
1725        i_sub(self, rhs)
1726    }
1727}
1728
1729impl Mul for I {
1730    type Output = I;
1731    fn mul(self, rhs: I) -> I {
1732        i_mul(&self, &rhs)
1733    }
1734}
1735
1736impl Mul for &I {
1737    type Output = I;
1738    fn mul(self, rhs: &I) -> I {
1739        i_mul(self, rhs)
1740    }
1741}
1742
1743impl Div for I {
1744    type Output = I;
1745    fn div(self, rhs: I) -> I {
1746        i_div(&self, &rhs)
1747    }
1748}
1749
1750impl Div for &I {
1751    type Output = I;
1752    fn div(self, rhs: &I) -> I {
1753        i_div(self, rhs)
1754    }
1755}
1756
1757impl Rem for I {
1758    type Output = I;
1759    fn rem(self, rhs: I) -> I {
1760        i_rem(&self, &rhs)
1761    }
1762}
1763
1764impl Eq for I {}
1765
1766impl PartialOrd for I {
1767    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
1768        Some(self.cmp(other))
1769    }
1770}
1771
1772impl Ord for I {
1773    fn cmp(&self, other: &Self) -> Ordering {
1774        let self_sign = self.0[0] & 0x80;
1775        let other_sign = other.0[0] & 0x80;
1776        match (self_sign, other_sign) {
1777            (0, 0x80) => Ordering::Greater,
1778            (0x80, 0) => Ordering::Less,
1779            _ => self.0.cmp(&other.0),
1780        }
1781    }
1782}
1783
1784impl Rem for &I {
1785    type Output = I;
1786    fn rem(self, rhs: &I) -> I {
1787        i_rem(self, rhs)
1788    }
1789}
1790
1791impl I {
1792    pub const ZERO: Self = I([0u8; 32]);
1793
1794    pub const ONE: Self = I([
1795        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1796        0, 1,
1797    ]);
1798}
1799
1800impl Zero for I {
1801    fn zero() -> Self {
1802        I::ZERO
1803    }
1804    fn is_zero(&self) -> bool {
1805        self.0.iter().all(|&b| b == 0)
1806    }
1807}
1808
1809impl Default for I {
1810    fn default() -> Self {
1811        I::ZERO
1812    }
1813}
1814
1815impl One for I {
1816    fn one() -> Self {
1817        I::ONE
1818    }
1819}
1820
1821#[test]
1822fn test_is_zeroes() {
1823    assert!(U::ZERO.is_zero());
1824    assert!(U::ONE.is_some());
1825    assert!(I::ZERO.is_zero());
1826    assert!(I::ONE.is_some());
1827}
1828
1829#[cfg(all(
1830    test,
1831    feature = "alloy-enabled",
1832    feature = "proptest",
1833    feature = "std",
1834    not(target_arch = "wasm32")
1835))]
1836mod test {
1837    use proptest::prelude::*;
1838
1839    use super::*;
1840
1841    fn strat_any_u256() -> impl Strategy<Value = U256> {
1842        // Arbitrary seems to be having some issues with U256:
1843        any::<[u8; 32]>().prop_map(U256::from_be_bytes)
1844    }
1845
1846    proptest! {
1847        #[test]
1848        fn wrapping_div_b_zero_denominator_yields_zero(numerator in any::<[u8; 4]>()) {
1849            let zero = [0u8; 4];
1850            prop_assert_eq!(wrapping_div_quo_rem_b::<4>(&numerator, &zero).0, zero);
1851        }
1852
1853        #[test]
1854        fn wrapping_div_b_matches_integer_division(
1855            numerator in any::<[u8; 4]>(),
1856            denominator in any::<[u8; 4]>().prop_filter("denominator must be non-zero", |d| *d != [0u8; 4])
1857        ) {
1858            let numerator_u32 = u32::from_be_bytes(numerator);
1859            let denominator_u32 = u32::from_be_bytes(denominator);
1860            let expected = numerator_u32 / denominator_u32;
1861            prop_assert_eq!(
1862                wrapping_div_quo_rem_b::<4>(&numerator, &denominator).0,
1863                expected.to_be_bytes()
1864            );
1865        }
1866
1867        #[test]
1868        fn wrapping_mod_b_matches_integer_modulo(
1869            numerator in any::<[u8; 4]>(),
1870            denominator in any::<[u8; 4]>().prop_filter("denominator must be non-zero", |d| *d != [0u8; 4])
1871        ) {
1872            let numerator_u32 = u32::from_be_bytes(numerator);
1873            let denominator_u32 = u32::from_be_bytes(denominator);
1874            let expected = numerator_u32 % denominator_u32;
1875            prop_assert_eq!(
1876                wrapping_div_quo_rem_b::<4>(&numerator, &denominator).1,
1877                expected.to_be_bytes()
1878            );
1879        }
1880
1881        #[test]
1882        fn wrapping_add_b_handles_carry(lhs in any::<[u8; 4]>(), rhs in any::<[u8; 4]>()) {
1883            let lhs_u32 = u32::from_be_bytes(lhs);
1884            let rhs_u32 = u32::from_be_bytes(rhs);
1885            let expected = lhs_u32.wrapping_add(rhs_u32);
1886            prop_assert_eq!(wrapping_add_b::<4>(&lhs, &rhs), expected.to_be_bytes());
1887        }
1888
1889        #[test]
1890        fn wrapping_sub_b_handles_borrow(lhs in any::<[u8; 4]>(), rhs in any::<[u8; 4]>()) {
1891            let lhs_u32 = u32::from_be_bytes(lhs);
1892            let rhs_u32 = u32::from_be_bytes(rhs);
1893            let expected = lhs_u32.wrapping_sub(rhs_u32);
1894            prop_assert_eq!(wrapping_sub_b::<4>(&lhs, &rhs), expected.to_be_bytes());
1895        }
1896
1897        #[test]
1898        fn wrapping_mul_b_matches_wrapping_arithmetic(lhs in any::<[u8; 32]>(), rhs in any::<[u8; 32]>()) {
1899            let lhs_u = U::from(lhs);
1900            let rhs_u = U::from(rhs);
1901            let expected = lhs_u.wrapping_mul(&rhs_u);
1902            prop_assert_eq!(wrapping_mul_b::<32>(&lhs, &rhs), expected.0);
1903        }
1904
1905        #[test]
1906        fn const_wrapping_div_agrees_with_wrapping_div_b(
1907            numerator in any::<[u8; 32]>(),
1908            denominator in any::<[u8; 32]>().prop_filter("denominator must be non-zero", |d| *d != [0u8; 32])
1909        ) {
1910            let numerator_u = U::from(numerator);
1911            let denominator_u = U::from(denominator);
1912            prop_assert_eq!(
1913                wrapping_div_const(&numerator_u, &denominator_u).0,
1914                wrapping_div_quo_rem_b::<32>(&numerator, &denominator).0
1915            );
1916        }
1917
1918        #[test]
1919        fn u_predicates_track_zero_and_true(bytes in any::<[u8; 32]>()) {
1920            let value = U::from(bytes);
1921            let is_zero = bytes.iter().all(|&b| b == 0);
1922            prop_assert_eq!(value.is_zero(), is_zero);
1923            prop_assert_eq!(value.is_some(), !is_zero);
1924            prop_assert_eq!(value.is_true(), bytes[31] == 1);
1925        }
1926
1927        #[test]
1928        fn test_u_is_zero(x in any::<[u8; 32]>()) {
1929            let x = U::from(x);
1930            let ex = U256::from_be_bytes(x.0);
1931            assert_eq!(ex.is_zero(), x.is_zero());
1932        }
1933
1934        #[test]
1935        fn test_u_div(x in any::<U>(), y in any::<U>()) {
1936            let ex = U256::from_be_bytes(x.0);
1937            let ey = U256::from_be_bytes(y.0);
1938            assert_eq!((ex.wrapping_div(ey)).to_be_bytes(), x.wrapping_div(&y).0);
1939        }
1940
1941        #[test]
1942        fn test_u_mul(x in any::<U>(), y in any::<U>()) {
1943            let ex = U256::from_be_bytes(x.0);
1944            let ey = U256::from_be_bytes(y.0);
1945            assert_eq!((ex.wrapping_mul(ey)).to_be_bytes(), wrapping_mul(&x,  &y).0);
1946        }
1947
1948        #[test]
1949        fn test_u_mod(x in any::<U>(), y in any::<U>()) {
1950            let ex = U256::from_be_bytes(x.0);
1951            let ey = U256::from_be_bytes(y.0);
1952            assert_eq!((ex % ey).to_be_bytes(), (x % y).0);
1953        }
1954
1955        #[test]
1956        fn test_u_add(x in any::<U>(), y in any::<U>()) {
1957            let ex = U256::from_be_bytes(x.0);
1958            let ey = U256::from_be_bytes(y.0);
1959            let e = U::from(ex.wrapping_add(ey).to_be_bytes::<32>());
1960            assert_eq!(e, x.wrapping_add(&y), "{e} != {}", x + y);
1961        }
1962
1963        #[test]
1964        fn test_u_sub(x in any::<U>(), y in any::<U>()) {
1965            let ex = U256::from_be_bytes(x.0);
1966            let ey = U256::from_be_bytes(y.0);
1967            assert_eq!((ex.wrapping_sub(ey)).to_be_bytes(), x.wrapping_sub(&y).0);
1968        }
1969
1970        #[test]
1971        fn test_u_cmp(x in any::<U>(), y in any::<U>()) {
1972            let ex = U256::from_be_bytes(x.0);
1973            let ey = U256::from_be_bytes(y.0);
1974            assert_eq!(ex.cmp(&ey), x.cmp(&y));
1975        }
1976
1977        #[test]
1978        fn test_u_to_str(x in any::<U>()) {
1979            assert_eq!(U256::from_be_bytes(x.0).to_string(), x.to_string());
1980        }
1981
1982        #[test]
1983        fn test_u_shl(x in any::<U>(), i in any::<usize>()) {
1984            let l = U((U256::from_be_bytes(x.0) << i).to_be_bytes::<32>());
1985            assert_eq!(l, x << i);
1986        }
1987
1988        #[test]
1989        fn test_u_shr(x in any::<U>(), i in any::<usize>()) {
1990            let l = U((U256::from_be_bytes(x.0) >> i).to_be_bytes::<32>());
1991            assert_eq!(l, x >> i);
1992        }
1993
1994        #[test]
1995        fn test_trailing_zeros(x in any::<U>()) {
1996            assert_eq!(U256::from_be_bytes(x.0).trailing_zeros(), x.trailing_zeros());
1997        }
1998
1999        #[test]
2000        fn test_i_is_zero(x in any::<U>()) {
2001            let ex = I256::from_be_bytes(x.0);
2002            assert_eq!(ex.is_zero(), x.is_zero());
2003        }
2004
2005        #[test]
2006        fn test_i_div(x in any::<I>(), y in any::<I>()) {
2007            let ex = I256::from_be_bytes(x.0);
2008            let ey = I256::from_be_bytes(y.0);
2009            assert_eq!((ex / ey).to_be_bytes(), (x / y).0);
2010        }
2011
2012        #[test]
2013        fn test_i_mul(x in any::<I>(), y in any::<I>()) {
2014            let ex = I256::from_be_bytes(x.0);
2015            let ey = I256::from_be_bytes(y.0);
2016            assert_eq!((ex.wrapping_mul(ey)).to_be_bytes(), (x * y).0);
2017        }
2018
2019        #[test]
2020        fn test_i_mod(x in any::<I>(), y in any::<I>()) {
2021            let ex = I256::from_be_bytes(x.0);
2022            let ey = I256::from_be_bytes(y.0);
2023            assert_eq!((ex % ey).to_be_bytes(), (x % y).0);
2024        }
2025
2026        #[test]
2027        fn test_i_add(x in any::<I>(), y in any::<I>()) {
2028            let ex = I256::from_be_bytes(x.0);
2029            let ey = I256::from_be_bytes(y.0);
2030            assert_eq!((ex.wrapping_add(ey)).to_be_bytes(), (x + y).0);
2031        }
2032
2033        #[test]
2034        fn test_i_sub(x in any::<I>(), y in any::<I>()) {
2035            let ex = I256::from_be_bytes(x.0);
2036            let ey = I256::from_be_bytes(y.0);
2037            assert_eq!((ex.wrapping_sub(ey)).to_be_bytes(), (x - y).0);
2038        }
2039
2040        #[test]
2041        fn test_i_cmp(x in any::<I>(), y in any::<I>()) {
2042            let ex = I256::from_be_bytes(x.0);
2043            let ey = I256::from_be_bytes(y.0);
2044            assert_eq!(ex.cmp(&ey), x.cmp(&y));
2045        }
2046
2047        #[test]
2048        fn test_u_u8(x in any::<u8>()) {
2049            let mut b = [0u8; 32];
2050            b[32-size_of::<u8>()..].copy_from_slice(&x.to_be_bytes());
2051            assert_eq!(&U256::from_be_bytes(b).to_be_bytes(), U::from(x).as_slice());
2052        }
2053
2054        #[test]
2055        fn test_u_u16(x in any::<u16>()) {
2056            let mut b = [0u8; 32];
2057            b[32-size_of::<u16>()..].copy_from_slice(&x.to_be_bytes());
2058            assert_eq!(&U256::from_be_bytes(b).to_be_bytes(), U::from(x).as_slice());
2059        }
2060
2061        #[test]
2062        fn test_u_u32(x in any::<u32>()) {
2063            let mut b = [0u8; 32];
2064            b[32-size_of::<u32>()..].copy_from_slice(&x.to_be_bytes());
2065            assert_eq!(&U256::from_be_bytes(b).to_be_bytes(), U::from(x).as_slice());
2066        }
2067
2068        #[test]
2069        fn test_u_u64(x in any::<u64>()) {
2070            let mut b = [0u8; 32];
2071            b[32-size_of::<u64>()..].copy_from_slice(&x.to_be_bytes());
2072            assert_eq!(&U256::from_be_bytes(b).to_be_bytes(), U::from(x).as_slice());
2073        }
2074
2075        #[test]
2076        fn test_u_u128(x in any::<u128>()) {
2077            let mut b = [0u8; 32];
2078            b[32-size_of::<u128>()..].copy_from_slice(&x.to_be_bytes());
2079            assert_eq!(&U256::from_be_bytes(b).to_be_bytes(), U::from(x).as_slice());
2080        }
2081
2082        #[test]
2083        fn test_to_and_from_addrs(x in any::<Address>()) {
2084            let y: Address = U::from(x).into();
2085            assert_eq!(x, y)
2086        }
2087
2088        #[test]
2089        fn test_u_conv_to_and_from_u8(x in any::<u8>()) {
2090            if let Some(exp) = x.checked_add(1) {
2091                let cmp = U::from(x).wrapping_add(&U::ONE);
2092                assert_eq!(exp, cmp.into(), "exp: {exp} ne {cmp}");
2093            }
2094        }
2095
2096        #[test]
2097        fn test_print_to_and_from(x in any::<[u8; 32]>()) {
2098            let e = format!("{}", U256::from_be_bytes(x));
2099            let v = format!("{}", U(x));
2100            assert_eq!(e, v);
2101        }
2102
2103        #[test]
2104        fn test_u_from_str(x in strat_any_u256()) {
2105            let v = U::from_str(x.to_string().as_str()).unwrap();
2106            assert_eq!(
2107                U::from(x.to_be_bytes::<32>()),
2108                v,
2109                "{x} != {v}",
2110            )
2111        }
2112
2113        #[test]
2114        fn array_truncate(x in any::<[u8; 20]>()) {
2115            assert_eq!(x, U::from(x).const_addr());
2116        }
2117    }
2118}