arnaucube
arnaucube/poulpyPublic Self-hosted repository
poulpy/poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rs
poulpy-schemes/src/tfhe/bdd_arithmetic/bdd_2w_to_1w.rsRaw
  1use std::marker::PhantomData;
  2
  3use poulpy_core::{GLWECopy, GLWEPacking, ScratchTakeCore, layouts::GGSWPrepared};
  4use poulpy_hal::{
  5    api::ModuleLogN,
  6    layouts::{Backend, DataMut, DataRef, Module, Scratch},
  7};
  8
  9use crate::tfhe::{
 10    bdd_arithmetic::{
 11        BDDKeyPrepared, BitSize, ExecuteBDDCircuit, FheUint, FheUintPrepared, GetBitCircuitInfo, GetGGSWBit, UnsignedInteger,
 12        circuits,
 13    },
 14    blind_rotation::BlindRotationAlgo,
 15};
 16
 17impl<T: UnsignedInteger, BE: Backend> ExecuteBDDCircuit2WTo1W<T, BE> for Module<BE> where
 18    Self: Sized + ExecuteBDDCircuit<T, BE> + GLWEPacking<BE> + GLWECopy
 19{
 20}
 21
 22pub trait ExecuteBDDCircuit2WTo1W<T: UnsignedInteger, BE: Backend>
 23where
 24    Self: Sized + ModuleLogN + ExecuteBDDCircuit<T, BE> + GLWEPacking<BE> + GLWECopy,
 25{
 26    /// Operations Z x Z -> Z
 27    fn execute_bdd_circuit_2w_to_1w<R, C, A, B, DK, BRA>(
 28        &self,
 29        out: &mut FheUint<R, T>,
 30        circuit: &C,
 31        a: &FheUintPrepared<A, T, BE>,
 32        b: &FheUintPrepared<B, T, BE>,
 33        key: &BDDKeyPrepared<DK, BRA, BE>,
 34        scratch: &mut Scratch<BE>,
 35    ) where
 36        BRA: BlindRotationAlgo,
 37        DK: DataRef,
 38        C: GetBitCircuitInfo<T>,
 39        R: DataMut,
 40        A: DataRef,
 41        B: DataRef,
 42        Scratch<BE>: ScratchTakeCore<BE>,
 43    {
 44        // Collects inputs into a single array
 45        let inputs: Vec<&dyn GetGGSWBit<BE>> = [a as &dyn GetGGSWBit<BE>, b as &dyn GetGGSWBit<BE>].to_vec();
 46        let helper: FheUintHelper<'_, T, BE> = FheUintHelper {
 47            data: inputs,
 48            _phantom: PhantomData,
 49        };
 50
 51        let (mut out_bits, scratch_1) = scratch.take_glwe_slice(T::BITS as usize, out);
 52
 53        // Evaluates out[i] = circuit[i](a, b)
 54        self.execute_bdd_circuit(&mut out_bits, &helper, circuit, scratch_1);
 55
 56        // Repacks the bits
 57        out.pack(self, out_bits, &key.cbt.atk, scratch_1);
 58    }
 59}
 60
 61struct FheUintHelper<'a, T: UnsignedInteger, BE: Backend> {
 62    data: Vec<&'a dyn GetGGSWBit<BE>>,
 63    _phantom: PhantomData<T>,
 64}
 65
 66impl<'a, T: UnsignedInteger, BE: Backend> GetGGSWBit<BE> for FheUintHelper<'a, T, BE> {
 67    fn get_bit(&self, bit: usize) -> GGSWPrepared<&[u8], BE> {
 68        let lo: usize = bit % T::BITS as usize;
 69        let hi: usize = bit / T::BITS as usize;
 70        self.data[hi].get_bit(lo)
 71    }
 72}
 73
 74impl<'a, T: UnsignedInteger, BE: Backend> BitSize for FheUintHelper<'a, T, BE> {
 75    fn bit_size(&self) -> usize {
 76        T::BITS as usize * self.data.len()
 77    }
 78}
 79
 80pub struct JoinedBits<A, B> {
 81    pub lo: A,
 82    pub hi: B,
 83    pub split: usize, // 32 in your example
 84}
 85
 86impl<A, B, BE> GetGGSWBit<BE> for JoinedBits<A, B>
 87where
 88    BE: Backend,
 89    A: GetGGSWBit<BE>,
 90    B: GetGGSWBit<BE>,
 91{
 92    fn get_bit(&self, bit: usize) -> GGSWPrepared<&[u8], BE> {
 93        if bit < self.split {
 94            self.lo.get_bit(bit)
 95        } else {
 96            self.hi.get_bit(bit - self.split)
 97        }
 98    }
 99}
100
101#[macro_export]
102macro_rules! define_bdd_2w_to_1w_trait {
103    ($(#[$meta:meta])* $vis:vis $trait_name:ident, $method_name:ident) => {
104        $(#[$meta])*
105        $vis trait $trait_name<T: UnsignedInteger, BE: Backend> {
106            fn $method_name<A, M, K, BRA, B>(
107                &mut self,
108                module: &M,
109                a: &FheUintPrepared<A, T, BE>,
110                b: &FheUintPrepared<B, T, BE>,
111                key: &BDDKeyPrepared<K, BRA, BE>,
112                scratch: &mut Scratch<BE>,
113            ) where
114                M: ExecuteBDDCircuit2WTo1W<T, BE>,
115                A: DataRef,
116                B: DataRef,
117                K: DataRef,
118                BRA: BlindRotationAlgo,
119                Scratch<BE>: ScratchTakeCore<BE>;
120        }
121    };
122}
123
124#[macro_export]
125macro_rules! impl_bdd_2w_to_1w_trait {
126    ($trait_name:ident, $method_name:ident, $ty:ty, $n:literal, $circuit_ty:ty, $output_circuits:path) => {
127        impl<D: DataMut, BE: Backend> $trait_name<$ty, BE> for FheUint<D, $ty> {
128            fn $method_name<A, M, K, BRA, B>(
129                &mut self,
130                module: &M,
131                a: &FheUintPrepared<A, $ty, BE>,
132                b: &FheUintPrepared<B, $ty, BE>,
133                key: &BDDKeyPrepared<K, BRA, BE>,
134                scratch: &mut Scratch<BE>,
135            ) where
136                M: ExecuteBDDCircuit2WTo1W<$ty, BE>,
137                A: DataRef,
138                B: DataRef,
139                K: DataRef,
140                BRA: BlindRotationAlgo,
141                Scratch<BE>: ScratchTakeCore<BE>,
142            {
143                module.execute_bdd_circuit_2w_to_1w(self, &$output_circuits, a, b, key, scratch)
144            }
145        }
146    };
147}
148
149define_bdd_2w_to_1w_trait!(pub Add, add);
150define_bdd_2w_to_1w_trait!(pub Sub, sub);
151define_bdd_2w_to_1w_trait!(pub Sll, sll);
152define_bdd_2w_to_1w_trait!(pub Sra, sra);
153define_bdd_2w_to_1w_trait!(pub Srl, srl);
154define_bdd_2w_to_1w_trait!(pub Slt, slt);
155define_bdd_2w_to_1w_trait!(pub Sltu, sltu);
156define_bdd_2w_to_1w_trait!(pub Or, or);
157define_bdd_2w_to_1w_trait!(pub And, and);
158define_bdd_2w_to_1w_trait!(pub Xor, xor);
159
160impl_bdd_2w_to_1w_trait!(
161    Add,
162    add,
163    u32,
164    32,
165    circuits::u32::add_codegen::AnyBitCircuit,
166    circuits::u32::add_codegen::OUTPUT_CIRCUITS
167);
168
169impl_bdd_2w_to_1w_trait!(
170    Sub,
171    sub,
172    u32,
173    32,
174    circuits::u32::sub_codegen::AnyBitCircuit,
175    circuits::u32::sub_codegen::OUTPUT_CIRCUITS
176);
177
178impl_bdd_2w_to_1w_trait!(
179    Sll,
180    sll,
181    u32,
182    32,
183    circuits::u32::sll_codegen::AnyBitCircuit,
184    circuits::u32::sll_codegen::OUTPUT_CIRCUITS
185);
186
187impl_bdd_2w_to_1w_trait!(
188    Sra,
189    sra,
190    u32,
191    32,
192    circuits::u32::sra_codegen::AnyBitCircuit,
193    circuits::u32::sra_codegen::OUTPUT_CIRCUITS
194);
195
196impl_bdd_2w_to_1w_trait!(
197    Srl,
198    srl,
199    u32,
200    32,
201    circuits::u32::srl_codegen::AnyBitCircuit,
202    circuits::u32::srl_codegen::OUTPUT_CIRCUITS
203);
204
205impl_bdd_2w_to_1w_trait!(
206    Slt,
207    slt,
208    u32,
209    1,
210    circuits::u32::slt_codegen::AnyBitCircuit,
211    circuits::u32::slt_codegen::OUTPUT_CIRCUITS
212);
213
214impl_bdd_2w_to_1w_trait!(
215    Sltu,
216    sltu,
217    u32,
218    1,
219    circuits::u32::sltu_codegen::AnyBitCircuit,
220    circuits::u32::sltu_codegen::OUTPUT_CIRCUITS
221);
222
223impl_bdd_2w_to_1w_trait!(
224    And,
225    and,
226    u32,
227    32,
228    circuits::u32::and_codegen::AnyBitCircuit,
229    circuits::u32::and_codegen::OUTPUT_CIRCUITS
230);
231
232impl_bdd_2w_to_1w_trait!(
233    Or,
234    or,
235    u32,
236    32,
237    circuits::u32::or_codegen::AnyBitCircuit,
238    circuits::u32::or_codegen::OUTPUT_CIRCUITS
239);
240
241impl_bdd_2w_to_1w_trait!(
242    Xor,
243    xor,
244    u32,
245    32,
246    circuits::u32::xor_codegen::AnyBitCircuit,
247    circuits::u32::xor_codegen::OUTPUT_CIRCUITS
248);