openzeppelin_crypto/arithmetic/
mod.rs

1//! This module provides a generic interface, constant functions and common
2//! arithmetics for big integers.
3
4pub mod limb;
5pub mod uint;
6
7use core::{
8    fmt::{Debug, Display},
9    ops::{
10        BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Shl,
11        ShlAssign, Shr, ShrAssign,
12    },
13};
14
15use limb::Limb;
16use zeroize::Zeroize;
17
18use crate::bits::BitIteratorBE;
19
20/// Defines a big integer with a constant length.
21pub trait BigInteger:
22    'static
23    + Copy
24    + Clone
25    + Debug
26    + Default
27    + Display
28    + Eq
29    + Ord
30    + Send
31    + Sized
32    + Sync
33    + Zeroize
34    + From<u128>
35    + From<u64>
36    + From<u32>
37    + From<u16>
38    + From<u8>
39    + BitXorAssign<Self>
40    + for<'a> BitXorAssign<&'a Self>
41    + BitXor<Self, Output = Self>
42    + for<'a> BitXor<&'a Self, Output = Self>
43    + BitAndAssign<Self>
44    + for<'a> BitAndAssign<&'a Self>
45    + BitAnd<Self, Output = Self>
46    + for<'a> BitAnd<&'a Self, Output = Self>
47    + BitOrAssign<Self>
48    + for<'a> BitOrAssign<&'a Self>
49    + BitOr<Self, Output = Self>
50    + for<'a> BitOr<&'a Self, Output = Self>
51    + Shr<u32, Output = Self>
52    + ShrAssign<u32>
53    + Shl<u32, Output = Self>
54    + ShlAssign<u32>
55    + BitIteratorBE
56{
57    /// Number of `usize` limbs representing `Self`.
58    const NUM_LIMBS: usize;
59
60    /// Number of bits in the integer.
61    const BITS: usize = Self::LIMB_BITS * Self::NUM_LIMBS;
62
63    /// Number of bytes in the integer.
64    const BYTES: usize = Self::BITS / 8;
65
66    /// Number of bits in a limb.
67    const LIMB_BITS: usize;
68
69    /// The largest value that can be represented by this integer type.
70    const MAX: Self;
71
72    /// The multiplicative identity element of Self, 1.
73    const ONE: Self;
74
75    /// The additive identity element of Self, 0.
76    const ZERO: Self;
77
78    /// Returns true if this number is odd.
79    ///
80    /// # Examples
81    ///
82    /// ```
83    /// use openzeppelin_crypto::arithmetic::{BigInteger, uint::U64};
84    ///
85    /// let mut one = U64::from(1u64);
86    /// assert!(one.is_odd());
87    /// ```
88    fn is_odd(&self) -> bool;
89
90    /// Returns true if this number is even.
91    ///
92    /// # Examples
93    ///
94    /// ```
95    /// use openzeppelin_crypto::arithmetic::{BigInteger, uint::U64};
96    ///
97    /// let mut two = U64::from(2u64);
98    /// assert!(two.is_even());
99    /// ```
100    fn is_even(&self) -> bool;
101
102    /// Returns true if this number is zero.
103    ///
104    /// # Examples
105    ///
106    /// ```
107    /// use openzeppelin_crypto::arithmetic::{BigInteger, uint::U64};
108    ///
109    /// let mut zero = U64::from(0u64);
110    /// assert!(zero.is_zero());
111    /// ```
112    fn is_zero(&self) -> bool;
113
114    /// Return the minimum number of bits needed to encode this number.
115    ///
116    /// One bit is necessary to encode zero.
117    ///
118    /// # Examples
119    /// ```
120    /// use openzeppelin_crypto::arithmetic::{BigInteger, uint::U64};
121    ///
122    /// let zero = U64::from(0u64);
123    /// assert_eq!(zero.num_bits(), 1);
124    /// let one = U64::from(1u64);
125    /// assert_eq!(one.num_bits(), 1);
126    /// let max = U64::from(u64::MAX);
127    /// assert_eq!(max.num_bits(), 64);
128    /// let u32_max = U64::from(u32::MAX as u64);
129    /// assert_eq!(u32_max.num_bits(), 32);
130    /// ```
131    fn num_bits(&self) -> usize;
132
133    /// Find the `i`-th bit of `self`.
134    ///
135    /// # Examples
136    ///
137    /// ```
138    /// use openzeppelin_crypto::arithmetic::{BigInteger, uint::U64};
139    ///
140    /// let mut one = U64::from(1u64);
141    /// assert!(one.get_bit(0));
142    /// assert!(!one.get_bit(1));
143    /// ```
144    fn get_bit(&self, i: usize) -> bool;
145
146    /// Create bigint from little-endian bytes.
147    ///
148    /// # Panics
149    ///
150    /// * If the number of bytes is not equal to `Self::BYTES`.
151    fn from_bytes_le(bytes: &[u8]) -> Self;
152
153    /// Convert bigint to little-endian bytes.
154    fn into_bytes_le(self) -> alloc::vec::Vec<u8>;
155}