Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce BoolVar struct #94

Merged
merged 6 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion plonk/src/circuit/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// along with the Jellyfish library. If not, see <https://mit-license.org/>.

//! Basic instantiations of Plonk-based constraint systems
use super::{Arithmetization, Circuit, GateId, Variable, WireId};
use super::{Arithmetization, BoolVar, Circuit, GateId, Variable, WireId};
use crate::{
circuit::{gates::*, SortedLookupVecAndPolys},
constants::{compute_coset_representatives, GATE_WIDTH, N_MUL_SELECTORS},
Expand Down Expand Up @@ -264,6 +264,15 @@ impl<F: FftField> PlonkCircuit<F> {
pub fn range_size(&self) -> Result<usize, PlonkError> {
Ok(1 << self.range_bit_len()?)
}

/// creating a `BoolVar` without checking if `v` is a boolean value!
/// You should absolutely sure about what you are doing.
/// You should normally only use this API if you already enforce `v` to be a
/// boolean value using other constraints.
pub(crate) fn create_bool_variable_unchecked(&mut self, a: F) -> Result<BoolVar, PlonkError> {
alxiong marked this conversation as resolved.
Show resolved Hide resolved
let var = self.create_variable(a)?;
Ok(BoolVar::new_unchecked(var))
}
}

impl<F: FftField> Circuit<F> for PlonkCircuit<F> {
Expand Down
6 changes: 4 additions & 2 deletions plonk/src/circuit/customized/ecc/glv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,8 @@ where
};

// (f.3) either f.1 or f.2 is satisfied
let sat = circuit.conditional_select(k2_sign_var, k2_is_neg_sat, k2_is_pos_sat)?;
let sat =
circuit.conditional_select(k2_sign_var, k2_is_neg_sat.into(), k2_is_pos_sat.into())?;
zhenfeizhang marked this conversation as resolved.
Show resolved Hide resolved
circuit.enforce_true(sat)?;

// (g) tmp2 + lambda_2 * k2_sign * k2 + s2 = t * t_sign * r2
Expand Down Expand Up @@ -544,7 +545,8 @@ where
};

// (g.3) either g.1 or g.2 is satisfied
let sat = circuit.conditional_select(k2_sign_var, k2_is_neg_sat, k2_is_pos_sat)?;
let sat =
circuit.conditional_select(k2_sign_var, k2_is_neg_sat.into(), k2_is_pos_sat.into())?;
circuit.enforce_true(sat)?;

// extract the output
Expand Down
30 changes: 18 additions & 12 deletions plonk/src/circuit/customized/ecc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,18 @@ where
&mut self,
point0: &PointVariable,
point1: &PointVariable,
) -> Result<Variable, PlonkError> {
) -> Result<BoolVar, PlonkError> {
self.check_point_var_bound(point0)?;
self.check_point_var_bound(point1)?;
let x_eq = self.check_equal(point0.0, point1.0)?;
let y_eq = self.check_equal(point0.1, point1.1)?;
self.mul(x_eq, y_eq)

let res = self.create_bool_variable_unchecked(
self.witness(x_eq.into())? * self.witness(y_eq.into())?,
)?;
self.mul_gate(x_eq.into(), y_eq.into(), res.into())?;
alxiong marked this conversation as resolved.
Show resolved Hide resolved

Ok(res)
}
}

Expand Down Expand Up @@ -299,34 +305,34 @@ where
fn neutral_point_gate(
&mut self,
point_var: &PointVariable,
expected_neutral: Variable,
expected_neutral: BoolVar,
) -> Result<(), PlonkError> {
self.check_point_var_bound(point_var)?;
self.check_var_bound(expected_neutral)?;
self.check_var_bound(expected_neutral.into())?;

// constraint 1: b_x = is_equal(x, 0);
let b_x = self.check_equal(point_var.0, self.zero())?;
// constraint 2: b_y = is_equal(y, 1);
let b_y = self.check_equal(point_var.1, self.one())?;
// constraint 3: b = b_x * b_y;
self.mul_gate(b_x, b_y, expected_neutral)?;
self.mul_gate(b_x.into(), b_y.into(), expected_neutral.into())?;
Ok(())
}

/// Obtain a boolean variable indicating whether a point is the neutral
/// point (0, 1) Return variable with value 1 if it is, or 0 otherwise
/// Return error if input variables are invalid
pub fn is_neutral_point<P>(&mut self, point_var: &PointVariable) -> Result<Variable, PlonkError>
pub fn is_neutral_point<P>(&mut self, point_var: &PointVariable) -> Result<BoolVar, PlonkError>
where
P: Parameters<BaseField = F> + Clone,
{
self.check_point_var_bound(point_var)?;

let b = {
if self.point_witness(point_var)? == Point::from(GroupAffine::<P>::zero()) {
self.create_variable(F::one())?
self.create_bool_variable(true)?
} else {
self.create_variable(F::zero())?
self.create_bool_variable(false)?
}
};

Expand Down Expand Up @@ -636,8 +642,8 @@ mod test {
let p1_check = circuit.is_neutral_point::<P>(&p1)?;
let p2_check = circuit.is_neutral_point::<P>(&p2)?;

assert_eq!(circuit.witness(p1_check)?, F::one());
assert_eq!(circuit.witness(p2_check)?, F::zero());
assert_eq!(circuit.witness(p1_check.into())?, F::one());
assert_eq!(circuit.witness(p2_check.into())?, F::zero());
assert!(circuit.check_circuit_satisfiability(&[]).is_ok());
*circuit.witness_mut(p1.0) = F::one();
assert!(circuit.check_circuit_satisfiability(&[]).is_err());
Expand Down Expand Up @@ -1002,8 +1008,8 @@ mod test {
let p1_p2_eq = circuit.check_equal_point(&p1_var, &p2_var)?;
let p1_p3_eq = circuit.check_equal_point(&p1_var, &p3_var)?;

assert_eq!(circuit.witness(p1_p2_eq)?, F::one());
assert_eq!(circuit.witness(p1_p3_eq)?, F::zero());
assert_eq!(circuit.witness(p1_p2_eq.into())?, F::one());
assert_eq!(circuit.witness(p1_p3_eq.into())?, F::zero());
assert!(circuit.check_circuit_satisfiability(&[]).is_ok());
*circuit.witness_mut(p2_var.0) = F::zero();
assert!(circuit.check_circuit_satisfiability(&[]).is_err());
Expand Down
Loading