ivc/poseidon_55_0_7_3_7/
columns.rs

1//! The column layout will be as follow, supposing a state size of 3 elements:
2//! ```text
3//! | C1 | C2 | C3 | C4  | C5  | C6  | ... | C_(k) | C_(k + 1) | C_(k + 2) |
4//! |--- |----|----|-----|-----|-----|-----|-------|-----------|-----------|
5//! |  x |  y | z  | x'  |  y' |  z' | ... |  x''  |     y''   |    z''    |
6//!                | MDS \circ SBOX  |     |        MDS \circ SBOX         |
7//!                |-----------------|     |-------------------------------|
8//! ```
9//!
10//! where (x', y', z') = MDS(x^7, y^7, z^7), i.e. the result of the linear layer
11//!
12//! We will have, for N full rounds:
13//! - `3` input columns
14//! - `N * 3` round columns, indexed by the round number and the index in the state,
15//!   the number of rounds.
16//!
17//! The round constants are added as fixed selectors.
18
19use kimchi_msm::columns::{Column, ColumnIndexer};
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
22pub enum PoseidonColumn<const STATE_SIZE: usize, const NB_FULL_ROUND: usize> {
23    Input(usize),
24    Round(usize, usize),
25    RoundConstant(usize, usize),
26}
27
28impl<const STATE_SIZE: usize, const NB_FULL_ROUND: usize> ColumnIndexer<usize>
29    for PoseidonColumn<STATE_SIZE, NB_FULL_ROUND>
30{
31    const N_COL: usize = STATE_SIZE + NB_FULL_ROUND * STATE_SIZE;
32
33    fn to_column(self) -> Column<usize> {
34        match self {
35            PoseidonColumn::Input(i) => {
36                assert!(i < STATE_SIZE);
37                Column::Relation(i)
38            }
39            PoseidonColumn::Round(round, state_index) => {
40                assert!(state_index < STATE_SIZE);
41                // We start round 0
42                assert!(round < NB_FULL_ROUND);
43                let idx = STATE_SIZE + (round * STATE_SIZE + state_index);
44                Column::Relation(idx)
45            }
46            PoseidonColumn::RoundConstant(round, state_index) => {
47                assert!(state_index < STATE_SIZE);
48                // We start round 0
49                assert!(round < NB_FULL_ROUND);
50                let idx = round * STATE_SIZE + state_index;
51                Column::FixedSelector(idx)
52            }
53        }
54    }
55}