ark_marlin/
data_structures.rs

1use crate::ahp::indexer::*;
2use crate::ahp::prover::ProverMsg;
3use crate::Vec;
4use ark_ff::PrimeField;
5use ark_poly::univariate::DensePolynomial;
6use ark_poly_commit::{BatchLCProof, PolynomialCommitment};
7use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError};
8use ark_std::{
9    format,
10    io::{Read, Write},
11};
12
13/* ************************************************************************* */
14/* ************************************************************************* */
15/* ************************************************************************* */
16
17/// The universal public parameters for the argument system.
18pub type UniversalSRS<F, PC> = <PC as PolynomialCommitment<F, DensePolynomial<F>>>::UniversalParams;
19
20/* ************************************************************************* */
21/* ************************************************************************* */
22/* ************************************************************************* */
23
24/// Verification key for a specific index (i.e., R1CS matrices).
25#[derive(CanonicalSerialize, CanonicalDeserialize)]
26pub struct IndexVerifierKey<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> {
27    /// Stores information about the size of the index, as well as its field of
28    /// definition.
29    pub index_info: IndexInfo<F>,
30    /// Commitments to the indexed polynomials.
31    pub index_comms: Vec<PC::Commitment>,
32    /// The verifier key for this index, trimmed from the universal SRS.
33    pub verifier_key: PC::VerifierKey,
34}
35
36impl<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> ark_ff::ToBytes
37    for IndexVerifierKey<F, PC>
38{
39    fn write<W: Write>(&self, mut w: W) -> ark_std::io::Result<()> {
40        self.index_info.write(&mut w)?;
41        self.index_comms.write(&mut w)
42    }
43}
44
45impl<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> Clone
46    for IndexVerifierKey<F, PC>
47{
48    fn clone(&self) -> Self {
49        Self {
50            index_comms: self.index_comms.clone(),
51            index_info: self.index_info.clone(),
52            verifier_key: self.verifier_key.clone(),
53        }
54    }
55}
56
57impl<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> IndexVerifierKey<F, PC> {
58    /// Iterate over the commitments to indexed polynomials in `self`.
59    pub fn iter(&self) -> impl Iterator<Item = &PC::Commitment> {
60        self.index_comms.iter()
61    }
62}
63
64/* ************************************************************************* */
65/* ************************************************************************* */
66/* ************************************************************************* */
67
68/// Proving key for a specific index (i.e., R1CS matrices).
69#[derive(CanonicalSerialize, CanonicalDeserialize)]
70pub struct IndexProverKey<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> {
71    /// The index verifier key.
72    pub index_vk: IndexVerifierKey<F, PC>,
73    /// The randomness for the index polynomial commitments.
74    pub index_comm_rands: Vec<PC::Randomness>,
75    /// The index itself.
76    pub index: Index<F>,
77    /// The committer key for this index, trimmed from the universal SRS.
78    pub committer_key: PC::CommitterKey,
79}
80
81impl<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> Clone for IndexProverKey<F, PC>
82where
83    PC::Commitment: Clone,
84{
85    fn clone(&self) -> Self {
86        Self {
87            index_vk: self.index_vk.clone(),
88            index_comm_rands: self.index_comm_rands.clone(),
89            index: self.index.clone(),
90            committer_key: self.committer_key.clone(),
91        }
92    }
93}
94
95/* ************************************************************************* */
96/* ************************************************************************* */
97/* ************************************************************************* */
98
99/// A zkSNARK proof.
100#[derive(CanonicalSerialize, CanonicalDeserialize)]
101pub struct Proof<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> {
102    /// Commitments to the polynomials produced by the AHP prover.
103    pub commitments: Vec<Vec<PC::Commitment>>,
104    /// Evaluations of these polynomials.
105    pub evaluations: Vec<F>,
106    /// The field elements sent by the prover.
107    pub prover_messages: Vec<ProverMsg<F>>,
108    /// An evaluation proof from the polynomial commitment.
109    pub pc_proof: BatchLCProof<F, DensePolynomial<F>, PC>,
110}
111
112impl<F: PrimeField, PC: PolynomialCommitment<F, DensePolynomial<F>>> Proof<F, PC> {
113    /// Construct a new proof.
114    pub fn new(
115        commitments: Vec<Vec<PC::Commitment>>,
116        evaluations: Vec<F>,
117        prover_messages: Vec<ProverMsg<F>>,
118        pc_proof: BatchLCProof<F, DensePolynomial<F>, PC>,
119    ) -> Self {
120        Self {
121            commitments,
122            evaluations,
123            prover_messages,
124            pc_proof,
125        }
126    }
127
128    /// Prints information about the size of the proof.
129    pub fn print_size_info(&self) {
130        use ark_poly_commit::{PCCommitment, PCProof};
131
132        let size_of_fe_in_bytes = F::zero().into_repr().as_ref().len() * 8;
133        let mut num_comms_without_degree_bounds = 0;
134        let mut num_comms_with_degree_bounds = 0;
135        let mut size_bytes_comms_without_degree_bounds = 0;
136        let mut size_bytes_comms_with_degree_bounds = 0;
137        let mut size_bytes_proofs = 0;
138        for c in self.commitments.iter().flat_map(|c| c) {
139            if !c.has_degree_bound() {
140                num_comms_without_degree_bounds += 1;
141                size_bytes_comms_without_degree_bounds += c.size_in_bytes();
142            } else {
143                num_comms_with_degree_bounds += 1;
144                size_bytes_comms_with_degree_bounds += c.size_in_bytes();
145            }
146        }
147
148        let proofs: Vec<PC::Proof> = self.pc_proof.proof.clone().into();
149        let num_proofs = proofs.len();
150        for proof in &proofs {
151            size_bytes_proofs += proof.size_in_bytes();
152        }
153
154        let num_evals = self.evaluations.len();
155        let evals_size_in_bytes = num_evals * size_of_fe_in_bytes;
156        let num_prover_messages: usize = self
157            .prover_messages
158            .iter()
159            .map(|v| match v {
160                ProverMsg::EmptyMessage => 0,
161                ProverMsg::FieldElements(elems) => elems.len(),
162            })
163            .sum();
164        let prover_msg_size_in_bytes = num_prover_messages * size_of_fe_in_bytes;
165        let arg_size = size_bytes_comms_with_degree_bounds
166            + size_bytes_comms_without_degree_bounds
167            + size_bytes_proofs
168            + prover_msg_size_in_bytes
169            + evals_size_in_bytes;
170        let stats = format!(
171            "Argument size in bytes: {}\n\n\
172             Number of commitments without degree bounds: {}\n\
173             Size (in bytes) of commitments without degree bounds: {}\n\
174             Number of commitments with degree bounds: {}\n\
175             Size (in bytes) of commitments with degree bounds: {}\n\n\
176             Number of evaluation proofs: {}\n\
177             Size (in bytes) of evaluation proofs: {}\n\n\
178             Number of evaluations: {}\n\
179             Size (in bytes) of evaluations: {}\n\n\
180             Number of field elements in prover messages: {}\n\
181             Size (in bytes) of prover message: {}\n",
182            arg_size,
183            num_comms_without_degree_bounds,
184            size_bytes_comms_without_degree_bounds,
185            num_comms_with_degree_bounds,
186            size_bytes_comms_with_degree_bounds,
187            num_proofs,
188            size_bytes_proofs,
189            num_evals,
190            evals_size_in_bytes,
191            num_prover_messages,
192            prover_msg_size_in_bytes,
193        );
194        add_to_trace!(|| "Statistics about proof", || stats);
195    }
196}