kimchi_msm/ffa/
mod.rs

1pub mod columns;
2pub mod interpreter;
3pub mod lookups;
4
5#[cfg(test)]
6mod tests {
7
8    use crate::{
9        circuit_design::{ConstraintBuilderEnv, WitnessBuilderEnv},
10        columns::ColumnIndexer,
11        ffa::{
12            columns::FFAColumn,
13            interpreter::{self as ffa_interpreter},
14            lookups::LookupTable,
15        },
16        logup::LookupTableID,
17        Ff1, Fp,
18    };
19    use ark_ff::UniformRand;
20    use rand::{CryptoRng, RngCore};
21    use std::collections::BTreeMap;
22
23    type FFAWitnessBuilderEnv = WitnessBuilderEnv<
24        Fp,
25        FFAColumn,
26        { <FFAColumn as ColumnIndexer<usize>>::N_COL },
27        { <FFAColumn as ColumnIndexer<usize>>::N_COL },
28        0,
29        0,
30        LookupTable,
31    >;
32
33    /// Builds the FF addition circuit with random values. The witness
34    /// environment enforces the constraints internally, so it is
35    /// enough to just build the circuit to ensure it is satisfied.
36    fn build_ffa_circuit<RNG: RngCore + CryptoRng>(
37        rng: &mut RNG,
38        domain_size: usize,
39    ) -> FFAWitnessBuilderEnv {
40        let mut witness_env = FFAWitnessBuilderEnv::create();
41
42        for _row_i in 0..domain_size {
43            let a: Ff1 = <Ff1 as UniformRand>::rand(rng);
44            let b: Ff1 = <Ff1 as UniformRand>::rand(rng);
45
46            //use rand::Rng;
47            //let a: Ff1 = From::from(rng.gen_range(0..(1 << 50)));
48            //let b: Ff1 = From::from(rng.gen_range(0..(1 << 50)));
49            ffa_interpreter::ff_addition_circuit(&mut witness_env, a, b);
50            witness_env.next_row();
51        }
52
53        witness_env
54    }
55
56    #[test]
57    /// Tests if FFA circuit is valid.
58    pub fn test_ffa_circuit() {
59        let mut rng = o1_utils::tests::make_test_rng(None);
60        build_ffa_circuit(&mut rng, 1 << 4);
61    }
62
63    #[test]
64    pub fn heavy_test_ffa_completeness() {
65        let mut rng = o1_utils::tests::make_test_rng(None);
66        let domain_size = 1 << 15; // Otherwise we can't do 15-bit lookups.
67
68        let mut constraint_env = ConstraintBuilderEnv::<Fp, LookupTable>::create();
69        ffa_interpreter::constrain_ff_addition(&mut constraint_env);
70        let constraints = constraint_env.get_constraints();
71
72        let witness_env = build_ffa_circuit(&mut rng, domain_size);
73
74        // Fixed tables can be generated inside lookup_tables_data. Runtime should be generated here.
75        let mut lookup_tables_data = BTreeMap::new();
76        for table_id in LookupTable::all_variants().into_iter() {
77            lookup_tables_data.insert(
78                table_id,
79                vec![table_id
80                    .entries(domain_size as u64)
81                    .into_iter()
82                    .map(|x| vec![x])
83                    .collect()],
84            );
85        }
86        let proof_inputs = witness_env.get_proof_inputs(domain_size, lookup_tables_data);
87
88        crate::test::test_completeness_generic::<
89            { <FFAColumn as ColumnIndexer<usize>>::N_COL },
90            { <FFAColumn as ColumnIndexer<usize>>::N_COL },
91            0,
92            0,
93            LookupTable,
94            _,
95        >(
96            constraints,
97            Box::new([]),
98            proof_inputs,
99            domain_size,
100            &mut rng,
101        );
102    }
103}