w3f_ring_proof/
multi_ring_batch_verifier.rs1use ark_ec::pairing::Pairing;
2use ark_ec::twisted_edwards::{Affine, TECurveConfig};
3use ark_ec::CurveGroup;
4use ark_std::rand::RngCore;
5use w3f_pcs::pcs::kzg::params::KzgVerifierKey;
6use w3f_pcs::pcs::kzg::KZG;
7use w3f_pcs::pcs::PCS;
8use w3f_plonk_common::kzg_acc::KzgAccumulator;
9use w3f_plonk_common::transcript::PlonkTranscript;
10use w3f_plonk_common::verifier::Challenges;
11
12use crate::piop::PiopVerifier;
13use crate::ring_verifier::RingVerifier;
14use crate::RingProof;
15
16pub struct BatchItem<E, J>
18where
19 E: Pairing,
20 J: TECurveConfig<BaseField = E::ScalarField>,
21{
22 piop: PiopVerifier<E::ScalarField, <KZG<E> as PCS<E::ScalarField>>::C, Affine<J>>,
23 proof: RingProof<E::ScalarField, KZG<E>>,
24 challenges: Challenges<E::ScalarField>,
25 entropy: [u8; 32],
26}
27
28impl<E, J> BatchItem<E, J>
29where
30 E: Pairing,
31 J: TECurveConfig<BaseField = E::ScalarField>,
32{
33 pub fn new<T>(
39 verifier: &RingVerifier<E::ScalarField, KZG<E>, J, T>,
40 proof: RingProof<E::ScalarField, KZG<E>>,
41 result: Affine<J>,
42 ) -> Self
43 where
44 T: PlonkTranscript<E::ScalarField, KZG<E>>,
45 {
46 let (challenges, mut fs_rng) = verifier
47 .plonk_verifier
48 .restore_fs_with_rng::<PiopVerifier<_, _, Affine<J>>, _, _>(&result, &proof);
49 let seed = verifier.piop_params.seed;
50 let seed_plus_result = (seed + result).into_affine();
51 let domain_at_zeta = verifier.piop_params.domain.evaluate(challenges.zeta);
52 let piop = PiopVerifier::<_, _, Affine<J>>::init(
53 domain_at_zeta,
54 verifier.fixed_columns_committed.clone(),
55 proof.column_commitments.clone(),
56 proof.columns_at_zeta.clone(),
57 (seed.x, seed.y),
58 (seed_plus_result.x, seed_plus_result.y),
59 );
60
61 let mut entropy = [0_u8; 32];
62 fs_rng.fill_bytes(&mut entropy);
63
64 Self {
65 piop,
66 proof,
67 challenges,
68 entropy,
69 }
70 }
71}
72
73pub struct BatchVerifier<E: Pairing, T>
85where
86 T: PlonkTranscript<E::ScalarField, KZG<E>>,
87{
88 acc: KzgAccumulator<E>,
89 transcript: T,
90}
91
92impl<E: Pairing, T> BatchVerifier<E, T>
93where
94 T: PlonkTranscript<E::ScalarField, KZG<E>>,
95{
96 pub fn new(kzg_vk: KzgVerifierKey<E>, transcript: T) -> Self {
98 Self {
99 acc: KzgAccumulator::<E>::new(kzg_vk),
100 transcript,
101 }
102 }
103
104 pub fn push<J>(
106 &mut self,
107 verifier: &RingVerifier<E::ScalarField, KZG<E>, J, T>,
108 proof: RingProof<E::ScalarField, KZG<E>>,
109 result: Affine<J>,
110 ) where
111 J: TECurveConfig<BaseField = E::ScalarField>,
112 {
113 self.push_prepared(BatchItem::new(verifier, proof, result));
114 }
115
116 pub fn push_prepared<J>(&mut self, item: BatchItem<E, J>)
125 where
126 J: TECurveConfig<BaseField = E::ScalarField>,
127 {
128 let mut ts = self.transcript.clone();
129 ts._add_serializable(b"batch-entropy", &item.entropy);
130 self.acc
131 .accumulate(item.piop, item.proof, item.challenges, &mut ts.to_rng());
132 }
133
134 pub fn verify(&self) -> bool {
136 self.acc.verify()
137 }
138}