sp1_core_machine/operations/
bitwise.rs1use crate::air::SP1Operation;
2use serde::{Deserialize, Serialize};
3use slop_algebra::Field;
4use sp1_core_executor::{
5 events::{ByteLookupEvent, ByteRecord},
6 ByteOpcode, Opcode,
7};
8use sp1_derive::{AlignedBorrow, InputExpr, InputParams, IntoShape, SP1OperationBuilder};
9use sp1_hypercube::air::SP1AirBuilder;
10use sp1_primitives::consts::WORD_BYTE_SIZE;
11use struct_reflection::{StructReflection, StructReflectionHelper};
12
13#[derive(
15 AlignedBorrow,
16 Default,
17 Debug,
18 Clone,
19 Copy,
20 Serialize,
21 Deserialize,
22 IntoShape,
23 SP1OperationBuilder,
24 StructReflection,
25)]
26#[repr(C)]
27pub struct BitwiseOperation<T> {
28 pub result: [T; WORD_BYTE_SIZE],
30}
31
32impl<F: Field> BitwiseOperation<F> {
33 pub fn populate_bitwise(
34 &mut self,
35 record: &mut impl ByteRecord,
36 a_u64: u64,
37 b_u64: u64,
38 c_u64: u64,
39 opcode: Opcode,
40 ) {
41 let a = a_u64.to_le_bytes();
42 let b = b_u64.to_le_bytes();
43 let c = c_u64.to_le_bytes();
44
45 self.result = a.map(|x| F::from_canonical_u8(x));
46
47 for ((b_a, b_b), b_c) in a.into_iter().zip(b).zip(c) {
48 let byte_event =
49 ByteLookupEvent { opcode: ByteOpcode::from(opcode), a: b_a as u16, b: b_b, c: b_c };
50 record.add_byte_lookup_event(byte_event);
51 }
52 }
53
54 fn eval_bitwise<AB: SP1AirBuilder>(
59 builder: &mut AB,
60 a: [AB::Expr; WORD_BYTE_SIZE],
61 b: [AB::Expr; WORD_BYTE_SIZE],
62 cols: BitwiseOperation<AB::Var>,
63 opcode: AB::Expr,
64 is_real: AB::Expr,
65 ) {
66 for i in 0..WORD_BYTE_SIZE {
70 builder.send_byte(
71 opcode.clone(),
72 cols.result[i],
73 a[i].clone(),
74 b[i].clone(),
75 is_real.clone(),
76 );
77 }
78 }
79}
80
81#[derive(Clone, InputParams, InputExpr)]
82pub struct BitwiseOperationInput<AB: SP1AirBuilder> {
83 pub a: [AB::Expr; WORD_BYTE_SIZE],
84 pub b: [AB::Expr; WORD_BYTE_SIZE],
85 pub cols: BitwiseOperation<AB::Var>,
86 pub opcode: AB::Expr,
87 pub is_real: AB::Expr,
88}
89
90impl<AB: SP1AirBuilder> SP1Operation<AB> for BitwiseOperation<AB::F> {
91 type Input = BitwiseOperationInput<AB>;
92 type Output = ();
93
94 fn lower(builder: &mut AB, input: Self::Input) {
95 BitwiseOperation::<AB::F>::eval_bitwise(
96 builder,
97 input.a,
98 input.b,
99 input.cols,
100 input.opcode,
101 input.is_real,
102 );
103 }
104}