Skip to content

Commit

Permalink
Merge pull request #764 from dusk-network/mocello/763_fix_debug_panic
Browse files Browse the repository at this point in the history
Fix tests panic in debug
  • Loading branch information
moCello authored Aug 21, 2023
2 parents 5eabd2c + 0721229 commit 5be0ffe
Show file tree
Hide file tree
Showing 17 changed files with 285 additions and 395 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed

- Fix panic when creating proof for circuit with different circuit size [#760]
- Fix panic when testing in debug mode [#763]

### Removed

- Remove 'setup' funcion from common test module [#763]

### Changed

- Change range and logic component to be generic over the const `BIT_PAIRS` [#763]

## [0.14.1] - 2022-06-28

Expand Down Expand Up @@ -482,6 +491,7 @@ is necessary since `rkyv/validation` was required as a bound.
- Proof system module.

<!-- ISSUES -->
[#763]: https://github.com/dusk-network/plonk/issues/763
[#760]: https://github.com/dusk-network/plonk/issues/760
[#752]: https://github.com/dusk-network/plonk/pull/752
[#738]: https://github.com/dusk-network/plonk/issues/738
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rand_core::OsRng;
// Implement a circuit that checks:
// 1) a + b = c where C is a PI
// 2) a < 2^6
// 3) b < 2^5
// 3) b < 2^4
// 4) a * b = d where D is a PI
// 5) JubJub::GENERATOR * e(JubJubScalar) = f where F is a Public Input
#[derive(Debug, Default)]
Expand Down Expand Up @@ -50,8 +50,10 @@ impl Circuit for TestCircuit {
composer.append_gate(constraint);

// Check that a and b are in range
composer.component_range(a, 6);
composer.component_range(b, 5);
const HALF_SIX: usize = 3;
composer.component_range::<HALF_SIX>(a);
const HALF_FOUR: usize = 2;
composer.component_range::<HALF_FOUR>(b);

// Make second constraint a * b = d
let constraint =
Expand Down
6 changes: 3 additions & 3 deletions benches/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ impl<const DEGREE: usize> Circuit for BenchCircuit<DEGREE> {
composer.gate_add(Constraint::new().left(1).right(1).a(w_a).b(w_b));

composer.component_add_point(w_z, w_z);
composer.append_logic_and(w_a, w_b, 254);
composer.append_logic_xor(w_a, w_b, 254);
composer.append_logic_and::<128>(w_a, w_b);
composer.append_logic_xor::<128>(w_a, w_b);
composer.component_boolean(C::ONE);
composer.component_decomposition::<254>(w_a);
composer.component_mul_generator(
w_y,
dusk_jubjub::GENERATOR_EXTENDED,
)?;
composer.component_mul_point(w_y, w_z);
composer.component_range(w_a, 254);
composer.component_range::<128>(w_a);
composer.component_select(C::ONE, w_a, w_b);
composer.component_select_identity(C::ONE, w_z);
composer.component_select_one(C::ONE, w_a);
Expand Down
71 changes: 30 additions & 41 deletions src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,33 +105,26 @@ pub trait Composer: Sized + Index<Witness, Output = BlsScalar> {
self.append_custom_gate_internal(constraint)
}

/// Performs a logical AND or XOR op between the inputs provided for the
/// specified number of bits (counting from the least significant bit).
/// Performs a logical AND or XOR op between the inputs provided for
/// `num_bits = BIT_PAIRS * 2` bits (counting from the least significant).
///
/// Each logic gate adds `(num_bits / 2) + 1` gates to the circuit to
/// Each logic gate adds `BIT_PAIRS + 1` gates to the circuit to
/// perform the whole operation.
///
/// ## Constraint
/// - is_component_xor = 1 -> Performs XOR between the first `num_bits` for
/// `a` and `b`.
/// - is_component_xor = 0 -> Performs AND between the first `num_bits` for
/// `a` and `b`.
///
/// # Panics
/// This function will panic if the num_bits specified is not even, ie.
/// `num_bits % 2 != 0`.
fn append_logic_component(
fn append_logic_component<const BIT_PAIRS: usize>(
&mut self,
a: Witness,
b: Witness,
num_bits: usize,
is_component_xor: bool,
) -> Witness {
// the bits are iterated as chunks of two; hence, we require an even
// number
debug_assert_eq!(num_bits & 1, 0);

let num_bits = cmp::min(num_bits, 256);
let num_bits = cmp::min(BIT_PAIRS * 2, 256);
let num_quads = num_bits >> 1;

let bls_four = BlsScalar::from(4u64);
Expand Down Expand Up @@ -272,7 +265,13 @@ pub trait Composer: Sized + Index<Witness, Output = BlsScalar> {
let width = 2;
let wnaf_entries = scalar.compute_windowed_naf(width);

debug_assert_eq!(wnaf_entries.len(), bits);
// this will pass as long as `compute_windowed_naf` returns an array
// with 256 elements
debug_assert_eq!(
wnaf_entries.len(),
bits,
"the wnaf_entries array is expected to be 256 elements long"
);

// initialize the accumulators
let mut scalar_acc = vec![BlsScalar::zero()];
Expand Down Expand Up @@ -581,35 +580,25 @@ pub trait Composer: Sized + Index<Witness, Output = BlsScalar> {
}

/// Adds a logical AND gate that performs the bitwise AND between two values
/// for the specified first `num_bits` returning a [`Witness`]
/// specified first `num_bits = BIT_PAIRS * 2` bits returning a [`Witness`]
/// holding the result.
///
/// # Panics
///
/// If the `num_bits` specified in the fn params is odd.
fn append_logic_and(
fn append_logic_and<const BIT_PAIRS: usize>(
&mut self,
a: Witness,
b: Witness,
num_bits: usize,
) -> Witness {
self.append_logic_component(a, b, num_bits, false)
self.append_logic_component::<BIT_PAIRS>(a, b, false)
}

/// Adds a logical XOR gate that performs the XOR between two values for the
/// specified first `num_bits` returning a [`Witness`] holding the
/// result.
///
/// # Panics
///
/// If the `num_bits` specified in the fn params is odd.
fn append_logic_xor(
/// specified first `num_bits = BIT_PAIRS * 2` bits returning a [`Witness`]
/// holding the result.
fn append_logic_xor<const BIT_PAIRS: usize>(
&mut self,
a: Witness,
b: Witness,
num_bits: usize,
) -> Witness {
self.append_logic_component(a, b, num_bits, true)
self.append_logic_component::<BIT_PAIRS>(a, b, true)
}

/// Constrain `a` to be equal to `constant + pi`.
Expand Down Expand Up @@ -913,18 +902,18 @@ pub trait Composer: Sized + Index<Witness, Output = BlsScalar> {
}

/// Adds a range-constraint gate that checks and constrains a [`Witness`]
/// to be encoded in at most `num_bits`, which means that it will be within
/// the range `[0, 2^num_bits[`.
///
/// This function adds min(1, `num_bits/4`) gates to the circuit description
/// in order to add the range constraint.
/// to be encoded in at most `num_bits = BIT_PAIRS * 2` bits, which means
/// that the underlying [`BlsScalar`] of the [`Witness`] will be within the
/// range `[0, 2^num_bits[`, where `num_bits` is dividable by two.
///
///# Panics
/// This function will panic if the num_bits specified is not even, ie.
/// `num_bits % 2 != 0`.
fn component_range(&mut self, witness: Witness, num_bits: usize) {
// number of bits must be even
debug_assert_eq!(num_bits % 2, 0);
/// This function adds:
/// (num_bits - 1)/8 + 9 gates, when num_bits > 0,
/// and 7 gates, when num_bits = 0
/// to the circuit description.
fn component_range<const BIT_PAIRS: usize>(&mut self, witness: Witness) {
// the bits are iterated as chunks of two; hence, we require an even
// number
let num_bits = cmp::min(BIT_PAIRS * 2, 256);

// if num_bits = 0 constrain witness to 0
if num_bits == 0 {
Expand Down
Loading

0 comments on commit 5be0ffe

Please sign in to comment.