w3f_plonk_common/gadgets/
booleanity.rs

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