staging_common/gadgets/
booleanity.rs

1use ark_ff::{FftField, Field, Zero};
2use ark_poly::{Evaluations, GeneralEvaluationDomain};
3use ark_poly::univariate::DensePolynomial;
4use ark_std::{vec, vec::Vec};
5
6use crate::{Column, const_evals, FieldColumn};
7use crate::domain::Domain;
8use crate::gadgets::VerifierGadget;
9
10#[derive(Clone)]
11pub struct BitColumn<F: FftField> {
12    pub bits: Vec<bool>,
13    pub col: FieldColumn<F>,
14}
15
16
17impl<F: FftField> BitColumn<F> {
18    pub fn init(bits: Vec<bool>, domain: &Domain<F>) -> Self {
19        let bits_as_field_elements = bits.iter()
20            .map(|&b| if b { F::one() } else { F::zero() })
21            .collect();
22        let col = domain.private_column(bits_as_field_elements);
23        Self { bits, col }
24    }
25}
26
27
28impl<F: FftField> Column<F> for BitColumn<F> {
29    fn domain(&self) -> GeneralEvaluationDomain<F> {
30        self.col.domain()
31    }
32
33    fn domain_4x(&self) -> GeneralEvaluationDomain<F> {
34        self.col.domain_4x()
35    }
36
37    fn as_poly(&self) -> &DensePolynomial<F> {
38        self.col.as_poly()
39    }
40}
41
42
43pub struct Booleanity<F: FftField> {
44    bits: BitColumn<F>,
45}
46
47
48impl<'a, F: FftField> Booleanity<F> {
49    pub fn init(bits: BitColumn<F>) -> Self {
50        Self { bits }
51    }
52
53    pub fn constraints(&self) -> Vec<Evaluations<F>> {
54        let mut c = const_evals(F::one(), self.bits.domain_4x()); // c = 1
55        let b = &self.bits.col.evals_4x;
56        c -= b; // c = 1 - b
57        c *= b; // c = (1 - b) * b
58        vec![c]
59    }
60
61    pub fn constraints_linearized(&self, _z: &F) -> Vec<DensePolynomial<F>> {
62        vec![DensePolynomial::zero()]
63    }
64}
65
66
67pub struct BooleanityValues<F: Field> {
68    pub bits: F,
69}
70
71
72impl<F: Field> VerifierGadget<F> for BooleanityValues<F> {
73    fn evaluate_constraints_main(&self) -> Vec<F> {
74        let c = self.bits * (F::one() - self.bits);
75        vec![c]
76    }
77}