sp1_core_machine/operations/
is_zero.rs1use serde::{Deserialize, Serialize};
8use slop_air::AirBuilder;
9use slop_algebra::{AbstractField, Field};
10use sp1_derive::{AlignedBorrow, InputExpr, InputParams, IntoShape, SP1OperationBuilder};
11
12use sp1_hypercube::air::SP1AirBuilder;
13use struct_reflection::{StructReflection, StructReflectionHelper};
14
15use crate::air::SP1Operation;
16
17#[derive(
19 AlignedBorrow,
20 Default,
21 Debug,
22 Clone,
23 Copy,
24 Serialize,
25 Deserialize,
26 IntoShape,
27 SP1OperationBuilder,
28 StructReflection,
29)]
30#[repr(C)]
31pub struct IsZeroOperation<T> {
32 pub inverse: T,
34
35 pub result: T,
37}
38
39impl<F: Field> IsZeroOperation<F> {
40 pub fn populate(&mut self, a: u64) -> u64 {
41 self.populate_from_field_element(F::from_canonical_u64(a))
42 }
43
44 pub fn populate_from_field_element(&mut self, a: F) -> u64 {
45 if a == F::zero() {
46 self.inverse = F::zero();
47 self.result = F::one();
48 } else {
49 self.inverse = a.inverse();
50 self.result = F::zero();
51 }
52 let prod = self.inverse * a;
53 debug_assert!(prod == F::one() || prod == F::zero());
54 (a == F::zero()) as u64
55 }
56
57 fn eval_is_zero<AB: SP1AirBuilder>(
60 builder: &mut AB,
61 a: AB::Expr,
62 cols: IsZeroOperation<AB::Var>,
63 is_real: AB::Expr,
64 ) {
65 let one: AB::Expr = AB::Expr::one();
66
67 let is_zero = one.clone() - cols.inverse * a.clone();
78 builder.when(is_real.clone()).assert_eq(is_zero, cols.result);
79 builder.when(is_real.clone()).assert_bool(cols.result);
80
81 builder.when(is_real.clone()).when(cols.result).assert_zero(a.clone());
83 }
84}
85
86#[derive(Clone, InputParams, InputExpr)]
87pub struct IsZeroOperationInput<AB: SP1AirBuilder> {
88 pub a: AB::Expr,
89 pub cols: IsZeroOperation<AB::Var>,
90 pub is_real: AB::Expr,
91}
92
93impl<AB: SP1AirBuilder> SP1Operation<AB> for IsZeroOperation<AB::F> {
94 type Input = IsZeroOperationInput<AB>;
95 type Output = ();
96
97 fn lower(builder: &mut AB, input: Self::Input) {
98 Self::eval_is_zero(builder, input.a, input.cols, input.is_real);
99 }
100}