1use crate::{
2 core::{
3 circuits::boolean::{
4 boolean_value::{Boolean, BooleanValue},
5 byte::Byte,
6 },
7 expressions::{expr::Expr, other_expr::OtherExpr},
8 global_value::value::FieldValue,
9 },
10 traits::{
11 FromLeBits,
12 FromLeBytes,
13 MxeRescueKey,
14 MxeX25519PrivateKey,
15 Random,
16 Reveal,
17 ToMontgomery,
18 },
19 utils::{
20 curve_point::{Curve, CurvePoint},
21 elliptic_curve::{is_valid_x25519_public_key, AffineEdwardsPoint, F25519},
22 field::{BaseField, ScalarField},
23 matrix::Matrix,
24 },
25 MxeBitInput,
26 MxeInput,
27};
28use std::ops::Mul;
29
30pub const X25519_PRIVATE_KEY_COUNT: usize = 1;
31pub const X25519_PUBLIC_KEY_COUNT: usize = 1;
32pub const X25519_PUBLIC_KEY_BYTES_COUNT: usize = 32;
33pub const RESCUE_KEY_COUNT: usize = 5;
34pub const AES_128_KEY_COUNT: usize = 128;
35pub const AES_192_KEY_COUNT: usize = 192;
36pub const AES_256_KEY_COUNT: usize = 256;
37pub const ED25519_SECRET_KEY_COUNT: usize = 256;
38pub const ED25519_SIGNING_KEY_S_COUNT: usize = 1;
39pub const ED25519_SIGNING_KEY_HASH_PREFIX_COUNT: usize = 256;
40pub const ED25519_VERIFYING_KEY_COUNT: usize = 32;
41pub const ELGAMAL_SECRET_KEY_COUNT: usize = 1;
42pub const ELGAMAL_PUBKEY_COUNT: usize = 1;
43pub const ELGAMAL_PUBKEY_BYTES_COUNT: usize = 32;
44
45#[derive(Copy, Clone)]
51pub struct RescueKey<T: Clone + Copy + Random>([T; RESCUE_KEY_COUNT]);
52
53impl<T: Clone + Copy + Random> RescueKey<T> {
54 pub fn new_from_inner(a: [T; RESCUE_KEY_COUNT]) -> Self {
55 Self(a)
56 }
57
58 pub fn inner(&self) -> [T; RESCUE_KEY_COUNT] {
59 self.0
60 }
61
62 pub fn mxe_rescue_key() -> Self
64 where
65 T: MxeRescueKey,
66 {
67 Self(
68 (0..RESCUE_KEY_COUNT)
69 .map(|i| T::mxe_rescue_key(i))
70 .collect::<Vec<T>>()
71 .try_into()
72 .unwrap_or_else(|v: Vec<T>| {
73 panic!(
74 "Expected a Vec of length {} (found {})",
75 RESCUE_KEY_COUNT,
76 v.len()
77 )
78 }),
79 )
80 }
81}
82
83impl<T: Clone + Copy + Random> Random for RescueKey<T> {
84 fn random() -> Self {
85 Self(
86 (0..RESCUE_KEY_COUNT)
87 .map(|_| T::random())
88 .collect::<Vec<T>>()
89 .try_into()
90 .unwrap_or_else(|v: Vec<T>| {
91 panic!(
92 "Expected a Vec of length {} (found {})",
93 RESCUE_KEY_COUNT,
94 v.len()
95 )
96 }),
97 )
98 }
99}
100
101impl<T: Clone + Copy + Random> From<RescueKey<T>> for Matrix<T> {
102 fn from(key: RescueKey<T>) -> Self {
103 Matrix::from(key.0.to_vec())
104 }
105}
106
107macro_rules! impl_aes_key {
108 ($t: ident, $byte_len:expr, $key_func_trait: ident, $key_func:ident, $mxe_key: ident) => {
109 pub trait $key_func_trait {
110 fn $key_func(i: usize) -> Self;
111 }
112
113 impl $key_func_trait for BooleanValue {
114 fn $key_func(i: usize) -> Self {
115 assert!(i < 8 * $byte_len);
116 Self::from_expr(Expr::Other(OtherExpr::MxeKey(MxeInput::Bit(
117 MxeBitInput::$t(i),
118 ))))
119 }
120 }
121
122 impl $key_func_trait for bool {
123 fn $key_func(i: usize) -> Self {
124 debug_assert!(i < 8 * $byte_len);
125 ($mxe_key[i / 8] >> (i % 8)) & 1u8 == 1u8
126 }
127 }
128
129 #[derive(Clone, Copy)]
131 pub struct $t<B: Boolean>([Byte<B>; $byte_len]);
132
133 impl<B: Boolean> $t<B> {
134 pub fn new_from_inner(a: [Byte<B>; $byte_len]) -> Self {
135 Self(a)
136 }
137
138 pub fn inner(&self) -> [Byte<B>; $byte_len] {
139 self.0
140 }
141
142 pub fn mxe_aes_key() -> Self
144 where
145 B: $key_func_trait,
146 {
147 Self(
148 (0..8 * $byte_len)
149 .map(|i| B::$key_func(i))
150 .collect::<Vec<B>>()
151 .chunks(8)
152 .map(|chunk| {
153 Byte::new(chunk.to_vec().try_into().unwrap_or_else(|v: Vec<B>| {
154 panic!("Expected a Vec of length 8 (found {})", v.len())
155 }))
156 })
157 .collect::<Vec<Byte<B>>>()
158 .try_into()
159 .unwrap_or_else(|v: Vec<Byte<B>>| {
160 panic!("Expected a Vec of length {} (found {})", $byte_len, v.len())
161 }),
162 )
163 }
164 }
165
166 impl<B: Boolean> Random for $t<B> {
167 fn random() -> Self {
168 Self(
169 (0..$byte_len)
170 .map(|_| Byte::<B>::random())
171 .collect::<Vec<Byte<B>>>()
172 .try_into()
173 .unwrap_or_else(|v: Vec<Byte<B>>| {
174 panic!("Expected a Vec of length {} (found {})", $byte_len, v.len())
175 }),
176 )
177 }
178 }
179
180 impl $t<BooleanValue> {
181 pub fn compress(&self) -> [FieldValue<BaseField>; ($byte_len as usize).div_ceil(16)] {
182 self.0
183 .chunks(16)
184 .map(|bytes| {
185 FieldValue::<BaseField>::from_le_bits(
186 bytes
187 .into_iter()
188 .flat_map(|byte| byte.to_vec())
189 .collect::<Vec<BooleanValue>>(),
190 false,
191 )
192 })
193 .collect::<Vec<FieldValue<BaseField>>>()
194 .try_into()
195 .unwrap_or_else(|v: Vec<FieldValue<BaseField>>| {
196 panic!(
197 "Expected a Vec of length {} (found {})",
198 ($byte_len + 15) / 16,
199 v.len()
200 )
201 })
202 }
203 }
204 };
205}
206
207impl_aes_key!(AES128Key, 16, MxeAES128Key, mxe_aes_128_key, MXE_AES128_KEY);
208impl_aes_key!(AES192Key, 24, MxeAES192Key, mxe_aes_192_key, MXE_AES192_KEY);
209impl_aes_key!(AES256Key, 32, MxeAES256Key, mxe_aes_256_key, MXE_AES256_KEY);
210
211#[derive(Copy, Clone)]
214pub struct X25519PrivateKey<S: Clone + Copy> {
215 key: S,
216 pub is_expected_non_zero: bool,
217}
218
219impl<S: Clone + Copy> X25519PrivateKey<S> {
220 pub fn new(value: S, is_expected_non_zero: bool) -> Self {
221 Self {
222 key: value,
223 is_expected_non_zero,
224 }
225 }
226
227 pub fn inner(&self) -> S {
228 self.key
229 }
230
231 pub fn random<B: Boolean>() -> Self
242 where
243 S: FromLeBits<B>,
244 {
245 let mut bits = vec![B::from(false); 3];
246 for _ in 0..251 {
247 bits.push(B::random());
248 }
249 bits.push(B::from(true));
250 Self {
251 key: S::from_le_bits(bits, false),
252 is_expected_non_zero: true,
253 }
254 }
255
256 pub fn mxe_private_key() -> Self
258 where
259 S: MxeX25519PrivateKey,
260 {
261 Self {
262 key: S::mxe_x25519_private_key(),
263 is_expected_non_zero: true,
264 }
265 }
266}
267
268impl<S: Clone + Copy + From<ScalarField>> FromLeBytes for X25519PrivateKey<S> {
269 fn from_le_bytes(bytes: [u8; 32]) -> Self {
270 let mut key_bytes = bytes;
272 key_bytes[0] &= 0b1111_1000;
273 key_bytes[31] &= 0b0111_1111;
274 key_bytes[31] |= 0b0100_0000;
275 X25519PrivateKey::new(
278 S::from(ScalarField::from_le_bits(
279 key_bytes
280 .into_iter()
281 .flat_map(|byte| Byte::from(byte).to_vec())
282 .collect::<Vec<bool>>(),
283 false,
284 )),
285 true,
286 )
287 }
288}
289
290impl Default for X25519PrivateKey<ScalarField> {
291 fn default() -> Self {
292 Self::from_le_bytes([0u8; 32])
293 }
294}
295
296#[derive(Copy, Clone)]
299pub struct X25519PublicKey<C: Curve> {
300 point: C,
301 pub is_expected_non_identity: bool,
302}
303
304impl<C: Curve> X25519PublicKey<C> {
305 pub fn new(value: C, is_expected_non_identity: bool) -> Self {
306 Self {
307 point: value,
308 is_expected_non_identity,
309 }
310 }
311
312 pub fn new_from_private_key<S: Clone + Copy + Mul<C, Output = C>>(
313 private_key: X25519PrivateKey<S>,
314 ) -> Self {
315 Self {
316 point: private_key.inner() * C::generator(),
317 is_expected_non_identity: private_key.is_expected_non_zero,
318 }
319 }
320
321 pub fn inner(&self) -> C {
322 self.point
323 }
324
325 pub fn to_montgomery<Base: F25519>(self) -> (Base, Base)
326 where
327 C: ToMontgomery<Output = Base>,
328 {
329 self.point.to_montgomery(self.is_expected_non_identity)
330 }
331}
332
333impl X25519PublicKey<CurvePoint> {
334 pub fn to_le_bytes(&self) -> [u8; 32] {
337 self.to_montgomery().0.to_le_bytes().map(u8::from)
338 }
339
340 pub fn from_le_bytes(bytes: [u8; 32]) -> Option<Self> {
343 is_valid_x25519_public_key(bytes).map(|montgomery_point| {
344 let edwards_point = AffineEdwardsPoint::from_montgomery(montgomery_point);
346 Self {
347 point: CurvePoint::from(edwards_point),
348 is_expected_non_identity: true,
349 }
350 })
351 }
352}
353
354impl<C: Curve> Reveal for X25519PublicKey<C> {
355 fn reveal(self) -> Self {
356 Self {
357 point: self.point.reveal(),
358 is_expected_non_identity: self.is_expected_non_identity,
359 }
360 }
361}
362
363impl Default for X25519PublicKey<CurvePoint> {
364 fn default() -> Self {
365 Self::new_from_private_key(X25519PrivateKey::<ScalarField>::default())
366 }
367}
368
369pub(crate) const MXE_X25519_PRIVATE_KEY: [u8; 32] = [
371 207, 40, 181, 230, 45, 204, 46, 17, 8, 19, 251, 241, 43, 129, 216, 23, 86, 169, 218, 248, 95,
372 114, 111, 9, 188, 159, 223, 16, 124, 98, 41, 1,
373];
374
375pub(crate) const MXE_RESCUE_BASE_FIELD_KEY: [[u8; 32]; 5] = [
377 [
378 124, 219, 118, 100, 151, 174, 173, 201, 180, 159, 95, 202, 109, 154, 90, 104, 99, 221, 206,
379 79, 44, 221, 182, 198, 143, 180, 180, 121, 78, 223, 238, 12,
380 ],
381 [
382 158, 10, 32, 122, 234, 85, 113, 2, 69, 115, 151, 149, 163, 189, 216, 108, 160, 21, 118,
383 154, 185, 199, 198, 251, 142, 193, 168, 98, 218, 59, 20, 9,
384 ],
385 [
386 45, 115, 67, 23, 196, 46, 150, 202, 33, 22, 44, 144, 204, 34, 166, 30, 183, 63, 38, 213,
387 166, 150, 234, 191, 201, 13, 79, 86, 171, 100, 140, 15,
388 ],
389 [
390 209, 1, 108, 251, 175, 105, 199, 246, 83, 186, 72, 0, 15, 236, 105, 110, 5, 109, 41, 216,
391 148, 98, 208, 128, 32, 47, 224, 93, 90, 176, 33, 2,
392 ],
393 [
394 179, 142, 132, 221, 113, 147, 206, 83, 22, 121, 245, 155, 239, 204, 18, 158, 119, 190, 54,
395 17, 28, 17, 247, 191, 151, 147, 118, 151, 38, 169, 21, 4,
396 ],
397];
398
399pub(crate) const MXE_RESCUE_SCALAR_FIELD_KEY: [[u8; 32]; 5] = [
401 [
402 72, 239, 104, 144, 184, 215, 25, 76, 171, 209, 107, 34, 146, 39, 35, 134, 103, 10, 38, 148,
403 251, 155, 69, 207, 216, 234, 104, 220, 253, 63, 217, 14,
404 ],
405 [
406 11, 232, 48, 222, 61, 142, 29, 189, 73, 204, 120, 1, 111, 20, 233, 1, 101, 49, 169, 220,
407 66, 250, 21, 125, 132, 247, 11, 21, 128, 217, 231, 12,
408 ],
409 [
410 33, 164, 174, 155, 214, 77, 209, 93, 24, 230, 196, 38, 29, 5, 89, 76, 52, 85, 219, 66, 90,
411 7, 190, 27, 181, 51, 206, 187, 99, 72, 251, 2,
412 ],
413 [
414 7, 178, 214, 42, 8, 10, 134, 249, 244, 69, 192, 63, 96, 204, 229, 10, 126, 3, 33, 49, 174,
415 26, 149, 5, 254, 118, 230, 75, 149, 105, 145, 5,
416 ],
417 [
418 22, 94, 36, 119, 174, 65, 70, 75, 230, 11, 102, 41, 31, 194, 55, 255, 24, 25, 113, 181,
419 206, 213, 243, 203, 115, 152, 90, 177, 232, 228, 145, 3,
420 ],
421];
422
423pub(crate) const MXE_AES128_KEY: [u8; 16] = [
425 124, 219, 118, 100, 151, 174, 173, 201, 180, 159, 95, 202, 109, 154, 90, 104,
426];
427
428pub(crate) const MXE_AES192_KEY: [u8; 24] = [
430 159, 234, 203, 164, 191, 151, 2, 150, 165, 97, 217, 48, 4, 227, 91, 13, 244, 2, 222, 234, 226,
431 187, 253, 127,
432];
433
434pub(crate) const MXE_AES256_KEY: [u8; 32] = [
436 196, 120, 191, 34, 144, 89, 36, 185, 242, 159, 162, 158, 170, 37, 234, 191, 33, 141, 52, 147,
437 253, 3, 58, 49, 169, 146, 53, 185, 1, 55, 60, 87,
438];
439
440pub(crate) const MXE_ED25519_SECRET_KEY: [u8; 32] = [
442 13, 192, 52, 244, 242, 224, 239, 161, 194, 4, 155, 74, 60, 148, 207, 43, 188, 194, 251, 154,
443 142, 189, 227, 93, 25, 249, 65, 205, 121, 53, 203, 22,
444];
445
446pub(crate) const MXE_ED25519_SIGNING_KEY_S: [u8; 32] = [
448 60, 248, 182, 157, 91, 202, 9, 247, 187, 176, 179, 140, 115, 51, 98, 253, 44, 82, 56, 212, 19,
449 155, 154, 68, 254, 17, 132, 223, 74, 130, 165, 12,
450];
451
452pub(crate) const MXE_ED25519_SIGNING_KEY_HASH_PREFIX: [u8; 32] = [
454 217, 141, 36, 192, 41, 135, 248, 83, 212, 208, 84, 27, 188, 50, 69, 245, 68, 207, 121, 207, 6,
455 115, 30, 27, 94, 187, 91, 113, 18, 219, 27, 64,
456];
457
458pub(crate) const MXE_ED25519_VERIFYING_KEY: [u8; 32] = [
460 14, 32, 126, 133, 202, 216, 28, 182, 228, 95, 141, 94, 34, 155, 36, 238, 53, 102, 82, 241, 81,
461 180, 136, 239, 169, 22, 226, 133, 195, 171, 252, 7,
462];
463
464pub(crate) const MXE_ELGAMAL_SECRET_KEY: [u8; 32] = [
466 57, 71, 187, 92, 7, 239, 222, 40, 252, 52, 135, 191, 198, 199, 173, 77, 31, 119, 254, 244, 152,
467 71, 131, 255, 183, 183, 182, 191, 87, 99, 182, 3,
468];
469
470pub(crate) const MXE_ELGAMAL_PUBKEY: [u8; 32] = [
472 168, 163, 137, 87, 0, 80, 192, 23, 16, 133, 172, 238, 187, 164, 133, 148, 115, 126, 183, 16,
473 220, 95, 125, 82, 16, 175, 99, 114, 226, 131, 197, 111,
474];