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