1use crate::{
2 core::{
3 actually_used_field::ActuallyUsedField,
4 bounds::{BoolBounds, Bounds, CurveBounds, FieldBounds},
5 circuits::boolean::byte::Byte,
6 expressions::expr::EvalValue,
7 },
8 traits::FromLeBytes,
9 utils::{
10 crypto::key::{
11 AES_128_KEY_COUNT,
12 AES_192_KEY_COUNT,
13 AES_256_KEY_COUNT,
14 ED25519_SECRET_KEY_COUNT,
15 ED25519_SIGNING_KEY_HASH_PREFIX_COUNT,
16 ED25519_VERIFYING_KEY_COUNT,
17 MXE_AES128_KEY,
18 MXE_AES192_KEY,
19 MXE_AES256_KEY,
20 MXE_ED25519_SECRET_KEY,
21 MXE_ED25519_SIGNING_KEY_HASH_PREFIX,
22 MXE_ED25519_SIGNING_KEY_S,
23 MXE_ED25519_VERIFYING_KEY,
24 MXE_ELGAMAL_PUBKEY,
25 MXE_ELGAMAL_SECRET_KEY,
26 MXE_RESCUE_BASE_FIELD_KEY,
27 MXE_X25519_PRIVATE_KEY,
28 RESCUE_KEY_COUNT,
29 },
30 curve_point::CurvePoint,
31 field::{BaseField, ScalarField},
32 },
33};
34use curve25519_dalek_arcium_fork::ristretto::CompressedRistretto;
35use serde::{Deserialize, Serialize};
36use std::marker::PhantomData;
37
38pub trait ArxInput {
39 type Output;
40 fn is_plaintext(&self) -> bool;
41 fn mock_eval(&self) -> Self::Output;
42}
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
44pub enum MxeInput {
45 Bit(MxeBitInput),
46 ScalarOnly(MxeScalarInput),
47 Scalar(MxeFieldInput<ScalarField>),
48 Base(MxeFieldInput<BaseField>),
49 Curve(MxeCurveInput),
50}
51
52impl MxeInput {
53 pub fn bounds(&self) -> Bounds {
54 match self {
55 MxeInput::Bit(_) => Bounds::Bit(BoolBounds::new(true, true)),
56 MxeInput::ScalarOnly(_) => Bounds::Scalar(FieldBounds::All),
57 MxeInput::Scalar(i) => Bounds::Scalar(i.bounds()),
58 MxeInput::Base(i) => Bounds::Base(i.bounds()),
59 MxeInput::Curve(_) => Bounds::Curve(CurveBounds::All),
60 }
61 }
62}
63
64impl ArxInput for MxeInput {
65 type Output = EvalValue;
66 fn is_plaintext(&self) -> bool {
67 match self {
68 MxeInput::Bit(i) => i.is_plaintext(),
69 MxeInput::ScalarOnly(i) => i.is_plaintext(),
70 MxeInput::Scalar(i) => i.is_plaintext(),
71 MxeInput::Base(i) => i.is_plaintext(),
72 MxeInput::Curve(i) => i.is_plaintext(),
73 }
74 }
75 fn mock_eval(&self) -> Self::Output {
76 match self {
77 MxeInput::Bit(i) => EvalValue::Bit(i.mock_eval()),
78 MxeInput::ScalarOnly(i) => EvalValue::Scalar(i.mock_eval()),
79 MxeInput::Scalar(i) => EvalValue::Scalar(i.mock_eval()),
80 MxeInput::Base(i) => EvalValue::Base(i.mock_eval()),
81 MxeInput::Curve(i) => EvalValue::Curve(i.mock_eval()),
82 }
83 }
84}
85
86#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
87pub enum MxeBitInput {
88 AES128Key(usize),
90 AES192Key(usize),
92 AES256Key(usize),
94 Ed25519SecretKey(usize),
96 Ed25519SigningKeyHashPrefix(usize),
98}
99
100impl ArxInput for MxeBitInput {
101 type Output = bool;
102
103 fn is_plaintext(&self) -> bool {
104 false
105 }
106
107 fn mock_eval(&self) -> Self::Output {
108 match *self {
109 MxeBitInput::AES128Key(i) => {
110 if i < AES_128_KEY_COUNT {
111 Byte::from(MXE_AES128_KEY[i / 8]).get_bits()[i % 8]
112 } else {
113 false
114 }
115 }
116 MxeBitInput::AES192Key(i) => {
117 if i < AES_192_KEY_COUNT {
118 Byte::from(MXE_AES192_KEY[i / 8]).get_bits()[i % 8]
119 } else {
120 false
121 }
122 }
123 MxeBitInput::AES256Key(i) => {
124 if i < AES_256_KEY_COUNT {
125 Byte::from(MXE_AES256_KEY[i / 8]).get_bits()[i % 8]
126 } else {
127 false
128 }
129 }
130 MxeBitInput::Ed25519SecretKey(i) => {
131 if i < ED25519_SECRET_KEY_COUNT {
132 Byte::from(MXE_ED25519_SECRET_KEY[i / 8]).get_bits()[i % 8]
133 } else {
134 false
135 }
136 }
137 MxeBitInput::Ed25519SigningKeyHashPrefix(i) => {
138 if i < ED25519_SIGNING_KEY_HASH_PREFIX_COUNT {
139 Byte::from(MXE_ED25519_SIGNING_KEY_HASH_PREFIX[i / 8]).get_bits()[i % 8]
140 } else {
141 false
142 }
143 }
144 }
145 }
146}
147
148#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
149pub enum MxeScalarInput {
150 X25519PrivateKey(),
152 Ed25519SigningKeyS(),
154 ElGamalSecretKey(),
156}
157
158impl ArxInput for MxeScalarInput {
159 type Output = ScalarField;
160
161 fn is_plaintext(&self) -> bool {
162 false
163 }
164
165 fn mock_eval(&self) -> Self::Output {
166 match self {
167 MxeScalarInput::X25519PrivateKey() => {
168 ScalarField::from_le_bytes(MXE_X25519_PRIVATE_KEY)
169 }
170 MxeScalarInput::Ed25519SigningKeyS() => {
171 ScalarField::from_le_bytes(MXE_ED25519_SIGNING_KEY_S)
172 }
173 MxeScalarInput::ElGamalSecretKey() => {
174 ScalarField::from_le_bytes(MXE_ELGAMAL_SECRET_KEY)
175 }
176 }
177 }
178}
179
180#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
181pub enum MxeFieldInput<F: ActuallyUsedField> {
182 Ed25519VerifyingKey(usize),
184 RescueKey(usize),
186 Phantom(PhantomData<F>),
188}
189
190impl<F: ActuallyUsedField> MxeFieldInput<F> {
191 pub fn bounds(&self) -> FieldBounds<F> {
192 match self {
193 MxeFieldInput::Ed25519VerifyingKey(_) => FieldBounds::new(F::ZERO, F::from(255)),
194 MxeFieldInput::RescueKey(_) => FieldBounds::All,
195 MxeFieldInput::Phantom(_) => {
196 panic!("Phantom type cannot be created.")
197 }
198 }
199 }
200}
201
202impl<F: ActuallyUsedField> ArxInput for MxeFieldInput<F> {
203 type Output = F;
204 fn is_plaintext(&self) -> bool {
205 match self {
206 MxeFieldInput::Ed25519VerifyingKey(_) => true,
207 MxeFieldInput::RescueKey(_) => false,
208 MxeFieldInput::Phantom(_) => {
209 panic!("Phantom type is not supported")
210 }
211 }
212 }
213 fn mock_eval(&self) -> F {
214 match *self {
215 MxeFieldInput::Ed25519VerifyingKey(i) => {
216 if i < ED25519_VERIFYING_KEY_COUNT {
217 F::from(MXE_ED25519_VERIFYING_KEY[i] as u64)
218 } else {
219 F::ZERO
220 }
221 }
222 MxeFieldInput::RescueKey(i) => {
223 if i < RESCUE_KEY_COUNT {
224 F::from_le_bytes(MXE_RESCUE_BASE_FIELD_KEY[i])
225 } else {
226 F::ZERO
227 }
228 }
229 MxeFieldInput::Phantom(_) => {
230 panic!("Phantom type is not supported")
231 }
232 }
233 }
234}
235
236#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
237pub enum MxeCurveInput {
238 ElGamalPubkey(),
240}
241
242impl ArxInput for MxeCurveInput {
243 type Output = CurvePoint;
244
245 fn is_plaintext(&self) -> bool {
246 true
247 }
248 fn mock_eval(&self) -> CurvePoint {
249 match self {
250 MxeCurveInput::ElGamalPubkey() => {
251 let point = CompressedRistretto::from_slice(&MXE_ELGAMAL_PUBKEY)
252 .unwrap()
253 .decompress()
254 .unwrap();
255 CurvePoint::new(point)
256 }
257 }
258 }
259}