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