monero_bulletproofs/
batch_verifier.rs1use std_shims::vec::Vec;
2
3use curve25519_dalek::{
4 constants::ED25519_BASEPOINT_POINT,
5 traits::{IsIdentity, VartimeMultiscalarMul},
6 scalar::Scalar,
7 edwards::EdwardsPoint,
8};
9
10use monero_generators::{H as MONERO_H, Generators};
11
12use crate::{original, plus};
13
14#[derive(Default)]
15pub(crate) struct InternalBatchVerifier {
16 pub(crate) g: Scalar,
17 pub(crate) h: Scalar,
18 pub(crate) g_bold: Vec<Scalar>,
19 pub(crate) h_bold: Vec<Scalar>,
20 pub(crate) other: Vec<(Scalar, EdwardsPoint)>,
21}
22
23impl InternalBatchVerifier {
24 #[must_use]
25 fn verify(self, G: EdwardsPoint, H: EdwardsPoint, generators: &Generators) -> bool {
26 let capacity = 2 + self.g_bold.len() + self.h_bold.len() + self.other.len();
32 let mut scalars = Vec::with_capacity(capacity);
33 let mut points = Vec::with_capacity(capacity);
34
35 scalars.push(self.g);
36 points.push(G);
37
38 scalars.push(self.h);
39 points.push(H);
40
41 for (i, g_bold) in self.g_bold.into_iter().enumerate() {
42 scalars.push(g_bold);
43 points.push(generators.G[i]);
44 }
45
46 for (i, h_bold) in self.h_bold.into_iter().enumerate() {
47 scalars.push(h_bold);
48 points.push(generators.H[i]);
49 }
50
51 for (scalar, point) in self.other {
52 scalars.push(scalar);
53 points.push(point);
54 }
55
56 EdwardsPoint::vartime_multiscalar_mul(scalars, points).is_identity()
57 }
58}
59
60#[derive(Default)]
61pub(crate) struct BulletproofsBatchVerifier(pub(crate) InternalBatchVerifier);
62impl BulletproofsBatchVerifier {
63 #[must_use]
64 pub(crate) fn verify(self) -> bool {
65 self.0.verify(ED25519_BASEPOINT_POINT, *MONERO_H, &original::GENERATORS)
66 }
67}
68
69#[derive(Default)]
70pub(crate) struct BulletproofsPlusBatchVerifier(pub(crate) InternalBatchVerifier);
71impl BulletproofsPlusBatchVerifier {
72 #[must_use]
73 pub(crate) fn verify(self) -> bool {
74 self.0.verify(*MONERO_H, ED25519_BASEPOINT_POINT, &plus::GENERATORS)
77 }
78}
79
80#[derive(Default)]
86pub struct BatchVerifier {
87 pub(crate) original: BulletproofsBatchVerifier,
88 pub(crate) plus: BulletproofsPlusBatchVerifier,
89}
90impl BatchVerifier {
91 pub fn new() -> Self {
93 Self {
94 original: BulletproofsBatchVerifier(InternalBatchVerifier::default()),
95 plus: BulletproofsPlusBatchVerifier(InternalBatchVerifier::default()),
96 }
97 }
98
99 #[must_use]
103 pub fn verify(self) -> bool {
104 self.original.verify() && self.plus.verify()
105 }
106}