fancy_garbling/circuits/binary/
binary_constant.rs1use crate::{BinaryBundle, Fancy, circuit::Circuit, util::u128_to_bits};
2use swanky_channel::Channel;
3use swanky_error::Result;
4
5pub struct BinaryConstant<F: Fancy> {
10 value: u128,
11 nbits: usize,
12 zero: Option<F::Item>,
13 one: Option<F::Item>,
14}
15
16impl<F: Fancy> BinaryConstant<F> {
17 pub fn new(value: u128, nbits: usize) -> Self {
19 Self::new_with_constants(value, nbits, None, None)
20 }
21
22 pub fn new_with_constants(
25 value: u128,
26 nbits: usize,
27 zero: Option<F::Item>,
28 one: Option<F::Item>,
29 ) -> Self {
30 Self {
31 value,
32 nbits,
33 zero,
34 one,
35 }
36 }
37}
38
39impl<F: Fancy> Circuit<F> for BinaryConstant<F> {
40 type Input = ();
41 type Output = BinaryBundle<F::Item>;
42
43 fn execute(
44 &self,
45 backend: &mut F,
46 _: Self::Input,
47 channel: &mut Channel,
48 ) -> Result<Self::Output> {
49 let xs = u128_to_bits(self.value, self.nbits);
50 xs.into_iter()
51 .map(|x| match x != 0 {
52 true => {
53 if let Some(one) = &self.one {
54 Ok(one.clone())
55 } else {
56 backend.constant(1, 2, channel)
57 }
58 }
59 false => {
60 if let Some(zero) = &self.zero {
61 Ok(zero.clone())
62 } else {
63 backend.constant(0, 2, channel)
64 }
65 }
66 })
67 .collect::<Result<_>>()
68 .map(BinaryBundle::new)
69 }
70}
71
72pub mod test {
73 use super::*;
74 use crate::circuit::CircuitInputMapper;
75
76 pub struct TestBinaryConstant(pub u128, pub usize);
78 impl<F: Fancy> Circuit<F> for TestBinaryConstant {
79 type Input = <BinaryConstant<F> as Circuit<F>>::Input;
80 type Output = <BinaryConstant<F> as Circuit<F>>::Output;
81
82 fn execute(
83 &self,
84 backend: &mut F,
85 inputs: Self::Input,
86 channel: &mut swanky_channel::Channel,
87 ) -> Result<Self::Output> {
88 BinaryConstant::new(self.0, self.1).execute(backend, inputs, channel)
89 }
90 }
91
92 impl<F: Fancy> CircuitInputMapper<F> for TestBinaryConstant {
93 fn map(&self, inputs: Vec<<F as Fancy>::Item>) -> Self::Input {
94 assert!(inputs.is_empty());
95 }
96
97 fn ninputs(&self) -> usize {
98 0
99 }
100
101 fn modulus(&self, _: usize) -> u16 {
102 2
103 }
104 }
105
106 #[test]
107 fn binary_constant() {
108 use crate::dummy::{Dummy, DummyVal};
109 use rand::Rng;
110
111 let mut rng = rand::thread_rng();
112 for _ in 0..16 {
113 let nbits = 1 + rng.r#gen::<usize>() % 127;
114 let value = rng.r#gen::<u128>() % (nbits as u128);
115 let c = TestBinaryConstant(value, nbits);
116 let output = Dummy::eval(&c, ()).unwrap();
117 assert_eq!(DummyVal::from_binary(&output), value);
118 }
119 }
120}