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