Skip to content

Commit

Permalink
Fix range test panic
Browse files Browse the repository at this point in the history
Test asserts that the provided amount of bits are always even.
Added test to check for that panic.
  • Loading branch information
moCello committed Aug 16, 2023
1 parent 8f3a5ae commit 3ddd513
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 33 deletions.
4 changes: 2 additions & 2 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 @@ -51,7 +51,7 @@ impl Circuit for TestCircuit {

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

// Make second constraint a * b = d
let constraint =
Expand Down
15 changes: 7 additions & 8 deletions src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -915,18 +915,17 @@ 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[`.
/// to be encoded in at most `num_bits`, which means that the value of the
/// [`Witness`] 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.
/// This function adds (num_bits - 1)/8 + 9 gates to the circuit
/// description, when num_bits > 0,
/// and 7 gates when num_bits = 0
///
///# Panics
/// This function will panic if the num_bits specified is not even, ie.
/// `num_bits % 2 != 0`.
/// This function will panic if the num_bits specified is not even.
fn component_range(&mut self, witness: Witness, num_bits: usize) {
// number of bits must be even
debug_assert_eq!(num_bits % 2, 0);
assert_eq!(num_bits % 2, 0, "number of bits must be even");

// if num_bits = 0 constrain witness to 0
if num_bits == 0 {
Expand Down
34 changes: 11 additions & 23 deletions tests/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,29 +98,6 @@ fn range() {
let circuit = TestCircuit::new(a, bits);
check_unsatisfied_circuit(&prover, &circuit, rng, &msg);

// Test bits = 4
//
// Compile new circuit descriptions for the prover and verifier
let bits = 4;
let a = BlsScalar::from(15);
let circuit = TestCircuit::new(a, bits);
let (prover, verifier) =
Compiler::compile_with_circuit(&pp, label, &circuit)
.expect("Circuit should compile");

// Test:
// 15 < 2^4
let msg = "Verification of a satisfied circuit should pass";
let circuit = TestCircuit::new(a, bits);
check_satisfied_circuit(&prover, &verifier, &pi, &circuit, rng, &msg);

// Test fails:
// 16 !< 2^4
let msg = "Proof creation of an unsatisfied circuit should fail";
let a = BlsScalar::from(16);
let circuit = TestCircuit::new(a, bits);
check_unsatisfied_circuit(&prover, &circuit, rng, &msg);

// Test bits = 74
//
// Compile new circuit descriptions for the prover and verifier
Expand Down Expand Up @@ -173,4 +150,15 @@ fn range() {
let a = -BlsScalar::one();
let circuit = TestCircuit::new(a, bits);
check_satisfied_circuit(&prover, &verifier, &pi, &circuit, rng, &msg);

// Test with odd bits = 55
//
// Compilation is expected to panic
let bits = 55;
let a = BlsScalar::pow_of_2(74) - BlsScalar::one();
let circuit = TestCircuit::new(a, bits);
let result = std::panic::catch_unwind(|| {
Compiler::compile_with_circuit::<TestCircuit>(&pp, label, &circuit)
});
assert!(result.is_err());
}

0 comments on commit 3ddd513

Please sign in to comment.