Skip to main content

fancy_garbling/fancy/
binary.rs

1use crate::{
2    FancyBinary, FancyEncode, FancyOutput,
3    fancy::{
4        HasModulus,
5        bundle::{Bundle, BundleGadgets},
6    },
7    util,
8};
9use itertools::Itertools;
10#[cfg(feature = "serde")]
11use serde::{Deserialize, Serialize};
12use std::ops::{Deref, DerefMut};
13use swanky_channel::Channel;
14
15/// Bundle which is explicitly binary representation.
16#[derive(Clone)]
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
18pub struct BinaryBundle<W>(Bundle<W>);
19
20impl<W: Clone + HasModulus> BinaryBundle<W> {
21    /// Create a new binary bundle from a vector of wires.
22    pub fn new(ws: Vec<W>) -> BinaryBundle<W> {
23        BinaryBundle(Bundle::new(ws))
24    }
25}
26
27impl<W: Clone + HasModulus> Deref for BinaryBundle<W> {
28    type Target = Bundle<W>;
29
30    fn deref(&self) -> &Bundle<W> {
31        &self.0
32    }
33}
34
35impl<W: Clone + HasModulus> DerefMut for BinaryBundle<W> {
36    fn deref_mut(&mut self) -> &mut Bundle<W> {
37        &mut self.0
38    }
39}
40
41impl<W: Clone + HasModulus> From<Bundle<W>> for BinaryBundle<W> {
42    fn from(b: Bundle<W>) -> BinaryBundle<W> {
43        debug_assert!(b.moduli().iter().all(|&p| p == 2));
44        BinaryBundle(b)
45    }
46}
47
48impl<F: FancyBinary + FancyEncode + FancyOutput> BinaryGadgets for F {}
49
50/// Extension trait for `Fancy` providing gadgets that operate over bundles of mod2 wires.
51pub trait BinaryGadgets: BundleGadgets + FancyEncode {
52    /// Encode a binary input bundle.
53    fn bin_encode(
54        &mut self,
55        value: u128,
56        nbits: usize,
57        channel: &mut Channel,
58    ) -> swanky_error::Result<BinaryBundle<Self::Item>> {
59        let xs = util::u128_to_bits(value, nbits);
60        self.encode_many(&xs, &vec![2; nbits], channel)
61            .map(BinaryBundle::new)
62    }
63
64    /// Receive an binary input bundle.
65    fn bin_receive(
66        &mut self,
67        nbits: usize,
68        channel: &mut Channel,
69    ) -> swanky_error::Result<BinaryBundle<Self::Item>> {
70        self.receive_many(&vec![2; nbits], channel)
71            .map(BinaryBundle::new)
72    }
73
74    /// Encode many binary input bundles.
75    fn bin_encode_many(
76        &mut self,
77        values: &[u128],
78        nbits: usize,
79        channel: &mut Channel,
80    ) -> swanky_error::Result<Vec<BinaryBundle<Self::Item>>> {
81        let xs = values
82            .iter()
83            .flat_map(|x| util::u128_to_bits(*x, nbits))
84            .collect_vec();
85        let mut wires = self.encode_many(&xs, &vec![2; values.len() * nbits], channel)?;
86        let buns = (0..values.len())
87            .map(|_| {
88                let ws = wires.drain(0..nbits).collect_vec();
89                BinaryBundle::new(ws)
90            })
91            .collect_vec();
92        Ok(buns)
93    }
94
95    /// Receive many binary input bundles.
96    fn bin_receive_many(
97        &mut self,
98        ninputs: usize,
99        nbits: usize,
100        channel: &mut Channel,
101    ) -> swanky_error::Result<Vec<BinaryBundle<Self::Item>>> {
102        let mut wires = self.receive_many(&vec![2; ninputs * nbits], channel)?;
103        let buns = (0..ninputs)
104            .map(|_| {
105                let ws = wires.drain(0..nbits).collect_vec();
106                BinaryBundle::new(ws)
107            })
108            .collect_vec();
109        Ok(buns)
110    }
111
112    /// Output a binary bundle and interpret the result as a `u128`.
113    fn bin_output(
114        &mut self,
115        x: &BinaryBundle<Self::Item>,
116        channel: &mut Channel,
117    ) -> swanky_error::Result<Option<u128>> {
118        Ok(self
119            .output_bundle(x, channel)?
120            .map(|bs| util::u128_from_bits(&bs)))
121    }
122
123    /// Output a slice of binary bundles and interpret the results as a `u128`.
124    fn bin_outputs(
125        &mut self,
126        xs: &[BinaryBundle<Self::Item>],
127        channel: &mut Channel,
128    ) -> swanky_error::Result<Option<Vec<u128>>> {
129        let mut zs = Vec::with_capacity(xs.len());
130        for x in xs.iter() {
131            let z = self.bin_output(x, channel)?;
132            zs.push(z);
133        }
134        Ok(zs.into_iter().collect())
135    }
136}