fast
This commit is contained in:
+72
-68
@@ -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
@@ -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))
|
||||
*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user