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#[derive(Clone, CanonicalSerialize, CanonicalDeserialize)]
68pub struct FixedColumns<F: PrimeField, G: AffineRepr<BaseField = F>> {
69 pub points: AffineColumn<F, G>,
74 pub ring_selector: FieldColumn<F>,
78}
79
80#[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>, }
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 }
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}