w3f_ring_proof/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3use ark_ff::PrimeField;
4use ark_serialize::CanonicalSerialize;
5use ark_std::rand::RngCore;
6use w3f_pcs::pcs::PCS;
7
8pub use piop::index;
9pub use w3f_plonk_common::domain::Domain;
10use w3f_plonk_common::Proof;
11
12pub use crate::piop::{params::PiopParams, FixedColumnsCommitted, ProverKey, VerifierKey};
13use crate::piop::{RingCommitments, RingEvaluations};
14
15mod piop;
16pub mod ring;
17pub mod ring_prover;
18pub mod ring_verifier;
19
20pub type RingProof<F, CS> = Proof<F, CS, RingCommitments<F, <CS as PCS<F>>::C>, RingEvaluations<F>>;
21
22/// Polynomial Commitment Schemes.
23pub use w3f_pcs::pcs;
24
25#[derive(Clone)]
26pub struct ArkTranscript(ark_transcript::Transcript);
27
28impl<F: PrimeField, CS: PCS<F>> w3f_plonk_common::transcript::PlonkTranscript<F, CS>
29    for ArkTranscript
30{
31    fn _128_bit_point(&mut self, label: &'static [u8]) -> F {
32        self.0.challenge(label).read_reduce()
33    }
34
35    fn _add_serializable(&mut self, label: &'static [u8], message: &impl CanonicalSerialize) {
36        self.0.label(label);
37        self.0.append(message);
38    }
39
40    fn to_rng(mut self) -> impl RngCore {
41        self.0.challenge(b"transcript_rng")
42    }
43}
44
45impl ArkTranscript {
46    pub fn new(label: &'static [u8]) -> Self {
47        Self(ark_transcript::Transcript::new_labeled(label))
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use ark_bls12_381::Bls12_381;
54    use ark_ec::CurveGroup;
55    use ark_ed_on_bls12_381_bandersnatch::{BandersnatchConfig, EdwardsAffine, Fq, Fr};
56    use ark_std::ops::Mul;
57    use ark_std::rand::Rng;
58    use ark_std::{end_timer, start_timer, test_rng, UniformRand};
59    use w3f_pcs::pcs::kzg::KZG;
60
61    use w3f_plonk_common::test_helpers::random_vec;
62
63    use crate::piop::FixedColumnsCommitted;
64    use crate::ring::{Ring, RingBuilderKey};
65    use crate::ring_prover::RingProver;
66    use crate::ring_verifier::RingVerifier;
67
68    use super::*;
69
70    fn _test_ring_proof<CS: PCS<Fq>>(domain_size: usize) {
71        let rng = &mut test_rng();
72
73        let (pcs_params, piop_params) = setup::<_, CS>(rng, domain_size);
74
75        let max_keyset_size = piop_params.keyset_part_size;
76        let keyset_size: usize = rng.gen_range(0..max_keyset_size);
77        let pks = random_vec::<EdwardsAffine, _>(keyset_size, rng);
78        let k = rng.gen_range(0..keyset_size); // prover's secret index
79        let pk = pks[k].clone();
80
81        let (prover_key, verifier_key) = index::<_, CS, _>(&pcs_params, &piop_params, &pks);
82
83        // PROOF generation
84        let secret = Fr::rand(rng); // prover's secret scalar
85        let result = piop_params.h.mul(secret) + pk;
86        let ring_prover = RingProver::init(
87            prover_key,
88            piop_params.clone(),
89            k,
90            ArkTranscript::new(b"w3f-ring-proof-test"),
91        );
92        let t_prove = start_timer!(|| "Prove");
93        let proof = ring_prover.prove(secret);
94        end_timer!(t_prove);
95
96        let ring_verifier = RingVerifier::init(
97            verifier_key,
98            piop_params,
99            ArkTranscript::new(b"w3f-ring-proof-test"),
100        );
101        let t_verify = start_timer!(|| "Verify");
102        let res = ring_verifier.verify(proof, result.into_affine());
103        end_timer!(t_verify);
104        assert!(res);
105    }
106
107    #[test]
108    fn test_lagrangian_commitment() {
109        let rng = &mut test_rng();
110
111        let domain_size = 2usize.pow(9);
112
113        let (pcs_params, piop_params) = setup::<_, KZG<Bls12_381>>(rng, domain_size);
114        let ring_builder_key = RingBuilderKey::from_srs(&pcs_params, domain_size);
115
116        let max_keyset_size = piop_params.keyset_part_size;
117        let keyset_size: usize = rng.gen_range(0..max_keyset_size);
118        let pks = random_vec::<EdwardsAffine, _>(keyset_size, rng);
119
120        let (_, verifier_key) = index::<_, KZG<Bls12_381>, _>(&pcs_params, &piop_params, &pks);
121
122        let ring = Ring::<_, Bls12_381, _>::with_keys(&piop_params, &pks, &ring_builder_key);
123
124        let fixed_columns_committed = FixedColumnsCommitted::from_ring(&ring);
125        assert_eq!(
126            fixed_columns_committed,
127            verifier_key.fixed_columns_committed
128        );
129    }
130
131    fn setup<R: Rng, CS: PCS<Fq>>(
132        rng: &mut R,
133        domain_size: usize,
134    ) -> (CS::Params, PiopParams<Fq, BandersnatchConfig>) {
135        let setup_degree = 3 * domain_size;
136        let pcs_params = CS::setup(setup_degree, rng);
137
138        let domain = Domain::new(domain_size, true);
139        let h = EdwardsAffine::rand(rng);
140        let seed = EdwardsAffine::rand(rng);
141        let padding = EdwardsAffine::rand(rng);
142        let piop_params = PiopParams::setup(domain, h, seed, padding);
143
144        (pcs_params, piop_params)
145    }
146
147    #[test]
148    fn test_ring_proof_kzg() {
149        _test_ring_proof::<KZG<Bls12_381>>(2usize.pow(10));
150    }
151
152    #[test]
153    fn test_ring_proof_id() {
154        _test_ring_proof::<w3f_pcs::pcs::IdentityCommitment>(2usize.pow(10));
155    }
156}