This commit is contained in:
Your Name
2025-04-24 07:11:04 -04:00
parent 6b872a58f7
commit 7846426509
2 changed files with 80 additions and 71 deletions
+62 -58
View File
@@ -1,6 +1,5 @@
use crate::{gate::Gate, gate_type::GateType}; 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 input_bits: Vec<bool>, // Input wires
@@ -9,7 +8,7 @@ pub struct Circuit {
impl Circuit { impl Circuit {
pub fn eval(self) -> bool { pub fn eval(self) -> 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(&self.input_bits, &evaluated_gates);
@@ -18,7 +17,7 @@ impl Circuit {
match evaluated_gates.pop() { match evaluated_gates.pop() {
Some(result) => result, Some(result) => result,
None => panic!("Bruh moment") None => panic!("Bruh moment"),
} }
} }
@@ -27,8 +26,12 @@ impl Circuit {
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(input_bits: Vec<bool>, n: usize) -> Self {
if input_bits.len() < 2*n { if input_bits.len() < 2 * n {
panic!("Expected input_bits to be of at least length {}, but it was {}", 2*n, input_bits.len()) panic!(
"Expected input_bits to be of at least length {}, but it was {}",
2 * n,
input_bits.len()
)
} }
/* /*
@@ -74,69 +77,70 @@ 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 { input_bits, gates };
} }
} }
fn create_n_bit_comparator_gates(n: usize) -> Vec<Gate> {
fn create_n_bit_comparator_gates(n: usize) -> Vec<Gate>{
let mut indices: Vec<usize> = vec![0; n]; let mut indices: Vec<usize> = vec![0; n];
let mut all_gates: Vec<Gate> = vec!(); let mut all_gates: Vec<Gate> = Vec::with_capacity(1+3*n);
let mut and_gate_indices: Vec<usize> = vec!(); let mut and_gate_indices: Vec<usize> = vec![0; n];
for curr in 0..n {
// Gate(A_current > B_current)
let gt_gate = Gate::new(GateType::Bigger, vec![], vec![curr, curr + n]);
let gt_gate_index = all_gates.len();
all_gates.push(gt_gate);
// print!("( ({}) ", format!("{} > {}", format!("A{}", n-1-curr), format!("B{}", n-1-curr)));
rec_n_bit_comperator_gates(0, n, &mut all_gates, &mut and_gate_indices, &mut indices, ); let mut current_bit_gate_indices: Vec<usize> = Vec::with_capacity(curr+1);
current_bit_gate_indices.push(gt_gate_index);
// Bit to the left of curr. The one at array-index 0 doesn't have one.
if curr != 0 {
// Gate(A_i = B_i)
let eq_gate = Gate::new(GateType::Equal, vec![], vec![curr - 1, curr - 1 + n]);
// remember which gate-index this bit belongs to.
indices[n - curr] = all_gates.len();
all_gates.push(eq_gate);
}
for i in 0..curr {
// Translate i to the key'th bit position because the array index does not match the bit index
// i.e.
//
// let input_bits = vec![
// A2 A1 A0 <- A_key
// 0 1 2 <- i iterates all array indices less than curr
// false, false, true,
//
// B2 B1 B0
// 3 4 5
// false, true, false
// ];
let key = n - 1 - i;
// print!("&& ({}) ", format!("{} = {}", format!("A{}", key), format!("B{}", key)));
// Index of Gate(A_i = B_i).
// You could maybe find a solution without the indices vector but it's insanely cheap anyway and maybe even better
let eq_gate_index = indices[key];
current_bit_gate_indices.push(eq_gate_index);
}
// The AND spanning all gates for this bit
let and_gate_index = all_gates.len();
let and_gate = Gate::new(GateType::And, current_bit_gate_indices, vec![]);
// println!(")");
all_gates.push(and_gate);
and_gate_indices.push(and_gate_index);
}
// the OR spanning all ANDs // the OR spanning all ANDs
let or_gate = Gate::new( GateType::Or, and_gate_indices, vec!()); let or_gate = Gate::new(GateType::Or, and_gate_indices, vec![]);
all_gates.push(or_gate); all_gates.push(or_gate);
return all_gates; return all_gates;
} }
fn rec_n_bit_comperator_gates(curr: usize, max: usize, all_gates: &mut Vec<Gate>, and_gate_incides: &mut Vec<usize>, indices: &mut Vec<usize>){
// Incrementing gate index
let a_curr_gt_b_curr_gate_index = all_gates.len();
// Gate(A_current > B_current)
let a_curr_gt_b_curr_gate = Gate::new(GateType::Bigger, vec!(), vec!(curr, curr+max));
// A_current>B_current
//print!(" ( ({}) ", format!("{} > {}", format!("A{}", max-1-curr), format!("B{}", max-1-curr)));
all_gates.push(a_curr_gt_b_curr_gate);
let mut this_recursion_gate_indices: Vec<usize> = vec!(a_curr_gt_b_curr_gate_index);
for i in 0..curr {
let key = max-1-i;
if i == curr-1 {
// Gate(A_current > B_current)
let a_i_eq_b_i_gate = Gate::new(GateType::Equal, vec!(), vec!(i, i+max));
let a_curr_gt_b_curr_gate_index = all_gates.len();
indices[key] = a_curr_gt_b_curr_gate_index;
all_gates.push(a_i_eq_b_i_gate);
}
let eq_gate_index = indices[key];
//print!("&& ({}) ", format!("{} = {}", format!("A{}", key), format!("B{}", key)));
// Index of this equality gate
this_recursion_gate_indices.push(eq_gate_index);
}
let and_curr_index = all_gates.len();
let and_curr_gate = Gate::new(GateType::And, this_recursion_gate_indices, vec!());
all_gates.push(and_curr_gate);
and_gate_incides.push(and_curr_index);
if curr+1 == max {
//println!(")");
return;
}
//println!(") ||");
return rec_n_bit_comperator_gates(curr+1, max, all_gates, and_gate_incides, indices);
}
+8 -3
View File
@@ -1,6 +1,11 @@
use apet_ex1::circuit::Circuit; use apet_ex1::{circuit::Circuit, scalar_to_bits::scalar_to_bits};
use curve25519_dalek::Scalar;
use num_bigint::BigUint;
use rand::rngs::OsRng;
fn main() { fn main() {
/*
let input_bits = vec![ let input_bits = vec![
// A2 A1 A0 // A2 A1 A0
// 0 1 2 // 0 1 2
@@ -14,7 +19,8 @@ fn main() {
let c = Circuit::compare_n_bit_numbers(input_bits, 3); let c = Circuit::compare_n_bit_numbers(input_bits, 3);
let res = c.eval(); let res = c.eval();
println!("1 > 2 ? {}", res); println!("1 > 2 ? {}", res);
/* */
let a = Scalar::random(&mut OsRng); let a = Scalar::random(&mut OsRng);
let b = Scalar::random(&mut OsRng); let b = Scalar::random(&mut OsRng);
// Convert to bit representation // Convert to bit representation
@@ -34,5 +40,4 @@ fn main() {
let b_int = BigUint::from_bytes_le(&b.to_bytes()); let b_int = BigUint::from_bytes_le(&b.to_bytes());
println!("{}", circuit_result == (a_int > b_int)) println!("{}", circuit_result == (a_int > b_int))
*/
} }