sp1_core_machine/bytes/
air.rs1use 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 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}