sp1_core_machine/bytes/
air.rs

1use core::borrow::Borrow;
2
3use p3_air::{Air, BaseAir, PairBuilder};
4use p3_field::{AbstractField, Field};
5use p3_matrix::Matrix;
6use sp1_core_executor::ByteOpcode;
7use sp1_stark::air::SP1AirBuilder;
8
9use super::{
10    columns::{ByteMultCols, BytePreprocessedCols, NUM_BYTE_MULT_COLS},
11    ByteChip,
12};
13
14impl<F: Field> BaseAir<F> for ByteChip<F> {
15    fn width(&self) -> usize {
16        NUM_BYTE_MULT_COLS
17    }
18}
19
20impl<AB: SP1AirBuilder + PairBuilder> Air<AB> for ByteChip<AB::F> {
21    fn eval(&self, builder: &mut AB) {
22        let main = builder.main();
23        let local_mult = main.row_slice(0);
24        let local_mult: &ByteMultCols<AB::Var> = (*local_mult).borrow();
25
26        let prep = builder.preprocessed();
27        let prep = prep.row_slice(0);
28        let local: &BytePreprocessedCols<AB::Var> = (*prep).borrow();
29
30        // Send all the lookups for each operation.
31        for (i, opcode) in ByteOpcode::all().iter().enumerate() {
32            let field_op = opcode.as_field::<AB::F>();
33            let mult = local_mult.multiplicities[i];
34            match opcode {
35                ByteOpcode::AND => {
36                    builder.receive_byte(field_op, local.and, local.b, local.c, mult)
37                }
38                ByteOpcode::OR => builder.receive_byte(field_op, local.or, local.b, local.c, mult),
39                ByteOpcode::XOR => {
40                    builder.receive_byte(field_op, local.xor, local.b, local.c, mult)
41                }
42                ByteOpcode::SLL => {
43                    builder.receive_byte(field_op, local.sll, local.b, local.c, mult)
44                }
45                ByteOpcode::U8Range => {
46                    builder.receive_byte(field_op, AB::F::zero(), local.b, local.c, mult)
47                }
48                ByteOpcode::ShrCarry => builder.receive_byte_pair(
49                    field_op,
50                    local.shr,
51                    local.shr_carry,
52                    local.b,
53                    local.c,
54                    mult,
55                ),
56                ByteOpcode::LTU => {
57                    builder.receive_byte(field_op, local.ltu, local.b, local.c, mult)
58                }
59                ByteOpcode::MSB => {
60                    builder.receive_byte(field_op, local.msb, local.b, AB::F::zero(), mult)
61                }
62                ByteOpcode::U16Range => builder.receive_byte(
63                    field_op,
64                    local.value_u16,
65                    AB::F::zero(),
66                    AB::F::zero(),
67                    mult,
68                ),
69            }
70        }
71    }
72}