mina_tree/proofs/public_input/
prepared_statement.rs1use ark_ff::{BigInteger256, Zero};
2use mina_curves::pasta::{Fp, Fq};
3use mina_p2p_messages::v2::{
4 CompositionTypesBranchDataStableV1, PicklesBaseProofsVerifiedStableV1,
5};
6
7use crate::proofs::{
8 field::{CircuitVar, FieldWitness},
9 step::{FeatureFlags, OptFlag, Packed},
10 to_field_elements::ToFieldElements,
11 util::{four_u64_to_field, two_u64_to_field},
12};
13
14#[derive(Clone, Debug)]
15pub struct Plonk<F: FieldWitness> {
16 pub alpha: [u64; 2],
17 pub beta: [u64; 2],
18 pub gamma: [u64; 2],
19 pub zeta: [u64; 2],
20 pub zeta_to_srs_length: F::Shifting,
21 pub zeta_to_domain_size: F::Shifting,
22 pub perm: F::Shifting,
23 pub lookup: Option<[u64; 2]>,
24 pub feature_flags: FeatureFlags<bool>,
25}
26
27#[derive(Clone, Debug)]
28pub struct DeferredValues<F: FieldWitness> {
29 pub plonk: Plonk<F>,
30 pub combined_inner_product: F::Shifting,
31 pub b: F::Shifting,
32 pub xi: [u64; 2],
33 pub bulletproof_challenges: Vec<F>,
34 pub branch_data: CompositionTypesBranchDataStableV1,
35}
36
37#[derive(Clone, Debug)]
38pub struct ProofState {
39 pub deferred_values: DeferredValues<Fp>,
40 pub sponge_digest_before_evaluations: [u64; 4],
41 pub messages_for_next_wrap_proof: [u64; 4],
42}
43
44#[derive(Debug)]
45pub struct PreparedStatement {
46 pub proof_state: ProofState,
47 pub messages_for_next_step_proof: [u64; 4],
48}
49
50impl PreparedStatement {
51 pub fn to_public_input(&self, npublic_input: usize) -> anyhow::Result<Vec<Fq>> {
54 let PreparedStatement {
55 proof_state:
56 ProofState {
57 deferred_values:
58 DeferredValues {
59 plonk:
60 Plonk {
61 alpha,
62 beta,
63 gamma,
64 zeta,
65 zeta_to_srs_length,
66 zeta_to_domain_size,
67 perm,
68 lookup,
69 feature_flags,
70 },
71 combined_inner_product,
72 b,
73 xi,
74 bulletproof_challenges,
75 branch_data:
76 CompositionTypesBranchDataStableV1 {
77 proofs_verified,
78 domain_log2,
79 },
80 },
81 sponge_digest_before_evaluations,
82 messages_for_next_wrap_proof,
83 },
84 messages_for_next_step_proof,
85 } = &self;
86
87 let mut fields: Vec<Fq> = Vec::with_capacity(npublic_input);
91
92 let to_fq = |fp: Fp| -> Fq {
93 let bigint: BigInteger256 = fp.into();
94 bigint.try_into().unwrap() };
96
97 {
99 fields.push(to_fq(combined_inner_product.shifted));
100 fields.push(to_fq(b.shifted));
101 fields.push(to_fq(zeta_to_srs_length.shifted));
102 fields.push(to_fq(zeta_to_domain_size.shifted));
103 fields.push(to_fq(perm.shifted));
104 }
105
106 {
108 fields.push(two_u64_to_field(beta));
109 fields.push(two_u64_to_field(gamma));
110 }
111
112 {
114 fields.push(two_u64_to_field(alpha));
115 fields.push(two_u64_to_field(zeta));
116 fields.push(two_u64_to_field(xi));
117 }
118
119 {
121 fields.push(four_u64_to_field(sponge_digest_before_evaluations)?);
122 fields.push(four_u64_to_field(messages_for_next_wrap_proof)?);
123 fields.push(four_u64_to_field(messages_for_next_step_proof)?);
124 }
125
126 fields.extend(bulletproof_challenges.iter().copied().map(to_fq));
127
128 {
130 let proofs_verified = match proofs_verified {
132 PicklesBaseProofsVerifiedStableV1::N0 => 0b00,
133 PicklesBaseProofsVerifiedStableV1::N1 => 0b10,
134 PicklesBaseProofsVerifiedStableV1::N2 => 0b11,
135 };
136 let domain_log2: u8 = domain_log2.0.into();
138 let domain_log2: u64 = domain_log2 as u64;
139 let branch_data: u64 = (domain_log2 << 2) | proofs_verified;
140
141 fields.push(Fq::from(branch_data));
142 }
143
144 let lookup_value = lookup.as_ref().map(two_u64_to_field);
145
146 feature_flags.to_field_elements(&mut fields);
147
148 let FeatureFlags {
149 range_check0,
150 range_check1,
151 foreign_field_add: _,
152 foreign_field_mul,
153 xor,
154 rot,
155 lookup,
156 runtime_tables: _,
157 } = feature_flags;
158
159 let uses_lookup = [
161 range_check0,
162 range_check1,
163 foreign_field_mul,
164 xor,
165 rot,
166 lookup,
167 ]
168 .iter()
169 .any(|b| **b);
170
171 uses_lookup.to_field_elements(&mut fields);
172
173 if uses_lookup {
174 fields.push(lookup_value.unwrap_or(Fq::zero()));
175 } else {
176 fields.push(Fq::zero());
177 }
178
179 assert_eq!(fields.len(), npublic_input);
180
181 Ok(fields)
182 }
183
184 pub fn to_public_input_cvar(
185 &self,
186 hack_feature_flags: OptFlag,
187 npublic_input: usize,
188 ) -> anyhow::Result<Vec<Packed>> {
189 let PreparedStatement {
190 proof_state:
191 ProofState {
192 deferred_values:
193 DeferredValues {
194 plonk:
195 Plonk {
196 alpha,
197 beta,
198 gamma,
199 zeta,
200 zeta_to_srs_length,
201 zeta_to_domain_size,
202 perm,
203 lookup: _,
204 feature_flags: _,
205 },
206 combined_inner_product,
207 b,
208 xi,
209 bulletproof_challenges,
210 branch_data:
211 CompositionTypesBranchDataStableV1 {
212 proofs_verified,
213 domain_log2,
214 },
215 },
216 sponge_digest_before_evaluations,
217 messages_for_next_wrap_proof,
218 },
219 messages_for_next_step_proof,
220 } = &self;
221
222 let mut fields: Vec<Packed> = Vec::with_capacity(npublic_input);
226
227 let to_fq = |fp: Fp| -> Fq {
228 let bigint: BigInteger256 = fp.into();
229 bigint.try_into().unwrap() };
231
232 let var = |x| Packed::Field(CircuitVar::Var(x));
233 let bits = |n, x| Packed::PackedBits(CircuitVar::Var(x), n);
234
235 {
237 fields.push(var(to_fq(combined_inner_product.shifted)));
238 fields.push(var(to_fq(b.shifted)));
239 fields.push(var(to_fq(zeta_to_srs_length.shifted)));
240 fields.push(var(to_fq(zeta_to_domain_size.shifted)));
241 fields.push(var(to_fq(perm.shifted)));
242 }
243
244 {
246 fields.push(bits(128, two_u64_to_field(beta)));
247 fields.push(bits(128, two_u64_to_field(gamma)));
248 }
249
250 {
252 fields.push(bits(128, two_u64_to_field(alpha)));
253 fields.push(bits(128, two_u64_to_field(zeta)));
254 fields.push(bits(128, two_u64_to_field(xi)));
255 }
256
257 {
259 fields.push(bits(
260 255,
261 four_u64_to_field(sponge_digest_before_evaluations)?,
262 ));
263 fields.push(bits(255, four_u64_to_field(messages_for_next_wrap_proof)?));
264 fields.push(bits(255, four_u64_to_field(messages_for_next_step_proof)?));
265 }
266
267 fields.extend(
268 bulletproof_challenges
269 .iter()
270 .copied()
271 .map(|v| bits(128, to_fq(v))),
272 );
273
274 {
276 let proofs_verified = match proofs_verified {
278 PicklesBaseProofsVerifiedStableV1::N0 => 0b00,
279 PicklesBaseProofsVerifiedStableV1::N1 => 0b10,
280 PicklesBaseProofsVerifiedStableV1::N2 => 0b11,
281 };
282 let domain_log2: u8 = domain_log2.0.into();
284 let domain_log2: u64 = domain_log2 as u64;
285 let branch_data: u64 = (domain_log2 << 2) | proofs_verified;
286
287 fields.push(bits(10, Fq::from(branch_data)));
288 }
289
290 let zero = Fq::zero();
292 let circuit_var = match hack_feature_flags {
293 OptFlag::Yes => todo!(),
294 OptFlag::No => CircuitVar::Constant,
295 OptFlag::Maybe => CircuitVar::Var,
296 };
297 while fields.len() < npublic_input - 1 {
298 fields.push(Packed::PackedBits(circuit_var(zero), 1));
299 }
300 fields.push(Packed::PackedBits(circuit_var(zero), 128));
301
302 Ok(fields)
303 }
304}