1#![allow(non_snake_case)]
2
3use ark_ec::{AffineRepr, CurveGroup, VariableBaseMSM};
4use ark_ff::{Field, PrimeField, UniformRand};
5use ark_serialize::CanonicalSerialize;
6use ark_std::{borrow::BorrowMut, boxed::Box, mem, vec, vec::Vec, One, Zero};
7use clear_on_drop::clear::Clear;
8use merlin::Transcript;
9use rand_core::{CryptoRng, RngCore};
10
11use super::{
12 ConstraintSystem, LinearCombination, R1CSProof, RandomizableConstraintSystem,
13 RandomizedConstraintSystem, Variable,
14};
15
16use crate::errors::R1CSError;
17use crate::generators::{BulletproofGens, PedersenGens};
18use crate::inner_product_proof::InnerProductProof;
19use crate::transcript::TranscriptProtocol;
20
21pub struct Prover<'g, G: AffineRepr, T: BorrowMut<Transcript>> {
31 transcript: T,
32 pc_gens: &'g PedersenGens<G>,
33 constraints: Vec<LinearCombination<G::ScalarField>>,
35 secrets: Secrets<G>,
37
38 deferred_constraints:
41 Vec<Box<dyn Fn(&mut RandomizingProver<'g, G, T>) -> Result<(), R1CSError>>>,
42
43 pending_multiplier: Option<usize>,
45}
46
47struct Secrets<G: AffineRepr> {
50 a_L: Vec<G::ScalarField>,
52 a_R: Vec<G::ScalarField>,
54 a_O: Vec<G::ScalarField>,
56 v: Vec<G::ScalarField>,
58 v_blinding: Vec<G::ScalarField>,
60}
61
62pub struct RandomizingProver<'g, G: AffineRepr, T: BorrowMut<Transcript>> {
70 prover: Prover<'g, G, T>,
71}
72
73impl<G: AffineRepr> Drop for Secrets<G> {
75 fn drop(&mut self) {
76 self.v.clear();
77 self.v_blinding.clear();
78
79 for e in self.a_L.iter_mut() {
85 e.clear();
86 }
87 for e in self.a_R.iter_mut() {
88 e.clear();
89 }
90 for e in self.a_O.iter_mut() {
91 e.clear();
92 }
93 }
94}
95
96impl<'g, G: AffineRepr, T: BorrowMut<Transcript>> ConstraintSystem<G::ScalarField>
97 for Prover<'g, G, T>
98{
99 fn transcript(&mut self) -> &mut Transcript {
100 self.transcript.borrow_mut()
101 }
102
103 fn multiply(
104 &mut self,
105 mut left: LinearCombination<G::ScalarField>,
106 mut right: LinearCombination<G::ScalarField>,
107 ) -> (
108 Variable<G::ScalarField>,
109 Variable<G::ScalarField>,
110 Variable<G::ScalarField>,
111 ) {
112 let l = self.eval(&left);
114 let r = self.eval(&right);
115 let o = l * r;
116
117 let l_var = Variable::MultiplierLeft(self.secrets.a_L.len());
119 let r_var = Variable::MultiplierRight(self.secrets.a_R.len());
120 let o_var = Variable::MultiplierOutput(self.secrets.a_O.len());
121 self.secrets.a_L.push(l);
123 self.secrets.a_R.push(r);
124 self.secrets.a_O.push(o);
125
126 left.terms.push((l_var, -G::ScalarField::one()));
128 right.terms.push((r_var, -G::ScalarField::one()));
129 self.constrain(left);
130 self.constrain(right);
131
132 (l_var, r_var, o_var)
133 }
134
135 fn allocate(
136 &mut self,
137 assignment: Option<G::ScalarField>,
138 ) -> Result<Variable<G::ScalarField>, R1CSError> {
139 let scalar = assignment.ok_or(R1CSError::MissingAssignment)?;
140
141 match self.pending_multiplier {
142 None => {
143 let i = self.secrets.a_L.len();
144 self.pending_multiplier = Some(i);
145 self.secrets.a_L.push(scalar);
146 self.secrets.a_R.push(G::ScalarField::zero());
147 self.secrets.a_O.push(G::ScalarField::zero());
148 Ok(Variable::MultiplierLeft(i))
149 }
150 Some(i) => {
151 self.pending_multiplier = None;
152 self.secrets.a_R[i] = scalar;
153 self.secrets.a_O[i] = self.secrets.a_L[i] * self.secrets.a_R[i];
154 Ok(Variable::MultiplierRight(i))
155 }
156 }
157 }
158
159 fn allocate_multiplier(
160 &mut self,
161 input_assignments: Option<(G::ScalarField, G::ScalarField)>,
162 ) -> Result<
163 (
164 Variable<G::ScalarField>,
165 Variable<G::ScalarField>,
166 Variable<G::ScalarField>,
167 ),
168 R1CSError,
169 > {
170 let (l, r) = input_assignments.ok_or(R1CSError::MissingAssignment)?;
171 let o = l * r;
172
173 let l_var = Variable::MultiplierLeft(self.secrets.a_L.len());
175 let r_var = Variable::MultiplierRight(self.secrets.a_R.len());
176 let o_var = Variable::MultiplierOutput(self.secrets.a_O.len());
177 self.secrets.a_L.push(l);
179 self.secrets.a_R.push(r);
180 self.secrets.a_O.push(o);
181
182 Ok((l_var, r_var, o_var))
183 }
184
185 fn multipliers_len(&self) -> usize {
186 self.secrets.a_L.len()
187 }
188
189 fn constrain(&mut self, lc: LinearCombination<G::ScalarField>) {
190 self.constraints.push(lc);
193 }
194}
195
196impl<'g, G: AffineRepr, T: BorrowMut<Transcript>> RandomizableConstraintSystem<G::ScalarField>
197 for Prover<'g, G, T>
198{
199 type RandomizedCS = RandomizingProver<'g, G, T>;
200
201 fn specify_randomized_constraints<F>(&mut self, callback: F) -> Result<(), R1CSError>
202 where
203 F: 'static + Fn(&mut Self::RandomizedCS) -> Result<(), R1CSError>,
204 {
205 self.deferred_constraints.push(Box::new(callback));
206 Ok(())
207 }
208}
209
210impl<'g, G: AffineRepr, T: BorrowMut<Transcript>> ConstraintSystem<G::ScalarField>
211 for RandomizingProver<'g, G, T>
212{
213 fn transcript(&mut self) -> &mut Transcript {
214 self.prover.transcript.borrow_mut()
215 }
216
217 fn multiply(
218 &mut self,
219 left: LinearCombination<G::ScalarField>,
220 right: LinearCombination<G::ScalarField>,
221 ) -> (
222 Variable<G::ScalarField>,
223 Variable<G::ScalarField>,
224 Variable<G::ScalarField>,
225 ) {
226 self.prover.multiply(left, right)
227 }
228
229 fn allocate(
230 &mut self,
231 assignment: Option<G::ScalarField>,
232 ) -> Result<Variable<G::ScalarField>, R1CSError> {
233 self.prover.allocate(assignment)
234 }
235
236 fn allocate_multiplier(
237 &mut self,
238 input_assignments: Option<(G::ScalarField, G::ScalarField)>,
239 ) -> Result<
240 (
241 Variable<G::ScalarField>,
242 Variable<G::ScalarField>,
243 Variable<G::ScalarField>,
244 ),
245 R1CSError,
246 > {
247 self.prover.allocate_multiplier(input_assignments)
248 }
249
250 fn multipliers_len(&self) -> usize {
251 self.prover.multipliers_len()
252 }
253
254 fn constrain(&mut self, lc: LinearCombination<G::ScalarField>) {
255 self.prover.constrain(lc)
256 }
257}
258
259impl<'g, G: AffineRepr, T: BorrowMut<Transcript>> RandomizedConstraintSystem<G::ScalarField>
260 for RandomizingProver<'g, G, T>
261{
262 fn challenge_scalar(&mut self, label: &'static [u8]) -> G::ScalarField {
263 <Transcript as TranscriptProtocol<G>>::challenge_scalar(
264 self.prover.transcript.borrow_mut(),
265 label,
266 )
267 }
268}
269
270impl<'g, G: AffineRepr, T: BorrowMut<Transcript>> Prover<'g, G, T> {
271 pub fn new(pc_gens: &'g PedersenGens<G>, mut transcript: T) -> Self {
292 <Transcript as TranscriptProtocol<G>>::r1cs_domain_sep(transcript.borrow_mut());
293
294 Prover {
295 pc_gens,
296 transcript,
297 secrets: Secrets {
298 v: Vec::new(),
299 v_blinding: Vec::new(),
300 a_L: Vec::new(),
301 a_R: Vec::new(),
302 a_O: Vec::new(),
303 },
304 constraints: Vec::new(),
305 deferred_constraints: Vec::new(),
306 pending_multiplier: None,
307 }
308 }
309
310 pub fn commit(
328 &mut self,
329 v: G::ScalarField,
330 v_blinding: G::ScalarField,
331 ) -> (G, Variable<G::ScalarField>) {
332 let i = self.secrets.v.len();
333 self.secrets.v.push(v);
334 self.secrets.v_blinding.push(v_blinding);
335
336 let V = self.pc_gens.commit(v, v_blinding);
338 self.transcript.borrow_mut().append_point(b"V", &V);
339
340 (V, Variable::Committed(i))
341 }
342
343 fn flattened_constraints(
355 &mut self,
356 z: &G::ScalarField,
357 ) -> (
358 Vec<G::ScalarField>,
359 Vec<G::ScalarField>,
360 Vec<G::ScalarField>,
361 Vec<G::ScalarField>,
362 ) {
363 let n = self.secrets.a_L.len();
364 let m = self.secrets.v.len();
365
366 let mut wL = vec![G::ScalarField::zero(); n];
367 let mut wR = vec![G::ScalarField::zero(); n];
368 let mut wO = vec![G::ScalarField::zero(); n];
369 let mut wV = vec![G::ScalarField::zero(); m];
370
371 let mut exp_z = *z;
372 for lc in self.constraints.iter() {
373 for (var, coeff) in &lc.terms {
374 match var {
375 Variable::MultiplierLeft(i) => {
376 wL[*i] += exp_z * coeff;
377 }
378 Variable::MultiplierRight(i) => {
379 wR[*i] += exp_z * coeff;
380 }
381 Variable::MultiplierOutput(i) => {
382 wO[*i] += exp_z * coeff;
383 }
384 Variable::Committed(i) => {
385 wV[*i] -= exp_z * coeff;
386 }
387 Variable::One() => {
388 }
390 _ => {}
391 }
392 }
393 exp_z *= z;
394 }
395
396 (wL, wR, wO, wV)
397 }
398
399 fn eval(&self, lc: &LinearCombination<G::ScalarField>) -> G::ScalarField {
400 lc.terms
401 .iter()
402 .map(|(var, coeff)| {
403 *coeff
404 * match var {
405 Variable::MultiplierLeft(i) => self.secrets.a_L[*i],
406 Variable::MultiplierRight(i) => self.secrets.a_R[*i],
407 Variable::MultiplierOutput(i) => self.secrets.a_O[*i],
408 Variable::Committed(i) => self.secrets.v[*i],
409 Variable::One() => G::ScalarField::one(),
410 _ => G::ScalarField::zero(),
411 }
412 })
413 .sum()
414 }
415
416 fn create_randomized_constraints(mut self) -> Result<Self, R1CSError> {
419 self.pending_multiplier = None;
421
422 if self.deferred_constraints.len() == 0 {
423 <Transcript as TranscriptProtocol<G>>::r1cs_1phase_domain_sep(
424 self.transcript.borrow_mut(),
425 );
426 Ok(self)
427 } else {
428 <Transcript as TranscriptProtocol<G>>::r1cs_2phase_domain_sep(
429 self.transcript.borrow_mut(),
430 );
431 let mut callbacks = mem::replace(&mut self.deferred_constraints, Vec::new());
435 let mut wrapped_self = RandomizingProver { prover: self };
436 for callback in callbacks.drain(..) {
437 callback(&mut wrapped_self)?;
438 }
439 Ok(wrapped_self.prover)
440 }
441 }
442
443 pub fn prove<R: CryptoRng + RngCore>(
445 self,
446 prng: &mut R,
447 bp_gens: &BulletproofGens<G>,
448 ) -> Result<R1CSProof<G>, R1CSError> {
449 self.prove_and_return_transcript(prng, bp_gens)
450 .map(|(proof, _transcript)| proof)
451 }
452
453 pub fn prove_and_return_transcript<R: CryptoRng + RngCore>(
455 mut self,
456 prng: &mut R,
457 bp_gens: &BulletproofGens<G>,
458 ) -> Result<(R1CSProof<G>, T), R1CSError> {
459 use crate::util;
460 use ark_std::iter;
461
462 self.transcript
467 .borrow_mut()
468 .append_u64(b"m", self.secrets.v.len() as u64);
469
470 let mut rng = {
484 let mut builder = self.transcript.borrow_mut().build_rng();
485
486 for v_b in &self.secrets.v_blinding {
488 let mut bytes = Vec::new();
489 v_b.serialize_uncompressed(&mut bytes).unwrap();
490 builder = builder.rekey_with_witness_bytes(b"v_blinding", &bytes);
491 }
492
493 builder.finalize(prng)
494 };
495
496 let n1 = self.secrets.a_L.len();
498
499 if bp_gens.gens_capacity < n1 {
500 return Err(R1CSError::InvalidGeneratorsLength);
501 }
502
503 let gens = bp_gens.share(0);
505
506 let i_blinding1 = G::ScalarField::rand(&mut rng);
507 let o_blinding1 = G::ScalarField::rand(&mut rng);
508 let s_blinding1 = G::ScalarField::rand(&mut rng);
509
510 let mut s_L1: Vec<G::ScalarField> =
511 (0..n1).map(|_| G::ScalarField::rand(&mut rng)).collect();
512 let mut s_R1: Vec<G::ScalarField> =
513 (0..n1).map(|_| G::ScalarField::rand(&mut rng)).collect();
514
515 let A_I1 = G::Group::msm(
517 &iter::once(&self.pc_gens.B_blinding)
518 .chain(gens.G(n1))
519 .chain(gens.H(n1))
520 .map(|f| f.clone())
521 .collect::<Vec<G>>(),
522 &iter::once(&i_blinding1)
523 .chain(self.secrets.a_L.iter())
524 .chain(self.secrets.a_R.iter())
525 .map(|f| *f)
526 .collect::<Vec<G::ScalarField>>(),
527 )
528 .unwrap()
529 .into_affine();
530
531 let A_O1 = G::Group::msm(
533 &iter::once(&self.pc_gens.B_blinding)
534 .chain(gens.G(n1))
535 .map(|f| f.clone())
536 .collect::<Vec<G>>(),
537 &iter::once(&o_blinding1)
538 .chain(self.secrets.a_O.iter())
539 .map(|f| *f)
540 .collect::<Vec<G::ScalarField>>(),
541 )
542 .unwrap()
543 .into_affine();
544
545 let S1 = G::Group::msm(
547 &iter::once(&self.pc_gens.B_blinding)
548 .chain(gens.G(n1))
549 .chain(gens.H(n1))
550 .map(|f| f.clone())
551 .collect::<Vec<G>>(),
552 &iter::once(&s_blinding1)
553 .chain(s_L1.iter())
554 .chain(s_R1.iter())
555 .map(|f| *f)
556 .collect::<Vec<G::ScalarField>>(),
557 )
558 .unwrap()
559 .into_affine();
560
561 let transcript = self.transcript.borrow_mut();
562 transcript.append_point(b"A_I1", &A_I1);
563 transcript.append_point(b"A_O1", &A_O1);
564 transcript.append_point(b"S1", &S1);
565
566 self = self.create_randomized_constraints()?;
568
569 let n = self.secrets.a_L.len();
573 let n2 = n - n1;
574 let padded_n = self.secrets.a_L.len().next_power_of_two();
575 let pad = padded_n - n;
576
577 if bp_gens.gens_capacity < padded_n {
578 return Err(R1CSError::InvalidGeneratorsLength);
579 }
580
581 let has_2nd_phase_commitments = n2 > 0;
584
585 let (i_blinding2, o_blinding2, s_blinding2) = if has_2nd_phase_commitments {
586 (
587 G::ScalarField::rand(&mut rng),
588 G::ScalarField::rand(&mut rng),
589 G::ScalarField::rand(&mut rng),
590 )
591 } else {
592 (
593 G::ScalarField::zero(),
594 G::ScalarField::zero(),
595 G::ScalarField::zero(),
596 )
597 };
598
599 let mut s_L2: Vec<G::ScalarField> =
600 (0..n2).map(|_| G::ScalarField::rand(&mut rng)).collect();
601 let mut s_R2: Vec<G::ScalarField> =
602 (0..n2).map(|_| G::ScalarField::rand(&mut rng)).collect();
603
604 let (A_I2, A_O2, S2) = if has_2nd_phase_commitments {
605 (
606 G::Group::msm(
608 &iter::once(&self.pc_gens.B_blinding)
609 .chain(gens.G(n).skip(n1))
610 .chain(gens.H(n).skip(n1))
611 .map(|f| f.clone())
612 .collect::<Vec<G>>(),
613 &iter::once(&i_blinding2)
614 .chain(self.secrets.a_L.iter().skip(n1))
615 .chain(self.secrets.a_R.iter().skip(n1))
616 .map(|f| *f)
617 .collect::<Vec<G::ScalarField>>(),
618 )
619 .unwrap()
620 .into_affine(),
621 G::Group::msm(
623 &iter::once(&self.pc_gens.B_blinding)
624 .chain(gens.G(n).skip(n1))
625 .map(|f| f.clone())
626 .collect::<Vec<G>>(),
627 &iter::once(&o_blinding2)
628 .chain(self.secrets.a_O.iter().skip(n1))
629 .map(|f| *f)
630 .collect::<Vec<G::ScalarField>>(),
631 )
632 .unwrap()
633 .into_affine(),
634 G::Group::msm(
636 &iter::once(&self.pc_gens.B_blinding)
637 .chain(gens.G(n).skip(n1))
638 .chain(gens.H(n).skip(n1))
639 .map(|f| f.clone())
640 .collect::<Vec<G>>(),
641 &iter::once(&s_blinding2)
642 .chain(s_L2.iter())
643 .chain(s_R2.iter())
644 .map(|f| *f)
645 .collect::<Vec<G::ScalarField>>(),
646 )
647 .unwrap()
648 .into_affine(),
649 )
650 } else {
651 (G::zero(), G::zero(), G::zero())
656 };
657
658 let transcript = self.transcript.borrow_mut();
659 transcript.append_point(b"A_I2", &A_I2);
660 transcript.append_point(b"A_O2", &A_O2);
661 transcript.append_point(b"S2", &S2);
662
663 let y: G::ScalarField =
666 <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"y");
667 let z = <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"z");
668
669 let (wL, wR, wO, wV) = self.flattened_constraints(&z);
670
671 let mut l_poly = util::VecPoly3::<G>::zero(n);
672 let mut r_poly = util::VecPoly3::<G>::zero(n);
673
674 let mut exp_y = G::ScalarField::one(); let y_inv = y.inverse().unwrap();
676 let exp_y_inv = util::exp_iter::<G>(y_inv)
677 .take(padded_n)
678 .collect::<Vec<_>>();
679
680 let sLsR = s_L1
681 .iter()
682 .chain(s_L2.iter())
683 .zip(s_R1.iter().chain(s_R2.iter()));
684 for (i, (sl, sr)) in sLsR.enumerate() {
685 l_poly.1[i] = self.secrets.a_L[i] + exp_y_inv[i] * wR[i];
688 l_poly.2[i] = self.secrets.a_O[i];
690 l_poly.3[i] = *sl;
692 r_poly.0[i] = wO[i] - exp_y;
694 r_poly.1[i] = exp_y * self.secrets.a_R[i] + wL[i];
696 r_poly.3[i] = exp_y * sr;
699
700 exp_y = exp_y * y; }
702
703 let t_poly = util::VecPoly3::special_inner_product(&l_poly, &r_poly);
704
705 let t_1_blinding = G::ScalarField::rand(&mut rng);
706 let t_3_blinding = G::ScalarField::rand(&mut rng);
707 let t_4_blinding = G::ScalarField::rand(&mut rng);
708 let t_5_blinding = G::ScalarField::rand(&mut rng);
709 let t_6_blinding = G::ScalarField::rand(&mut rng);
710
711 let T_1 = self.pc_gens.commit(t_poly.t1, t_1_blinding);
712 let T_3 = self.pc_gens.commit(t_poly.t3, t_3_blinding);
713 let T_4 = self.pc_gens.commit(t_poly.t4, t_4_blinding);
714 let T_5 = self.pc_gens.commit(t_poly.t5, t_5_blinding);
715 let T_6 = self.pc_gens.commit(t_poly.t6, t_6_blinding);
716
717 let transcript = self.transcript.borrow_mut();
718 transcript.append_point(b"T_1", &T_1);
719 transcript.append_point(b"T_3", &T_3);
720 transcript.append_point(b"T_4", &T_4);
721 transcript.append_point(b"T_5", &T_5);
722 transcript.append_point(b"T_6", &T_6);
723
724 let u = <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"u");
725 let x = <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"x");
726
727 let t_2_blinding: G::ScalarField = wV
730 .iter()
731 .zip(self.secrets.v_blinding.iter())
732 .map(|(c, v_blinding)| *v_blinding * c)
733 .sum();
734
735 let t_blinding_poly = util::Poly6::<G> {
736 t1: t_1_blinding,
737 t2: t_2_blinding,
738 t3: t_3_blinding,
739 t4: t_4_blinding,
740 t5: t_5_blinding,
741 t6: t_6_blinding,
742 };
743
744 let t_x = t_poly.eval(x);
745 let t_x_blinding = t_blinding_poly.eval(x);
746 let mut l_vec = l_poly.eval(x);
747 l_vec.append(&mut vec![G::ScalarField::zero(); pad]);
748
749 let mut r_vec = r_poly.eval(x);
750 r_vec.append(&mut vec![G::ScalarField::zero(); pad]);
751
752 for i in n..padded_n {
754 r_vec[i] = -exp_y;
755 exp_y = exp_y * y; }
757
758 let i_blinding = i_blinding1 + u * i_blinding2;
759 let o_blinding = o_blinding1 + u * o_blinding2;
760 let s_blinding = s_blinding1 + u * s_blinding2;
761
762 let e_blinding = x * (i_blinding + x * (o_blinding + x * s_blinding));
763
764 <Transcript as TranscriptProtocol<G>>::append_scalar(transcript, b"t_x", &t_x);
765 <Transcript as TranscriptProtocol<G>>::append_scalar(
766 transcript,
767 b"t_x_blinding",
768 &t_x_blinding,
769 );
770 <Transcript as TranscriptProtocol<G>>::append_scalar(
771 transcript,
772 b"e_blinding",
773 &e_blinding,
774 );
775
776 let w: G::ScalarField =
778 <Transcript as TranscriptProtocol<G>>::challenge_scalar(transcript, b"w");
779 let Q = self.pc_gens.B.mul_bigint(w.into_bigint());
780
781 let G_factors = iter::repeat(G::ScalarField::one())
782 .take(n1)
783 .chain(iter::repeat(u).take(n2 + pad))
784 .collect::<Vec<_>>();
785 let H_factors = exp_y_inv
786 .into_iter()
787 .zip(G_factors.iter())
788 .map(|(y, u_or_1)| y * u_or_1)
789 .collect::<Vec<_>>();
790
791 let ipp_proof = InnerProductProof::create(
792 transcript,
793 &Q.into_affine(),
794 &G_factors,
795 &H_factors,
796 gens.G(padded_n).cloned().collect(),
797 gens.H(padded_n).cloned().collect(),
798 l_vec,
799 r_vec,
800 );
801
802 for scalar in s_L1
806 .iter_mut()
807 .chain(s_L2.iter_mut())
808 .chain(s_R1.iter_mut())
809 .chain(s_R2.iter_mut())
810 {
811 scalar.clear();
812 }
813 let proof = R1CSProof {
814 A_I1,
815 A_O1,
816 S1,
817 A_I2,
818 A_O2,
819 S2,
820 T_1,
821 T_3,
822 T_4,
823 T_5,
824 T_6,
825 t_x,
826 t_x_blinding,
827 e_blinding,
828 ipp_proof,
829 };
830 Ok((proof, self.transcript))
831 }
832}