1use ark_ff::{Field, PrimeField};
2use mina_poseidon::{
3 constants::PlonkSpongeConstantsKimchi as SC,
4 poseidon::{ArithmeticSponge, ArithmeticSpongeParams, Sponge},
5 sponge::{DefaultFrSponge, ScalarChallenge},
6};
7
8use crate::proof::{PointEvaluations, ProofEvaluations};
9
10pub trait FrSponge<Fr: Field> {
16 fn new(p: &'static ArithmeticSpongeParams<Fr>) -> Self;
18
19 fn absorb(&mut self, x: &Fr);
21
22 fn absorb_multiple(&mut self, x: &[Fr]);
24
25 fn challenge(&mut self) -> ScalarChallenge<Fr>;
27
28 fn digest(self) -> Fr;
30
31 fn absorb_evaluations(&mut self, e: &ProofEvaluations<PointEvaluations<Vec<Fr>>>);
34}
35
36impl<Fr: PrimeField> FrSponge<Fr> for DefaultFrSponge<Fr, SC> {
37 fn new(params: &'static ArithmeticSpongeParams<Fr>) -> DefaultFrSponge<Fr, SC> {
38 DefaultFrSponge {
39 sponge: ArithmeticSponge::new(params),
40 last_squeezed: vec![],
41 }
42 }
43
44 fn absorb(&mut self, x: &Fr) {
45 self.last_squeezed = vec![];
46 self.sponge.absorb(&[*x]);
47 }
48
49 fn absorb_multiple(&mut self, x: &[Fr]) {
50 self.last_squeezed = vec![];
51 self.sponge.absorb(x);
52 }
53
54 fn challenge(&mut self) -> ScalarChallenge<Fr> {
55 ScalarChallenge(self.squeeze(mina_poseidon::sponge::CHALLENGE_LENGTH_IN_LIMBS))
56 }
57
58 fn digest(mut self) -> Fr {
59 self.sponge.squeeze()
60 }
61
62 fn absorb_evaluations(&mut self, e: &ProofEvaluations<PointEvaluations<Vec<Fr>>>) {
64 self.last_squeezed = vec![];
65
66 let ProofEvaluations {
67 public: _, w,
69 z,
70 s,
71 coefficients,
72 generic_selector,
73 poseidon_selector,
74 complete_add_selector,
75 mul_selector,
76 emul_selector,
77 endomul_scalar_selector,
78 range_check0_selector,
79 range_check1_selector,
80 foreign_field_add_selector,
81 foreign_field_mul_selector,
82 xor_selector,
83 rot_selector,
84 lookup_aggregation,
85 lookup_table,
86 lookup_sorted,
87 runtime_lookup_table,
88 runtime_lookup_table_selector,
89 xor_lookup_selector,
90 lookup_gate_lookup_selector,
91 range_check_lookup_selector,
92 foreign_field_mul_lookup_selector,
93 } = e;
94
95 let mut points = vec![
96 z,
97 generic_selector,
98 poseidon_selector,
99 complete_add_selector,
100 mul_selector,
101 emul_selector,
102 endomul_scalar_selector,
103 ];
104 w.iter().for_each(|w_i| points.push(w_i));
105 coefficients.iter().for_each(|c_i| points.push(c_i));
106 s.iter().for_each(|s_i| points.push(s_i));
107
108 if let Some(range_check0_selector) = range_check0_selector.as_ref() {
111 points.push(range_check0_selector)
112 }
113 if let Some(range_check1_selector) = range_check1_selector.as_ref() {
114 points.push(range_check1_selector)
115 }
116 if let Some(foreign_field_add_selector) = foreign_field_add_selector.as_ref() {
117 points.push(foreign_field_add_selector)
118 }
119 if let Some(foreign_field_mul_selector) = foreign_field_mul_selector.as_ref() {
120 points.push(foreign_field_mul_selector)
121 }
122 if let Some(xor_selector) = xor_selector.as_ref() {
123 points.push(xor_selector)
124 }
125 if let Some(rot_selector) = rot_selector.as_ref() {
126 points.push(rot_selector)
127 }
128 if let Some(lookup_aggregation) = lookup_aggregation.as_ref() {
129 points.push(lookup_aggregation)
130 }
131 if let Some(lookup_table) = lookup_table.as_ref() {
132 points.push(lookup_table)
133 }
134 for lookup_sorted in lookup_sorted {
135 if let Some(lookup_sorted) = lookup_sorted.as_ref() {
136 points.push(lookup_sorted)
137 }
138 }
139 if let Some(runtime_lookup_table) = runtime_lookup_table.as_ref() {
140 points.push(runtime_lookup_table)
141 }
142 if let Some(runtime_lookup_table_selector) = runtime_lookup_table_selector.as_ref() {
143 points.push(runtime_lookup_table_selector)
144 }
145 if let Some(xor_lookup_selector) = xor_lookup_selector.as_ref() {
146 points.push(xor_lookup_selector)
147 }
148 if let Some(lookup_gate_lookup_selector) = lookup_gate_lookup_selector.as_ref() {
149 points.push(lookup_gate_lookup_selector)
150 }
151 if let Some(range_check_lookup_selector) = range_check_lookup_selector.as_ref() {
152 points.push(range_check_lookup_selector)
153 }
154 if let Some(foreign_field_mul_lookup_selector) = foreign_field_mul_lookup_selector.as_ref()
155 {
156 points.push(foreign_field_mul_lookup_selector)
157 }
158
159 points.into_iter().for_each(|p| {
160 self.sponge.absorb(&p.zeta);
161 self.sponge.absorb(&p.zeta_omega);
162 })
163 }
164}