kimchi_msm/serialization/
column.rs

1use crate::{
2    columns::{Column, ColumnIndexer},
3    serialization::{interpreter::N_LIMBS_LARGE, N_INTERMEDIATE_LIMBS},
4    N_LIMBS,
5};
6
7/// Total number of columns in the serialization circuit, including fixed selectors.
8pub const N_COL_SER: usize = N_INTERMEDIATE_LIMBS + 6 * N_LIMBS + N_LIMBS_LARGE + 12;
9
10/// Number of fixed selectors for serialization circuit.
11pub const N_FSEL_SER: usize = 2;
12
13/// Columns used by the serialization subcircuit.
14#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15pub enum SerializationColumn {
16    /// A fixed selector column that gives one the current row, starting with 0.
17    CurrentRow,
18    /// For current row i, this is i - 2^{ceil(log(i)) - 1}
19    PreviousCoeffRow,
20    /// 3 88-bit inputs. For the row #i this represents the IPA challenge xi_{log(i)}.
21    ChalKimchi(usize),
22    /// N_INTERMEDIATE_LIMBS intermediate values, 4 bits long. Represent parts of the IPA challenge.
23    ChalIntermediate(usize),
24    /// N_LIMBS values, representing the converted IPA challenge.
25    ChalConverted(usize),
26    /// Previous coefficient C_j, this one is looked up. For the row i, the expected
27    /// value is (C_i >> 1).
28    CoeffInput(usize),
29    /// Trusted (for range) foreign field modulus, in 4 big limbs.
30    FFieldModulus(usize),
31    /// Quotient limbs (small)
32    QuotientSmall(usize),
33    /// Quotient limbs (large)
34    QuotientLarge(usize),
35    /// Sign of the quotient, one bit
36    QuotientSign,
37    /// Carry limbs
38    Carry(usize),
39    /// The resulting coefficient C_i = C_{i - 2^{ceil(log i) - 1}} * xi_{log(i)}. In small limbs.
40    CoeffResult(usize),
41}
42
43impl ColumnIndexer<usize> for SerializationColumn {
44    const N_COL: usize = N_COL_SER;
45    fn to_column(self) -> Column<usize> {
46        match self {
47            Self::CurrentRow => Column::FixedSelector(0),
48            Self::PreviousCoeffRow => Column::FixedSelector(1),
49            Self::ChalKimchi(j) => {
50                assert!(j < 3);
51                Column::Relation(j)
52            }
53            Self::ChalIntermediate(j) => {
54                assert!(j < N_INTERMEDIATE_LIMBS);
55                Column::Relation(3 + j)
56            }
57            Self::ChalConverted(j) => {
58                assert!(j < N_LIMBS);
59                Column::Relation(N_INTERMEDIATE_LIMBS + 3 + j)
60            }
61            Self::CoeffInput(j) => {
62                assert!(j < N_LIMBS);
63                Column::Relation(N_INTERMEDIATE_LIMBS + N_LIMBS + 3 + j)
64            }
65            Self::FFieldModulus(j) => {
66                assert!(j < 4);
67                Column::Relation(N_INTERMEDIATE_LIMBS + 2 * N_LIMBS + 3 + j)
68            }
69            Self::QuotientSmall(j) => {
70                assert!(j < N_LIMBS);
71                Column::Relation(N_INTERMEDIATE_LIMBS + 2 * N_LIMBS + 7 + j)
72            }
73            Self::QuotientLarge(j) => {
74                assert!(j < N_LIMBS_LARGE);
75                Column::Relation(N_INTERMEDIATE_LIMBS + 3 * N_LIMBS + 7 + j)
76            }
77            Self::QuotientSign => {
78                Column::Relation(N_INTERMEDIATE_LIMBS + 3 * N_LIMBS + N_LIMBS_LARGE + 7)
79            }
80            Self::Carry(j) => {
81                assert!(j < 2 * N_LIMBS + 2);
82                Column::Relation(N_INTERMEDIATE_LIMBS + 3 * N_LIMBS + N_LIMBS_LARGE + 8 + j)
83            }
84            Self::CoeffResult(j) => {
85                assert!(j < N_LIMBS);
86                Column::Relation(N_INTERMEDIATE_LIMBS + 5 * N_LIMBS + N_LIMBS_LARGE + 10 + j)
87            }
88        }
89    }
90}