kimchi_msm/fec/
columns.rs

1use crate::{
2    columns::{Column, ColumnIndexer},
3    serialization::interpreter::{N_LIMBS_LARGE, N_LIMBS_SMALL},
4};
5
6/// Number of columns in the FEC circuits.
7pub const FEC_N_COLUMNS: usize =
8    FECColumnInput::N_COL + FECColumnOutput::N_COL + FECColumnInter::N_COL;
9
10/// FEC ADD inputs: two points = four coordinates, and each in 4
11/// "large format" limbs.
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
13pub enum FECColumnInput {
14    XP(usize), // 4
15    YP(usize), // 4
16    XQ(usize), // 4
17    YQ(usize), // 4
18}
19
20/// FEC ADD outputs: one point, each in 17 limb output format.
21#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
22pub enum FECColumnOutput {
23    XR(usize), // 17
24    YR(usize), // 17
25}
26
27/// FEC ADD intermediate (work) columns.
28#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
29pub enum FECColumnInter {
30    F(usize),      // 4
31    S(usize),      // 17
32    Q1(usize),     // 17
33    Q2(usize),     // 17
34    Q3(usize),     // 17
35    Q1Sign,        // 1
36    Q2Sign,        // 1
37    Q3Sign,        // 1
38    Q1L(usize),    // 4
39    Q2L(usize),    // 4
40    Q3L(usize),    // 4
41    Carry1(usize), // 36
42    Carry2(usize), // 36
43    Carry3(usize), // 36
44}
45
46/// Columns used by the FEC Addition subcircuit.
47#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
48pub enum FECColumn {
49    Input(FECColumnInput),
50    Output(FECColumnOutput),
51    Inter(FECColumnInter),
52}
53
54impl ColumnIndexer<usize> for FECColumnInput {
55    const N_COL: usize = 4 * N_LIMBS_LARGE;
56    fn to_column(self) -> Column<usize> {
57        match self {
58            FECColumnInput::XP(i) => {
59                assert!(i < N_LIMBS_LARGE);
60                Column::Relation(i)
61            }
62            FECColumnInput::YP(i) => {
63                assert!(i < N_LIMBS_LARGE);
64                Column::Relation(N_LIMBS_LARGE + i)
65            }
66            FECColumnInput::XQ(i) => {
67                assert!(i < N_LIMBS_LARGE);
68                Column::Relation(2 * N_LIMBS_LARGE + i)
69            }
70            FECColumnInput::YQ(i) => {
71                assert!(i < N_LIMBS_LARGE);
72                Column::Relation(3 * N_LIMBS_LARGE + i)
73            }
74        }
75    }
76}
77
78impl ColumnIndexer<usize> for FECColumnOutput {
79    const N_COL: usize = 2 * N_LIMBS_SMALL;
80    fn to_column(self) -> Column<usize> {
81        match self {
82            FECColumnOutput::XR(i) => {
83                assert!(i < N_LIMBS_SMALL);
84                Column::Relation(i)
85            }
86            FECColumnOutput::YR(i) => {
87                assert!(i < N_LIMBS_SMALL);
88                Column::Relation(N_LIMBS_SMALL + i)
89            }
90        }
91    }
92}
93
94impl ColumnIndexer<usize> for FECColumnInter {
95    const N_COL: usize = 4 * N_LIMBS_LARGE + 10 * N_LIMBS_SMALL + 9;
96    fn to_column(self) -> Column<usize> {
97        match self {
98            FECColumnInter::F(i) => {
99                assert!(i < N_LIMBS_LARGE);
100                Column::Relation(i)
101            }
102            FECColumnInter::S(i) => {
103                assert!(i < N_LIMBS_SMALL);
104                Column::Relation(N_LIMBS_LARGE + i)
105            }
106            FECColumnInter::Q1(i) => {
107                assert!(i < N_LIMBS_SMALL);
108                Column::Relation(N_LIMBS_LARGE + N_LIMBS_SMALL + i)
109            }
110            FECColumnInter::Q2(i) => {
111                assert!(i < N_LIMBS_SMALL);
112                Column::Relation(N_LIMBS_LARGE + 2 * N_LIMBS_SMALL + i)
113            }
114            FECColumnInter::Q3(i) => {
115                assert!(i < N_LIMBS_SMALL);
116                Column::Relation(N_LIMBS_LARGE + 3 * N_LIMBS_SMALL + i)
117            }
118            FECColumnInter::Q1Sign => Column::Relation(N_LIMBS_LARGE + 4 * N_LIMBS_SMALL),
119            FECColumnInter::Q2Sign => Column::Relation(N_LIMBS_LARGE + 4 * N_LIMBS_SMALL + 1),
120            FECColumnInter::Q3Sign => Column::Relation(N_LIMBS_LARGE + 4 * N_LIMBS_SMALL + 2),
121            FECColumnInter::Q1L(i) => {
122                assert!(i < N_LIMBS_LARGE);
123                Column::Relation(N_LIMBS_LARGE + 4 * N_LIMBS_SMALL + 3 + i)
124            }
125            FECColumnInter::Q2L(i) => {
126                assert!(i < N_LIMBS_LARGE);
127                Column::Relation(2 * N_LIMBS_LARGE + 4 * N_LIMBS_SMALL + 3 + i)
128            }
129            FECColumnInter::Q3L(i) => {
130                assert!(i < N_LIMBS_LARGE);
131                Column::Relation(3 * N_LIMBS_LARGE + 4 * N_LIMBS_SMALL + 3 + i)
132            }
133            FECColumnInter::Carry1(i) => {
134                assert!(i < 2 * N_LIMBS_SMALL + 2);
135                Column::Relation(4 * N_LIMBS_LARGE + 4 * N_LIMBS_SMALL + 3 + i)
136            }
137            FECColumnInter::Carry2(i) => {
138                assert!(i < 2 * N_LIMBS_SMALL + 2);
139                Column::Relation(4 * N_LIMBS_LARGE + 6 * N_LIMBS_SMALL + 5 + i)
140            }
141            FECColumnInter::Carry3(i) => {
142                assert!(i < 2 * N_LIMBS_SMALL + 2);
143                Column::Relation(4 * N_LIMBS_LARGE + 8 * N_LIMBS_SMALL + 7 + i)
144            }
145        }
146    }
147}
148
149impl ColumnIndexer<usize> for FECColumn {
150    const N_COL: usize = FEC_N_COLUMNS;
151    fn to_column(self) -> Column<usize> {
152        match self {
153            FECColumn::Input(input) => input.to_column(),
154            FECColumn::Inter(inter) => inter.to_column().add_rel_offset(FECColumnInput::N_COL),
155            FECColumn::Output(output) => output
156                .to_column()
157                .add_rel_offset(FECColumnInput::N_COL + FECColumnInter::N_COL),
158        }
159    }
160}