Skip to main content

w3f_ring_proof/piop/
mod.rs

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