1#![allow(non_snake_case)]
2
3use ark_ec::{AffineRepr, VariableBaseMSM};
4use ark_ff::{Field, UniformRand};
5use ark_std::{
6 borrow::BorrowMut,
7 boxed::Box,
8 iter, mem,
9 rand::{CryptoRng, RngCore},
10 vec,
11 vec::Vec,
12 One, Zero,
13};
14use merlin::Transcript;
15
16use super::{
17 ConstraintSystem, LinearCombination, R1CSProof, RandomizableConstraintSystem,
18 RandomizedConstraintSystem, Variable,
19};
20
21use crate::errors::R1CSError;
22use crate::generators::{BulletproofGens, PedersenGens};
23use crate::transcript::TranscriptProtocol;
24
25pub struct Verifier<G: AffineRepr, T: BorrowMut<Transcript>> {
35 transcript: T,
36 constraints: Vec<LinearCombination<G::ScalarField>>,
37
38 num_vars: usize,
46 V: Vec<G>,
47
48 deferred_constraints: Vec<Box<dyn Fn(&mut RandomizingVerifier<G, T>) -> Result<(), R1CSError>>>,
53
54 pending_multiplier: Option<usize>,
56}
57
58pub struct RandomizingVerifier<G: AffineRepr, T: BorrowMut<Transcript>> {
66 verifier: Verifier<G, T>,
67}
68
69impl<T: BorrowMut<Transcript>, G: AffineRepr> ConstraintSystem<G::ScalarField> for Verifier<G, T> {
70 fn transcript(&mut self) -> &mut Transcript {
71 self.transcript.borrow_mut()
72 }
73
74 fn multiply(
75 &mut self,
76 mut left: LinearCombination<G::ScalarField>,
77 mut right: LinearCombination<G::ScalarField>,
78 ) -> (
79 Variable<G::ScalarField>,
80 Variable<G::ScalarField>,
81 Variable<G::ScalarField>,
82 ) {
83 let var = self.num_vars;
84 self.num_vars += 1;
85
86 let l_var = Variable::MultiplierLeft(var);
88 let r_var = Variable::MultiplierRight(var);
89 let o_var = Variable::MultiplierOutput(var);
90
91 left.terms.push((l_var, -G::ScalarField::one()));
93 right.terms.push((r_var, -G::ScalarField::one()));
94 self.constrain(left);
95 self.constrain(right);
96
97 (l_var, r_var, o_var)
98 }
99
100 fn allocate(
101 &mut self,
102 _: Option<G::ScalarField>,
103 ) -> Result<Variable<G::ScalarField>, R1CSError> {
104 match self.pending_multiplier {
105 None => {
106 let i = self.num_vars;
107 self.num_vars += 1;
108 self.pending_multiplier = Some(i);
109 Ok(Variable::MultiplierLeft(i))
110 }
111 Some(i) => {
112 self.pending_multiplier = None;
113 Ok(Variable::MultiplierRight(i))
114 }
115 }
116 }
117
118 fn allocate_multiplier(
119 &mut self,
120 _: Option<(G::ScalarField, G::ScalarField)>,
121 ) -> Result<
122 (
123 Variable<G::ScalarField>,
124 Variable<G::ScalarField>,
125 Variable<G::ScalarField>,
126 ),
127 R1CSError,
128 > {
129 let var = self.num_vars;
130 self.num_vars += 1;
131
132 let l_var = Variable::MultiplierLeft(var);
134 let r_var = Variable::MultiplierRight(var);
135 let o_var = Variable::MultiplierOutput(var);
136
137 Ok((l_var, r_var, o_var))
138 }
139
140 fn multipliers_len(&self) -> usize {
141 self.num_vars
142 }
143
144 fn constrain(&mut self, lc: LinearCombination<G::ScalarField>) {
145 self.constraints.push(lc);
149 }
150}
151
152impl<T: BorrowMut<Transcript>, G: AffineRepr> RandomizableConstraintSystem<G::ScalarField>
153 for Verifier<G, T>
154{
155 type RandomizedCS = RandomizingVerifier<G, T>;
156
157 fn specify_randomized_constraints<F>(&mut self, callback: F) -> Result<(), R1CSError>
158 where
159 F: 'static + Fn(&mut Self::RandomizedCS) -> Result<(), R1CSError>,
160 {
161 self.deferred_constraints.push(Box::new(callback));
162 Ok(())
163 }
164}
165
166impl<T: BorrowMut<Transcript>, G: AffineRepr> ConstraintSystem<G::ScalarField>
167 for RandomizingVerifier<G, T>
168{
169 fn transcript(&mut self) -> &mut Transcript {
170 self.verifier.transcript.borrow_mut()
171 }
172
173 fn multiply(
174 &mut self,
175 left: LinearCombination<G::ScalarField>,
176 right: LinearCombination<G::ScalarField>,
177 ) -> (
178 Variable<G::ScalarField>,
179 Variable<G::ScalarField>,
180 Variable<G::ScalarField>,
181 ) {
182 self.verifier.multiply(left, right)
183 }
184
185 fn allocate(
186 &mut self,
187 assignment: Option<G::ScalarField>,
188 ) -> Result<Variable<G::ScalarField>, R1CSError> {
189 self.verifier.allocate(assignment)
190 }
191
192 fn allocate_multiplier(
193 &mut self,
194 input_assignments: Option<(G::ScalarField, G::ScalarField)>,
195 ) -> Result<
196 (
197 Variable<G::ScalarField>,
198 Variable<G::ScalarField>,
199 Variable<G::ScalarField>,
200 ),
201 R1CSError,
202 > {
203 self.verifier.allocate_multiplier(input_assignments)
204 }
205
206 fn multipliers_len(&self) -> usize {
207 self.verifier.multipliers_len()
208 }
209
210 fn constrain(&mut self, lc: LinearCombination<G::ScalarField>) {
211 self.verifier.constrain(lc)
212 }
213}
214
215impl<T: BorrowMut<Transcript>, G: AffineRepr> RandomizedConstraintSystem<G::ScalarField>
216 for RandomizingVerifier<G, T>
217{
218 fn challenge_scalar(&mut self, label: &'static [u8]) -> G::ScalarField {
219 <Transcript as TranscriptProtocol<G>>::challenge_scalar(
220 self.verifier.transcript.borrow_mut(),
221 label,
222 )
223 }
224}
225
226impl<G: AffineRepr, T: BorrowMut<Transcript>> Verifier<G, T> {
227 pub fn new(mut transcript: T) -> Self {
253 <Transcript as TranscriptProtocol<G>>::r1cs_domain_sep(transcript.borrow_mut());
254
255 Verifier {
256 transcript,
257 num_vars: 0,
258 V: Vec::new(),
259 constraints: Vec::new(),
260 deferred_constraints: Vec::new(),
261 pending_multiplier: None,
262 }
263 }
264
265 pub fn commit(&mut self, commitment: G) -> Variable<G::ScalarField> {
280 let i = self.V.len();
281 self.V.push(commitment);
282
283 self.transcript.borrow_mut().append_point(b"V", &commitment);
285
286 Variable::Committed(i)
287 }
288
289 fn flattened_constraints(
305 &mut self,
306 z: &G::ScalarField,
307 ) -> (
308 Vec<G::ScalarField>,
309 Vec<G::ScalarField>,
310 Vec<G::ScalarField>,
311 Vec<G::ScalarField>,
312 G::ScalarField,
313 ) {
314 let n = self.num_vars;
315 let m = self.V.len();
316
317 let mut wL = vec![G::ScalarField::zero(); n];
318 let mut wR = vec![G::ScalarField::zero(); n];
319 let mut wO = vec![G::ScalarField::zero(); n];
320 let mut wV = vec![G::ScalarField::zero(); m];
321 let mut wc = G::ScalarField::zero();
322
323 let mut exp_z = *z;
324 for lc in self.constraints.iter() {
325 for (var, coeff) in &lc.terms {
326 match var {
327 Variable::MultiplierLeft(i) => {
328 wL[*i] += exp_z * coeff;
329 }
330 Variable::MultiplierRight(i) => {
331 wR[*i] += exp_z * coeff;
332 }
333 Variable::MultiplierOutput(i) => {
334 wO[*i] += exp_z * coeff;
335 }
336 Variable::Committed(i) => {
337 wV[*i] -= exp_z * coeff;
338 }
339 Variable::One() => {
340 wc -= exp_z * coeff;
341 }
342 _ => {}
343 }
344 }
345 exp_z *= z;
346 }
347
348 (wL, wR, wO, wV, wc)
349 }
350
351 fn create_randomized_constraints(mut self) -> Result<Self, R1CSError> {
354 self.pending_multiplier = None;
356
357 if self.deferred_constraints.len() == 0 {
358 <Transcript as TranscriptProtocol<G>>::r1cs_1phase_domain_sep(
359 self.transcript.borrow_mut(),
360 );
361 Ok(self)
362 } else {
363 <Transcript as TranscriptProtocol<G>>::r1cs_2phase_domain_sep(
364 self.transcript.borrow_mut(),
365 );
366 let mut callbacks = mem::replace(&mut self.deferred_constraints, Vec::new());
370 let mut wrapped_self = RandomizingVerifier { verifier: self };
371 for callback in callbacks.drain(..) {
372 callback(&mut wrapped_self)?;
373 }
374 Ok(wrapped_self.verifier)
375 }
376 }
377
378 pub(super) fn verification_scalars(
395 mut self,
396 proof: &R1CSProof<G>,
397 bp_gens: &BulletproofGens<G>,
398 ) -> Result<(Self, Vec<G::ScalarField>), R1CSError> {
399 let transcript = self.transcript.borrow_mut();
404 transcript.append_u64(b"m", self.V.len() as u64);
405
406 let n1 = self.num_vars;
407 transcript.validate_and_append_point(b"A_I1", &proof.A_I1)?;
408 transcript.validate_and_append_point(b"A_O1", &proof.A_O1)?;
409 transcript.validate_and_append_point(b"S1", &proof.S1)?;
410
411 self = self.create_randomized_constraints()?;
413
414 let transcript = self.transcript.borrow_mut();
415
416 let n = self.num_vars;
418 let n2 = n - n1;
419 let padded_n = self.num_vars.next_power_of_two();
420 let pad = padded_n - n;
421
422 use crate::inner_product_proof::inner_product;
423 use crate::util;
424
425 if bp_gens.gens_capacity < padded_n {
426 return Err(R1CSError::InvalidGeneratorsLength);
427 }
428
429 transcript.append_point(b"A_I2", &proof.A_I2);
431 transcript.append_point(b"A_O2", &proof.A_O2);
432 transcript.append_point(b"S2", &proof.S2);
433
434 let y: G::ScalarField =
435 <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"y");
436 let z = <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"z");
437
438 transcript.validate_and_append_point(b"T_1", &proof.T_1)?;
439 transcript.validate_and_append_point(b"T_3", &proof.T_3)?;
440 transcript.validate_and_append_point(b"T_4", &proof.T_4)?;
441 transcript.validate_and_append_point(b"T_5", &proof.T_5)?;
442 transcript.validate_and_append_point(b"T_6", &proof.T_6)?;
443
444 let u = <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"u");
445 let x = <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"x");
446
447 <Transcript as TranscriptProtocol<G>>::append_scalar(transcript, b"t_x", &proof.t_x);
448 <Transcript as TranscriptProtocol<G>>::append_scalar(
449 transcript,
450 b"t_x_blinding",
451 &proof.t_x_blinding,
452 );
453 <Transcript as TranscriptProtocol<G>>::append_scalar(
454 transcript,
455 b"e_blinding",
456 &proof.e_blinding,
457 );
458
459 let w: G::ScalarField =
460 <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"w");
461
462 let (wL, wR, wO, wV, wc) = self.flattened_constraints(&z);
463
464 let (u_sq, u_inv_sq, s) = proof
466 .ipp_proof
467 .verification_scalars(padded_n, self.transcript.borrow_mut())
468 .map_err(|_| R1CSError::VerificationError)?;
469
470 let a = proof.ipp_proof.a;
471 let b = proof.ipp_proof.b;
472
473 let y_inv = y.inverse().unwrap();
474 let y_inv_vec = util::exp_iter::<G>(y_inv)
475 .take(padded_n)
476 .collect::<Vec<G::ScalarField>>();
477 let yneg_wR = wR
478 .into_iter()
479 .zip(y_inv_vec.iter())
480 .map(|(wRi, exp_y_inv)| wRi * exp_y_inv)
481 .chain(iter::repeat(G::ScalarField::zero()).take(pad))
482 .collect::<Vec<G::ScalarField>>();
483
484 let delta = inner_product(&yneg_wR[0..n], &wL);
485
486 let u_for_g = iter::repeat(G::ScalarField::one())
487 .take(n1)
488 .chain(iter::repeat(u).take(n2 + pad));
489 let u_for_h = u_for_g.clone();
490
491 let g_scalars: Vec<_> = yneg_wR
493 .iter()
494 .zip(u_for_g)
495 .zip(s.iter().take(padded_n))
496 .map(|((yneg_wRi, u_or_1), s_i)| u_or_1 * (x * yneg_wRi - a * s_i))
497 .collect();
498
499 let h_scalars: Vec<_> = y_inv_vec
500 .iter()
501 .zip(u_for_h)
502 .zip(s.iter().rev().take(padded_n))
503 .zip(
504 wL.into_iter()
505 .chain(iter::repeat(G::ScalarField::zero()).take(pad)),
506 )
507 .zip(
508 wO.into_iter()
509 .chain(iter::repeat(G::ScalarField::zero()).take(pad)),
510 )
511 .map(|((((y_inv_i, u_or_1), s_i_inv), wLi), wOi)| {
512 u_or_1 * (*y_inv_i * (x * wLi + wOi - b * s_i_inv) - G::ScalarField::one())
513 })
514 .collect();
515
516 let r: G::ScalarField = <Transcript as TranscriptProtocol<G>>::challenge_scalar(
517 &mut self.transcript.borrow_mut().clone(),
518 b"r",
519 );
520
521 let xx = x * x;
522 let rxx = r * xx;
523 let xxx = x * xx;
524
525 let T_scalars = [r * x, rxx * x, rxx * xx, rxx * xxx, rxx * xx * xx];
527
528 let mut scalars: Vec<G::ScalarField> = vec![];
529 scalars.push(w * (proof.t_x - a * b) + r * (xx * (wc + delta) - proof.t_x));
530 scalars.push(-proof.e_blinding - r * proof.t_x_blinding);
531 scalars.extend_from_slice(&g_scalars);
532 scalars.extend_from_slice(&h_scalars);
533 scalars.extend_from_slice(&[x, xx, xxx, u * x, u * xx, u * xxx]);
534 for wVi in wV.iter() {
535 scalars.push(*wVi * rxx);
536 }
537 scalars.extend_from_slice(&T_scalars);
538 scalars.extend_from_slice(&u_sq);
539 scalars.extend_from_slice(&u_inv_sq);
540 Ok((self, scalars))
541 }
542
543 pub fn verify(
550 self,
551 proof: &R1CSProof<G>,
552 pc_gens: &PedersenGens<G>,
553 bp_gens: &BulletproofGens<G>,
554 ) -> Result<(), R1CSError> {
555 self.verify_and_return_transcript(proof, pc_gens, bp_gens)
556 .map(|_| ())
557 }
558 pub fn verify_and_return_transcript(
560 mut self,
561 proof: &R1CSProof<G>,
562 pc_gens: &PedersenGens<G>,
563 bp_gens: &BulletproofGens<G>,
564 ) -> Result<T, R1CSError> {
565 let (verifier, scalars) = self.verification_scalars(proof, bp_gens)?;
566 self = verifier;
567 let T_points = [proof.T_1, proof.T_3, proof.T_4, proof.T_5, proof.T_6];
568
569 let gens = bp_gens.share(0);
571
572 let padded_n = self.num_vars.next_power_of_two();
573
574 let mega_check = G::Group::msm(
575 &iter::once(&pc_gens.B)
576 .chain(iter::once(&pc_gens.B_blinding))
577 .chain(gens.G(padded_n))
578 .chain(gens.H(padded_n))
579 .chain(iter::once(&proof.A_I1))
580 .chain(iter::once(&proof.A_O1))
581 .chain(iter::once(&proof.S1))
582 .chain(iter::once(&proof.A_I2))
583 .chain(iter::once(&proof.A_O2))
584 .chain(iter::once(&proof.S2))
585 .chain(self.V.iter())
586 .chain(T_points.iter())
587 .chain(proof.ipp_proof.L_vec.iter())
588 .chain(proof.ipp_proof.R_vec.iter())
589 .map(|f| f.clone())
590 .collect::<Vec<G>>(),
591 &scalars,
592 )
593 .unwrap();
594
595 if !mega_check.is_zero() {
596 return Err(R1CSError::VerificationError);
597 }
598
599 Ok(self.transcript)
600 }
601}
602
603pub fn batch_verify<'a, G: AffineRepr, I, R: CryptoRng + RngCore>(
605 prng: &mut R,
606 instances: I,
607 pc_gens: &PedersenGens<G>,
608 bp_gens: &BulletproofGens<G>,
609) -> Result<(), R1CSError>
610where
611 I: IntoIterator<Item = (Verifier<G, &'a mut Transcript>, &'a R1CSProof<G>)>,
612{
613 let mut max_n_padded = 0;
614 let mut verifiers: Vec<Verifier<G, _>> = vec![];
615 let mut proofs: Vec<&R1CSProof<G>> = vec![];
616 let mut verification_scalars = vec![];
617 for (verifier, proof) in instances.into_iter() {
618 let (verifier, scalars) = verifier.verification_scalars(proof, bp_gens)?;
620 let n = verifier.num_vars.next_power_of_two();
621 if n > max_n_padded {
622 max_n_padded = n;
623 }
624 verification_scalars.push(scalars);
625 verifiers.push(verifier);
626 proofs.push(proof);
627 }
628 let mut all_scalars = vec![];
629 let mut all_elems = vec![];
630
631 for _ in 0..(2 * max_n_padded + 2) {
632 all_scalars.push(G::ScalarField::zero());
633 }
634 all_elems.push(pc_gens.B);
635 all_elems.push(pc_gens.B_blinding);
636 let gens = bp_gens.share(0);
637 for G in gens.G(max_n_padded) {
638 all_elems.push(*G);
639 }
640 for H in gens.H(max_n_padded) {
641 all_elems.push(*H);
642 }
643
644 for ((verifier, proof), scalars) in verifiers
645 .into_iter()
646 .zip(proofs.iter())
647 .zip(verification_scalars.iter())
648 {
649 let alpha = G::ScalarField::rand(prng);
650 let scaled_scalars: Vec<G::ScalarField> = scalars.into_iter().map(|s| alpha * s).collect();
651 let padded_n = verifier.num_vars.next_power_of_two();
652 all_scalars[0] += scaled_scalars[0]; all_scalars[1] += scaled_scalars[1]; for (i, s) in (&scaled_scalars[2..2 + padded_n]).iter().enumerate() {
656 all_scalars[i + 2] += *s;
657 }
658 for (i, s) in (&scaled_scalars[2 + padded_n..2 + 2 * padded_n])
660 .iter()
661 .enumerate()
662 {
663 all_scalars[2 + max_n_padded + i] += *s;
664 }
665
666 for s in (&scaled_scalars[2 + 2 * padded_n..]).iter() {
667 all_scalars.push(*s);
668 }
669 all_elems.push(proof.A_I1);
670 all_elems.push(proof.A_O1);
671 all_elems.push(proof.S1);
672 all_elems.push(proof.A_I2);
673 all_elems.push(proof.A_O2);
674 all_elems.push(proof.S2);
675 all_elems.extend_from_slice(verifier.V.as_slice());
676 all_elems.push(proof.T_1);
677 all_elems.push(proof.T_3);
678 all_elems.push(proof.T_4);
679 all_elems.push(proof.T_5);
680 all_elems.push(proof.T_6);
681 all_elems.extend_from_slice(&proof.ipp_proof.L_vec);
682 all_elems.extend_from_slice(&proof.ipp_proof.R_vec);
683 }
684
685 let multi_exp = G::Group::msm(&all_elems, &all_scalars).unwrap();
686 if !multi_exp.is_zero() {
687 Err(R1CSError::VerificationError)
688 } else {
689 Ok(())
690 }
691}