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_RESCUE_SCALAR_FIELD_KEY,
28 MXE_X25519_PRIVATE_KEY,
29 RESCUE_KEY_COUNT,
30 },
31 curve_point::CurvePoint,
32 field::{BaseField, ScalarField},
33 },
34};
35use curve25519_dalek_arcium_fork::ristretto::CompressedRistretto;
36use ff::PrimeField;
37use serde::{Deserialize, Serialize};
38use std::marker::PhantomData;
39
40pub trait ArxInput {
42 type Output;
43 fn is_plaintext(&self) -> bool;
45 fn mock_eval(&self) -> Self::Output;
47}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
51pub enum MxeInput {
52 Bit(MxeBitInput),
53 ScalarOnly(MxeScalarInput),
54 Scalar(MxeFieldInput<ScalarField>),
55 Base(MxeFieldInput<BaseField>),
56 Curve(MxeCurveInput),
57}
58
59impl MxeInput {
60 pub fn bounds(&self) -> Bounds {
62 match self {
63 MxeInput::Bit(_) => Bounds::Bit(BoolBounds::new(true, true)),
64 MxeInput::ScalarOnly(_) => Bounds::Scalar(FieldBounds::All),
65 MxeInput::Scalar(i) => Bounds::Scalar(i.bounds()),
66 MxeInput::Base(i) => Bounds::Base(i.bounds()),
67 MxeInput::Curve(_) => Bounds::Curve(CurveBounds::All),
68 }
69 }
70}
71
72impl ArxInput for MxeInput {
73 type Output = EvalValue;
74 fn is_plaintext(&self) -> bool {
75 match self {
76 MxeInput::Bit(i) => i.is_plaintext(),
77 MxeInput::ScalarOnly(i) => i.is_plaintext(),
78 MxeInput::Scalar(i) => i.is_plaintext(),
79 MxeInput::Base(i) => i.is_plaintext(),
80 MxeInput::Curve(i) => i.is_plaintext(),
81 }
82 }
83 fn mock_eval(&self) -> Self::Output {
84 match self {
85 MxeInput::Bit(i) => EvalValue::Bit(i.mock_eval()),
86 MxeInput::ScalarOnly(i) => EvalValue::Scalar(i.mock_eval()),
87 MxeInput::Scalar(i) => EvalValue::Scalar(i.mock_eval()),
88 MxeInput::Base(i) => EvalValue::Base(i.mock_eval()),
89 MxeInput::Curve(i) => EvalValue::Curve(i.mock_eval()),
90 }
91 }
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
96pub enum MxeBitInput {
97 AES128Key(usize),
99 AES192Key(usize),
101 AES256Key(usize),
103 Ed25519SecretKey(usize),
105 Ed25519SigningKeyHashPrefix(usize),
107}
108
109impl ArxInput for MxeBitInput {
110 type Output = bool;
111
112 fn is_plaintext(&self) -> bool {
113 false
114 }
115
116 fn mock_eval(&self) -> Self::Output {
117 match *self {
118 MxeBitInput::AES128Key(i) => {
119 if i < AES_128_KEY_COUNT {
120 Byte::from(MXE_AES128_KEY[i / 8]).get_bits()[i % 8]
121 } else {
122 false
123 }
124 }
125 MxeBitInput::AES192Key(i) => {
126 if i < AES_192_KEY_COUNT {
127 Byte::from(MXE_AES192_KEY[i / 8]).get_bits()[i % 8]
128 } else {
129 false
130 }
131 }
132 MxeBitInput::AES256Key(i) => {
133 if i < AES_256_KEY_COUNT {
134 Byte::from(MXE_AES256_KEY[i / 8]).get_bits()[i % 8]
135 } else {
136 false
137 }
138 }
139 MxeBitInput::Ed25519SecretKey(i) => {
140 if i < ED25519_SECRET_KEY_COUNT {
141 Byte::from(MXE_ED25519_SECRET_KEY[i / 8]).get_bits()[i % 8]
142 } else {
143 false
144 }
145 }
146 MxeBitInput::Ed25519SigningKeyHashPrefix(i) => {
147 if i < ED25519_SIGNING_KEY_HASH_PREFIX_COUNT {
148 Byte::from(MXE_ED25519_SIGNING_KEY_HASH_PREFIX[i / 8]).get_bits()[i % 8]
149 } else {
150 false
151 }
152 }
153 }
154 }
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
159pub enum MxeScalarInput {
160 X25519PrivateKey(),
162 Ed25519SigningKeyS(),
164 ElGamalSecretKey(),
166}
167
168impl ArxInput for MxeScalarInput {
169 type Output = ScalarField;
170
171 fn is_plaintext(&self) -> bool {
172 false
173 }
174
175 fn mock_eval(&self) -> Self::Output {
176 match self {
177 MxeScalarInput::X25519PrivateKey() => {
178 ScalarField::from_le_bytes(MXE_X25519_PRIVATE_KEY)
179 }
180 MxeScalarInput::Ed25519SigningKeyS() => {
181 ScalarField::from_le_bytes(MXE_ED25519_SIGNING_KEY_S)
182 }
183 MxeScalarInput::ElGamalSecretKey() => {
184 ScalarField::from_le_bytes(MXE_ELGAMAL_SECRET_KEY)
185 }
186 }
187 }
188}
189
190#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
192pub enum MxeFieldInput<F: ActuallyUsedField> {
193 Ed25519VerifyingKey(usize),
195 RescueKey(usize),
197 Phantom(PhantomData<F>),
199}
200
201impl<F: ActuallyUsedField> MxeFieldInput<F> {
202 pub fn bounds(&self) -> FieldBounds<F> {
203 match self {
204 MxeFieldInput::Ed25519VerifyingKey(_) => FieldBounds::new(F::ZERO, F::from(255)),
205 MxeFieldInput::RescueKey(_) => FieldBounds::All,
206 MxeFieldInput::Phantom(_) => {
207 panic!("Phantom type cannot be created.")
208 }
209 }
210 }
211}
212
213impl<F: ActuallyUsedField> ArxInput for MxeFieldInput<F> {
214 type Output = F;
215 fn is_plaintext(&self) -> bool {
216 match self {
217 MxeFieldInput::Ed25519VerifyingKey(_) => true,
218 MxeFieldInput::RescueKey(_) => false,
219 MxeFieldInput::Phantom(_) => {
220 panic!("Phantom type is not supported")
221 }
222 }
223 }
224 fn mock_eval(&self) -> F {
225 match *self {
226 MxeFieldInput::Ed25519VerifyingKey(i) => {
227 if i < ED25519_VERIFYING_KEY_COUNT {
228 F::from(MXE_ED25519_VERIFYING_KEY[i] as u64)
229 } else {
230 F::ZERO
231 }
232 }
233 MxeFieldInput::RescueKey(i) => {
234 if i < RESCUE_KEY_COUNT {
235 match F::MODULUS {
236 BaseField::MODULUS => F::from_le_bytes(MXE_RESCUE_BASE_FIELD_KEY[i]),
237 ScalarField::MODULUS => F::from_le_bytes(MXE_RESCUE_SCALAR_FIELD_KEY[i]),
238 _ => F::ZERO,
239 }
240 } else {
241 F::ZERO
242 }
243 }
244 MxeFieldInput::Phantom(_) => {
245 panic!("Phantom type is not supported")
246 }
247 }
248 }
249}
250
251#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
253pub enum MxeCurveInput {
254 ElGamalPubkey(),
256}
257
258impl ArxInput for MxeCurveInput {
259 type Output = CurvePoint;
260
261 fn is_plaintext(&self) -> bool {
262 true
263 }
264 fn mock_eval(&self) -> CurvePoint {
265 match self {
266 MxeCurveInput::ElGamalPubkey() => {
267 let point = CompressedRistretto::from_slice(&MXE_ELGAMAL_PUBKEY)
268 .unwrap()
269 .decompress()
270 .unwrap();
271 CurvePoint::new(point)
272 }
273 }
274 }
275}