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