arcis_compiler/core/
actually_used_field.rs1use crate::{
2 core::{
3 bounds::{Bounds, FieldBounds},
4 expressions::{
5 conversion_expr::ConversionExpr,
6 domain::Domain,
7 expr::{EvalValue, Expr},
8 field_expr::FieldExpr,
9 InputKind,
10 },
11 },
12 traits::{
13 FromF25519,
14 FromLeBits,
15 FromLeBytes,
16 GetBit,
17 MxeRescueKey,
18 MxeX25519PrivateKey,
19 Random,
20 Reveal,
21 WithBooleanBounds,
22 },
23 utils::{
24 crypto::key::{
25 MXE_RESCUE_BASE_FIELD_KEY,
26 MXE_RESCUE_SCALAR_FIELD_KEY,
27 MXE_X25519_PRIVATE_KEY,
28 RESCUE_KEY_COUNT,
29 },
30 field::{BaseField, ScalarField},
31 used_field::UsedField,
32 },
33};
34use ff::PrimeField;
35
36type Curve = primitives::algebra::elliptic_curve::Curve25519Ristretto;
37type Gate = core_utils::circuit::Gate<Curve>;
38
39pub trait ActuallyUsedField: UsedField {
41 fn bounds_to_field_bounds(b: Bounds) -> FieldBounds<Self>;
42 fn field_bounds_to_bounds(field: FieldBounds<Self>) -> Bounds;
43 fn field_expr_to_expr<T: Clone>(expr: FieldExpr<Self, T>) -> Expr<T>;
44 fn conversion_expr_to_expr<T: Clone>(expr: ConversionExpr<Self, T>) -> Expr<T>;
45 fn expr_to_field_expr<T: Clone>(expr: Expr<T>) -> Option<FieldExpr<Self, T>>;
46 fn expr_to_conversion_expr<T: Clone>(expr: Expr<T>) -> Option<ConversionExpr<Self, T>>;
47 fn eval_value_to_field(eval_value: EvalValue) -> Self;
48 fn field_to_eval_value(a: Self) -> EvalValue;
49 fn field_to_constant_gate(a: Self) -> Gate;
50 fn field_type() -> core_utils::circuit::FieldType;
51 fn algebraic_type() -> core_utils::circuit::AlgebraicType;
52 fn input(kind: InputKind) -> core_utils::circuit::Input<Curve>;
53}
54
55impl ActuallyUsedField for ScalarField {
56 fn bounds_to_field_bounds(b: Bounds) -> FieldBounds<Self> {
57 if let Bounds::Scalar(s) = b {
58 s
59 } else {
60 panic!("invalid bounds");
61 }
62 }
63 fn field_bounds_to_bounds(b: FieldBounds<Self>) -> Bounds {
64 Bounds::Scalar(b)
65 }
66 fn field_expr_to_expr<T: Clone>(expr: FieldExpr<Self, T>) -> Expr<T> {
67 Expr::Scalar(expr)
68 }
69 fn conversion_expr_to_expr<T: Clone>(expr: ConversionExpr<Self, T>) -> Expr<T> {
70 Expr::ScalarConversion(expr)
71 }
72
73 fn expr_to_field_expr<T: Clone>(expr: Expr<T>) -> Option<FieldExpr<Self, T>> {
74 if let Expr::Scalar(e) = expr {
75 Some(e)
76 } else {
77 None
78 }
79 }
80
81 fn expr_to_conversion_expr<T: Clone>(expr: Expr<T>) -> Option<ConversionExpr<Self, T>> {
82 if let Expr::ScalarConversion(e) = expr {
83 Some(e)
84 } else {
85 None
86 }
87 }
88 fn eval_value_to_field(eval_value: EvalValue) -> Self {
89 let EvalValue::Scalar(x) = eval_value else {
90 panic!("wrong inner type for eval_value")
91 };
92 x
93 }
94 fn field_to_eval_value(a: Self) -> EvalValue {
95 EvalValue::Scalar(a)
96 }
97
98 fn field_to_constant_gate(a: Self) -> Gate {
99 Gate::Input {
100 input_type: core_utils::circuit::Input::Scalar(core_utils::circuit::ScalarPlaintext::<
101 Curve,
102 >::Fixed(
103 primitives::algebra::elliptic_curve::Scalar::<Curve>::from_le_bytes(
104 &a.to_le_bytes(),
105 )
106 .expect("failed to convert"),
107 )),
108 }
109 }
110 fn field_type() -> core_utils::circuit::FieldType {
111 core_utils::circuit::FieldType::ScalarField
112 }
113
114 fn algebraic_type() -> core_utils::circuit::AlgebraicType {
115 core_utils::circuit::AlgebraicType::ScalarField
116 }
117 fn input(kind: InputKind) -> core_utils::circuit::Input<Curve> {
118 let algebraic_type = Self::algebraic_type();
119 kind.to_input(algebraic_type)
120 }
121}
122
123impl ActuallyUsedField for BaseField {
124 fn bounds_to_field_bounds(b: Bounds) -> FieldBounds<Self> {
125 BaseField::unwrap(b)
126 }
127
128 fn field_bounds_to_bounds(field: FieldBounds<Self>) -> Bounds {
129 BaseField::wrap(field)
130 }
131
132 fn field_expr_to_expr<T: Clone>(expr: FieldExpr<Self, T>) -> Expr<T> {
133 Expr::Base(expr)
134 }
135
136 fn conversion_expr_to_expr<T: Clone>(expr: ConversionExpr<Self, T>) -> Expr<T> {
137 Expr::BaseConversion(expr)
138 }
139
140 fn expr_to_field_expr<T: Clone>(expr: Expr<T>) -> Option<FieldExpr<Self, T>> {
141 if let Expr::Base(e) = expr {
142 Some(e)
143 } else {
144 None
145 }
146 }
147
148 fn expr_to_conversion_expr<T: Clone>(expr: Expr<T>) -> Option<ConversionExpr<Self, T>> {
149 if let Expr::BaseConversion(e) = expr {
150 Some(e)
151 } else {
152 None
153 }
154 }
155
156 fn eval_value_to_field(eval_value: EvalValue) -> Self {
157 BaseField::unwrap(eval_value)
158 }
159 fn field_to_eval_value(a: Self) -> EvalValue {
160 EvalValue::Base(a)
161 }
162 fn field_to_constant_gate(a: Self) -> Gate {
163 Gate::Input {
164 input_type: core_utils::circuit::Input::BaseField(
165 core_utils::circuit::BaseFieldPlaintext::<Curve>::Fixed(primitives::algebra::elliptic_curve::curve::BaseFieldElement::<Curve>::from_le_bytes(&a.to_le_bytes()).expect("failed to convert")),
166 ),
167 }
168 }
169 fn field_type() -> core_utils::circuit::FieldType {
170 core_utils::circuit::FieldType::BaseField
171 }
172
173 fn algebraic_type() -> core_utils::circuit::AlgebraicType {
174 core_utils::circuit::AlgebraicType::BaseField
175 }
176 fn input(kind: InputKind) -> core_utils::circuit::Input<Curve> {
177 let algebraic_type = Self::algebraic_type();
178 let batched = core_utils::circuit::Batched::No;
179 match kind {
180 InputKind::Secret => core_utils::circuit::Input::Share {
181 algebraic_type,
182 batched,
183 },
184 InputKind::SecretFromPlayer(i) => core_utils::circuit::Input::SecretPlaintext {
185 inputer: i,
186 algebraic_type,
187 batched,
188 },
189 InputKind::Plaintext => {
190 core_utils::circuit::Input::BaseField(core_utils::circuit::BaseFieldPlaintext::<
191 Curve,
192 >::Input(1))
193 }
194 }
195 }
196}
197
198impl<F: ActuallyUsedField> GetBit for F {
199 type Output = bool;
200
201 fn get_bit(&self, index: usize, signed: bool) -> Self::Output {
202 if signed {
203 self.signed_bit(index)
204 } else {
205 self.unsigned_bit(index)
206 }
207 }
208}
209
210impl<F: ActuallyUsedField> FromLeBits<bool> for F {
211 fn from_le_bits(bits: Vec<bool>, signed: bool) -> Self {
212 let n = bits.len();
213 bits.into_iter()
214 .enumerate()
215 .map(|(i, x)| {
216 if x {
217 if signed && i + 1 == n {
218 F::negative_power_of_two(i)
219 } else {
220 F::power_of_two(i)
221 }
222 } else {
223 F::ZERO
224 }
225 })
226 .sum()
227 }
228}
229
230impl FromF25519<BaseField> for BaseField {
231 fn from_F25519(value: BaseField) -> Vec<BaseField> {
232 vec![value]
233 }
234}
235
236impl FromF25519<BaseField> for ScalarField {
237 fn from_F25519(value: BaseField) -> Vec<ScalarField> {
239 let bytes = value.to_le_bytes();
240 let chunk_size = ScalarField::NUM_BITS.div_ceil(8) as usize - 1;
242 bytes
243 .chunks(chunk_size)
244 .map(|chunk| {
245 let mut chunk_bytes = [0u8; 32];
246 chunk_bytes[..chunk.len()].copy_from_slice(chunk);
247 ScalarField::from_le_bytes(chunk_bytes)
248 })
249 .collect::<Vec<ScalarField>>()
250 }
251}
252
253impl<F: ActuallyUsedField> Random for F {
254 fn random() -> Self {
255 let rng = &mut rand::thread_rng();
256 F::random(rng)
257 }
258}
259
260impl<F: ActuallyUsedField> Reveal for F {
261 fn reveal(self) -> Self {
262 self
263 }
264}
265
266impl<F: ActuallyUsedField> WithBooleanBounds for F {
267 fn with_boolean_bounds(&self) -> Self {
268 assert!(self.le(&F::from(1)));
269 *self
270 }
271}
272
273impl MxeX25519PrivateKey for ScalarField {
274 fn mxe_x25519_private_key() -> Self {
275 ScalarField::from_le_bytes(MXE_X25519_PRIVATE_KEY)
276 }
277}
278
279impl MxeRescueKey for BaseField {
280 fn mxe_rescue_key(i: usize) -> Self {
281 debug_assert!(i < RESCUE_KEY_COUNT);
282 BaseField::from_le_bytes(MXE_RESCUE_BASE_FIELD_KEY[i])
283 }
284}
285
286impl MxeRescueKey for ScalarField {
287 fn mxe_rescue_key(i: usize) -> Self {
288 debug_assert!(i < RESCUE_KEY_COUNT);
289 ScalarField::from_le_bytes(MXE_RESCUE_SCALAR_FIELD_KEY[i])
290 }
291}