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