1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! The `BinarySM` module implements the Binary State Machine,
//! coordinating sub-state machines to handle various binary operations seamlessly.
//!
//! Key components of this module include:
//! - The `BinarySM` struct, encapsulating the basic and extension state machines along with their
//! table counterparts.
//! - `ComponentBuilder` trait implementations for creating counters, planners, and input collectors
//! specific to binary operations.
use std::sync::Arc;
use crate::{
BinaryAddHiInstance, BinaryAddHiSM, BinaryAddInstance, BinaryAddSM, BinaryBasicInstance,
BinaryBasicSM, BinaryCounter, BinaryExtensionInstance, BinaryExtensionSM, BinaryPlanner,
};
use pil2_std_lib::Std;
use proofman_fields::PrimeField64;
use zisk_common::{ComponentBuilder, ComponentPlanBuilder, Instance, InstanceCtx, Planner};
use zisk_pil::{
BinaryAddHiTrace, BinaryAddTrace, BinaryExtensionFullTrace, BinaryExtensionTrace, BinaryTrace,
};
/// The `BinarySM` struct represents the Binary State Machine,
/// managing basic, extension and specific add binary operations.
#[allow(dead_code)]
pub struct BinarySM<F: PrimeField64> {
/// Binary Basic state machine
binary_basic_sm: Arc<BinaryBasicSM<F>>,
/// Binary Extension state machine
binary_extension_sm: Arc<BinaryExtensionSM<F>>,
/// Binary Add state machine (optimal only for addition)
binary_add_sm: Arc<BinaryAddSM<F>>,
/// Binary Add Hi state machine (packs the additions that fit in the low 32-bit limb)
binary_add_hi_sm: Arc<BinaryAddHiSM<F>>,
std: Arc<Std<F>>,
}
impl<F: PrimeField64> BinarySM<F> {
/// Creates a new instance of the `BinarySM` state machine.
///
/// # Arguments
/// * `std` - PIL2 standard library utilities.
///
/// # Returns
/// An `Arc`-wrapped instance of `BinarySM`.
pub fn new(std: Arc<Std<F>>) -> Arc<Self> {
let binary_basic_sm = BinaryBasicSM::new(std.clone());
let binary_extension_sm = BinaryExtensionSM::new(std.clone());
let binary_add_sm = BinaryAddSM::new(std.clone());
let binary_add_hi_sm = BinaryAddHiSM::new(std.clone());
Arc::new(Self {
binary_basic_sm,
binary_extension_sm,
binary_add_sm,
binary_add_hi_sm,
std,
})
}
}
impl<F: PrimeField64> ComponentPlanBuilder<F> for BinarySM<F> {
type Counter = BinaryCounter;
fn counter(_is_asm_emulator: bool) -> Self::Counter {
BinaryCounter::new()
}
fn planner(_is_asm_emulator: bool) -> Box<dyn Planner> {
Box::new(BinaryPlanner::<F>::new())
}
}
impl<F: PrimeField64> ComponentBuilder<F> for BinarySM<F> {
/// Builds an instance for binary operations.
///
/// # Arguments
/// * `ictx` - The instance context.
///
/// # Returns
/// A boxed implementation of `Instance` for binary operations.
fn build_instance(&self, ictx: InstanceCtx) -> Box<dyn Instance<F>> {
match ictx.plan.air_id {
BinaryTrace::<()>::AIR_ID => Box::new(BinaryBasicInstance::new(
self.binary_basic_sm.clone(),
ictx,
self.std.clone(),
)),
// Both extension airs share one instance type; it picks the row layout by air_id.
BinaryExtensionTrace::<()>::AIR_ID | BinaryExtensionFullTrace::<()>::AIR_ID => {
Box::new(BinaryExtensionInstance::new(
self.binary_extension_sm.clone(),
ictx,
self.std.clone(),
))
}
BinaryAddTrace::<()>::AIR_ID => {
Box::new(BinaryAddInstance::new(self.binary_add_sm.clone(), ictx, self.std.clone()))
}
BinaryAddHiTrace::<()>::AIR_ID => Box::new(BinaryAddHiInstance::new(
self.binary_add_hi_sm.clone(),
ictx,
self.std.clone(),
)),
_ => panic!("BinarySM::get_instance() Unsupported air_id: {:?}", ictx.plan.air_id),
}
}
}