openvm_circuit_primitives/xor/
bus.rs
1use openvm_stark_backend::{
2 interaction::{InteractionBuilder, LookupBus},
3 p3_field::FieldAlgebra,
4};
5
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub struct XorBus(pub LookupBus);
9
10impl XorBus {
11 pub fn send<T>(
12 &self,
13 x: impl Into<T>,
14 y: impl Into<T>,
15 x_xor_y: impl Into<T>,
16 ) -> XorBusInteraction<T> {
17 self.push(x, y, x_xor_y, true)
18 }
19
20 pub fn receive<T>(
21 &self,
22 x: impl Into<T>,
23 y: impl Into<T>,
24 x_xor_y: impl Into<T>,
25 ) -> XorBusInteraction<T> {
26 self.push(x, y, x_xor_y, false)
27 }
28
29 pub fn push<T>(
30 &self,
31 x: impl Into<T>,
32 y: impl Into<T>,
33 x_xor_y: impl Into<T>,
34 is_lookup: bool,
35 ) -> XorBusInteraction<T> {
36 XorBusInteraction {
37 x: x.into(),
38 y: y.into(),
39 x_xor_y: x_xor_y.into(),
40 bus: self.0,
41 is_lookup,
42 }
43 }
44}
45
46#[derive(Clone, Copy, Debug)]
47pub struct XorBusInteraction<T> {
48 pub x: T,
49 pub y: T,
50 pub x_xor_y: T,
51
52 pub bus: LookupBus,
53 pub is_lookup: bool,
54}
55
56impl<T: FieldAlgebra> XorBusInteraction<T> {
57 pub fn eval<AB>(self, builder: &mut AB, count: impl Into<AB::Expr>)
59 where
60 AB: InteractionBuilder<Expr = T>,
61 {
62 let key = [self.x, self.y, self.x_xor_y];
63 if self.is_lookup {
64 self.bus.lookup_key(builder, key, count);
65 } else {
66 self.bus.add_key_with_lookups(builder, key, count);
67 }
68 }
69}