arnaucube
arnaucube/testudoPublic Self-hosted repository
testudo/src/nizk.rs
src/nizk.rsRaw
  1use super::bullet::BulletReductionProof;
  2use super::commitments::{Commitments, MultiCommitGens};
  3use super::errors::ProofVerifyError;
  4use super::group::CompressedGroup;
  5use super::math::Math;
  6use super::scalar::Scalar;
  7use super::transcript::{AppendToTranscript, ProofTranscript};
  8use merlin::Transcript;
  9use serde::{Deserialize, Serialize};
 10
 11#[derive(Serialize, Deserialize, Debug)]
 12pub struct KnowledgeProof {
 13  alpha: CompressedGroup,
 14  z1: Scalar,
 15  z2: Scalar,
 16}
 17
 18impl KnowledgeProof {
 19  fn protocol_name() -> &'static [u8] {
 20    b"knowledge proof"
 21  }
 22
 23  pub fn prove(
 24    gens_n: &MultiCommitGens,
 25    transcript: &mut Transcript,
 26    random_tape: &mut Transcript,
 27    x: &Scalar,
 28    r: &Scalar,
 29  ) -> (KnowledgeProof, CompressedGroup) {
 30    transcript.append_protocol_name(KnowledgeProof::protocol_name());
 31
 32    // produce two random Scalars
 33    let t1 = random_tape.challenge_scalar(b"t1");
 34    let t2 = random_tape.challenge_scalar(b"t2");
 35
 36    let C = x.commit(&r, gens_n).compress();
 37    C.append_to_transcript(b"C", transcript);
 38
 39    let alpha = t1.commit(&t2, gens_n).compress();
 40    alpha.append_to_transcript(b"alpha", transcript);
 41
 42    let c = transcript.challenge_scalar(b"c");
 43
 44    let z1 = x * &c + &t1;
 45    let z2 = r * &c + &t2;
 46
 47    (KnowledgeProof { alpha, z1, z2 }, C)
 48  }
 49
 50  pub fn verify(
 51    &self,
 52    gens_n: &MultiCommitGens,
 53    transcript: &mut Transcript,
 54    C: &CompressedGroup,
 55  ) -> Result<(), ProofVerifyError> {
 56    transcript.append_protocol_name(KnowledgeProof::protocol_name());
 57    C.append_to_transcript(b"C", transcript);
 58    self.alpha.append_to_transcript(b"alpha", transcript);
 59
 60    let c = transcript.challenge_scalar(b"c");
 61
 62    let lhs = self.z1.commit(&self.z2, gens_n).compress();
 63    let rhs = (&c * C.decompress().expect("Could not decompress C")
 64      + self
 65        .alpha
 66        .decompress()
 67        .expect("Could not decompress self.alpha"))
 68    .compress();
 69
 70    if lhs == rhs {
 71      Ok(())
 72    } else {
 73      Err(ProofVerifyError)
 74    }
 75  }
 76}
 77
 78#[derive(Serialize, Deserialize, Debug)]
 79pub struct EqualityProof {
 80  alpha: CompressedGroup,
 81  z: Scalar,
 82}
 83
 84impl EqualityProof {
 85  fn protocol_name() -> &'static [u8] {
 86    b"equality proof"
 87  }
 88
 89  pub fn prove(
 90    gens_n: &MultiCommitGens,
 91    transcript: &mut Transcript,
 92    random_tape: &mut Transcript,
 93    v1: &Scalar,
 94    s1: &Scalar,
 95    v2: &Scalar,
 96    s2: &Scalar,
 97  ) -> (EqualityProof, CompressedGroup, CompressedGroup) {
 98    transcript.append_protocol_name(EqualityProof::protocol_name());
 99
100    // produce a random Scalar
101    let r = random_tape.challenge_scalar(b"r");
102
103    let C1 = v1.commit(&s1, gens_n).compress();
104    C1.append_to_transcript(b"C1", transcript);
105
106    let C2 = v2.commit(&s2, gens_n).compress();
107    C2.append_to_transcript(b"C2", transcript);
108
109    let alpha = (&r * gens_n.h).compress();
110    alpha.append_to_transcript(b"alpha", transcript);
111
112    let c = transcript.challenge_scalar(b"c");
113
114    let z = &c * (s1 - s2) + &r;
115
116    (EqualityProof { alpha, z }, C1, C2)
117  }
118
119  pub fn verify(
120    &self,
121    gens_n: &MultiCommitGens,
122    transcript: &mut Transcript,
123    C1: &CompressedGroup,
124    C2: &CompressedGroup,
125  ) -> Result<(), ProofVerifyError> {
126    transcript.append_protocol_name(EqualityProof::protocol_name());
127    C1.append_to_transcript(b"C1", transcript);
128    C2.append_to_transcript(b"C2", transcript);
129    self.alpha.append_to_transcript(b"alpha", transcript);
130
131    let c = transcript.challenge_scalar(b"c");
132    let rhs = {
133      let C = &C1.decompress().unwrap() - &C2.decompress().unwrap();
134      (&c * C + &self.alpha.decompress().unwrap()).compress()
135    };
136
137    let lhs = (&self.z * gens_n.h).compress();
138
139    if lhs == rhs {
140      Ok(())
141    } else {
142      Err(ProofVerifyError)
143    }
144  }
145}
146
147#[derive(Serialize, Deserialize, Debug)]
148pub struct ProductProof {
149  alpha: CompressedGroup,
150  beta: CompressedGroup,
151  delta: CompressedGroup,
152  z: [Scalar; 5],
153}
154
155impl ProductProof {
156  fn protocol_name() -> &'static [u8] {
157    b"product proof"
158  }
159
160  pub fn prove(
161    gens_n: &MultiCommitGens,
162    transcript: &mut Transcript,
163    random_tape: &mut Transcript,
164    x: &Scalar,
165    rX: &Scalar,
166    y: &Scalar,
167    rY: &Scalar,
168    z: &Scalar,
169    rZ: &Scalar,
170  ) -> (
171    ProductProof,
172    CompressedGroup,
173    CompressedGroup,
174    CompressedGroup,
175  ) {
176    transcript.append_protocol_name(ProductProof::protocol_name());
177
178    // produce five random Scalar
179    let b1 = random_tape.challenge_scalar(b"b1");
180    let b2 = random_tape.challenge_scalar(b"b2");
181    let b3 = random_tape.challenge_scalar(b"b3");
182    let b4 = random_tape.challenge_scalar(b"b4");
183    let b5 = random_tape.challenge_scalar(b"b5");
184
185    let X = x.commit(&rX, gens_n).compress();
186    X.append_to_transcript(b"X", transcript);
187
188    let Y = y.commit(&rY, gens_n).compress();
189    Y.append_to_transcript(b"Y", transcript);
190
191    let Z = z.commit(&rZ, gens_n).compress();
192    Z.append_to_transcript(b"Z", transcript);
193
194    let alpha = b1.commit(&b2, gens_n).compress();
195    alpha.append_to_transcript(b"alpha", transcript);
196
197    let beta = b3.commit(&b4, gens_n).compress();
198    beta.append_to_transcript(b"beta", transcript);
199
200    let delta = {
201      let gens_X = &MultiCommitGens {
202        n: 1,
203        G: vec![X.decompress().unwrap()],
204        h: gens_n.h,
205      };
206      b3.commit(&b5, gens_X).compress()
207    };
208    delta.append_to_transcript(b"delta", transcript);
209
210    let c = transcript.challenge_scalar(b"c");
211
212    let z1 = &b1 + &c * x;
213    let z2 = &b2 + &c * rX;
214    let z3 = &b3 + &c * y;
215    let z4 = &b4 + &c * rY;
216    let z5 = &b5 + &c * (rZ - rX * y);
217    let z = [z1, z2, z3, z4, z5];
218
219    (
220      ProductProof {
221        alpha,
222        beta,
223        delta,
224        z,
225      },
226      X,
227      Y,
228      Z,
229    )
230  }
231
232  fn check_equality(
233    P: &CompressedGroup,
234    X: &CompressedGroup,
235    c: &Scalar,
236    gens_n: &MultiCommitGens,
237    z1: &Scalar,
238    z2: &Scalar,
239  ) -> bool {
240    let lhs = (P.decompress().unwrap() + c * X.decompress().unwrap()).compress();
241    let rhs = z1.commit(&z2, gens_n).compress();
242
243    if lhs == rhs {
244      true
245    } else {
246      false
247    }
248  }
249
250  pub fn verify(
251    &self,
252    gens_n: &MultiCommitGens,
253    transcript: &mut Transcript,
254    X: &CompressedGroup,
255    Y: &CompressedGroup,
256    Z: &CompressedGroup,
257  ) -> Result<(), ProofVerifyError> {
258    transcript.append_protocol_name(ProductProof::protocol_name());
259
260    X.append_to_transcript(b"X", transcript);
261    Y.append_to_transcript(b"Y", transcript);
262    Z.append_to_transcript(b"Z", transcript);
263    self.alpha.append_to_transcript(b"alpha", transcript);
264    self.beta.append_to_transcript(b"beta", transcript);
265    self.delta.append_to_transcript(b"delta", transcript);
266
267    let z1 = self.z[0];
268    let z2 = self.z[1];
269    let z3 = self.z[2];
270    let z4 = self.z[3];
271    let z5 = self.z[4];
272
273    let c = transcript.challenge_scalar(b"c");
274
275    if ProductProof::check_equality(&self.alpha, &X, &c, &gens_n, &z1, &z2)
276      && ProductProof::check_equality(&self.beta, &Y, &c, &gens_n, &z3, &z4)
277      && ProductProof::check_equality(
278        &self.delta,
279        &Z,
280        &c,
281        &MultiCommitGens {
282          n: 1,
283          G: vec![X.decompress().unwrap()],
284          h: gens_n.h,
285        },
286        &z3,
287        &z5,
288      )
289    {
290      Ok(())
291    } else {
292      Err(ProofVerifyError)
293    }
294  }
295}
296
297#[derive(Debug, Serialize, Deserialize)]
298pub struct DotProductProof {
299  delta: CompressedGroup,
300  beta: CompressedGroup,
301  z: Vec<Scalar>,
302  z_delta: Scalar,
303  z_beta: Scalar,
304}
305
306impl DotProductProof {
307  fn protocol_name() -> &'static [u8] {
308    b"dot product proof"
309  }
310
311  pub fn compute_dotproduct(a: &Vec<Scalar>, b: &Vec<Scalar>) -> Scalar {
312    assert_eq!(a.len(), b.len());
313    (0..a.len()).map(|i| &a[i] * &b[i]).sum()
314  }
315
316  pub fn prove(
317    gens_1: &MultiCommitGens,
318    gens_n: &MultiCommitGens,
319    transcript: &mut Transcript,
320    random_tape: &mut Transcript,
321    x: &Vec<Scalar>,
322    r_x: &Scalar,
323    a: &Vec<Scalar>,
324    y: &Scalar,
325    r_y: &Scalar,
326  ) -> (DotProductProof, CompressedGroup, CompressedGroup) {
327    transcript.append_protocol_name(DotProductProof::protocol_name());
328
329    let n = x.len();
330    assert_eq!(x.len(), a.len());
331    assert_eq!(gens_n.n, a.len());
332    assert_eq!(gens_1.n, 1);
333
334    // produce randomness for the proofs
335    let d = random_tape.challenge_vector(b"d", n);
336    let r_delta = random_tape.challenge_scalar(b"r_delta");
337    let r_beta = random_tape.challenge_scalar(b"r_beta");
338
339    let Cx = x.commit(&r_x, gens_n).compress();
340    Cx.append_to_transcript(b"Cx", transcript);
341
342    let Cy = y.commit(&r_y, gens_1).compress();
343    Cy.append_to_transcript(b"Cy", transcript);
344
345    let delta = d.commit(&r_delta, gens_n).compress();
346    delta.append_to_transcript(b"delta", transcript);
347
348    let dotproduct_a_d = DotProductProof::compute_dotproduct(&a, &d);
349
350    let beta = dotproduct_a_d.commit(&r_beta, gens_1).compress();
351    beta.append_to_transcript(b"beta", transcript);
352
353    let c = transcript.challenge_scalar(b"c");
354
355    let z = (0..d.len())
356      .map(|i| c * x[i] + d[i])
357      .collect::<Vec<Scalar>>();
358
359    let z_delta = c * r_x + r_delta;
360    let z_beta = c * r_y + r_beta;
361
362    (
363      DotProductProof {
364        delta,
365        beta,
366        z,
367        z_delta,
368        z_beta,
369      },
370      Cx,
371      Cy,
372    )
373  }
374
375  pub fn verify(
376    &self,
377    gens_1: &MultiCommitGens,
378    gens_n: &MultiCommitGens,
379    transcript: &mut Transcript,
380    a: &Vec<Scalar>,
381    Cx: &CompressedGroup,
382    Cy: &CompressedGroup,
383  ) -> Result<(), ProofVerifyError> {
384    assert_eq!(gens_n.n, a.len());
385    assert_eq!(gens_1.n, 1);
386
387    transcript.append_protocol_name(DotProductProof::protocol_name());
388    Cx.append_to_transcript(b"Cx", transcript);
389    Cy.append_to_transcript(b"Cy", transcript);
390    self.delta.append_to_transcript(b"delta", transcript);
391    self.beta.append_to_transcript(b"beta", transcript);
392
393    let c = transcript.challenge_scalar(b"c");
394
395    let mut result = &c * Cx.decompress().unwrap() + self.delta.decompress().unwrap()
396      == self.z.commit(&self.z_delta, gens_n);
397
398    let dotproduct_z_a = DotProductProof::compute_dotproduct(&self.z, &a);
399    result &= &c * Cy.decompress().unwrap() + self.beta.decompress().unwrap()
400      == dotproduct_z_a.commit(&self.z_beta, gens_1);
401
402    if result {
403      Ok(())
404    } else {
405      Err(ProofVerifyError)
406    }
407  }
408}
409
410pub struct DotProductProofGens {
411  n: usize,
412  pub gens_n: MultiCommitGens,
413  pub gens_1: MultiCommitGens,
414}
415
416impl DotProductProofGens {
417  pub fn new(n: usize, label: &[u8]) -> Self {
418    let (gens_n, gens_1) = MultiCommitGens::new(n + 1, label).split_at_mut(n);
419    DotProductProofGens { n, gens_n, gens_1 }
420  }
421}
422
423#[derive(Debug, Serialize, Deserialize)]
424pub struct DotProductProofLog {
425  bullet_reduction_proof: BulletReductionProof,
426  delta: CompressedGroup,
427  beta: CompressedGroup,
428  z1: Scalar,
429  z2: Scalar,
430}
431
432impl DotProductProofLog {
433  fn protocol_name() -> &'static [u8] {
434    b"dot product proof (log)"
435  }
436
437  pub fn compute_dotproduct(a: &Vec<Scalar>, b: &Vec<Scalar>) -> Scalar {
438    assert_eq!(a.len(), b.len());
439    (0..a.len()).map(|i| &a[i] * &b[i]).sum()
440  }
441
442  pub fn prove(
443    gens: &DotProductProofGens,
444    transcript: &mut Transcript,
445    random_tape: &mut Transcript,
446    x: &Vec<Scalar>,
447    r_x: &Scalar,
448    a: &Vec<Scalar>,
449    y: &Scalar,
450    r_y: &Scalar,
451  ) -> (DotProductProofLog, CompressedGroup, CompressedGroup) {
452    transcript.append_protocol_name(DotProductProofLog::protocol_name());
453
454    let n = x.len();
455    assert_eq!(x.len(), a.len());
456    assert_eq!(gens.n, n);
457
458    // produce randomness for generating a proof
459    let d = random_tape.challenge_scalar(b"d");
460    let r_delta = random_tape.challenge_scalar(b"r_delta");
461    let r_beta = random_tape.challenge_scalar(b"r_delta");
462    let blinds_vec = {
463      let v1 = random_tape.challenge_vector(b"blinds_vec_1", 2 * n.log2());
464      let v2 = random_tape.challenge_vector(b"blinds_vec_2", 2 * n.log2());
465      (0..v1.len())
466        .map(|i| (v1[i], v2[i]))
467        .collect::<Vec<(Scalar, Scalar)>>()
468    };
469
470    let Cx = x.commit(&r_x, &gens.gens_n).compress();
471    Cx.append_to_transcript(b"Cx", transcript);
472
473    let Cy = y.commit(&r_y, &gens.gens_1).compress();
474    Cy.append_to_transcript(b"Cy", transcript);
475
476    let r_Gamma = r_x + r_y;
477    let (bullet_reduction_proof, _Gamma_hat, x_hat, a_hat, g_hat, rhat_Gamma) =
478      BulletReductionProof::prove(
479        transcript,
480        &gens.gens_1.G[0],
481        &gens.gens_n.G,
482        &gens.gens_n.h,
483        x,
484        a,
485        &r_Gamma,
486        &blinds_vec,
487      );
488    let y_hat = x_hat * a_hat;
489
490    let delta = {
491      let gens_hat = MultiCommitGens {
492        n: 1,
493        G: vec![g_hat],
494        h: gens.gens_1.h,
495      };
496      d.commit(&r_delta, &gens_hat).compress()
497    };
498    delta.append_to_transcript(b"delta", transcript);
499
500    let beta = d.commit(&r_beta, &gens.gens_1).compress();
501    beta.append_to_transcript(b"beta", transcript);
502
503    let c = transcript.challenge_scalar(b"c");
504
505    let z1 = d + c * y_hat;
506    let z2 = a_hat * (c * rhat_Gamma + r_beta) + r_delta;
507
508    (
509      DotProductProofLog {
510        bullet_reduction_proof,
511        delta,
512        beta,
513        z1,
514        z2,
515      },
516      Cx,
517      Cy,
518    )
519  }
520
521  pub fn verify(
522    &self,
523    n: usize,
524    gens: &DotProductProofGens,
525    transcript: &mut Transcript,
526    a: &Vec<Scalar>,
527    Cx: &CompressedGroup,
528    Cy: &CompressedGroup,
529  ) -> Result<(), ProofVerifyError> {
530    assert_eq!(gens.n, n);
531    assert_eq!(a.len(), n);
532
533    transcript.append_protocol_name(DotProductProofLog::protocol_name());
534    Cx.append_to_transcript(b"Cx", transcript);
535    Cy.append_to_transcript(b"Cy", transcript);
536
537    let Gamma = Cx.decompress().unwrap() + Cy.decompress().unwrap();
538
539    let (g_hat, Gamma_hat, a_hat) = self
540      .bullet_reduction_proof
541      .verify(n, a, transcript, &Gamma, &gens.gens_n.G)
542      .unwrap();
543
544    self.delta.append_to_transcript(b"delta", transcript);
545    self.beta.append_to_transcript(b"beta", transcript);
546
547    let c = transcript.challenge_scalar(b"c");
548
549    let c_s = &c;
550    let beta_s = self.beta.decompress().unwrap();
551    let a_hat_s = &a_hat;
552    let delta_s = self.delta.decompress().unwrap();
553    let z1_s = &self.z1;
554    let z2_s = &self.z2;
555
556    let lhs = ((Gamma_hat * c_s + beta_s) * a_hat_s + delta_s).compress();
557    let rhs = ((g_hat + &gens.gens_1.G[0] * a_hat_s) * z1_s + gens.gens_1.h * z2_s).compress();
558
559    assert_eq!(lhs, rhs);
560
561    if lhs == rhs {
562      Ok(())
563    } else {
564      Err(ProofVerifyError)
565    }
566  }
567}
568
569#[cfg(test)]
570mod tests {
571  use super::*;
572  use rand::rngs::OsRng;
573  #[test]
574  fn check_knowledgeproof() {
575    let mut csprng: OsRng = OsRng;
576
577    let gens_1 = MultiCommitGens::new(1, b"test-knowledgeproof");
578
579    let x = Scalar::random(&mut csprng);
580    let r = Scalar::random(&mut csprng);
581
582    let mut random_tape = {
583      let mut csprng: OsRng = OsRng;
584      let mut tape = Transcript::new(b"proof");
585      tape.append_scalar(b"init_randomness", &Scalar::random(&mut csprng));
586      tape
587    };
588    let mut prover_transcript = Transcript::new(b"example");
589    let (proof, committed_value) =
590      KnowledgeProof::prove(&gens_1, &mut prover_transcript, &mut random_tape, &x, &r);
591
592    let mut verifier_transcript = Transcript::new(b"example");
593    assert!(proof
594      .verify(&gens_1, &mut verifier_transcript, &committed_value)
595      .is_ok());
596  }
597
598  #[test]
599  fn check_equalityproof() {
600    let mut csprng: OsRng = OsRng;
601
602    let gens_1 = MultiCommitGens::new(1, b"test-equalityproof");
603    let v1 = Scalar::random(&mut csprng);
604    let v2 = v1;
605    let s1 = Scalar::random(&mut csprng);
606    let s2 = Scalar::random(&mut csprng);
607
608    let mut random_tape = {
609      let mut csprng: OsRng = OsRng;
610      let mut tape = Transcript::new(b"proof");
611      tape.append_scalar(b"init_randomness", &Scalar::random(&mut csprng));
612      tape
613    };
614    let mut prover_transcript = Transcript::new(b"example");
615    let (proof, C1, C2) = EqualityProof::prove(
616      &gens_1,
617      &mut prover_transcript,
618      &mut random_tape,
619      &v1,
620      &s1,
621      &v2,
622      &s2,
623    );
624
625    let mut verifier_transcript = Transcript::new(b"example");
626    assert!(proof
627      .verify(&gens_1, &mut verifier_transcript, &C1, &C2)
628      .is_ok());
629  }
630
631  #[test]
632  fn check_productproof() {
633    let mut csprng: OsRng = OsRng;
634
635    let gens_1 = MultiCommitGens::new(1, b"test-productproof");
636    let x = Scalar::random(&mut csprng);
637    let rX = Scalar::random(&mut csprng);
638    let y = Scalar::random(&mut csprng);
639    let rY = Scalar::random(&mut csprng);
640    let z = x * y;
641    let rZ = Scalar::random(&mut csprng);
642
643    let mut random_tape = {
644      let mut csprng: OsRng = OsRng;
645      let mut tape = Transcript::new(b"proof");
646      tape.append_scalar(b"init_randomness", &Scalar::random(&mut csprng));
647      tape
648    };
649    let mut prover_transcript = Transcript::new(b"example");
650    let (proof, X, Y, Z) = ProductProof::prove(
651      &gens_1,
652      &mut prover_transcript,
653      &mut random_tape,
654      &x,
655      &rX,
656      &y,
657      &rY,
658      &z,
659      &rZ,
660    );
661
662    let mut verifier_transcript = Transcript::new(b"example");
663    assert!(proof
664      .verify(&gens_1, &mut verifier_transcript, &X, &Y, &Z)
665      .is_ok());
666  }
667
668  #[test]
669  fn check_dotproductproof() {
670    let mut csprng: OsRng = OsRng;
671
672    let n = 1024;
673
674    let gens_1 = MultiCommitGens::new(1, b"test-two");
675    let gens_1024 = MultiCommitGens::new(n, b"test-1024");
676
677    let mut x: Vec<Scalar> = Vec::new();
678    let mut a: Vec<Scalar> = Vec::new();
679    for _ in 0..n {
680      x.push(Scalar::random(&mut csprng));
681      a.push(Scalar::random(&mut csprng));
682    }
683    let y = DotProductProofLog::compute_dotproduct(&x, &a);
684    let r_x = Scalar::random(&mut csprng);
685    let r_y = Scalar::random(&mut csprng);
686
687    let mut random_tape = {
688      let mut csprng: OsRng = OsRng;
689      let mut tape = Transcript::new(b"proof");
690      tape.append_scalar(b"init_randomness", &Scalar::random(&mut csprng));
691      tape
692    };
693    let mut prover_transcript = Transcript::new(b"example");
694    let (proof, Cx, Cy) = DotProductProof::prove(
695      &gens_1,
696      &gens_1024,
697      &mut prover_transcript,
698      &mut random_tape,
699      &x,
700      &r_x,
701      &a,
702      &y,
703      &r_y,
704    );
705
706    let mut verifier_transcript = Transcript::new(b"example");
707    assert!(proof
708      .verify(&gens_1, &gens_1024, &mut verifier_transcript, &a, &Cx, &Cy)
709      .is_ok());
710  }
711
712  #[test]
713  fn check_dotproductproof_log() {
714    let mut csprng: OsRng = OsRng;
715
716    let n = 1024;
717
718    let gens = DotProductProofGens::new(n, b"test-1024");
719
720    let x: Vec<Scalar> = (0..n).map(|_i| Scalar::random(&mut csprng)).collect();
721    let a: Vec<Scalar> = (0..n).map(|_i| Scalar::random(&mut csprng)).collect();
722    let y = DotProductProof::compute_dotproduct(&x, &a);
723
724    let r_x = Scalar::random(&mut csprng);
725    let r_y = Scalar::random(&mut csprng);
726
727    let mut random_tape = {
728      let mut csprng: OsRng = OsRng;
729      let mut tape = Transcript::new(b"proof");
730      tape.append_scalar(b"init_randomness", &Scalar::random(&mut csprng));
731      tape
732    };
733    let mut prover_transcript = Transcript::new(b"example");
734    let (proof, Cx, Cy) = DotProductProofLog::prove(
735      &gens,
736      &mut prover_transcript,
737      &mut random_tape,
738      &x,
739      &r_x,
740      &a,
741      &y,
742      &r_y,
743    );
744
745    let mut verifier_transcript = Transcript::new(b"example");
746    assert!(proof
747      .verify(n, &gens, &mut verifier_transcript, &a, &Cx, &Cy)
748      .is_ok());
749  }
750}