Skip to content

Commit b437c22

Browse files
committed
Fr, multiplexer
1 parent a4ff7ec commit b437c22

File tree

9 files changed

+719
-416
lines changed

9 files changed

+719
-416
lines changed

src/circuits/basic.rs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,37 @@ pub fn selector(a: Wirex, b: Wirex, c: Wirex) -> Circuit {
6464
Circuit::new(vec![g], vec![gate_1, gate_2, gate_3, gate_4])
6565
}
6666

67+
pub fn multiplexer(a: Wires, s: Wires, w: usize) -> Circuit {
68+
let n = 2_usize.pow(w.try_into().unwrap());
69+
assert_eq!(a.len(), n);
70+
assert_eq!(s.len(), w);
71+
72+
if w == 1 {
73+
return selector(a[1].clone(), a[0].clone(), s[0].clone());
74+
}
75+
76+
let mut circuit = Circuit::empty();
77+
78+
let a1 = a[0..(n / 2)].to_vec();
79+
let a2 = a[(n / 2)..n].to_vec();
80+
let su = s[0..w-1].to_vec();
81+
let sv = s[w-1].clone();
82+
83+
let b1 = circuit.extend(multiplexer(a1, su.clone(), w-1))[0].clone();
84+
let b2 = circuit.extend(multiplexer(a2, su.clone(), w-1))[0].clone();
85+
86+
let b = circuit.extend(selector(b2, b1, sv))[0].clone();
87+
88+
circuit.add_wire(b);
89+
90+
circuit
91+
}
92+
6793
#[cfg(test)]
6894
mod tests {
69-
use crate::{bag::*, circuits::basic::{full_adder, full_subtracter, half_adder, half_subtracter, selector}};
95+
use rand::{rng, Rng};
96+
97+
use crate::{bag::*, circuits::basic::{full_adder, full_subtracter, half_adder, half_subtracter, multiplexer, selector}};
7098

7199
#[test]
72100
fn test_half_adder() {
@@ -232,5 +260,36 @@ mod tests {
232260
assert_eq!(d_wire.borrow().get_value(), d);
233261
}
234262
}
263+
264+
#[test]
265+
fn test_multiplexer() {
266+
let w = 5;
267+
let n = 2_usize.pow(w as u32);
268+
let a: Wires = (0..n).map(|_| { Rc::new(RefCell::new(Wire::new())) }).collect();
269+
let s: Wires = (0..w).map(|_| { Rc::new(RefCell::new(Wire::new())) }).collect();
270+
271+
for wire in a.clone() {
272+
wire.borrow_mut().set(rng().random());
273+
}
274+
275+
let mut u = 0;
276+
for wire in s.iter().rev() {
277+
let x = rng().random();
278+
u = u + u + if x {1} else {0};
279+
wire.borrow_mut().set(x);
280+
}
281+
282+
let circuit = multiplexer(a.clone(), s.clone(), w);
283+
circuit.print_gate_type_counts();
284+
285+
for mut gate in circuit.1 {
286+
gate.evaluate();
287+
}
288+
289+
let result = circuit.0[0].clone().borrow().get_value();
290+
let expected = a[u].clone().borrow().get_value();
291+
292+
assert_eq!(result, expected);
293+
}
235294
}
236295

src/circuits/bigint/cmp.rs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use num_bigint::BigUint;
2+
use crate::circuits::basic::multiplexer;
23
use crate::circuits::bigint::utils::{bits_from_biguint, wires_for_u254};
34
use crate::circuits::bigint::U254;
45
use crate::{bag::*, circuits::basic::selector};
@@ -100,11 +101,31 @@ impl<const N_BITS: usize> BigIntImpl<N_BITS> {
100101
circuit.add_wires(result);
101102
circuit
102103
}
104+
105+
pub fn multiplexer(a: Vec<Wires>, s: Wires, w: usize) -> Circuit {
106+
let n = 2_usize.pow(w.try_into().unwrap());
107+
assert_eq!(a.len(), n);
108+
for x in a.clone() {
109+
assert_eq!(x.len(), N_BITS);
110+
}
111+
assert_eq!(s.len(), w);
112+
let mut circuit = Circuit::empty();
113+
114+
for i in 0..N_BITS {
115+
let ith_wires = a.iter().map(|x| { x[i].clone() }).collect();
116+
let ith_result = circuit.extend(multiplexer(ith_wires, s.clone(), w))[0].clone();
117+
circuit.add_wire(ith_result);
118+
}
119+
120+
circuit
121+
}
103122
}
104123

105124
#[cfg(test)]
106125
mod tests {
107126
use std::str::FromStr;
127+
use rand::{rng, Rng};
128+
108129
use crate::circuits::bigint::{utils::{biguint_from_wires, random_u254, wires_set_from_u254}, U254};
109130
use super::*;
110131

@@ -214,4 +235,36 @@ mod tests {
214235
let c = biguint_from_wires(circuit.0);
215236
assert_eq!(c, BigUint::ZERO);
216237
}
238+
239+
#[test]
240+
fn test_multiplexer() {
241+
let w = 5;
242+
let n = 2_usize.pow(w as u32);
243+
let a: Vec<BigUint> = (0..n).map(|_| { random_u254() }).collect();
244+
let s: Wires = (0..w).map(|_| { Rc::new(RefCell::new(Wire::new())) }).collect();
245+
246+
let mut a_wires = Vec::new();
247+
for e in a.clone() {
248+
a_wires.push(wires_set_from_u254(e));
249+
}
250+
251+
let mut u = 0;
252+
for wire in s.iter().rev() {
253+
let x = rng().random();
254+
u = u + u + if x {1} else {0};
255+
wire.borrow_mut().set(x);
256+
}
257+
258+
let circuit = U254::multiplexer(a_wires, s.clone(), w);
259+
circuit.print_gate_type_counts();
260+
261+
for mut gate in circuit.1 {
262+
gate.evaluate();
263+
}
264+
265+
let result = biguint_from_wires(circuit.0);
266+
let expected = a[u].clone();
267+
268+
assert_eq!(result, expected);
269+
}
217270
}

0 commit comments

Comments
 (0)