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;
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::Constant(core_utils::circuit::Constant::Scalar(
100 primitives::algebra::elliptic_curve::Scalar::<Curve>::from_le_bytes(&a.to_le_bytes())
101 .expect("failed to convert"),
102 ))
103 }
104 fn field_type() -> core_utils::circuit::FieldType {
105 core_utils::circuit::FieldType::ScalarField
106 }
107
108 fn algebraic_type() -> core_utils::circuit::AlgebraicType {
109 core_utils::circuit::AlgebraicType::ScalarField
110 }
111 fn input(kind: InputKind) -> core_utils::circuit::Input {
112 let algebraic_type = Self::algebraic_type();
113 kind.to_input(algebraic_type)
114 }
115}
116
117impl ActuallyUsedField for BaseField {
118 fn bounds_to_field_bounds(b: Bounds) -> FieldBounds<Self> {
119 BaseField::unwrap(b)
120 }
121
122 fn field_bounds_to_bounds(field: FieldBounds<Self>) -> Bounds {
123 BaseField::wrap(field)
124 }
125
126 fn field_expr_to_expr<T: Clone>(expr: FieldExpr<Self, T>) -> Expr<T> {
127 Expr::Base(expr)
128 }
129
130 fn conversion_expr_to_expr<T: Clone>(expr: ConversionExpr<Self, T>) -> Expr<T> {
131 Expr::BaseConversion(expr)
132 }
133
134 fn expr_to_field_expr<T: Clone>(expr: Expr<T>) -> Option<FieldExpr<Self, T>> {
135 if let Expr::Base(e) = expr {
136 Some(e)
137 } else {
138 None
139 }
140 }
141
142 fn expr_to_conversion_expr<T: Clone>(expr: Expr<T>) -> Option<ConversionExpr<Self, T>> {
143 if let Expr::BaseConversion(e) = expr {
144 Some(e)
145 } else {
146 None
147 }
148 }
149
150 fn eval_value_to_field(eval_value: EvalValue) -> Self {
151 BaseField::unwrap(eval_value)
152 }
153 fn field_to_eval_value(a: Self) -> EvalValue {
154 EvalValue::Base(a)
155 }
156 fn field_to_constant_gate(a: Self) -> Gate {
157 Gate::Constant(core_utils::circuit::Constant::BaseField(
158 primitives::algebra::elliptic_curve::curve::BaseFieldElement::<Curve>::from_le_bytes(
159 &a.to_le_bytes(),
160 )
161 .expect("failed to convert"),
162 ))
163 }
164 fn field_type() -> core_utils::circuit::FieldType {
165 core_utils::circuit::FieldType::BaseField
166 }
167
168 fn algebraic_type() -> core_utils::circuit::AlgebraicType {
169 core_utils::circuit::AlgebraicType::BaseField
170 }
171 fn input(kind: InputKind) -> core_utils::circuit::Input {
172 let algebraic_type = Self::algebraic_type();
173 match kind {
174 InputKind::Secret => core_utils::circuit::Input::Share {
175 algebraic_type,
176 batch_size: 1,
177 },
178 InputKind::SecretFromPlayer(i) => core_utils::circuit::Input::SecretPlaintext {
179 inputer: i,
180 algebraic_type,
181 batch_size: 1,
182 },
183 InputKind::Plaintext => core_utils::circuit::Input::Plaintext {
184 algebraic_type,
185 batch_size: 1,
186 },
187 }
188 }
189}
190
191impl<F: ActuallyUsedField> GetBit for F {
192 type Output = bool;
193
194 fn get_bit(&self, index: usize, signed: bool) -> Self::Output {
195 if signed {
196 self.signed_bit(index)
197 } else {
198 self.unsigned_bit(index)
199 }
200 }
201}
202
203impl<F: ActuallyUsedField> FromLeBits<bool> for F {
204 fn from_le_bits(bits: Vec<bool>, signed: bool) -> Self {
205 let n = bits.len();
206 bits.into_iter()
207 .enumerate()
208 .map(|(i, x)| {
209 if x {
210 if signed && i + 1 == n {
211 F::negative_power_of_two(i)
212 } else {
213 F::power_of_two(i)
214 }
215 } else {
216 F::ZERO
217 }
218 })
219 .sum()
220 }
221}
222
223impl FromF25519<BaseField> for BaseField {
224 fn from_F25519(value: BaseField) -> Vec<BaseField> {
225 vec![value]
226 }
227}
228
229impl FromF25519<BaseField> for ScalarField {
230 fn from_F25519(value: BaseField) -> Vec<ScalarField> {
232 let bytes = value.to_le_bytes();
233 let chunk_size = ScalarField::NUM_BITS.div_ceil(8) as usize - 1;
235 bytes
236 .chunks(chunk_size)
237 .map(|chunk| {
238 let mut chunk_bytes = [0u8; 32];
239 chunk_bytes[..chunk.len()].copy_from_slice(chunk);
240 ScalarField::from_le_bytes(chunk_bytes)
241 })
242 .collect::<Vec<ScalarField>>()
243 }
244}
245
246impl<F: ActuallyUsedField> Random for F {
247 fn random() -> Self {
248 let rng = &mut rand::thread_rng();
249 F::random(rng)
250 }
251}
252
253impl<F: ActuallyUsedField> Reveal for F {
254 fn reveal(self) -> Self {
255 self
256 }
257}
258
259impl<F: ActuallyUsedField> WithBooleanBounds for F {
260 fn with_boolean_bounds(&self) -> Self {
261 assert!(self.le(&F::from(1)));
262 *self
263 }
264}
265
266impl MxeX25519PrivateKey for ScalarField {
267 fn mxe_x25519_private_key() -> Self {
268 ScalarField::from_le_bytes(MXE_X25519_PRIVATE_KEY)
269 }
270}
271
272impl MxeRescueKey for BaseField {
273 fn mxe_rescue_key(i: usize) -> Self {
274 debug_assert!(i < RESCUE_KEY_COUNT);
275 BaseField::from_le_bytes(MXE_RESCUE_BASE_FIELD_KEY[i])
276 }
277}
278
279impl MxeRescueKey for ScalarField {
280 fn mxe_rescue_key(i: usize) -> Self {
281 debug_assert!(i < RESCUE_KEY_COUNT);
282 ScalarField::from_le_bytes(MXE_RESCUE_SCALAR_FIELD_KEY[i])
283 }
284}