Skip to content

Commit

Permalink
Update Constraint to take witness value (#620)
Browse files Browse the repository at this point in the history
Constraints contains also witness indexes. The `gate` functions are
supposed to take plain `Constraint`s while `component` functions can
receive witnesses and build internal constraints.

Resolves #624
See also: #587
  • Loading branch information
vlopes11 authored Oct 15, 2021
1 parent 0efc9d3 commit a186471
Show file tree
Hide file tree
Showing 19 changed files with 432 additions and 379 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Change `StandardComposer` to `TurboComposer`. [#288](https://github.com/dusk-network/plonk/issue/288)
- Change `TurboComposer` to consistent API. [#587](https://github.com/dusk-network/plonk/issue/587)
- Change `plonkup_gate` to use public inputs. [#584](https://github.com/dusk-network/plonk/issue/584)
- Change `Constraint` to accept witness args. [#624](https://github.com/dusk-network/plonk/issue/624)

### Fixed

Expand Down
28 changes: 10 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,33 +43,25 @@ impl Circuit for TestCircuit {
let constraint = Constraint::new()
.left(1)
.right(1)
.public(-self.c);
.public(-self.c)
.a(a)
.b(b);

composer.append_gate(
a,
b,
composer.constant_zero(),
composer.constant_zero(),
constraint,
);
composer.append_gate(constraint);

// Check that a and b are in range
composer.component_range(a, 1 << 6);
composer.component_range(b, 1 << 5);

// Make second constraint a * b = d
let constraint = Constraint::new()
.mul(1)
.mult(1)
.output(1)
.public(-self.d);

composer.append_gate(
a,
b,
composer.constant_zero(),
composer.constant_zero(),
constraint,
);
.public(-self.d)
.a(a)
.b(b);

composer.append_gate(constraint);

let e = composer.append_witness(self.e);
let scalar_mul_result = composer
Expand Down
11 changes: 7 additions & 4 deletions benches/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Circuit for BenchCircuit {
let mut b = BlsScalar::from(3u64);
let mut c;

let zero = composer.constant_zero();
let zero = TurboComposer::constant_zero();

while composer.gates() < self.padded_gates() {
a += BlsScalar::one();
Expand All @@ -45,13 +45,16 @@ impl Circuit for BenchCircuit {
let z = composer.append_witness(c);

let constraint = Constraint::new()
.mul(1)
.mult(1)
.left(1)
.right(1)
.output(-BlsScalar::one())
.constant(1);
.constant(1)
.a(x)
.b(y)
.o(z);

composer.append_gate(x, y, z, zero, constraint);
composer.append_gate(constraint);
}

Ok(())
Expand Down
28 changes: 10 additions & 18 deletions src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,41 +152,33 @@ impl VerifierData {
/// composer: &mut TurboComposer,
/// ) -> Result<(), Error> {
/// // Add fixed witness zero
/// let zero = composer.constant_zero();
/// let zero = TurboComposer::constant_zero();
/// let a = composer.append_witness(self.a);
/// let b = composer.append_witness(self.b);
///
/// // Make first constraint a + b = c
/// let constraint = Constraint::new()
/// .left(1)
/// .right(1)
/// .public(-self.c);
/// .public(-self.c)
/// .a(a)
/// .b(b);
///
/// composer.append_gate(
/// a,
/// b,
/// zero,
/// zero,
/// constraint,
/// );
/// composer.append_gate(constraint);
///
/// // Check that a and b are in range
/// composer.component_range(a, 1 << 6);
/// composer.component_range(b, 1 << 5);
///
/// // Make second constraint a * b = d
/// let constraint = Constraint::new()
/// .mul(1)
/// .mult(1)
/// .output(1)
/// .public(-self.d);
/// .public(-self.d)
/// .a(a)
/// .b(b);
///
/// composer.append_gate(
/// a,
/// b,
/// zero,
/// zero,
/// constraint,
/// );
/// composer.append_gate(constraint);
///
/// let e = composer.append_witness(self.e);
/// let scalar_mul_result =
Expand Down
2 changes: 1 addition & 1 deletion src/constraint_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub(crate) mod logic;
pub(crate) mod range;
pub(crate) mod witness;

pub(crate) use constraint::Selector;
pub(crate) use constraint::{Selector, WiredWitness};
pub(crate) use witness::WireData;

mod arithmetic;
Expand Down
150 changes: 84 additions & 66 deletions src/constraint_system/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,36 +10,30 @@ use dusk_bls12_381::BlsScalar;
impl TurboComposer {
/// Evaluate and return `o` by appending a new constraint into the circuit.
///
/// The output of the constraint will be overwritten with
/// `o := q_l · a + q_r · b + q_4 · d + q_c + PI`
pub fn gate_add(
&mut self,
a: Witness,
b: Witness,
d: Witness,
s: Constraint,
) -> Witness {
pub fn gate_add(&mut self, s: Constraint) -> Witness {
let s = Constraint::arithmetic(&s).output(-BlsScalar::one());
let o = self.append_output_witness(a, b, d, s);

self.append_gate(a, b, o, d, s);
let o = self.append_output_witness(s);
let s = s.o(o);

self.append_gate(s);

o
}

/// Evaluate and return `o` by appending a new constraint into the circuit.
///
/// The output of the constraint will be overwritten with
/// `o := q_m · a · b + q_4 · d + q_c + PI`
pub fn gate_mul(
&mut self,
a: Witness,
b: Witness,
d: Witness,
s: Constraint,
) -> Witness {
pub fn gate_mul(&mut self, s: Constraint) -> Witness {
let s = Constraint::arithmetic(&s).output(-BlsScalar::one());
let o = self.append_output_witness(a, b, d, s);

self.append_gate(a, b, o, d, s);
let o = self.append_output_witness(s);
let s = s.o(o);

self.append_gate(s);

o
}
Expand All @@ -48,32 +42,30 @@ impl TurboComposer {
#[cfg(feature = "std")]
#[cfg(test)]
mod tests {
use crate::constraint_system::helper::*;
use crate::constraint_system::Constraint;
use crate::constraint_system::{helper, Constraint};
use dusk_bls12_381::BlsScalar;

#[test]
fn test_public_inputs() {
gadget_tester(
helper::gadget_tester(
|composer| {
let one = composer.append_witness(BlsScalar::one());
let zero = composer.constant_zero();

composer.append_dummy_gates();

let constraint = Constraint::new().left(1).right(1).public(1);
let should_be_three =
composer.gate_add(one, one, zero, constraint);
let constraint =
Constraint::new().left(1).right(1).public(1).a(one).b(one);
let should_be_three = composer.gate_add(constraint);

composer.assert_equal_constant(
should_be_three,
BlsScalar::from(3),
None,
);

let constraint = Constraint::new().left(1).right(1).public(2);
let should_be_four =
composer.gate_add(one, one, zero, constraint);
let constraint =
Constraint::new().left(1).right(1).public(2).a(one).b(one);
let should_be_four = composer.gate_add(constraint);

composer.assert_equal_constant(
should_be_four,
Expand All @@ -88,19 +80,31 @@ mod tests {

#[test]
fn test_correct_add_mul_gate() {
let res = gadget_tester(
let res = helper::gadget_tester(
|composer| {
// Verify that (4+5+5) * (6+7+7) = 280
let four = composer.append_witness(BlsScalar::from(4));
let five = composer.append_witness(BlsScalar::from(5));
let six = composer.append_witness(BlsScalar::from(6));
let seven = composer.append_witness(BlsScalar::from(7));
let zero = composer.constant_zero();

let constraint = Constraint::new().left(1).right(1).fourth(1);

let fourteen = composer.gate_add(four, five, five, constraint);
let twenty = composer.gate_add(six, seven, seven, constraint);
let constraint = Constraint::new()
.left(1)
.right(1)
.fourth(1)
.a(four)
.b(five)
.d(five);
let fourteen = composer.gate_add(constraint);

let constraint = Constraint::new()
.left(1)
.right(1)
.fourth(1)
.a(six)
.b(seven)
.d(seven);
let twenty = composer.gate_add(constraint);

// There are quite a few ways to check the equation is correct,
// depending on your circumstance If we already
Expand All @@ -109,9 +113,9 @@ mod tests {
// can compute it using the `mul` If the output
// is public, we can also constrain the output wire of the mul
// gate to it. This is what this test does
let constraint = Constraint::new().mul(1);
let output =
composer.gate_mul(fourteen, twenty, zero, constraint);
let constraint =
Constraint::new().mult(1).a(fourteen).b(twenty);
let output = composer.gate_mul(constraint);

composer.assert_equal_constant(
output,
Expand All @@ -126,24 +130,23 @@ mod tests {

#[test]
fn test_correct_add_gate() {
let res = gadget_tester(
helper::gadget_tester(
|composer| {
let zero = composer.constant_zero();
let one = composer.append_witness(BlsScalar::one());

let constraint = Constraint::new().left(1).constant(2);
let c = composer.gate_add(one, zero, zero, constraint);
let constraint = Constraint::new().left(1).constant(2).a(one);
let c = composer.gate_add(constraint);

composer.assert_equal_constant(c, BlsScalar::from(3), None);
},
32,
);
assert!(res.is_ok())
)
.expect("Circuit consistency failed");
}

#[test]
fn test_correct_big_add_mul_gate() {
let res = gadget_tester(
let res = helper::gadget_tester(
|composer| {
// Verify that (4+5+5) * (6+7+7) + (8*9) = 352
let four = composer.append_witness(BlsScalar::from(4));
Expand All @@ -152,14 +155,31 @@ mod tests {
let seven = composer.append_witness(BlsScalar::from(7));
let nine = composer.append_witness(BlsScalar::from(9));

let constraint = Constraint::new().left(1).right(1).fourth(1);

let fourteen = composer.gate_add(four, five, five, constraint);
let twenty = composer.gate_add(six, seven, seven, constraint);

let constraint = Constraint::new().mul(1).fourth(8);
let output =
composer.gate_mul(fourteen, twenty, nine, constraint);
let constraint = Constraint::new()
.left(1)
.right(1)
.fourth(1)
.a(four)
.b(five)
.d(five);
let fourteen = composer.gate_add(constraint);

let constraint = Constraint::new()
.left(1)
.right(1)
.fourth(1)
.a(six)
.b(seven)
.d(seven);
let twenty = composer.gate_add(constraint);

let constraint = Constraint::new()
.mult(1)
.fourth(8)
.a(fourteen)
.b(twenty)
.d(nine);
let output = composer.gate_mul(constraint);

composer.assert_equal_constant(
output,
Expand All @@ -174,28 +194,26 @@ mod tests {

#[test]
fn test_incorrect_add_mul_gate() {
let res = gadget_tester(
let res = helper::gadget_tester(
|composer| {
// Verify that (5+5) * (6+7) != 117
let five = composer.append_witness(BlsScalar::from(5));
let six = composer.append_witness(BlsScalar::from(6));
let seven = composer.append_witness(BlsScalar::from(7));
let zero = composer.constant_zero();

let constraint = Constraint::new().left(1).right(1);
let five_plus_five =
composer.gate_add(five, five, zero, constraint);
let constraint =
Constraint::new().left(1).right(1).a(five).b(five);
let five_plus_five = composer.gate_add(constraint);

let six_plus_seven =
composer.gate_add(six, seven, zero, constraint);
let constraint =
Constraint::new().left(1).right(1).a(six).b(seven);
let six_plus_seven = composer.gate_add(constraint);

let constraint = Constraint::new().mul(1);
let output = composer.gate_mul(
five_plus_five,
six_plus_seven,
zero,
constraint,
);
let constraint = Constraint::new()
.mult(1)
.a(five_plus_five)
.b(six_plus_seven);
let output = composer.gate_mul(constraint);

composer.assert_equal_constant(
output,
Expand Down
Loading

0 comments on commit a186471

Please sign in to comment.