sp1_core_machine/operations/
and.rs

1use p3_field::{AbstractField, Field};
2use sp1_derive::AlignedBorrow;
3
4use sp1_core_executor::{
5    events::{ByteLookupEvent, ByteRecord},
6    ByteOpcode,
7};
8use sp1_primitives::consts::WORD_SIZE;
9use sp1_stark::{air::SP1AirBuilder, Word};
10
11/// A set of columns needed to compute the and of two words.
12#[derive(AlignedBorrow, Default, Debug, Clone, Copy)]
13#[repr(C)]
14pub struct AndOperation<T> {
15    /// The result of `x & y`.
16    pub value: Word<T>,
17}
18
19impl<F: Field> AndOperation<F> {
20    pub fn populate(&mut self, record: &mut impl ByteRecord, x: u32, y: u32) -> u32 {
21        let expected = x & y;
22        let x_bytes = x.to_le_bytes();
23        let y_bytes = y.to_le_bytes();
24        for i in 0..WORD_SIZE {
25            let and = x_bytes[i] & y_bytes[i];
26            self.value[i] = F::from_canonical_u8(and);
27
28            let byte_event = ByteLookupEvent {
29                opcode: ByteOpcode::AND,
30                a1: and as u16,
31                a2: 0,
32                b: x_bytes[i],
33                c: y_bytes[i],
34            };
35            record.add_byte_lookup_event(byte_event);
36        }
37        expected
38    }
39
40    #[allow(unused_variables)]
41    pub fn eval<AB: SP1AirBuilder>(
42        builder: &mut AB,
43        a: Word<AB::Var>,
44        b: Word<AB::Var>,
45        cols: AndOperation<AB::Var>,
46        is_real: AB::Var,
47    ) {
48        for i in 0..WORD_SIZE {
49            builder.send_byte(
50                AB::F::from_canonical_u32(ByteOpcode::AND as u32),
51                cols.value[i],
52                a[i],
53                b[i],
54                is_real,
55            );
56        }
57    }
58}