1use crate::{
2 core::circuits::boolean::{boolean_value::Boolean, byte::Byte},
3 utils::{elliptic_curve::F25519, number::Number},
4};
5use std::ops::Not;
6
7pub trait Equal<Other>: Sized {
8 type Output: Not<Output = Self::Output>;
9
10 fn eq(self, other: Other) -> Self::Output;
11 fn ne(self, other: Other) -> Self::Output {
12 Self::eq(self, other).not()
13 }
14}
15
16pub trait IsZero {
17 type Output;
18
19 fn is_zero(&self) -> Self::Output;
20}
21
22pub trait GreaterEqual<Other>: Sized {
23 type Output: Not<Output = Self::Output>;
24
25 fn ge(self, other: Other) -> Self::Output;
26 fn lt(self, other: Other) -> Self::Output {
27 Self::ge(self, other).not()
28 }
29}
30
31pub trait GreaterThan<Other>: Sized {
32 type Output: Not<Output = Self::Output>;
33
34 fn gt(self, other: Other) -> Self::Output;
35 fn le(self, other: Other) -> Self::Output {
36 Self::gt(self, other).not()
37 }
38}
39
40impl<T> Equal<T> for T
42where
43 T: Eq,
44{
45 type Output = bool;
46
47 fn eq(self, other: T) -> Self::Output {
48 self == other
49 }
50}
51
52impl<T> GreaterEqual<T> for T
54where
55 T: PartialOrd,
56{
57 type Output = bool;
58
59 fn ge(self, other: T) -> Self::Output {
60 self >= other
61 }
62}
63
64impl<T> GreaterThan<T> for T
66where
67 T: PartialOrd,
68{
69 type Output = bool;
70
71 fn gt(self, other: T) -> Self::Output {
72 self > other
73 }
74}
75
76pub trait Selectable<T = Self> {
77 type Conditional;
78 type Output;
79
80 fn construct_selection(condition: Self::Conditional, a: Self, b: T) -> Self::Output;
81}
82
83pub trait Select<T, U, V> {
84 fn select(self, a: T, b: V) -> U;
85}
86
87pub trait Enc<T> {
88 fn reveal(self) -> T;
89}
90
91pub trait FromLeBits<B: Boolean> {
92 fn from_le_bits(bits: Vec<B>, signed: bool) -> Self;
93}
94
95pub trait GetBit {
96 type Output: Boolean;
97
98 fn get_bit(&self, index: usize, signed: bool) -> Self::Output;
99}
100
101pub trait FromLeBytes {
102 fn from_le_bytes(bytes: [u8; 32]) -> Self;
103}
104
105pub trait ToLeBytes {
106 type BooleanOutput: Boolean;
107
108 fn to_le_bytes(self) -> [Byte<Self::BooleanOutput>; 32];
109}
110
111pub trait Random {
112 fn random() -> Self;
113}
114
115pub trait RandomBit {
116 fn random() -> Self;
117}
118
119pub trait Reveal {
120 fn reveal(self) -> Self;
121}
122
123pub trait Invert {
124 fn invert(self, is_expected_non_zero: bool) -> Self;
125}
126
127pub trait Pow {
128 fn pow(self, e: &Number, is_expected_non_zero: bool) -> Self;
129}
130
131pub trait Keccak {
132 fn f1600(state: [Byte<Self>; 200]) -> [Byte<Self>; 200]
133 where
134 Self: Boolean;
135
136 fn sponge<const N: usize>(
137 rate: usize,
138 capacity: usize,
139 input_bytes: Vec<Byte<Self>>,
140 ) -> [Byte<Self>; N]
141 where
142 Self: Boolean,
143 {
144 if input_bytes.len() > 1 << 20 {
145 panic!(
146 "sha3 not supported on inputs of more than 2^20 bytes (found {})",
147 input_bytes.len()
148 );
149 }
150 if rate + capacity != 1600 || rate % 8 != 0 {
151 panic!("rate + capacity must equal 1600 and rate must be a multiple of 8 (found rate: {rate}, capacity: {capacity})");
152 }
153 let mut state = [Byte::from(0u8); 200];
154 let rate_in_bytes = rate / 8;
155 input_bytes.chunks(rate_in_bytes).for_each(|chunk| {
157 chunk.iter().copied().enumerate().for_each(|(i, c)| {
158 state[i] ^= c;
159 });
160 if chunk.len() == rate_in_bytes {
161 state = Keccak::f1600(state);
162 }
163 });
164 let block_size = input_bytes.len() % rate_in_bytes;
166 state[block_size] ^= Byte::from(0x06);
167 state[rate_in_bytes - 1] ^= Byte::from(0x80);
168 state = Keccak::f1600(state);
169 (0..N)
171 .step_by(rate_in_bytes)
172 .fold(Vec::new(), |mut acc, pos| {
173 let block_size = (N - pos).min(rate_in_bytes);
174 acc.append(&mut state[0..block_size].to_vec());
175 if acc.len() < N {
176 state = Keccak::f1600(state);
177 }
178 acc
179 })
180 .try_into()
181 .unwrap_or_else(|v: Vec<Byte<Self>>| {
182 panic!("Expected a Vec of length {N} (found {})", v.len())
183 })
184 }
185}
186
187pub trait WithBooleanBounds {
188 fn with_boolean_bounds(&self) -> Self;
189}
190
191pub trait ToMontgomery {
192 type Output: F25519;
193
194 fn to_montgomery(self, is_expected_non_identity: bool) -> (Self::Output, Self::Output);
195}
196
197pub trait MxeX25519PrivateKey {
198 fn mxe_x25519_private_key() -> Self;
199}
200
201pub trait MxeRescueKey {
202 fn mxe_rescue_key(i: usize) -> Self;
203}
204
205pub trait FromF25519<T: F25519> {
208 #[allow(non_snake_case)]
209 fn from_F25519(value: T) -> Vec<Self>
210 where
211 Self: Sized;
212}