1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use ark_ff::FftField;
use ark_poly::{Evaluations, Radix2EvaluationDomain};
use kimchi_msm::columns::Column;

use crate::{
    interpreters::mips::column::{N_MIPS_SEL_COLS, SCRATCH_SIZE, SCRATCH_SIZE_INVERSE},
    pickles::proof::WitnessColumns,
};
use kimchi::circuits::{
    berkeley_columns::{BerkeleyChallengeTerm, BerkeleyChallenges},
    domains::{Domain, EvaluationDomains},
    expr::{ColumnEnvironment as TColumnEnvironment, Constants},
};

type Evals<F> = Evaluations<F, Radix2EvaluationDomain<F>>;

/// The collection of polynomials (all in evaluation form) and constants
/// required to evaluate an expression as a polynomial.
///
/// All are evaluations.
pub struct ColumnEnvironment<'a, F: FftField> {
    /// The witness column polynomials. Includes relation columns and dynamic
    /// selector columns.
    pub witness: &'a WitnessColumns<Evals<F>, [Evals<F>; N_MIPS_SEL_COLS]>,
    /// The value `prod_{j != 1} (1 - ω^j)`, used for efficiently
    /// computing the evaluations of the unnormalized Lagrange basis
    /// polynomials.
    pub l0_1: F,
    /// Constant values required
    pub constants: Constants<F>,
    /// Challenges from the IOP.
    // FIXME: change for other challenges
    pub challenges: BerkeleyChallenges<F>,
    /// The domains used in the PLONK argument.
    pub domain: EvaluationDomains<F>,
}

pub fn get_all_columns() -> Vec<Column> {
    let mut cols =
        Vec::<Column>::with_capacity(SCRATCH_SIZE + SCRATCH_SIZE_INVERSE + 2 + N_MIPS_SEL_COLS);
    for i in 0..SCRATCH_SIZE + SCRATCH_SIZE_INVERSE + 2 {
        cols.push(Column::Relation(i));
    }
    for i in 0..N_MIPS_SEL_COLS {
        cols.push(Column::DynamicSelector(i));
    }
    cols
}

impl<G> WitnessColumns<G, [G; N_MIPS_SEL_COLS]> {
    pub fn get_column(&self, col: &Column) -> Option<&G> {
        match *col {
            Column::Relation(i) => {
                if i < SCRATCH_SIZE {
                    let res = &self.scratch[i];
                    Some(res)
                } else if i < SCRATCH_SIZE + SCRATCH_SIZE_INVERSE {
                    let res = &self.scratch_inverse[i - SCRATCH_SIZE];
                    Some(res)
                } else if i == SCRATCH_SIZE + SCRATCH_SIZE_INVERSE {
                    let res = &self.instruction_counter;
                    Some(res)
                } else if i == SCRATCH_SIZE + SCRATCH_SIZE_INVERSE + 1 {
                    let res = &self.error;
                    Some(res)
                } else {
                    panic!("We should not have that many relation columns. We have {} columns and index {} was given", SCRATCH_SIZE + SCRATCH_SIZE_INVERSE + 2, i);
                }
            }
            Column::DynamicSelector(i) => {
                assert!(
                    i < N_MIPS_SEL_COLS,
                    "We do not have that many dynamic selector columns. We have {} columns and index {} was given",
                    N_MIPS_SEL_COLS,
                    i
                );
                let res = &self.selector[i];
                Some(res)
            }
            _ => {
                panic!(
                    "We should not have any other type of columns. The column {:?} was given",
                    col
                );
            }
        }
    }
}

impl<'a, F: FftField> TColumnEnvironment<'a, F, BerkeleyChallengeTerm, BerkeleyChallenges<F>>
    for ColumnEnvironment<'a, F>
{
    // FIXME: do we change to the MIPS column type?
    // We do not want to keep kimchi_msm/generic prover
    type Column = Column;

    fn get_column(&self, col: &Self::Column) -> Option<&'a Evals<F>> {
        self.witness.get_column(col)
    }

    fn get_domain(&self, d: Domain) -> Radix2EvaluationDomain<F> {
        match d {
            Domain::D1 => self.domain.d1,
            Domain::D2 => self.domain.d2,
            Domain::D4 => self.domain.d4,
            Domain::D8 => self.domain.d8,
        }
    }

    fn column_domain(&self, _col: &Self::Column) -> Domain {
        Domain::D8
    }

    fn get_constants(&self) -> &Constants<F> {
        &self.constants
    }

    fn get_challenges(&self) -> &BerkeleyChallenges<F> {
        &self.challenges
    }

    fn vanishes_on_zero_knowledge_and_previous_rows(
        &self,
    ) -> &'a Evaluations<F, Radix2EvaluationDomain<F>> {
        panic!("Not supposed to be used in MIPS. We do not support zero-knowledge for now")
    }

    fn l0_1(&self) -> F {
        self.l0_1
    }
}