1use ark_ff::{BigInteger256, Field};
2use kimchi::proof::ProofEvaluations;
3use mina_curves::pasta::{Fp, Fq};
4use o1_utils::field_helpers::FieldHelpers;
5
6use crate::proofs::field::FieldWitness;
7
8use super::plonk_checks::NPOWERS_OF_ALPHA;
9
10pub enum CurrOrNext {
11 Curr,
12 Next,
13}
14
15pub enum Column {
16 Witness(usize),
17 }
19
20fn square<F>(field: F) -> F
23where
24 F: Field,
25{
26 field * field
27}
28
29fn cell<T>(v: T) -> T {
30 v
31}
32
33fn double<F>(fp: F) -> F
34where
35 F: Field,
36{
37 fp.double()
38}
39
40pub fn field_from_hex<F>(mut s: &str) -> F
41where
42 F: Field + From<BigInteger256>,
43{
44 if s.starts_with("0x") {
45 s = &s[2..];
46 }
47
48 F::from_hex(s).expect("Must not fail")
49}
50
51fn field<F: FieldWitness>(s: &str) -> F {
52 field_from_hex(s)
53}
54
55fn get_var<F>(evals: &ProofEvaluations<[F; 2]>) -> impl Fn(Column, CurrOrNext) -> F + '_
57where
58 F: Field,
59{
60 use Column::*;
61 use CurrOrNext::*;
62
63 |col: Column, row: CurrOrNext| match (col, row) {
65 (Witness(i), Curr) => evals.w[i][0],
66 (Witness(i), Next) => evals.w[i][1],
67 }
70}
71
72#[allow(clippy::double_parens)]
75#[allow(unused_parens)]
76pub fn complete_add<F: FieldWitness>(
77 evals: &ProofEvaluations<[F; 2]>,
78 powers_of_alpha: &[F; NPOWERS_OF_ALPHA],
79) -> F {
80 use Column::*;
81 use CurrOrNext::*;
82
83 let var = get_var(evals);
84 let alpha_pow = |i: usize| powers_of_alpha[i];
85 let field = field::<F>;
86
87 let x_0 = { (cell(var(Witness(2), Curr)) - cell(var(Witness(0), Curr))) };
89 let x_1 = { (cell(var(Witness(3), Curr)) - cell(var(Witness(1), Curr))) };
90 let x_2 = { (cell(var(Witness(0), Curr)) * cell(var(Witness(0), Curr))) };
91 ((((((((cell(var(Witness(10), Curr)) * x_0)
92 - (field("0x0000000000000000000000000000000000000000000000000000000000000001")
93 - cell(var(Witness(7), Curr))))
94 + (alpha_pow(1) * (cell(var(Witness(7), Curr)) * x_0)))
95 + (alpha_pow(2)
96 * ((cell(var(Witness(7), Curr))
97 * (((double(cell(var(Witness(8), Curr))) * cell(var(Witness(1), Curr)))
98 - double(x_2))
99 - x_2))
100 + ((field(
101 "0x0000000000000000000000000000000000000000000000000000000000000001",
102 ) - cell(var(Witness(7), Curr)))
103 * ((x_0 * cell(var(Witness(8), Curr))) - x_1)))))
104 + (alpha_pow(3)
105 * (((cell(var(Witness(0), Curr)) + cell(var(Witness(2), Curr)))
106 + cell(var(Witness(4), Curr)))
107 - (cell(var(Witness(8), Curr)) * cell(var(Witness(8), Curr))))))
108 + (alpha_pow(4)
109 * (((cell(var(Witness(8), Curr))
110 * (cell(var(Witness(0), Curr)) - cell(var(Witness(4), Curr))))
111 - cell(var(Witness(1), Curr)))
112 - cell(var(Witness(5), Curr)))))
113 + (alpha_pow(5) * (x_1 * (cell(var(Witness(7), Curr)) - cell(var(Witness(6), Curr))))))
114 + (alpha_pow(6) * ((x_1 * cell(var(Witness(9), Curr))) - cell(var(Witness(6), Curr)))))
115}
116
117#[allow(clippy::double_parens)]
118#[allow(unused_parens)]
119pub fn var_base_mul<F: FieldWitness>(
120 evals: &ProofEvaluations<[F; 2]>,
121 powers_of_alpha: &[F; NPOWERS_OF_ALPHA],
122) -> F {
123 use Column::*;
124 use CurrOrNext::*;
125
126 let var = get_var(evals);
127 let alpha_pow = |i: usize| powers_of_alpha[i];
128 let field = field::<F>;
129
130 let x_0 = { (cell(var(Witness(7), Next)) * cell(var(Witness(7), Next))) };
132 let x_1 = {
133 let x_0 = { (cell(var(Witness(7), Next)) * cell(var(Witness(7), Next))) };
134 (cell(var(Witness(2), Curr))
135 - ((x_0 - cell(var(Witness(2), Curr))) - cell(var(Witness(0), Curr))))
136 };
137 let x_2 = {
138 let x_1 = {
139 let x_0 = { (cell(var(Witness(7), Next)) * cell(var(Witness(7), Next))) };
140 (cell(var(Witness(2), Curr))
141 - ((x_0 - cell(var(Witness(2), Curr))) - cell(var(Witness(0), Curr))))
142 };
143 (double(cell(var(Witness(3), Curr))) - (x_1 * cell(var(Witness(7), Next))))
144 };
145 let x_3 = { (cell(var(Witness(8), Next)) * cell(var(Witness(8), Next))) };
146 let x_4 = {
147 let x_3 = { (cell(var(Witness(8), Next)) * cell(var(Witness(8), Next))) };
148 (cell(var(Witness(7), Curr))
149 - ((x_3 - cell(var(Witness(7), Curr))) - cell(var(Witness(0), Curr))))
150 };
151 let x_5 = {
152 let x_4 = {
153 let x_3 = { (cell(var(Witness(8), Next)) * cell(var(Witness(8), Next))) };
154 (cell(var(Witness(7), Curr))
155 - ((x_3 - cell(var(Witness(7), Curr))) - cell(var(Witness(0), Curr))))
156 };
157 (double(cell(var(Witness(8), Curr))) - (x_4 * cell(var(Witness(8), Next))))
158 };
159 let x_6 = { (cell(var(Witness(9), Next)) * cell(var(Witness(9), Next))) };
160 let x_7 = {
161 let x_6 = { (cell(var(Witness(9), Next)) * cell(var(Witness(9), Next))) };
162 (cell(var(Witness(9), Curr))
163 - ((x_6 - cell(var(Witness(9), Curr))) - cell(var(Witness(0), Curr))))
164 };
165 let x_8 = {
166 let x_7 = {
167 let x_6 = { (cell(var(Witness(9), Next)) * cell(var(Witness(9), Next))) };
168 (cell(var(Witness(9), Curr))
169 - ((x_6 - cell(var(Witness(9), Curr))) - cell(var(Witness(0), Curr))))
170 };
171 (double(cell(var(Witness(10), Curr))) - (x_7 * cell(var(Witness(9), Next))))
172 };
173 let x_9 = { (cell(var(Witness(10), Next)) * cell(var(Witness(10), Next))) };
174 let x_10 = {
175 let x_9 = { (cell(var(Witness(10), Next)) * cell(var(Witness(10), Next))) };
176 (cell(var(Witness(11), Curr))
177 - ((x_9 - cell(var(Witness(11), Curr))) - cell(var(Witness(0), Curr))))
178 };
179 let x_11 = {
180 let x_10 = {
181 let x_9 = { (cell(var(Witness(10), Next)) * cell(var(Witness(10), Next))) };
182 (cell(var(Witness(11), Curr))
183 - ((x_9 - cell(var(Witness(11), Curr))) - cell(var(Witness(0), Curr))))
184 };
185 (double(cell(var(Witness(12), Curr))) - (x_10 * cell(var(Witness(10), Next))))
186 };
187 let x_12 = { (cell(var(Witness(11), Next)) * cell(var(Witness(11), Next))) };
188 let x_13 = {
189 let x_12 = { (cell(var(Witness(11), Next)) * cell(var(Witness(11), Next))) };
190 (cell(var(Witness(13), Curr))
191 - ((x_12 - cell(var(Witness(13), Curr))) - cell(var(Witness(0), Curr))))
192 };
193 let x_14 = {
194 let x_13 = {
195 let x_12 = { (cell(var(Witness(11), Next)) * cell(var(Witness(11), Next))) };
196 (cell(var(Witness(13), Curr))
197 - ((x_12 - cell(var(Witness(13), Curr))) - cell(var(Witness(0), Curr))))
198 };
199 (double(cell(var(Witness(14), Curr))) - (x_13 * cell(var(Witness(11), Next))))
200 };
201 (((((((((((((((((((((cell(var(Witness(5), Curr))
202 - (cell(var(Witness(6), Next))
203 + double(
204 (cell(var(Witness(5), Next))
205 + double(
206 (cell(var(Witness(4), Next))
207 + double(
208 (cell(var(Witness(3), Next))
209 + double(
210 (cell(var(Witness(2), Next))
211 + double(cell(var(Witness(4), Curr)))),
212 )),
213 )),
214 )),
215 )))
216 + (alpha_pow(1)
217 * (square(cell(var(Witness(2), Next)))
218 - cell(var(Witness(2), Next)))))
219 + (alpha_pow(2)
220 * (((cell(var(Witness(2), Curr)) - cell(var(Witness(0), Curr)))
221 * cell(var(Witness(7), Next)))
222 - (cell(var(Witness(3), Curr))
223 - ((double(cell(var(Witness(2), Next)))
224 - field(
225 "0x0000000000000000000000000000000000000000000000000000000000000001",
226 ))
227 * cell(var(Witness(1), Curr)))))))
228 + (alpha_pow(3)
229 * ((x_2 * x_2)
230 - ((x_1 * x_1)
231 * ((cell(var(Witness(7), Curr))
232 - cell(var(Witness(0), Curr)))
233 + x_0)))))
234 + (alpha_pow(4)
235 * (((cell(var(Witness(8), Curr)) + cell(var(Witness(3), Curr)))
236 * x_1)
237 - ((cell(var(Witness(2), Curr)) - cell(var(Witness(7), Curr)))
238 * x_2))))
239 + (alpha_pow(5)
240 * (square(cell(var(Witness(3), Next))) - cell(var(Witness(3), Next)))))
241 + (alpha_pow(6)
242 * (((cell(var(Witness(7), Curr)) - cell(var(Witness(0), Curr)))
243 * cell(var(Witness(8), Next)))
244 - (cell(var(Witness(8), Curr))
245 - ((double(cell(var(Witness(3), Next)))
246 - field(
247 "0x0000000000000000000000000000000000000000000000000000000000000001",
248 ))
249 * cell(var(Witness(1), Curr)))))))
250 + (alpha_pow(7)
251 * ((x_5 * x_5)
252 - ((x_4 * x_4)
253 * ((cell(var(Witness(9), Curr)) - cell(var(Witness(0), Curr)))
254 + x_3)))))
255 + (alpha_pow(8)
256 * (((cell(var(Witness(10), Curr)) + cell(var(Witness(8), Curr))) * x_4)
257 - ((cell(var(Witness(7), Curr)) - cell(var(Witness(9), Curr))) * x_5))))
258 + (alpha_pow(9)
259 * (square(cell(var(Witness(4), Next))) - cell(var(Witness(4), Next)))))
260 + (alpha_pow(10)
261 * (((cell(var(Witness(9), Curr)) - cell(var(Witness(0), Curr)))
262 * cell(var(Witness(9), Next)))
263 - (cell(var(Witness(10), Curr))
264 - ((double(cell(var(Witness(4), Next)))
265 - field(
266 "0x0000000000000000000000000000000000000000000000000000000000000001",
267 ))
268 * cell(var(Witness(1), Curr)))))))
269 + (alpha_pow(11)
270 * ((x_8 * x_8)
271 - ((x_7 * x_7)
272 * ((cell(var(Witness(11), Curr)) - cell(var(Witness(0), Curr)))
273 + x_6)))))
274 + (alpha_pow(12)
275 * (((cell(var(Witness(12), Curr)) + cell(var(Witness(10), Curr))) * x_7)
276 - ((cell(var(Witness(9), Curr)) - cell(var(Witness(11), Curr))) * x_8))))
277 + (alpha_pow(13)
278 * (square(cell(var(Witness(5), Next))) - cell(var(Witness(5), Next)))))
279 + (alpha_pow(14)
280 * (((cell(var(Witness(11), Curr)) - cell(var(Witness(0), Curr)))
281 * cell(var(Witness(10), Next)))
282 - (cell(var(Witness(12), Curr))
283 - ((double(cell(var(Witness(5), Next)))
284 - field(
285 "0x0000000000000000000000000000000000000000000000000000000000000001",
286 ))
287 * cell(var(Witness(1), Curr)))))))
288 + (alpha_pow(15)
289 * ((x_11 * x_11)
290 - ((x_10 * x_10)
291 * ((cell(var(Witness(13), Curr)) - cell(var(Witness(0), Curr))) + x_9)))))
292 + (alpha_pow(16)
293 * (((cell(var(Witness(14), Curr)) + cell(var(Witness(12), Curr))) * x_10)
294 - ((cell(var(Witness(11), Curr)) - cell(var(Witness(13), Curr))) * x_11))))
295 + (alpha_pow(17) * (square(cell(var(Witness(6), Next))) - cell(var(Witness(6), Next)))))
296 + (alpha_pow(18)
297 * (((cell(var(Witness(13), Curr)) - cell(var(Witness(0), Curr)))
298 * cell(var(Witness(11), Next)))
299 - (cell(var(Witness(14), Curr))
300 - ((double(cell(var(Witness(6), Next)))
301 - field(
302 "0x0000000000000000000000000000000000000000000000000000000000000001",
303 ))
304 * cell(var(Witness(1), Curr)))))))
305 + (alpha_pow(19)
306 * ((x_14 * x_14)
307 - ((x_13 * x_13)
308 * ((cell(var(Witness(0), Next)) - cell(var(Witness(0), Curr))) + x_12)))))
309 + (alpha_pow(20)
310 * (((cell(var(Witness(1), Next)) + cell(var(Witness(14), Curr))) * x_13)
311 - ((cell(var(Witness(13), Curr)) - cell(var(Witness(0), Next))) * x_14))))
312}
313
314#[allow(clippy::double_parens)]
315#[allow(unused_parens)]
316pub fn endo_mul<F: FieldWitness>(
317 evals: &ProofEvaluations<[F; 2]>,
318 powers_of_alpha: &[F; NPOWERS_OF_ALPHA],
319) -> F {
320 use Column::*;
321 use CurrOrNext::*;
322
323 let var = get_var(evals);
324 let alpha_pow = |i: usize| powers_of_alpha[i];
325 let endo_coefficient: F = mina_poseidon::sponge::endo_coefficient();
326 let field = field::<F>;
327
328 let x_0 = {
330 ((field("0x0000000000000000000000000000000000000000000000000000000000000001")
331 + (cell(var(Witness(11), Curr))
332 * (endo_coefficient
333 - field(
334 "0x0000000000000000000000000000000000000000000000000000000000000001",
335 ))))
336 * cell(var(Witness(0), Curr)))
337 };
338 let x_1 = {
339 ((field("0x0000000000000000000000000000000000000000000000000000000000000001")
340 + (cell(var(Witness(13), Curr))
341 * (endo_coefficient
342 - field(
343 "0x0000000000000000000000000000000000000000000000000000000000000001",
344 ))))
345 * cell(var(Witness(0), Curr)))
346 };
347 let x_2 = { square(cell(var(Witness(9), Curr))) };
348 let x_3 = { square(cell(var(Witness(10), Curr))) };
349 let x_4 = { (cell(var(Witness(4), Curr)) - cell(var(Witness(7), Curr))) };
350 let x_5 = { (cell(var(Witness(7), Curr)) - cell(var(Witness(4), Next))) };
351 let x_6 = { (cell(var(Witness(5), Next)) + cell(var(Witness(8), Curr))) };
352 let x_7 = { (cell(var(Witness(8), Curr)) + cell(var(Witness(5), Curr))) };
353 (((((((((((square(cell(var(Witness(11), Curr))) - cell(var(Witness(11), Curr)))
354 + (alpha_pow(1)
355 * (square(cell(var(Witness(12), Curr))) - cell(var(Witness(12), Curr)))))
356 + (alpha_pow(2)
357 * (square(cell(var(Witness(13), Curr))) - cell(var(Witness(13), Curr)))))
358 + (alpha_pow(3)
359 * (square(cell(var(Witness(14), Curr))) - cell(var(Witness(14), Curr)))))
360 + (alpha_pow(4)
361 * (((x_0 - cell(var(Witness(4), Curr))) * cell(var(Witness(9), Curr)))
362 - (((double(cell(var(Witness(12), Curr)))
363 - field(
364 "0x0000000000000000000000000000000000000000000000000000000000000001",
365 ))
366 * cell(var(Witness(1), Curr)))
367 - cell(var(Witness(5), Curr))))))
368 + (alpha_pow(5)
369 * ((((double(cell(var(Witness(4), Curr))) - x_2) + x_0)
370 * ((x_4 * cell(var(Witness(9), Curr))) + x_7))
371 - (double(cell(var(Witness(5), Curr))) * x_4))))
372 + (alpha_pow(6)
373 * (square(x_7) - (square(x_4) * ((x_2 - x_0) + cell(var(Witness(7), Curr)))))))
374 + (alpha_pow(7)
375 * (((x_1 - cell(var(Witness(7), Curr))) * cell(var(Witness(10), Curr)))
376 - (((double(cell(var(Witness(14), Curr)))
377 - field(
378 "0x0000000000000000000000000000000000000000000000000000000000000001",
379 ))
380 * cell(var(Witness(1), Curr)))
381 - cell(var(Witness(8), Curr))))))
382 + (alpha_pow(8)
383 * ((((double(cell(var(Witness(7), Curr))) - x_3) + x_1)
384 * ((x_5 * cell(var(Witness(10), Curr))) + x_6))
385 - (double(cell(var(Witness(8), Curr))) * x_5))))
386 + (alpha_pow(9)
387 * (square(x_6) - (square(x_5) * ((x_3 - x_1) + cell(var(Witness(4), Next)))))))
388 + (alpha_pow(10)
389 * ((double(
390 (double(
391 (double((double(cell(var(Witness(6), Curr))) + cell(var(Witness(11), Curr))))
392 + cell(var(Witness(12), Curr))),
393 ) + cell(var(Witness(13), Curr))),
394 ) + cell(var(Witness(14), Curr)))
395 - cell(var(Witness(6), Next)))))
396}
397
398pub fn endo_mul_scalar<F: FieldWitness>(
399 evals: &ProofEvaluations<[F; 2]>,
400 powers_of_alpha: &[F; NPOWERS_OF_ALPHA],
401) -> F {
402 use std::any::TypeId;
403
404 if TypeId::of::<F>() == TypeId::of::<Fp>() {
406 endo_mul_scalar_fp(evals, powers_of_alpha)
407 } else if TypeId::of::<F>() == TypeId::of::<Fq>() {
408 endo_mul_scalar_fq(evals, powers_of_alpha)
409 } else {
410 unimplemented!()
411 }
412}
413
414#[allow(clippy::double_parens)]
415#[allow(unused_parens)]
416#[rustfmt::skip] fn endo_mul_scalar_fp<F: FieldWitness>(
418 evals: &ProofEvaluations<[F; 2]>,
419 powers_of_alpha: &[F; NPOWERS_OF_ALPHA]
420) -> F {
421 use Column::*;
422 use CurrOrNext::*;
423
424 let var = get_var(evals);
425 let alpha_pow = |i: usize| powers_of_alpha[i];
426 let field = field::<F>;
427
428 let x_0 = {
430 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
431 * cell(var(Witness(6), Curr)))
432 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
433 * cell(var(Witness(6), Curr)))
434 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
435 * cell(var(Witness(6), Curr)))
436 };
437 let x_1 = {
438 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
439 * cell(var(Witness(7), Curr)))
440 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
441 * cell(var(Witness(7), Curr)))
442 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
443 * cell(var(Witness(7), Curr)))
444 };
445 let x_2 = {
446 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
447 * cell(var(Witness(8), Curr)))
448 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
449 * cell(var(Witness(8), Curr)))
450 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
451 * cell(var(Witness(8), Curr)))
452 };
453 let x_3 = {
454 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
455 * cell(var(Witness(9), Curr)))
456 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
457 * cell(var(Witness(9), Curr)))
458 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
459 * cell(var(Witness(9), Curr)))
460 };
461 let x_4 = {
462 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
463 * cell(var(Witness(10), Curr)))
464 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
465 * cell(var(Witness(10), Curr)))
466 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
467 * cell(var(Witness(10), Curr)))
468 };
469 let x_5 = {
470 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
471 * cell(var(Witness(11), Curr)))
472 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
473 * cell(var(Witness(11), Curr)))
474 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
475 * cell(var(Witness(11), Curr)))
476 };
477 let x_6 = {
478 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
479 * cell(var(Witness(12), Curr)))
480 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
481 * cell(var(Witness(12), Curr)))
482 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
483 * cell(var(Witness(12), Curr)))
484 };
485 let x_7 = {
486 (((((field("0x1555555555555555555555555555555560C232FEADC45309330F104F00000001")
487 * cell(var(Witness(13), Curr)))
488 + field("0x2000000000000000000000000000000011234C7E04A67C8DCC9698767FFFFFFE"))
489 * cell(var(Witness(13), Curr)))
490 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56E229849987882780000002"))
491 * cell(var(Witness(13), Curr)))
492 };
493 ((((((((((((double(double((double(double((double(double((double(double((double(double(
495 (double(double((double(double((double(double(cell(var(Witness(0), Curr))))
496 + cell(var(Witness(6), Curr))))) + cell(var(Witness(7), Curr)))))
497 + cell(var(Witness(8), Curr))))) + cell(var(Witness(9), Curr)))))
498 + cell(var(Witness(10), Curr))))) + cell(var(Witness(11), Curr)))))
499 + cell(var(Witness(12), Curr))))) + cell(var(Witness(13), Curr)))
500 - cell(var(Witness(1), Curr))) + (alpha_pow(1) * ((double((double((double((double(
501 (double((double((double((double(cell(var(Witness(2), Curr))) + x_0)) + x_1)) + x_2))
502 + x_3)) + x_4)) + x_5)) + x_6)) + x_7) - cell(var(Witness(4), Curr))))) + (alpha_pow(2)
503 * ((double((double((double((double((double((double((double((double(cell
504 (var(Witness(3), Curr))) + (x_0
505 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
506 * cell(var(Witness(6), Curr)))
507 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
508 * cell(var(Witness(6), Curr)))
509 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")))))
510 + (x_1 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
511 * cell(var(Witness(7), Curr)))
512 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
513 * cell(var(Witness(7), Curr)))
514 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")))))
515 + (x_2 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
516 * cell(var(Witness(8), Curr)))
517 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
518 * cell(var(Witness(8), Curr)))
519 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")))))
520 + (x_3 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
521 * cell(var(Witness(9), Curr)))
522 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
523 * cell(var(Witness(9), Curr)))
524 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")))))
525 + (x_4 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
526 * cell(var(Witness(10), Curr)))
527 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
528 * cell(var(Witness(10), Curr)))
529 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")))))
530 + (x_5 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
531 * cell(var(Witness(11), Curr)))
532 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
533 * cell(var(Witness(11), Curr)))
534 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")))))
535 + (x_6 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
536 * cell(var(Witness(12), Curr)))
537 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
538 * cell(var(Witness(12), Curr)))
539 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")))))
540 + (x_7 + ((((field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000")
541 * cell(var(Witness(13), Curr)))
542 + field("0x0000000000000000000000000000000000000000000000000000000000000003"))
543 * cell(var(Witness(13), Curr)))
544 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ED00000000"))))
545 - cell(var(Witness(5), Curr))))) + (alpha_pow(3) * ((((((cell(var(Witness(6), Curr))
546 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
547 * cell(var(Witness(6), Curr)))
548 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
549 * cell(var(Witness(6), Curr)))
550 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
551 * cell(var(Witness(6), Curr))))) + (alpha_pow(4) * ((((((cell(var(Witness(7), Curr))
552 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
553 * cell(var(Witness(7), Curr)))
554 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
555 * cell(var(Witness(7), Curr)))
556 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
557 * cell(var(Witness(7), Curr))))) + (alpha_pow(5) * ((((((cell(var(Witness(8), Curr))
558 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
559 * cell(var(Witness(8), Curr)))
560 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
561 * cell(var(Witness(8), Curr)))
562 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
563 * cell(var(Witness(8), Curr))))) + (alpha_pow(6) * ((((((cell(var(Witness(9), Curr))
564 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
565 * cell(var(Witness(9), Curr)))
566 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
567 * cell(var(Witness(9), Curr)))
568 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
569 * cell(var(Witness(9), Curr))))) + (alpha_pow(7) * ((((((cell(var(Witness(10), Curr))
570 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
571 * cell(var(Witness(10), Curr)))
572 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
573 * cell(var(Witness(10), Curr)))
574 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
575 * cell(var(Witness(10), Curr))))) + (alpha_pow(8) * ((((((cell(var(Witness(11), Curr))
576 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
577 * cell(var(Witness(11), Curr)))
578 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
579 * cell(var(Witness(11), Curr)))
580 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
581 * cell(var(Witness(11), Curr))))) + (alpha_pow(9) * ((((((cell(var(Witness(12), Curr))
582 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
583 * cell(var(Witness(12), Curr)))
584 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
585 * cell(var(Witness(12), Curr)))
586 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
587 * cell(var(Witness(12), Curr))))) + (alpha_pow(10) * ((((((cell(var(Witness(13), Curr))
588 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
589 * cell(var(Witness(13), Curr)))
590 + field("0x000000000000000000000000000000000000000000000000000000000000000B"))
591 * cell(var(Witness(13), Curr)))
592 + field("0x40000000000000000000000000000000224698FC094CF91B992D30ECFFFFFFFB"))
593 * cell(var(Witness(13), Curr)))))
594}
595
596#[allow(clippy::double_parens)]
597#[allow(unused_parens)]
598#[rustfmt::skip] fn endo_mul_scalar_fq<F: FieldWitness>(
600 evals: &ProofEvaluations<[F; 2]>,
601 powers_of_alpha: &[F; NPOWERS_OF_ALPHA],
602) -> F {
603 use Column::*;
604 use CurrOrNext::*;
605
606 let var = get_var(evals);
607 let alpha_pow = |i: usize| powers_of_alpha[i];
608 let field = field::<F>;
609
610 let x_0 = {
612 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
613 * cell(var(Witness(6), Curr)))
614 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
615 * cell(var(Witness(6), Curr)))
616 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
617 * cell(var(Witness(6), Curr)))
618 };
619 let x_1 = {
620 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
621 * cell(var(Witness(7), Curr)))
622 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
623 * cell(var(Witness(7), Curr)))
624 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
625 * cell(var(Witness(7), Curr)))
626 };
627 let x_2 = {
628 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
629 * cell(var(Witness(8), Curr)))
630 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
631 * cell(var(Witness(8), Curr)))
632 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
633 * cell(var(Witness(8), Curr)))
634 };
635 let x_3 = {
636 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
637 * cell(var(Witness(9), Curr)))
638 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
639 * cell(var(Witness(9), Curr)))
640 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
641 * cell(var(Witness(9), Curr)))
642 };
643 let x_4 = {
644 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
645 * cell(var(Witness(10), Curr)))
646 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
647 * cell(var(Witness(10), Curr)))
648 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
649 * cell(var(Witness(10), Curr)))
650 };
651 let x_5 = {
652 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
653 * cell(var(Witness(11), Curr)))
654 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
655 * cell(var(Witness(11), Curr)))
656 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
657 * cell(var(Witness(11), Curr)))
658 };
659 let x_6 = {
660 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
661 * cell(var(Witness(12), Curr)))
662 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
663 * cell(var(Witness(12), Curr)))
664 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
665 * cell(var(Witness(12), Curr)))
666 };
667 let x_7 = {
668 (((((field("0x1555555555555555555555555555555560C232FEADDC3849D96CF90B00000001")
669 * cell(var(Witness(13), Curr)))
670 + field("0x2000000000000000000000000000000011234C7E04CA546EC62375907FFFFFFE"))
671 * cell(var(Witness(13), Curr)))
672 + field("0x0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB061197F56EE1C24ECB67C8580000002"))
673 * cell(var(Witness(13), Curr)))
674 };
675
676 ((((((((((((double(double((double(double((double(double((double(double((double(double((double(double((double(double((double(double(cell(var(Witness(0), Curr)))) + cell(var(Witness(6), Curr))))) + cell(var(Witness(7), Curr))))) + cell(var(Witness(8), Curr))))) + cell(var(Witness(9), Curr))))) + cell(var(Witness(10), Curr))))) + cell(var(Witness(11), Curr))))) + cell(var(Witness(12), Curr))))) + cell(var(Witness(13), Curr))) - cell(var(Witness(1), Curr))) + (alpha_pow(1) * ((double((double((double((double((double((double((double((double(cell(var(Witness(2), Curr))) + x_0)) + x_1)) + x_2)) + x_3)) + x_4)) + x_5)) + x_6)) + x_7) - cell(var(Witness(4), Curr))))) + (alpha_pow(2) * ((double((double((double((double((double((double((double((double(cell(var(Witness(3), Curr))) + (x_0 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(6), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(6), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000"))))) + (x_1 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(7), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(7), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000"))))) + (x_2 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(8), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(8), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000"))))) + (x_3 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(9), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(9), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000"))))) + (x_4 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(10), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(10), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000"))))) + (x_5 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(11), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(11), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000"))))) + (x_6 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(12), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(12), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000"))))) + (x_7 + ((((field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000") * cell(var(Witness(13), Curr))) + field("0x0000000000000000000000000000000000000000000000000000000000000003")) * cell(var(Witness(13), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB2100000000")))) - cell(var(Witness(5), Curr))))) + (alpha_pow(3) * ((((((cell(var(Witness(6), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(6), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(6), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(6), Curr))))) + (alpha_pow(4) * ((((((cell(var(Witness(7), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(7), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(7), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(7), Curr))))) + (alpha_pow(5) * ((((((cell(var(Witness(8), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(8), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(8), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(8), Curr))))) + (alpha_pow(6) * ((((((cell(var(Witness(9), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(9), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(9), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(9), Curr))))) + (alpha_pow(7) * ((((((cell(var(Witness(10), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(10), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(10), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(10), Curr))))) + (alpha_pow(8) * ((((((cell(var(Witness(11), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(11), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(11), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(11), Curr))))) + (alpha_pow(9) * ((((((cell(var(Witness(12), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(12), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(12), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(12), Curr))))) + (alpha_pow(10) * ((((((cell(var(Witness(13), Curr)) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(13), Curr))) + field("0x000000000000000000000000000000000000000000000000000000000000000B")) * cell(var(Witness(13), Curr))) + field("0x40000000000000000000000000000000224698FC0994A8DD8C46EB20FFFFFFFB")) * cell(var(Witness(13), Curr)))))
678}
679
680#[cfg(test)]
681mod tests {
682 use kimchi::{
683 circuits::expr::Linearization,
684 linearization::{constraints_expr, linearization_columns},
685 };
686 use mina_curves::pasta::{Fp, Fq};
687 use sha2::{Digest, Sha256};
688 #[cfg(target_family = "wasm")]
689 use wasm_bindgen_test::wasm_bindgen_test as test;
690
691 fn generate_plonk() {
697 let lookup_configuration = None;
698 let fp_evaluated_cols = linearization_columns::<Fp>(lookup_configuration);
699 let (fp_linearization, _powers_of_alpha) = constraints_expr::<Fp>(None, true);
700
701 let Linearization {
702 constant_term: _,
703 index_terms: mut index_terms_fp,
704 } = fp_linearization.linearize(fp_evaluated_cols).unwrap();
705
706 index_terms_fp.sort_by(|(x, _), (y, _)| x.cmp(y));
709
710 let fp_other_terms: Vec<(String, String)> = index_terms_fp
711 .iter()
712 .map(|(col, expr)| (format!("{:?}", col), expr.ocaml_str()))
713 .collect();
714
715 let sum = |s: &str| {
716 let mut hasher = Sha256::new();
717 hasher.update(s.as_bytes());
718 hex::encode(hasher.finalize())
719 };
720
721 for (v, terms) in &fp_other_terms {
723 println!("value={:?} sum=\n{}\n", v, sum(terms));
724
725 let terms = terms.replace(" in ", "};");
727 let terms = terms.replace('=', "={");
728
729 println!("value={:?} code=\n{}\n", v, terms);
731 }
732
733 let value_of = |s: &str| &fp_other_terms.iter().find(|(v, _)| v == s).unwrap().1;
736
737 let fp_sum_complete_add = sum(value_of("Index(CompleteAdd)"));
738 assert_eq!(
739 fp_sum_complete_add,
740 "c478727783cc551528384c6f05c26414bf64bbd1dc6a0c47c30eb917a825b9a0"
741 );
742
743 let fp_sum_var_base_mul = sum(value_of("Index(VarBaseMul)"));
744 assert_eq!(
745 fp_sum_var_base_mul,
746 "4437fea516a70ff606b11eda22cfde29e2d95b86154010b5886b3510909d2ab2"
747 );
748
749 let fp_sum_endomul = sum(value_of("Index(EndoMul)"));
750 assert_eq!(
751 fp_sum_endomul,
752 "561f3c95177dc76aa596d506be6e1dd5530dd3a9f44d25d2f5e4e9ad1c89176e"
753 );
754
755 let fp_sum_endomul_scalar = sum(value_of("Index(EndoMulScalar)"));
756 assert_eq!(
757 fp_sum_endomul_scalar,
758 "d56e30e8015f38922a7069cc87daaf21ffb15d96cc80fdd9b257e3267145b919"
759 );
760
761 let fq_evaluated_cols = linearization_columns::<Fq>(lookup_configuration);
764 let (fq_linearization, _powers_of_alpha) = constraints_expr::<Fq>(None, true);
765
766 let Linearization {
767 constant_term,
768 index_terms: mut index_terms_fq,
769 } = fq_linearization.linearize(fq_evaluated_cols).unwrap();
770
771 dbg!(constant_term.ocaml_str());
772
773 index_terms_fq.sort_by(|(x, _), (y, _)| x.cmp(y));
776
777 let fq_other_terms: Vec<(String, String)> = index_terms_fq
780 .iter()
781 .map(|(col, expr)| (format!("{:?}", col), expr.ocaml_str()))
782 .collect();
783
784 let value_of = |s: &str| &fq_other_terms.iter().find(|(v, _)| v == s).unwrap().1;
785
786 let fq_sum_complete_add = sum(value_of("Index(CompleteAdd)"));
787 assert_eq!(fq_sum_complete_add, fp_sum_complete_add);
788
789 let fq_sum_var_base_mul = sum(value_of("Index(VarBaseMul)"));
790 assert_eq!(fq_sum_var_base_mul, fp_sum_var_base_mul);
791
792 let fq_sum_endomul = sum(value_of("Index(EndoMul)"));
793 assert_eq!(fq_sum_endomul, fp_sum_endomul);
794
795 let fq_sum_endomul_scalar = sum(value_of("Index(EndoMulScalar)"));
796 assert_ne!(fq_sum_endomul_scalar, fp_sum_endomul_scalar);
797 assert_eq!(
798 fq_sum_endomul_scalar,
799 "bcf65a903f377ad4c115d4357817a7129381b42ff3a23e41f4fc2c735943db0f"
800 );
801 }
802}