No range check when `num_bits = 0`
moCello opened this issue · 0 comments
moCello commented
Describe the bug
When adding a range gate with zero bits, any witness always satisfies the circuit.
To Reproduce
In 'tests'
use dusk_plonk::prelude::*;
use rand::rngs::StdRng;
use rand::SeedableRng;
mod common;
use common::{check_satisfied_circuit, check_unsatisfied_circuit, setup};
#[test]
fn range() {
#[derive(Default)]
pub struct TestCircuit {
a: BlsScalar,
bits: usize,
}
impl TestCircuit {
pub fn new(a: BlsScalar, bits: usize) -> Self {
Self { a, bits }
}
}
impl Circuit for TestCircuit {
fn circuit<C>(&self, composer: &mut C) -> Result<(), Error>
where
C: Composer,
{
let w_a = composer.append_witness(self.a);
composer.component_range(w_a, self.bits);
Ok(())
}
}
// Compile common circuit descriptions for the prover and verifier to be
// used by all tests
let label = b"component_range";
let rng = &mut StdRng::seed_from_u64(0xb1eeb);
let capacity = 1 << 6;
let (prover, verifier) =
setup(capacity, rng, label, &TestCircuit::default());
// public input to be used by all tests
let pi = vec![];
// Test bits = zero
//
// Test default works:
// 0 < 2^0
// This is an edge case but one can argue that this case can pass
let msg = "Default circuit verification should pass";
let circuit = TestCircuit::default();
check_satisfied_circuit(&prover, &verifier, &pi, &circuit, rng, &msg);
// Test:
// 1 !< 2^0
// In this case it shouldn't be possible to generate a circuit that is satisfied
let msg = "Verification of satisfied circuit should pass";
let bits = 0;
let a = BlsScalar::one();
let circuit = TestCircuit::new(a, bits);
check_unsatisfied_circuit(&prover, &circuit, rng, &msg);
// Test:
// random !< 2^0
// In this case it shouldn't be possible to generate a circuit that is satisfied
let msg = "Unsatisfied circuit should fail";
let a = BlsScalar::random(rng);
assert!(a != BlsScalar::zero());
let circuit = TestCircuit::new(a, bits);
check_unsatisfied_circuit(&prover, &circuit, rng, &msg);
}
Expected behaviour
No witness should satisfy a range gate with 0 bits (since no number can be encoded in 0 bits). An edge case would be BlsScalar::zero()
itself as one can argue that zero is encodable in 0 bits.
Additional context
This bug came up in issue #735 and the above test is in 'tests/range.rs'