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