1use alloc::sync::Arc;
2use core::{
3 any::Any,
4 ops::{Add, Div, Mul, Neg, Sub},
5};
6use std::{
7 any::TypeId,
8 hash::Hash,
9 iter::{Product, Sum},
10 mem,
11 ops::{AddAssign, DivAssign, MulAssign, SubAssign},
12};
13
14use openvm_stark_backend::p3_field::{
15 ExtensionField, Field, FieldArray, PrimeCharacteristicRing, PrimeField,
16};
17use serde::{Deserialize, Serialize};
18
19use super::{utils::prime_field_to_usize, Ext, Felt, Usize, Var};
20
21const NUM_RANDOM_ELEMENTS: usize = 4;
22
23pub type Digest<T> = FieldArray<T, NUM_RANDOM_ELEMENTS>;
24
25pub fn elements<F: Field>() -> Digest<F> {
26 let powers = [1671541671, 1254988180, 442438744, 1716490559];
27 let generator = F::GENERATOR;
28
29 Digest::from(powers.map(|p| generator.exp_u64(p)))
30}
31
32pub fn ext_elements<F: Field, EF: ExtensionField<F>>() -> Digest<EF> {
33 let powers = [1021539871, 1430550064, 447478069, 1248903325];
34 let generator = EF::GENERATOR;
35
36 Digest::from(powers.map(|p| generator.exp_u64(p)))
37}
38
39fn digest_id<F: Field>(id: u32) -> Digest<F> {
40 let elements = elements();
41 Digest::from(
42 elements
43 .0
44 .map(|e: F| (e + F::from_u32(id)).try_inverse().unwrap_or(F::ONE)),
45 )
46}
47
48fn digest_id_ext<F: Field, EF: ExtensionField<F>>(id: u32) -> Digest<EF> {
49 let elements = ext_elements();
50 Digest::from(
51 elements
52 .0
53 .map(|e: EF| (e + EF::from_u32(id)).try_inverse().unwrap_or(EF::ONE)),
54 )
55}
56
57fn div_digests<F: Field>(a: Digest<F>, b: Digest<F>) -> Digest<F> {
58 Digest::from(core::array::from_fn(|i| a.0[i] / b.0[i]))
59}
60
61#[derive(Debug, Clone)]
63pub enum SymbolicVar<N: Field> {
64 Const(N, Digest<N>),
65 Val(Var<N>, Digest<N>),
66 Add(Arc<SymbolicVar<N>>, Arc<SymbolicVar<N>>, Digest<N>),
67 Mul(Arc<SymbolicVar<N>>, Arc<SymbolicVar<N>>, Digest<N>),
68 Sub(Arc<SymbolicVar<N>>, Arc<SymbolicVar<N>>, Digest<N>),
69 Neg(Arc<SymbolicVar<N>>, Digest<N>),
70}
71
72#[derive(Debug, Clone)]
73pub enum SymbolicFelt<F: Field> {
74 Const(F, Digest<F>),
75 Val(Felt<F>, Digest<F>),
76 Add(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
77 Mul(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
78 Sub(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
79 Div(Arc<SymbolicFelt<F>>, Arc<SymbolicFelt<F>>, Digest<F>),
80 Neg(Arc<SymbolicFelt<F>>, Digest<F>),
81}
82
83#[derive(Debug, Clone)]
84pub enum SymbolicExt<F: Field, EF: Field> {
85 Const(EF, Digest<EF>),
86 Base(Arc<SymbolicFelt<F>>, Digest<EF>),
87 Val(Ext<F, EF>, Digest<EF>),
88 Add(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
89 Mul(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
90 Sub(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
91 Div(Arc<SymbolicExt<F, EF>>, Arc<SymbolicExt<F, EF>>, Digest<EF>),
92 Neg(Arc<SymbolicExt<F, EF>>, Digest<EF>),
93}
94
95#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
97pub enum RVar<N> {
98 Const(N),
99 Val(Var<N>),
100}
101
102impl<N: PrimeField> RVar<N> {
103 pub fn zero() -> Self {
104 RVar::Const(N::ZERO)
105 }
106 pub fn one() -> Self {
107 RVar::Const(N::ONE)
108 }
109 pub fn from_field(n: N) -> Self {
110 RVar::Const(n)
111 }
112 pub fn is_const(&self) -> bool {
113 match self {
114 RVar::Const(_) => true,
115 RVar::Val(_) => false,
116 }
117 }
118 pub fn value(&self) -> usize {
119 match self {
120 RVar::Const(c) => prime_field_to_usize(*c),
121 _ => panic!("RVar::value() called on non-const value"),
122 }
123 }
124 pub fn field_value(&self) -> N {
125 match self {
126 RVar::Const(c) => *c,
127 _ => panic!("RVar::field_value() called on non-const value"),
128 }
129 }
130
131 pub fn variable(&self) -> Var<N> {
132 match self {
133 RVar::Const(_) => panic!("RVar::variable() called on const value"),
134 RVar::Val(var) => *var,
135 }
136 }
137}
138
139impl<N: Field> Hash for SymbolicVar<N> {
140 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
141 for elem in self.digest().0.iter() {
142 elem.hash(state);
143 }
144 }
145}
146
147impl<N: Field> PartialEq for SymbolicVar<N> {
148 fn eq(&self, other: &Self) -> bool {
149 if self.digest() != other.digest() {
150 return false;
151 }
152 match (self, other) {
153 (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => a == b,
154 (SymbolicVar::Val(a, _), SymbolicVar::Val(b, _)) => a == b,
155 (SymbolicVar::Add(a, b, _), SymbolicVar::Add(c, d, _)) => a == c && b == d,
156 (SymbolicVar::Mul(a, b, _), SymbolicVar::Mul(c, d, _)) => a == c && b == d,
157 (SymbolicVar::Sub(a, b, _), SymbolicVar::Sub(c, d, _)) => a == c && b == d,
158 (SymbolicVar::Neg(a, _), SymbolicVar::Neg(b, _)) => a == b,
159 _ => false,
160 }
161 }
162}
163
164impl<N: Field> Eq for SymbolicVar<N> {}
165
166impl<F: Field> Hash for SymbolicFelt<F> {
167 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
168 for elem in self.digest().0.iter() {
169 elem.hash(state);
170 }
171 }
172}
173
174impl<F: Field> PartialEq for SymbolicFelt<F> {
175 fn eq(&self, other: &Self) -> bool {
176 if self.digest() != other.digest() {
177 return false;
178 }
179 match (self, other) {
180 (SymbolicFelt::Const(a, _), SymbolicFelt::Const(b, _)) => a == b,
181 (SymbolicFelt::Val(a, _), SymbolicFelt::Val(b, _)) => a == b,
182 (SymbolicFelt::Add(a, b, _), SymbolicFelt::Add(c, d, _)) => a == c && b == d,
183 (SymbolicFelt::Mul(a, b, _), SymbolicFelt::Mul(c, d, _)) => a == c && b == d,
184 (SymbolicFelt::Sub(a, b, _), SymbolicFelt::Sub(c, d, _)) => a == c && b == d,
185 (SymbolicFelt::Div(a, b, _), SymbolicFelt::Div(c, d, _)) => a == c && b == d,
186 (SymbolicFelt::Neg(a, _), SymbolicFelt::Neg(b, _)) => a == b,
187 _ => false,
188 }
189 }
190}
191
192impl<F: Field> Eq for SymbolicFelt<F> {}
193
194impl<F: Field, EF: Field> Hash for SymbolicExt<F, EF> {
195 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
196 for elem in self.digest().0.iter() {
197 elem.hash(state);
198 }
199 }
200}
201
202impl<F: Field, EF: Field> PartialEq for SymbolicExt<F, EF> {
203 fn eq(&self, other: &Self) -> bool {
204 if self.digest() != other.digest() {
205 return false;
206 }
207 match (self, other) {
208 (SymbolicExt::Const(a, _), SymbolicExt::Const(b, _)) => a == b,
209 (SymbolicExt::Base(a, _), SymbolicExt::Base(b, _)) => a == b,
210 (SymbolicExt::Val(a, _), SymbolicExt::Val(b, _)) => a == b,
211 (SymbolicExt::Add(a, b, _), SymbolicExt::Add(c, d, _)) => a == c && b == d,
212 (SymbolicExt::Mul(a, b, _), SymbolicExt::Mul(c, d, _)) => a == c && b == d,
213 (SymbolicExt::Sub(a, b, _), SymbolicExt::Sub(c, d, _)) => a == c && b == d,
214 (SymbolicExt::Div(a, b, _), SymbolicExt::Div(c, d, _)) => a == c && b == d,
215 (SymbolicExt::Neg(a, _), SymbolicExt::Neg(b, _)) => a == b,
216 _ => false,
217 }
218 }
219}
220
221impl<F: Field, EF: Field> Eq for SymbolicExt<F, EF> {}
222
223impl<N: Field> SymbolicVar<N> {
224 pub(crate) const fn digest(&self) -> Digest<N> {
225 match self {
226 SymbolicVar::Const(_, d) => *d,
227 SymbolicVar::Val(_, d) => *d,
228 SymbolicVar::Add(_, _, d) => *d,
229 SymbolicVar::Mul(_, _, d) => *d,
230 SymbolicVar::Sub(_, _, d) => *d,
231 SymbolicVar::Neg(_, d) => *d,
232 }
233 }
234}
235
236impl<F: Field> SymbolicFelt<F> {
237 pub(crate) const fn digest(&self) -> Digest<F> {
238 match self {
239 SymbolicFelt::Const(_, d) => *d,
240 SymbolicFelt::Val(_, d) => *d,
241 SymbolicFelt::Add(_, _, d) => *d,
242 SymbolicFelt::Mul(_, _, d) => *d,
243 SymbolicFelt::Sub(_, _, d) => *d,
244 SymbolicFelt::Div(_, _, d) => *d,
245 SymbolicFelt::Neg(_, d) => *d,
246 }
247 }
248}
249
250impl<F: Field, EF: Field> SymbolicExt<F, EF> {
251 pub(crate) const fn digest(&self) -> Digest<EF> {
252 match self {
253 SymbolicExt::Const(_, d) => *d,
254 SymbolicExt::Base(_, d) => *d,
255 SymbolicExt::Val(_, d) => *d,
256 SymbolicExt::Add(_, _, d) => *d,
257 SymbolicExt::Mul(_, _, d) => *d,
258 SymbolicExt::Sub(_, _, d) => *d,
259 SymbolicExt::Div(_, _, d) => *d,
260 SymbolicExt::Neg(_, d) => *d,
261 }
262 }
263}
264
265#[derive(Debug, Clone)]
266pub enum ExtOperand<F: Field, EF: ExtensionField<F>> {
267 Base(F),
268 Const(EF),
269 Felt(Felt<F>),
270 Ext(Ext<F, EF>),
271 SymFelt(SymbolicFelt<F>),
272 Sym(SymbolicExt<F, EF>),
273}
274
275impl<F: Field, EF: ExtensionField<F>> ExtOperand<F, EF> {
276 pub fn digest(&self) -> Digest<EF> {
277 match self {
278 ExtOperand::Base(f) => SymbolicFelt::from(*f).digest().0.map(EF::from).into(),
279 ExtOperand::Const(ef) => (*ef).into(),
280 ExtOperand::Felt(f) => SymbolicFelt::from(*f).digest().0.map(EF::from).into(),
281 ExtOperand::Ext(e) => digest_id_ext::<F, EF>(e.0),
282 ExtOperand::SymFelt(f) => f.digest().0.map(EF::from).into(),
283 ExtOperand::Sym(e) => e.digest(),
284 }
285 }
286
287 pub fn symbolic(self) -> SymbolicExt<F, EF> {
288 let digest = self.digest();
289 match self {
290 ExtOperand::Base(f) => SymbolicExt::Base(Arc::new(SymbolicFelt::from(f)), digest),
291 ExtOperand::Const(ef) => SymbolicExt::Const(ef, digest),
292 ExtOperand::Felt(f) => SymbolicExt::Base(Arc::new(SymbolicFelt::from(f)), digest),
293 ExtOperand::Ext(e) => SymbolicExt::Val(e, digest),
294 ExtOperand::SymFelt(f) => SymbolicExt::Base(Arc::new(f), digest),
295 ExtOperand::Sym(e) => e,
296 }
297 }
298}
299
300pub trait ExtConst<F: Field, EF: ExtensionField<F>> {
301 fn cons(self) -> SymbolicExt<F, EF>;
302}
303
304impl<F: Field, EF: ExtensionField<F>> ExtConst<F, EF> for EF {
305 fn cons(self) -> SymbolicExt<F, EF> {
306 SymbolicExt::Const(self, self.into())
307 }
308}
309
310pub trait ExtensionOperand<F: Field, EF: ExtensionField<F>> {
311 fn to_operand(self) -> ExtOperand<F, EF>;
312}
313
314impl<N: Field> PrimeCharacteristicRing for SymbolicVar<N> {
315 type PrimeSubfield = N::PrimeSubfield;
316
317 const ZERO: Self = SymbolicVar::Const(N::ZERO, FieldArray([N::ZERO; 4]));
318 const ONE: Self = SymbolicVar::Const(N::ONE, FieldArray([N::ONE; 4]));
319 const TWO: Self = SymbolicVar::Const(N::TWO, FieldArray([N::TWO; 4]));
320 const NEG_ONE: Self = SymbolicVar::Const(N::NEG_ONE, FieldArray([N::NEG_ONE; 4]));
321
322 fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
323 SymbolicVar::from(N::from_prime_subfield(f))
324 }
325}
326
327trait NotSymbolicVar {}
329impl<N: Field> NotSymbolicVar for N {}
330impl<N: Field> NotSymbolicVar for Var<N> {}
331impl<N: PrimeField> NotSymbolicVar for Usize<N> {}
332impl<N: Field> NotSymbolicVar for RVar<N> {}
333
334impl<F: Field> PrimeCharacteristicRing for SymbolicFelt<F> {
335 type PrimeSubfield = F::PrimeSubfield;
336
337 const ZERO: Self = SymbolicFelt::Const(F::ZERO, FieldArray([F::ZERO; 4]));
338 const ONE: Self = SymbolicFelt::Const(F::ONE, FieldArray([F::ONE; 4]));
339 const TWO: Self = SymbolicFelt::Const(F::TWO, FieldArray([F::TWO; 4]));
340 const NEG_ONE: Self = SymbolicFelt::Const(F::NEG_ONE, FieldArray([F::NEG_ONE; 4]));
341
342 fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
343 SymbolicFelt::from(F::from_prime_subfield(f))
344 }
345}
346
347impl<F: Field, EF: ExtensionField<F>> PrimeCharacteristicRing for SymbolicExt<F, EF> {
348 type PrimeSubfield = F::PrimeSubfield;
349
350 const ZERO: Self = SymbolicExt::Const(EF::ZERO, FieldArray([EF::ZERO; 4]));
351 const ONE: Self =
352 SymbolicExt::Const(EF::ONE, FieldArray([EF::ZERO, EF::ZERO, EF::ZERO, EF::ONE]));
353 const TWO: Self =
354 SymbolicExt::Const(EF::TWO, FieldArray([EF::ZERO, EF::ZERO, EF::ZERO, EF::TWO]));
355 const NEG_ONE: Self = SymbolicExt::Const(
356 EF::NEG_ONE,
357 FieldArray([EF::ZERO, EF::ZERO, EF::ZERO, EF::NEG_ONE]),
358 );
359
360 fn from_prime_subfield(f: Self::PrimeSubfield) -> Self {
361 let ef = EF::from(F::from_prime_subfield(f));
362 SymbolicExt::Const(ef, ef.into())
363 }
364}
365
366impl<N: Field> From<N> for SymbolicVar<N> {
369 fn from(n: N) -> Self {
370 SymbolicVar::Const(n, n.into())
371 }
372}
373
374impl<F: Field> From<F> for SymbolicFelt<F> {
375 fn from(f: F) -> Self {
376 SymbolicFelt::Const(f, f.into())
377 }
378}
379
380impl<F: Field, EF: ExtensionField<F>> From<F> for SymbolicExt<F, EF> {
381 fn from(f: F) -> Self {
382 f.to_operand().symbolic()
383 }
384}
385
386impl<N: Field> From<Var<N>> for SymbolicVar<N> {
389 fn from(v: Var<N>) -> Self {
390 SymbolicVar::Val(v, digest_id(v.0))
391 }
392}
393
394impl<F: Field> From<Felt<F>> for SymbolicFelt<F> {
395 fn from(f: Felt<F>) -> Self {
396 SymbolicFelt::Val(f, digest_id(f.0))
397 }
398}
399
400impl<F: Field, EF: ExtensionField<F>> From<Ext<F, EF>> for SymbolicExt<F, EF> {
401 fn from(e: Ext<F, EF>) -> Self {
402 e.to_operand().symbolic()
403 }
404}
405
406impl<N: Field> Add for SymbolicVar<N> {
409 type Output = Self;
410
411 fn add(self, rhs: Self) -> Self::Output {
412 let digest = self.digest() + rhs.digest();
413 match (&self, &rhs) {
414 (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => {
415 return SymbolicVar::Const(*a + *b, digest);
416 }
417 (SymbolicVar::Const(a, _), _) => {
418 if a.is_zero() {
419 return rhs;
420 }
421 }
422 (_, SymbolicVar::Const(b, _)) => {
423 if b.is_zero() {
424 return self;
425 }
426 }
427 _ => (),
428 }
429 SymbolicVar::Add(Arc::new(self), Arc::new(rhs), digest)
430 }
431}
432
433impl<N: Field, RHS: Into<SymbolicVar<N>> + NotSymbolicVar> Add<RHS> for SymbolicVar<N> {
434 type Output = Self;
435
436 fn add(self, rhs: RHS) -> Self::Output {
437 self + rhs.into()
438 }
439}
440
441impl<F: Field> Add for SymbolicFelt<F> {
442 type Output = Self;
443
444 fn add(self, rhs: Self) -> Self::Output {
445 let digest = self.digest() + rhs.digest();
446 SymbolicFelt::Add(Arc::new(self), Arc::new(rhs), digest)
447 }
448}
449
450impl<F: Field, EF: ExtensionField<F>, E: ExtensionOperand<F, EF>> Add<E> for SymbolicExt<F, EF> {
451 type Output = Self;
452
453 fn add(self, rhs: E) -> Self::Output {
454 let rhs = rhs.to_operand().symbolic();
455 let digest = self.digest() + rhs.digest();
456 SymbolicExt::Add(Arc::new(self), Arc::new(rhs), digest)
457 }
458}
459
460impl<N: Field> Mul for SymbolicVar<N> {
461 type Output = Self;
462
463 fn mul(self, rhs: Self) -> Self::Output {
464 let digest = self.digest() * rhs.digest();
465 match (&self, &rhs) {
466 (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => {
467 return SymbolicVar::Const(*a * *b, digest);
468 }
469 (SymbolicVar::Const(a, _), _) => {
470 if a.is_zero() {
471 return self;
472 }
473 if a.is_one() {
474 return rhs;
475 }
476 }
477 (_, SymbolicVar::Const(b, _)) => {
478 if b.is_zero() {
479 return rhs;
480 }
481 if b.is_one() {
482 return self;
483 }
484 }
485 _ => (),
486 }
487 SymbolicVar::Mul(Arc::new(self), Arc::new(rhs), digest)
488 }
489}
490
491impl<N: Field, RHS: Into<SymbolicVar<N>> + NotSymbolicVar> Mul<RHS> for SymbolicVar<N> {
492 type Output = Self;
493
494 fn mul(self, rhs: RHS) -> Self::Output {
495 self * rhs.into()
496 }
497}
498
499impl<F: Field> Mul for SymbolicFelt<F> {
500 type Output = Self;
501
502 fn mul(self, rhs: Self) -> Self::Output {
503 let digest = self.digest() * rhs.digest();
504 SymbolicFelt::Mul(Arc::new(self), Arc::new(rhs), digest)
505 }
506}
507
508impl<F: Field, EF: ExtensionField<F>, E: Any> Mul<E> for SymbolicExt<F, EF> {
509 type Output = Self;
510
511 fn mul(self, rhs: E) -> Self::Output {
512 let rhs = rhs.to_operand();
513 let rhs_digest = rhs.digest();
514 let prod_digest = self.digest() * rhs_digest;
515 match rhs {
516 ExtOperand::Base(f) => SymbolicExt::Mul(
517 Arc::new(self),
518 Arc::new(SymbolicExt::Base(
519 Arc::new(SymbolicFelt::from(f)),
520 rhs_digest,
521 )),
522 prod_digest,
523 ),
524 ExtOperand::Const(ef) => SymbolicExt::Mul(
525 Arc::new(self),
526 Arc::new(SymbolicExt::Const(ef, rhs_digest)),
527 prod_digest,
528 ),
529 ExtOperand::Felt(f) => SymbolicExt::Mul(
530 Arc::new(self),
531 Arc::new(SymbolicExt::Base(
532 Arc::new(SymbolicFelt::from(f)),
533 rhs_digest,
534 )),
535 prod_digest,
536 ),
537 ExtOperand::Ext(e) => SymbolicExt::Mul(
538 Arc::new(self),
539 Arc::new(SymbolicExt::Val(e, rhs_digest)),
540 prod_digest,
541 ),
542 ExtOperand::SymFelt(f) => SymbolicExt::Mul(
543 Arc::new(self),
544 Arc::new(SymbolicExt::Base(Arc::new(f), rhs_digest)),
545 prod_digest,
546 ),
547 ExtOperand::Sym(e) => SymbolicExt::Mul(Arc::new(self), Arc::new(e), prod_digest),
548 }
549 }
550}
551
552impl<N: Field> Sub for SymbolicVar<N> {
553 type Output = Self;
554
555 fn sub(self, rhs: Self) -> Self::Output {
556 let digest = self.digest() - rhs.digest();
557 match (&self, &rhs) {
558 (SymbolicVar::Const(a, _), SymbolicVar::Const(b, _)) => {
559 return SymbolicVar::Const(*a - *b, digest);
560 }
561 (SymbolicVar::Const(a, _), _) => {
562 if a.is_zero() {
563 return rhs;
564 }
565 }
566 (_, SymbolicVar::Const(b, _)) => {
567 if b.is_zero() {
568 return self;
569 }
570 }
571 _ => (),
572 }
573 SymbolicVar::Sub(Arc::new(self), Arc::new(rhs), digest)
574 }
575}
576
577impl<N: Field, RHS: Into<SymbolicVar<N>> + NotSymbolicVar> Sub<RHS> for SymbolicVar<N> {
578 type Output = Self;
579
580 fn sub(self, rhs: RHS) -> Self::Output {
581 self - rhs.into()
582 }
583}
584
585impl<F: Field> Sub for SymbolicFelt<F> {
586 type Output = Self;
587
588 fn sub(self, rhs: Self) -> Self::Output {
589 let digest = self.digest() - rhs.digest();
590 SymbolicFelt::Sub(Arc::new(self), Arc::new(rhs), digest)
591 }
592}
593
594impl<F: Field, EF: ExtensionField<F>, E: Any> Sub<E> for SymbolicExt<F, EF> {
595 type Output = Self;
596
597 fn sub(self, rhs: E) -> Self::Output {
598 let rhs = rhs.to_operand();
599 let rhs_digest = rhs.digest();
600 let digest = self.digest() - rhs_digest;
601 match rhs {
602 ExtOperand::Base(f) => SymbolicExt::Sub(
603 Arc::new(self),
604 Arc::new(SymbolicExt::Base(
605 Arc::new(SymbolicFelt::from(f)),
606 rhs_digest,
607 )),
608 digest,
609 ),
610 ExtOperand::Const(ef) => SymbolicExt::Sub(
611 Arc::new(self),
612 Arc::new(SymbolicExt::Const(ef, rhs_digest)),
613 digest,
614 ),
615 ExtOperand::Felt(f) => SymbolicExt::Sub(
616 Arc::new(self),
617 Arc::new(SymbolicExt::Base(
618 Arc::new(SymbolicFelt::from(f)),
619 rhs_digest,
620 )),
621 digest,
622 ),
623 ExtOperand::Ext(e) => SymbolicExt::Sub(
624 Arc::new(self),
625 Arc::new(SymbolicExt::Val(e, rhs_digest)),
626 digest,
627 ),
628 ExtOperand::SymFelt(f) => SymbolicExt::Sub(
629 Arc::new(self),
630 Arc::new(SymbolicExt::Base(Arc::new(f), rhs_digest)),
631 digest,
632 ),
633 ExtOperand::Sym(e) => SymbolicExt::Sub(Arc::new(self), Arc::new(e), digest),
634 }
635 }
636}
637
638impl<F: Field> Div for SymbolicFelt<F> {
639 type Output = Self;
640
641 fn div(self, rhs: Self) -> Self::Output {
642 let self_digest = self.digest();
643 let rhs_digest = rhs.digest();
644 let digest = div_digests(self_digest, rhs_digest);
645 SymbolicFelt::Div(Arc::new(self), Arc::new(rhs), digest)
646 }
647}
648
649impl<F: Field, EF: ExtensionField<F>, E: Any> Div<E> for SymbolicExt<F, EF> {
650 type Output = Self;
651
652 fn div(self, rhs: E) -> Self::Output {
653 let rhs = rhs.to_operand();
654 let rhs_digest = rhs.digest();
655 let digest = div_digests(self.digest(), rhs_digest);
656 match rhs {
657 ExtOperand::Base(f) => SymbolicExt::Div(
658 Arc::new(self),
659 Arc::new(SymbolicExt::Base(
660 Arc::new(SymbolicFelt::from(f)),
661 rhs_digest,
662 )),
663 digest,
664 ),
665 ExtOperand::Const(ef) => SymbolicExt::Div(
666 Arc::new(self),
667 Arc::new(SymbolicExt::Const(ef, rhs_digest)),
668 digest,
669 ),
670 ExtOperand::Felt(f) => SymbolicExt::Div(
671 Arc::new(self),
672 Arc::new(SymbolicExt::Base(
673 Arc::new(SymbolicFelt::from(f)),
674 rhs_digest,
675 )),
676 digest,
677 ),
678 ExtOperand::Ext(e) => SymbolicExt::Div(
679 Arc::new(self),
680 Arc::new(SymbolicExt::Val(e, rhs_digest)),
681 digest,
682 ),
683 ExtOperand::SymFelt(f) => SymbolicExt::Div(
684 Arc::new(self),
685 Arc::new(SymbolicExt::Base(Arc::new(f), rhs_digest)),
686 digest,
687 ),
688 ExtOperand::Sym(e) => SymbolicExt::Div(Arc::new(self), Arc::new(e), digest),
689 }
690 }
691}
692
693impl<N: Field> Neg for SymbolicVar<N> {
694 type Output = Self;
695
696 fn neg(self) -> Self::Output {
697 let digest = -self.digest();
698 match &self {
699 SymbolicVar::Const(c, _) => SymbolicVar::Const(-*c, digest),
700 _ => SymbolicVar::Neg(Arc::new(self), digest),
701 }
702 }
703}
704
705impl<F: Field> Neg for SymbolicFelt<F> {
706 type Output = Self;
707
708 fn neg(self) -> Self::Output {
709 let digest = -self.digest();
710 SymbolicFelt::Neg(Arc::new(self), digest)
711 }
712}
713
714impl<F: Field, EF: ExtensionField<F>> Neg for SymbolicExt<F, EF> {
715 type Output = Self;
716
717 fn neg(self) -> Self::Output {
718 let digest = -self.digest();
719 SymbolicExt::Neg(Arc::new(self), digest)
720 }
721}
722
723impl<F: Field> Add<F> for SymbolicFelt<F> {
727 type Output = Self;
728
729 fn add(self, rhs: F) -> Self::Output {
730 self + SymbolicFelt::from(rhs)
731 }
732}
733
734impl<F: Field> Mul<F> for SymbolicFelt<F> {
735 type Output = Self;
736
737 fn mul(self, rhs: F) -> Self::Output {
738 self * SymbolicFelt::from(rhs)
739 }
740}
741
742impl<F: Field> Sub<F> for SymbolicFelt<F> {
743 type Output = Self;
744
745 fn sub(self, rhs: F) -> Self::Output {
746 self - SymbolicFelt::from(rhs)
747 }
748}
749
750impl<F: Field> Add<Felt<F>> for SymbolicFelt<F> {
754 type Output = SymbolicFelt<F>;
755
756 fn add(self, rhs: Felt<F>) -> Self::Output {
757 self + SymbolicFelt::from(rhs)
758 }
759}
760
761impl<F: Field> Mul<Felt<F>> for SymbolicFelt<F> {
762 type Output = SymbolicFelt<F>;
763
764 fn mul(self, rhs: Felt<F>) -> Self::Output {
765 self * SymbolicFelt::from(rhs)
766 }
767}
768
769impl<F: Field> Sub<Felt<F>> for SymbolicFelt<F> {
770 type Output = SymbolicFelt<F>;
771
772 fn sub(self, rhs: Felt<F>) -> Self::Output {
773 self - SymbolicFelt::from(rhs)
774 }
775}
776
777impl<F: Field> Div<SymbolicFelt<F>> for Felt<F> {
778 type Output = SymbolicFelt<F>;
779
780 fn div(self, rhs: SymbolicFelt<F>) -> Self::Output {
781 SymbolicFelt::<F>::from(self) / rhs
782 }
783}
784
785impl<F: Field> Add for Felt<F> {
788 type Output = SymbolicFelt<F>;
789
790 fn add(self, rhs: Self) -> Self::Output {
791 SymbolicFelt::<F>::from(self) + rhs
792 }
793}
794
795impl<F: Field> Add<F> for Felt<F> {
796 type Output = SymbolicFelt<F>;
797
798 fn add(self, rhs: F) -> Self::Output {
799 SymbolicFelt::from(self) + rhs
800 }
801}
802
803impl<N: Field> Mul for Var<N> {
804 type Output = SymbolicVar<N>;
805
806 fn mul(self, rhs: Self) -> Self::Output {
807 SymbolicVar::<N>::from(self) * rhs
808 }
809}
810
811impl<N: Field> Mul<N> for Var<N> {
812 type Output = SymbolicVar<N>;
813
814 fn mul(self, rhs: N) -> Self::Output {
815 SymbolicVar::from(self) * rhs
816 }
817}
818
819impl<F: Field> Mul for Felt<F> {
820 type Output = SymbolicFelt<F>;
821
822 fn mul(self, rhs: Self) -> Self::Output {
823 SymbolicFelt::<F>::from(self) * rhs
824 }
825}
826
827impl<F: Field> Mul<F> for Felt<F> {
828 type Output = SymbolicFelt<F>;
829
830 fn mul(self, rhs: F) -> Self::Output {
831 SymbolicFelt::from(self) * rhs
832 }
833}
834
835impl<F: Field> Sub for Felt<F> {
836 type Output = SymbolicFelt<F>;
837
838 fn sub(self, rhs: Self) -> Self::Output {
839 SymbolicFelt::<F>::from(self) - rhs
840 }
841}
842
843impl<F: Field> Sub<F> for Felt<F> {
844 type Output = SymbolicFelt<F>;
845
846 fn sub(self, rhs: F) -> Self::Output {
847 SymbolicFelt::from(self) - rhs
848 }
849}
850
851impl<F: Field, EF: ExtensionField<F>, E: Any> Add<E> for Ext<F, EF> {
852 type Output = SymbolicExt<F, EF>;
853
854 fn add(self, rhs: E) -> Self::Output {
855 let rhs: ExtOperand<F, EF> = rhs.to_operand();
856 let self_sym = self.to_operand().symbolic();
857 self_sym + rhs
858 }
859}
860
861impl<F: Field, EF: ExtensionField<F>, E: Any> Mul<E> for Ext<F, EF> {
862 type Output = SymbolicExt<F, EF>;
863
864 fn mul(self, rhs: E) -> Self::Output {
865 let self_sym = self.to_operand().symbolic();
866 self_sym * rhs
867 }
868}
869
870impl<F: Field, EF: ExtensionField<F>, E: Any> Sub<E> for Ext<F, EF> {
871 type Output = SymbolicExt<F, EF>;
872
873 fn sub(self, rhs: E) -> Self::Output {
874 let self_sym = self.to_operand().symbolic();
875 self_sym - rhs
876 }
877}
878
879impl<F: Field, EF: ExtensionField<F>, E: Any> Div<E> for Ext<F, EF> {
880 type Output = SymbolicExt<F, EF>;
881
882 fn div(self, rhs: E) -> Self::Output {
883 let self_sym = self.to_operand().symbolic();
884 self_sym / rhs
885 }
886}
887
888impl<F: Field, EF: ExtensionField<F>> Add<SymbolicExt<F, EF>> for Felt<F> {
889 type Output = SymbolicExt<F, EF>;
890
891 fn add(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
892 let self_sym = self.to_operand().symbolic();
893 self_sym + rhs
894 }
895}
896
897impl<F: Field, EF: ExtensionField<F>> Mul<SymbolicExt<F, EF>> for Felt<F> {
898 type Output = SymbolicExt<F, EF>;
899
900 fn mul(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
901 let self_sym = self.to_operand().symbolic();
902 self_sym * rhs
903 }
904}
905
906impl<F: Field, EF: ExtensionField<F>> Sub<SymbolicExt<F, EF>> for Felt<F> {
907 type Output = SymbolicExt<F, EF>;
908
909 fn sub(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
910 let self_sym = self.to_operand().symbolic();
911 self_sym - rhs
912 }
913}
914
915impl<F: Field, EF: ExtensionField<F>> Div<SymbolicExt<F, EF>> for Felt<F> {
916 type Output = SymbolicExt<F, EF>;
917
918 fn div(self, rhs: SymbolicExt<F, EF>) -> Self::Output {
919 let self_sym = self.to_operand().symbolic();
920 self_sym / rhs
921 }
922}
923
924impl<F: Field> Div for Felt<F> {
925 type Output = SymbolicFelt<F>;
926
927 fn div(self, rhs: Self) -> Self::Output {
928 SymbolicFelt::<F>::from(self) / rhs
929 }
930}
931
932impl<F: Field> Div<F> for Felt<F> {
933 type Output = SymbolicFelt<F>;
934
935 fn div(self, rhs: F) -> Self::Output {
936 SymbolicFelt::from(self) / rhs
937 }
938}
939
940impl<F: Field> Div<Felt<F>> for SymbolicFelt<F> {
941 type Output = SymbolicFelt<F>;
942
943 fn div(self, rhs: Felt<F>) -> Self::Output {
944 self / SymbolicFelt::from(rhs)
945 }
946}
947
948impl<F: Field> Div<F> for SymbolicFelt<F> {
949 type Output = SymbolicFelt<F>;
950
951 fn div(self, rhs: F) -> Self::Output {
952 self / SymbolicFelt::from(rhs)
953 }
954}
955
956impl<N: Field> Product for SymbolicVar<N> {
957 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
958 iter.fold(SymbolicVar::ONE, |acc, x| acc * x)
959 }
960}
961
962impl<N: Field> Sum for SymbolicVar<N> {
963 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
964 iter.fold(SymbolicVar::ZERO, |acc, x| acc + x)
965 }
966}
967
968impl<N: Field> AddAssign for SymbolicVar<N> {
969 fn add_assign(&mut self, rhs: Self) {
970 *self = self.clone() + rhs;
971 }
972}
973
974impl<N: Field> SubAssign for SymbolicVar<N> {
975 fn sub_assign(&mut self, rhs: Self) {
976 *self = self.clone() - rhs;
977 }
978}
979
980impl<N: Field> MulAssign for SymbolicVar<N> {
981 fn mul_assign(&mut self, rhs: Self) {
982 *self = self.clone() * rhs;
983 }
984}
985
986impl<N: Field> Default for SymbolicVar<N> {
987 fn default() -> Self {
988 SymbolicVar::ZERO
989 }
990}
991
992impl<F: Field> Sum for SymbolicFelt<F> {
993 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
994 iter.fold(SymbolicFelt::ZERO, |acc, x| acc + x)
995 }
996}
997
998impl<F: Field> Product for SymbolicFelt<F> {
999 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1000 iter.fold(SymbolicFelt::ONE, |acc, x| acc * x)
1001 }
1002}
1003
1004impl<F: Field> AddAssign for SymbolicFelt<F> {
1005 fn add_assign(&mut self, rhs: Self) {
1006 *self = self.clone() + rhs;
1007 }
1008}
1009
1010impl<F: Field> SubAssign for SymbolicFelt<F> {
1011 fn sub_assign(&mut self, rhs: Self) {
1012 *self = self.clone() - rhs;
1013 }
1014}
1015
1016impl<F: Field> MulAssign for SymbolicFelt<F> {
1017 fn mul_assign(&mut self, rhs: Self) {
1018 *self = self.clone() * rhs;
1019 }
1020}
1021
1022impl<F: Field> Default for SymbolicFelt<F> {
1023 fn default() -> Self {
1024 SymbolicFelt::ZERO
1025 }
1026}
1027
1028impl<F: Field, EF: ExtensionField<F>> Sum for SymbolicExt<F, EF> {
1029 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
1030 iter.fold(SymbolicExt::ZERO, |acc, x| acc + x)
1031 }
1032}
1033
1034impl<F: Field, EF: ExtensionField<F>> Product for SymbolicExt<F, EF> {
1035 fn product<I: Iterator<Item = Self>>(iter: I) -> Self {
1036 iter.fold(SymbolicExt::ONE, |acc, x| acc * x)
1037 }
1038}
1039
1040impl<F: Field, EF: ExtensionField<F>> Default for SymbolicExt<F, EF> {
1041 fn default() -> Self {
1042 SymbolicExt::ZERO
1043 }
1044}
1045
1046impl<F: Field, EF: ExtensionField<F>, E: Any> AddAssign<E> for SymbolicExt<F, EF> {
1047 fn add_assign(&mut self, rhs: E) {
1048 *self = self.clone() + rhs;
1049 }
1050}
1051
1052impl<F: Field, EF: ExtensionField<F>, E: Any> SubAssign<E> for SymbolicExt<F, EF> {
1053 fn sub_assign(&mut self, rhs: E) {
1054 *self = self.clone() - rhs;
1055 }
1056}
1057
1058impl<F: Field, EF: ExtensionField<F>, E: Any> MulAssign<E> for SymbolicExt<F, EF> {
1059 fn mul_assign(&mut self, rhs: E) {
1060 *self = self.clone() * rhs;
1061 }
1062}
1063
1064impl<F: Field, EF: ExtensionField<F>, E: Any> DivAssign<E> for SymbolicExt<F, EF> {
1065 fn div_assign(&mut self, rhs: E) {
1066 *self = self.clone() / rhs;
1067 }
1068}
1069
1070impl<F: Field, EF: ExtensionField<F>, E: Any> ExtensionOperand<F, EF> for E {
1071 fn to_operand(self) -> ExtOperand<F, EF> {
1072 match self.type_id() {
1073 ty if ty == TypeId::of::<F>() => {
1074 let value = unsafe { mem::transmute_copy::<E, F>(&self) };
1077 ExtOperand::<F, EF>::Base(value)
1078 }
1079 ty if ty == TypeId::of::<EF>() => {
1080 let value = unsafe { mem::transmute_copy::<E, EF>(&self) };
1083 ExtOperand::<F, EF>::Const(value)
1084 }
1085 ty if ty == TypeId::of::<Felt<F>>() => {
1086 let value = unsafe { mem::transmute_copy::<E, Felt<F>>(&self) };
1089 ExtOperand::<F, EF>::Felt(value)
1090 }
1091 ty if ty == TypeId::of::<Ext<F, EF>>() => {
1092 let value = unsafe { mem::transmute_copy::<E, Ext<F, EF>>(&self) };
1095 ExtOperand::<F, EF>::Ext(value)
1096 }
1097 ty if ty == TypeId::of::<SymbolicFelt<F>>() => {
1098 let value_ref = unsafe { mem::transmute::<&E, &SymbolicFelt<F>>(&self) };
1101 let value = value_ref.clone();
1102 ExtOperand::<F, EF>::SymFelt(value)
1103 }
1104 ty if ty == TypeId::of::<SymbolicExt<F, EF>>() => {
1105 let value_ref = unsafe { mem::transmute::<&E, &SymbolicExt<F, EF>>(&self) };
1108 let value = value_ref.clone();
1109 ExtOperand::<F, EF>::Sym(value)
1110 }
1111 ty if ty == TypeId::of::<ExtOperand<F, EF>>() => {
1112 let value_ref = unsafe { mem::transmute::<&E, &ExtOperand<F, EF>>(&self) };
1113 value_ref.clone()
1114 }
1115 _ => unimplemented!("unsupported type"),
1116 }
1117 }
1118}
1119
1120impl<F: Field> Add<SymbolicFelt<F>> for Felt<F> {
1121 type Output = SymbolicFelt<F>;
1122
1123 fn add(self, rhs: SymbolicFelt<F>) -> Self::Output {
1124 SymbolicFelt::<F>::from(self) + rhs
1125 }
1126}
1127
1128impl<F: Field, EF: ExtensionField<F>> From<Felt<F>> for SymbolicExt<F, EF> {
1129 fn from(value: Felt<F>) -> Self {
1130 value.to_operand().symbolic()
1131 }
1132}
1133
1134impl<F: Field, EF: ExtensionField<F>> Neg for Ext<F, EF> {
1135 type Output = SymbolicExt<F, EF>;
1136 fn neg(self) -> Self::Output {
1137 -SymbolicExt::from(self)
1138 }
1139}
1140
1141impl<F: Field> Neg for Felt<F> {
1142 type Output = SymbolicFelt<F>;
1143
1144 fn neg(self) -> Self::Output {
1145 -SymbolicFelt::from(self)
1146 }
1147}
1148
1149impl<N: Field> Neg for Var<N> {
1150 type Output = SymbolicVar<N>;
1151
1152 fn neg(self) -> Self::Output {
1153 -SymbolicVar::from(self)
1154 }
1155}
1156
1157impl<F: Field> MulAssign<Felt<F>> for SymbolicFelt<F> {
1158 fn mul_assign(&mut self, rhs: Felt<F>) {
1159 *self = self.clone() * Self::from(rhs);
1160 }
1161}
1162
1163impl<F: Field> Mul<SymbolicFelt<F>> for Felt<F> {
1164 type Output = SymbolicFelt<F>;
1165
1166 fn mul(self, rhs: SymbolicFelt<F>) -> Self::Output {
1167 SymbolicFelt::<F>::from(self) * rhs
1168 }
1169}
1170
1171impl<N: Field> Mul<SymbolicVar<N>> for Var<N> {
1172 type Output = SymbolicVar<N>;
1173
1174 fn mul(self, rhs: SymbolicVar<N>) -> Self::Output {
1175 SymbolicVar::<N>::from(self) * rhs
1176 }
1177}
1178
1179impl<N: Field, RHS: Into<SymbolicVar<N>>> Add<RHS> for Var<N> {
1180 type Output = SymbolicVar<N>;
1181
1182 fn add(self, rhs: RHS) -> Self::Output {
1183 SymbolicVar::from(self) + rhs.into()
1184 }
1185}
1186
1187impl<N: Field, RHS: Into<SymbolicVar<N>>> Sub<RHS> for Var<N> {
1188 type Output = SymbolicVar<N>;
1189
1190 fn sub(self, rhs: RHS) -> Self::Output {
1191 SymbolicVar::from(self) - rhs.into()
1192 }
1193}
1194
1195impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Add<RHS> for Usize<N> {
1196 type Output = SymbolicVar<N>;
1197
1198 fn add(self, rhs: RHS) -> Self::Output {
1199 SymbolicVar::from(self) + rhs.into()
1200 }
1201}
1202
1203impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Sub<RHS> for Usize<N> {
1204 type Output = SymbolicVar<N>;
1205
1206 fn sub(self, rhs: RHS) -> Self::Output {
1207 SymbolicVar::from(self) - rhs.into()
1208 }
1209}
1210
1211impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Mul<RHS> for Usize<N> {
1212 type Output = SymbolicVar<N>;
1213
1214 fn mul(self, rhs: RHS) -> Self::Output {
1215 SymbolicVar::from(self) * rhs.into()
1216 }
1217}
1218
1219impl<N: PrimeField> From<Usize<N>> for SymbolicVar<N> {
1220 fn from(value: Usize<N>) -> Self {
1221 match value {
1222 Usize::Const(n) => SymbolicVar::from(*n.borrow()),
1223 Usize::Var(n) => SymbolicVar::from(n),
1224 }
1225 }
1226}
1227
1228impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Add<RHS> for RVar<N> {
1229 type Output = SymbolicVar<N>;
1230
1231 fn add(self, rhs: RHS) -> Self::Output {
1232 SymbolicVar::from(self) + rhs.into()
1233 }
1234}
1235
1236impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Sub<RHS> for RVar<N> {
1237 type Output = SymbolicVar<N>;
1238
1239 fn sub(self, rhs: RHS) -> Self::Output {
1240 SymbolicVar::from(self) - rhs.into()
1241 }
1242}
1243
1244impl<N: PrimeField, RHS: Into<SymbolicVar<N>>> Mul<RHS> for RVar<N> {
1245 type Output = SymbolicVar<N>;
1246
1247 fn mul(self, rhs: RHS) -> Self::Output {
1248 SymbolicVar::from(self) * rhs.into()
1249 }
1250}
1251
1252impl<N: Field> From<RVar<N>> for SymbolicVar<N> {
1253 fn from(value: RVar<N>) -> Self {
1254 match value {
1255 RVar::Const(n) => SymbolicVar::from(n),
1256 RVar::Val(n) => SymbolicVar::from(n),
1257 }
1258 }
1259}
1260
1261impl<N: PrimeField> From<usize> for RVar<N> {
1262 fn from(value: usize) -> Self {
1263 RVar::Const(N::from_usize(value))
1264 }
1265}
1266
1267impl<N: Field> From<Var<N>> for RVar<N> {
1268 fn from(value: Var<N>) -> Self {
1269 RVar::Val(value)
1270 }
1271}