arcis_compiler/core/
mxe_input.rs

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    /// The MXE aes-128 key.
89    AES128Key(usize),
90    /// The MXE aes-192 key.
91    AES192Key(usize),
92    /// The MXE aes-256 key.
93    AES256Key(usize),
94    /// The MXE ed25519 secret key.
95    Ed25519SecretKey(usize),
96    /// The MXE ed25519 signing key hash-prefix.
97    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    /// The MXE x25519 private key.
151    X25519PrivateKey(),
152    /// The MXE ed25519 signing key s.
153    Ed25519SigningKeyS(),
154    /// The ElGamal secret key, used for c-spl.
155    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    /// The MXE ed25519 verifying key.
183    Ed25519VerifyingKey(usize),
184    /// Rescue Key.
185    RescueKey(usize),
186    /// Do not use.
187    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    /// The ElGamal pubkey, used for c-spl.
239    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}