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