Skip to main content

w3f_ring_proof/piop/
mod.rs

1use ark_ec::pairing::Pairing;
2use ark_ec::{AffineRepr, CurveGroup};
3use ark_ff::PrimeField;
4use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
5use ark_std::marker::PhantomData;
6use ark_std::{vec, vec::Vec};
7use w3f_pcs::pcs::commitment::WrappedAffine;
8use w3f_pcs::pcs::kzg::params::RawKzgVerifierKey;
9use w3f_pcs::pcs::kzg::KZG;
10use w3f_pcs::pcs::{Commitment, PcsParams, PCS};
11
12pub(crate) use prover::PiopProver;
13pub(crate) use verifier::PiopVerifier;
14use w3f_plonk_common::gadgets::ec::AffineColumn;
15use w3f_plonk_common::{ColumnsCommited, ColumnsEvaluated, FieldColumn};
16
17use crate::ring::Ring;
18use crate::PiopParams;
19
20pub mod params;
21pub mod prover;
22pub mod verifier;
23
24#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)]
25pub struct RingCommitments<F: PrimeField, C: Commitment<F>> {
26    pub(crate) bits: C,
27    pub(crate) inn_prod_acc: C,
28    pub(crate) cond_add_acc: [C; 2],
29    pub(crate) phantom: PhantomData<F>,
30}
31
32impl<F: PrimeField, C: Commitment<F>> ColumnsCommited<F, C> for RingCommitments<F, C> {
33    fn to_vec(self) -> Vec<C> {
34        vec![
35            self.bits,
36            self.inn_prod_acc,
37            self.cond_add_acc[0].clone(),
38            self.cond_add_acc[1].clone(),
39        ]
40    }
41}
42
43#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)]
44pub struct RingEvaluations<F: PrimeField> {
45    pub(crate) points: [F; 2],
46    pub(crate) ring_selector: F,
47    pub(crate) bits: F,
48    pub(crate) inn_prod_acc: F,
49    pub(crate) cond_add_acc: [F; 2],
50}
51
52impl<F: PrimeField> ColumnsEvaluated<F> for RingEvaluations<F> {
53    fn to_vec(self) -> Vec<F> {
54        vec![
55            self.points[0],
56            self.points[1],
57            self.ring_selector,
58            self.bits,
59            self.inn_prod_acc,
60            self.cond_add_acc[0],
61            self.cond_add_acc[1],
62        ]
63    }
64}
65
66// Columns commitment to which the verifier knows (or trusts).
67#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)]
68pub struct FixedColumns<F: PrimeField, G: AffineRepr<BaseField = F>> {
69    // Public keys of the ring participants in order,
70    // followed by the powers-of-2 multiples of the second Pedersen base.
71    // pk_1, ..., pk_n, H, 2H, 4H, ..., 2^sH
72    // 1          n                     n+s+1
73    pub points: AffineColumn<F, G>,
74    // Binary column that highlights which rows of the table correspond to the ring.
75    // 1, 1, ..., 1, 0, 0, ..., 0
76    // 1          n
77    pub ring_selector: FieldColumn<F>,
78}
79
80// Commitments to the fixed columns (see above).
81#[derive(Clone, CanonicalSerialize, CanonicalDeserialize, PartialEq, Eq, Debug)]
82pub struct FixedColumnsCommitted<F: PrimeField, C: Commitment<F>> {
83    pub points: [C; 2],
84    pub ring_selector: C,
85    pub phantom: PhantomData<F>,
86}
87
88impl<F: PrimeField, C: Commitment<F>> FixedColumnsCommitted<F, C> {
89    pub fn as_vec(&self) -> Vec<C> {
90        vec![
91            self.points[0].clone(),
92            self.points[1].clone(),
93            self.ring_selector.clone(),
94        ]
95    }
96}
97
98impl<C: CurveGroup> FixedColumnsCommitted<C::ScalarField, WrappedAffine<C>> {
99    pub fn from_ring<
100        E: Pairing<G1Affine = C::Affine>,
101        G: AffineRepr<BaseField = E::ScalarField>,
102    >(
103        ring: &Ring<E::ScalarField, E, G>,
104    ) -> Self {
105        let cx = WrappedAffine(ring.cx);
106        let cy = WrappedAffine(ring.cy);
107        Self {
108            points: [cx, cy],
109            ring_selector: WrappedAffine(ring.selector),
110            phantom: Default::default(),
111        }
112    }
113}
114
115impl<F: PrimeField, G: AffineRepr<BaseField = F>> FixedColumns<F, G> {
116    pub fn commit<CS: PCS<F>>(&self, ck: &CS::CK) -> FixedColumnsCommitted<F, CS::C> {
117        let points = [
118            CS::commit(ck, self.points.xs.as_poly()).unwrap(),
119            CS::commit(ck, self.points.ys.as_poly()).unwrap(),
120        ];
121        let ring_selector = CS::commit(ck, self.ring_selector.as_poly()).unwrap();
122        FixedColumnsCommitted {
123            points,
124            ring_selector,
125            phantom: Default::default(),
126        }
127    }
128}
129
130#[derive(CanonicalSerialize, CanonicalDeserialize)]
131pub struct ProverKey<F: PrimeField, CS: PCS<F>, G: AffineRepr<BaseField = F>> {
132    pub pcs_ck: CS::CK,
133    pub fixed_columns: FixedColumns<F, G>,
134    pub verifier_key: VerifierKey<F, CS>, // used in the Fiat-Shamir transform
135}
136
137impl<F: PrimeField, CS: PCS<F>, G: AffineRepr<BaseField = F>> Clone for ProverKey<F, CS, G> {
138    fn clone(&self) -> Self {
139        Self {
140            pcs_ck: self.pcs_ck.clone(),
141            fixed_columns: self.fixed_columns.clone(),
142            verifier_key: self.verifier_key.clone(),
143        }
144    }
145}
146
147#[derive(Debug, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize)]
148pub struct VerifierKey<F: PrimeField, CS: PCS<F>> {
149    pub pcs_raw_vk: <CS::Params as PcsParams>::RVK,
150    pub fixed_columns_committed: FixedColumnsCommitted<F, CS::C>,
151    //TODO: domain
152}
153
154impl<F: PrimeField, CS: PCS<F>> Clone for VerifierKey<F, CS> {
155    fn clone(&self) -> Self {
156        Self {
157            pcs_raw_vk: self.pcs_raw_vk.clone(),
158            fixed_columns_committed: self.fixed_columns_committed.clone(),
159        }
160    }
161}
162
163impl<E: Pairing> VerifierKey<E::ScalarField, KZG<E>> {
164    pub fn from_ring_and_kzg_vk<G: AffineRepr<BaseField = E::ScalarField>>(
165        ring: &Ring<E::ScalarField, E, G>,
166        kzg_vk: RawKzgVerifierKey<E>,
167    ) -> Self {
168        let fixed_columns = FixedColumnsCommitted::from_ring(&ring);
169        Self::from_commitment_and_kzg_vk(fixed_columns, kzg_vk)
170    }
171
172    pub fn from_commitment_and_kzg_vk(
173        commitment: FixedColumnsCommitted<E::ScalarField, WrappedAffine<E::G1>>,
174        kzg_vk: RawKzgVerifierKey<E>,
175    ) -> Self {
176        Self {
177            pcs_raw_vk: kzg_vk,
178            fixed_columns_committed: commitment,
179        }
180    }
181
182    pub fn commitment(&self) -> FixedColumnsCommitted<E::ScalarField, WrappedAffine<E::G1>> {
183        self.fixed_columns_committed.clone()
184    }
185}
186
187pub fn index<F: PrimeField, CS: PCS<F>, G: AffineRepr<BaseField = F>>(
188    pcs_params: &CS::Params,
189    piop_params: &PiopParams<G>,
190    keys: &[G],
191) -> (ProverKey<F, CS, G>, VerifierKey<F, CS>) {
192    let pcs_ck = pcs_params.ck();
193    let pcs_raw_vk = pcs_params.raw_vk();
194    let fixed_columns = piop_params.fixed_columns(&keys);
195    let fixed_columns_committed = fixed_columns.commit::<CS>(&pcs_ck);
196    let verifier_key = VerifierKey {
197        pcs_raw_vk: pcs_raw_vk.clone(),
198        fixed_columns_committed: fixed_columns_committed.clone(),
199    };
200    let prover_key = ProverKey {
201        pcs_ck,
202        fixed_columns,
203        verifier_key,
204    };
205    let verifier_key = VerifierKey {
206        pcs_raw_vk,
207        fixed_columns_committed,
208    };
209    (prover_key, verifier_key)
210}