diff --git a/src/circuit.rs b/src/circuit.rs index 9cbefa0..a241d1c 100644 --- a/src/circuit.rs +++ b/src/circuit.rs @@ -2,16 +2,15 @@ use crate::{gate::Gate, gate_type::GateType}; #[derive(Debug, Clone)] pub struct Circuit { - pub input_bits: Vec, // Input wires pub gates: Vec, // All gates } impl Circuit { - pub fn eval(self) -> bool { + pub fn eval(self, input_bits: Vec,) -> bool { let mut evaluated_gates = vec![]; for gate in self.gates { - let result = gate.eval(&self.input_bits, &evaluated_gates); + let result = gate.eval(&input_bits, &evaluated_gates); evaluated_gates.push(result); } @@ -25,14 +24,7 @@ impl Circuit { This method should create a circuit that outputs 1 if the first number A (encoded in the first n bits) is greater than the second number B (encoded in the next n bits) . */ - pub fn compare_n_bit_numbers(input_bits: Vec, n: usize) -> Self { - if input_bits.len() < 2 * n { - panic!( - "Expected input_bits to be of at least length {}, but it was {}", - 2 * n, - input_bits.len() - ) - } + pub fn compare_n_bit_numbers( n: usize) -> Self { /* base case n=1: 1-bit: @@ -77,42 +69,38 @@ impl Circuit { */ let gates = create_n_bit_comparator_gates(n); - return Circuit { input_bits, gates }; + return Circuit { gates }; } } fn create_n_bit_comparator_gates(n: usize) -> Vec { - let mut all_gates: Vec = Vec::with_capacity(3*n); - let mut and_gate_indices: Vec = vec![0; n]; + let mut all_gates: Vec = Vec::with_capacity(2+3*(n-1)); let mut eq_gate_indices: Vec = Vec::with_capacity(n-1); + let mut or_gate_input_indices: Vec = Vec::with_capacity(n); const EMPTY_VEC: Vec = Vec::new(); - for curr in 0..n { + all_gates.push(Gate::new(GateType::Bigger, EMPTY_VEC, vec![0, n])); + or_gate_input_indices.push(0); + + for curr in 1..n { // Gate(A_curr > B_curr) let mut and_gate_input_indices = vec!(all_gates.len()); - println!("GT = {}", all_gates.len()); all_gates.push(Gate::new(GateType::Bigger, EMPTY_VEC, vec![curr, curr + n])); - // Bit to the left of curr. The one at array-index 0 doesn't have one. - if curr != 0 { - // Gate(A_curr-1 = B_curr-1) - eq_gate_indices.push(all_gates.len()); - println!("EQ = {}", all_gates.len()); - all_gates.push(Gate::new(GateType::Equal, EMPTY_VEC, vec![curr - 1, curr - 1 + n])); - } + // Gate(A_curr-1 = B_curr-1) + eq_gate_indices.push(all_gates.len()); + all_gates.push(Gate::new(GateType::Equal, EMPTY_VEC, vec![curr - 1, curr - 1 + n])); and_gate_input_indices.extend(eq_gate_indices.iter()); // The AND spanning all gates for this bit - and_gate_indices.push(all_gates.len()); - println!("&& = {}", all_gates.len()); + or_gate_input_indices.push(all_gates.len()); all_gates.push(Gate::new(GateType::And, and_gate_input_indices, EMPTY_VEC)); } // the OR spanning all ANDs - let or_gate = Gate::new(GateType::Or, and_gate_indices, EMPTY_VEC); - all_gates.push(or_gate); + all_gates.push(Gate::new(GateType::Or, or_gate_input_indices, EMPTY_VEC)); return all_gates; } diff --git a/src/main.rs b/src/main.rs index 41d9aae..6949f0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -33,8 +33,8 @@ fn main() { input_bits.extend_from_slice(&b_bits); // Build and evaluate the comparison circuit - let circuit = Circuit::compare_n_bit_numbers(input_bits, 256); - let circuit_result = circuit.eval(); + let circuit = Circuit::compare_n_bit_numbers(256); + let circuit_result = circuit.eval(input_bits); let a_int = BigUint::from_bytes_le(&a.to_bytes()); let b_int = BigUint::from_bytes_le(&b.to_bytes()); diff --git a/tests/test.rs b/tests/test.rs index bda51ca..1aab068 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -6,6 +6,8 @@ mod tests { use rand::rngs::OsRng; #[test] fn test_scalar_comparison_via_circuit() { + let circuit = Circuit::compare_n_bit_numbers(256); + for _ in 0..100 { let a = Scalar::random(&mut OsRng); let b = Scalar::random(&mut OsRng); @@ -19,9 +21,8 @@ mod tests { input_bits.extend_from_slice(&a_bits); input_bits.extend_from_slice(&b_bits); - // Build and evaluate the comparison circuit - let circuit = Circuit::compare_n_bit_numbers(input_bits, 256); - let circuit_result = circuit.eval(); + // Evaluate the comparison circuit + let circuit_result = circuit.clone().eval(input_bits); // Compare expected result using BigUint let a_int = BigUint::from_bytes_le(&a.to_bytes());