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
+72 -68
View File
@@ -1,6 +1,5 @@
use crate::{gate::Gate, gate_type::GateType};
#[derive(Debug, Clone)]
pub struct Circuit {
pub input_bits: Vec<bool>, // Input wires
@@ -9,7 +8,7 @@ pub struct Circuit {
impl Circuit {
pub fn eval(self) -> bool {
let mut evaluated_gates = vec!();
let mut evaluated_gates = vec![];
for gate in self.gates {
let result = gate.eval(&self.input_bits, &evaluated_gates);
@@ -18,8 +17,8 @@ impl Circuit {
match evaluated_gates.pop() {
Some(result) => result,
None => panic!("Bruh moment")
}
None => panic!("Bruh moment"),
}
}
/*
@@ -27,13 +26,17 @@ impl Circuit {
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 {
if input_bits.len() < 2*n {
panic!("Expected input_bits to be of at least length {}, but it was {}", 2*n, input_bits.len())
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:
A B | A > B
-----------
0 0 | 0
@@ -62,81 +65,82 @@ impl Circuit {
1 1 1 0 | 1 | 1
1 1 1 1 | 0 | 0
The inductive pattern should become apparent now.
For illustration here's the case for n=4, which should show the
recursive characteristics of the formula.
The inductive pattern should become apparent now.
For illustration here's the case for n=4, which should show the
recursive characteristics of the formula.
(A3 > B3) ||
((A3 == B3) && (A2 > B2)) ||
(A3 > B3) ||
((A3 == B3) && (A2 > B2)) ||
((A3 == B3) && (A2 == B2) && (A1 > B1)) ||
((A3 == B3) && (A2 == B2) && (A1 == B1)) && (A0 > B0))
*/
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 all_gates: Vec<Gate> = vec!();
let mut and_gate_indices: Vec<usize> = vec!();
let mut all_gates: Vec<Gate> = Vec::with_capacity(1+3*n);
let mut and_gate_indices: Vec<usize> = vec![0; n];
rec_n_bit_comperator_gates(0, n, &mut all_gates, &mut and_gate_indices, &mut indices, );
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)));
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
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);
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() {
/*
let input_bits = vec![
// A2 A1 A0
// 0 1 2
@@ -14,7 +19,8 @@ fn main() {
let c = Circuit::compare_n_bit_numbers(input_bits, 3);
let res = c.eval();
println!("1 > 2 ? {}", res);
/*
*/
let a = Scalar::random(&mut OsRng);
let b = Scalar::random(&mut OsRng);
// Convert to bit representation
@@ -34,5 +40,4 @@ fn main() {
let b_int = BigUint::from_bytes_le(&b.to_bytes());
println!("{}", circuit_result == (a_int > b_int))
*/
}