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}