What if we didn't make a new circuit for every iteration in the test

This commit is contained in:
Your Name
2025-04-24 13:30:24 -04:00
parent 588bfe15fe
commit 44c9eb4785
3 changed files with 21 additions and 32 deletions
+15 -27
View File
@@ -2,16 +2,15 @@ use crate::{gate::Gate, gate_type::GateType};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Circuit { pub struct Circuit {
pub input_bits: Vec<bool>, // Input wires
pub gates: Vec<Gate>, // All gates pub gates: Vec<Gate>, // All gates
} }
impl Circuit { impl Circuit {
pub fn eval(self) -> bool { pub fn eval(self, input_bits: Vec<bool>,) -> bool {
let mut evaluated_gates = vec![]; let mut evaluated_gates = vec![];
for gate in self.gates { 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); 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 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) . bits) is greater than the second number B (encoded in the next n bits) .
*/ */
pub fn compare_n_bit_numbers(input_bits: Vec<bool>, n: usize) -> Self { pub fn compare_n_bit_numbers( 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()
)
}
/* /*
base case n=1: 1-bit: base case n=1: 1-bit:
@@ -77,42 +69,38 @@ impl Circuit {
*/ */
let gates = create_n_bit_comparator_gates(n); 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<Gate> { fn create_n_bit_comparator_gates(n: usize) -> Vec<Gate> {
let mut all_gates: Vec<Gate> = Vec::with_capacity(3*n); let mut all_gates: Vec<Gate> = Vec::with_capacity(2+3*(n-1));
let mut and_gate_indices: Vec<usize> = vec![0; n];
let mut eq_gate_indices: Vec<usize> = Vec::with_capacity(n-1); let mut eq_gate_indices: Vec<usize> = Vec::with_capacity(n-1);
let mut or_gate_input_indices: Vec<usize> = Vec::with_capacity(n);
const EMPTY_VEC: Vec<usize> = Vec::new(); const EMPTY_VEC: Vec<usize> = 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) // Gate(A_curr > B_curr)
let mut and_gate_input_indices = vec!(all_gates.len()); 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])); 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. // Gate(A_curr-1 = B_curr-1)
if curr != 0 { eq_gate_indices.push(all_gates.len());
// Gate(A_curr-1 = B_curr-1) all_gates.push(Gate::new(GateType::Equal, EMPTY_VEC, vec![curr - 1, curr - 1 + n]));
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]));
}
and_gate_input_indices.extend(eq_gate_indices.iter()); and_gate_input_indices.extend(eq_gate_indices.iter());
// The AND spanning all gates for this bit // The AND spanning all gates for this bit
and_gate_indices.push(all_gates.len()); or_gate_input_indices.push(all_gates.len());
println!("&& = {}", all_gates.len());
all_gates.push(Gate::new(GateType::And, and_gate_input_indices, EMPTY_VEC)); all_gates.push(Gate::new(GateType::And, and_gate_input_indices, EMPTY_VEC));
} }
// the OR spanning all ANDs // the OR spanning all ANDs
let or_gate = Gate::new(GateType::Or, and_gate_indices, EMPTY_VEC); all_gates.push(Gate::new(GateType::Or, or_gate_input_indices, EMPTY_VEC));
all_gates.push(or_gate);
return all_gates; return all_gates;
} }
+2 -2
View File
@@ -33,8 +33,8 @@ fn main() {
input_bits.extend_from_slice(&b_bits); input_bits.extend_from_slice(&b_bits);
// Build and evaluate the comparison circuit // Build and evaluate the comparison circuit
let circuit = Circuit::compare_n_bit_numbers(input_bits, 256); let circuit = Circuit::compare_n_bit_numbers(256);
let circuit_result = circuit.eval(); let circuit_result = circuit.eval(input_bits);
let a_int = BigUint::from_bytes_le(&a.to_bytes()); let a_int = BigUint::from_bytes_le(&a.to_bytes());
let b_int = BigUint::from_bytes_le(&b.to_bytes()); let b_int = BigUint::from_bytes_le(&b.to_bytes());
+4 -3
View File
@@ -6,6 +6,8 @@ mod tests {
use rand::rngs::OsRng; use rand::rngs::OsRng;
#[test] #[test]
fn test_scalar_comparison_via_circuit() { fn test_scalar_comparison_via_circuit() {
let circuit = Circuit::compare_n_bit_numbers(256);
for _ in 0..100 { for _ in 0..100 {
let a = Scalar::random(&mut OsRng); let a = Scalar::random(&mut OsRng);
let b = 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(&a_bits);
input_bits.extend_from_slice(&b_bits); input_bits.extend_from_slice(&b_bits);
// Build and evaluate the comparison circuit // Evaluate the comparison circuit
let circuit = Circuit::compare_n_bit_numbers(input_bits, 256); let circuit_result = circuit.clone().eval(input_bits);
let circuit_result = circuit.eval();
// Compare expected result using BigUint // Compare expected result using BigUint
let a_int = BigUint::from_bytes_le(&a.to_bytes()); let a_int = BigUint::from_bytes_le(&a.to_bytes());