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