kimchi/circuits/lookup/tables/
xor.rs

1use crate::circuits::lookup::tables::{LookupTable, XOR_TABLE_ID};
2use ark_ff::Field;
3
4//~ The lookup table for 4-bit xor.
5//~ Note that it is constructed so that `(0, 0, 0)` is the last position in the table.
6//~
7//~ This is because tables are extended to the full size of a column (essentially)
8//~ by padding them with their final value. And, having the value `(0, 0, 0)` here means
9//~ that when we commit to this table and use the dummy value in the `lookup_sorted`
10//~ columns, those entries that have the dummy value of
11//~
12//~ $$0 = 0 + j*0 + j^2*0$$
13//~
14//~ will translate into a scalar multiplication by 0, which is free.
15
16/// Returns the XOR lookup table
17///
18/// # Panics
19///
20/// Will panic if `data` is invalid.
21pub fn xor_table<F: Field>() -> LookupTable<F> {
22    let mut data = vec![vec![]; 3];
23
24    // XOR for all possible four-bit arguments.
25    // I suppose this could be computed a bit faster using symmetry but it's quite
26    // small (16*16 = 256 entries) so let's just keep it simple.
27    for i in 0u32..=0b1111 {
28        for j in 0u32..=0b1111 {
29            data[0].push(F::from(i));
30            data[1].push(F::from(j));
31            data[2].push(F::from(i ^ j));
32        }
33    }
34
35    for r in &mut data {
36        r.reverse();
37        // Just to be safe.
38        assert!(r[r.len() - 1].is_zero());
39    }
40    LookupTable {
41        id: XOR_TABLE_ID,
42        data,
43    }
44}
45
46pub const TABLE_SIZE: usize = 256;