o1vm/pickles/
lookup_env.rs

1use crate::{
2    interpreters::mips::witness::LookupMultiplicities,
3    lookups::{FixedLookupTables, LookupTable},
4};
5use ark_ff::One;
6use ark_poly::{univariate::DensePolynomial, Evaluations, Radix2EvaluationDomain};
7use kimchi::{circuits::domains::EvaluationDomains, curve::KimchiCurve};
8use poly_commitment::{commitment::BlindedCommitment, ipa::SRS, PolyComm, SRS as _};
9
10/// This is what the prover needs to remember
11/// while doing individual proofs, in order
12/// to prove the lookup protocol we do in the end
13pub struct LookupEnvironment<G: KimchiCurve> {
14    /// fixed tables pre-existing the protocol
15    pub tables_poly: Vec<Vec<DensePolynomial<G::ScalarField>>>,
16    pub tables_comm: Vec<Vec<BlindedCommitment<G>>>,
17    ///multiplicities
18    pub multiplicities: LookupMultiplicities,
19}
20
21/// Create a new prover environment, which interpolates the fixed tables
22/// and commit to them.
23/// Fills the multiplicities with zeroes
24impl<G: KimchiCurve> LookupEnvironment<G> {
25    pub fn new(srs: &SRS<G>, domain: EvaluationDomains<G::ScalarField>) -> Self {
26        let tables: Vec<LookupTable<G::ScalarField>> =
27            LookupTable::<G::ScalarField>::get_all_tables();
28        let eval_col = |evals: Vec<G::ScalarField>| {
29            Evaluations::<G::ScalarField, Radix2EvaluationDomain<G::ScalarField>>::from_vec_and_domain(evals, domain.d1)
30                .interpolate()
31        };
32        let eval_columns =
33            |evals: Vec<Vec<G::ScalarField>>| evals.into_iter().map(eval_col).collect();
34        let tables_poly: Vec<Vec<DensePolynomial<G::ScalarField>>> = tables
35            .into_iter()
36            .map(|lookup| eval_columns(lookup.entries))
37            .collect();
38        let tables_comm: Vec<Vec<BlindedCommitment<G>>> = tables_poly
39            .iter()
40            .map(|poly_vec| {
41                poly_vec
42                    .iter()
43                    .map(|poly| {
44                        srs.commit_custom(poly, 1, &PolyComm::new(vec![G::ScalarField::one()]))
45                            .unwrap()
46                    })
47                    .collect()
48            })
49            .collect();
50        LookupEnvironment {
51            tables_poly,
52            tables_comm,
53            multiplicities: LookupMultiplicities::new(),
54        }
55    }
56    /// Take a prover environment, a multiplicities, and returns
57    /// a prover environment with the multiplicities being the addition of both
58    pub fn add_multiplicities(&mut self, multiplicities: LookupMultiplicities) {
59        for (x, y) in self
60            .multiplicities
61            .pad_lookup
62            .iter_mut()
63            .zip(multiplicities.pad_lookup.iter())
64        {
65            *x += y
66        }
67
68        for (x, y) in self
69            .multiplicities
70            .round_constants_lookup
71            .iter_mut()
72            .zip(multiplicities.round_constants_lookup.iter())
73        {
74            *x += y
75        }
76
77        for (x, y) in self
78            .multiplicities
79            .at_most_4_lookup
80            .iter_mut()
81            .zip(multiplicities.at_most_4_lookup.iter())
82        {
83            *x += y
84        }
85
86        for (x, y) in self
87            .multiplicities
88            .byte_lookup
89            .iter_mut()
90            .zip(multiplicities.byte_lookup.iter())
91        {
92            *x += y
93        }
94
95        for (x, y) in self
96            .multiplicities
97            .range_check_16_lookup
98            .iter_mut()
99            .zip(multiplicities.range_check_16_lookup.iter())
100        {
101            *x += y
102        }
103
104        for (x, y) in self
105            .multiplicities
106            .sparse_lookup
107            .iter_mut()
108            .zip(multiplicities.sparse_lookup.iter())
109        {
110            *x += y
111        }
112
113        for (x, y) in self
114            .multiplicities
115            .reset_lookup
116            .iter_mut()
117            .zip(multiplicities.reset_lookup.iter())
118        {
119            *x += y
120        }
121    }
122}