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