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 itertools::Itertools;
  2use poulpy_core::layouts::prepared::GGSWCiphertextPreparedToRef;
  3use poulpy_hal::layouts::{Backend, DataMut, DataRef, Module, Scratch};
  4
  5use crate::tfhe::bdd_arithmetic::{
  6    BitCircuitInfo, Circuit, CircuitExecute, FheUintBlocks, FheUintBlocksPrep, UnsignedInteger, circuits,
  7};
  8
  9/// Operations Z x Z -> Z
 10pub(crate) struct Circuits2WTo1W<C: BitCircuitInfo + 'static, const WORD_SIZE: usize>(pub &'static Circuit<C, WORD_SIZE>);
 11
 12pub trait EvalBDD2WTo1W<BE: Backend, T: UnsignedInteger> {
 13    fn eval_bdd_2w_to_1w<R, A, B>(
 14        &self,
 15        module: &Module<BE>,
 16        out: &mut FheUintBlocks<R, T>,
 17        a: &FheUintBlocksPrep<A, BE, T>,
 18        b: &FheUintBlocksPrep<B, BE, T>,
 19        scratch: &mut Scratch<BE>,
 20    ) where
 21        R: DataMut,
 22        A: DataRef,
 23        B: DataRef;
 24}
 25
 26impl<C: BitCircuitInfo + 'static, const WORD_SIZE: usize, BE: Backend, T: UnsignedInteger> EvalBDD2WTo1W<BE, T>
 27    for Circuits2WTo1W<C, WORD_SIZE>
 28where
 29    Circuit<C, WORD_SIZE>: CircuitExecute<BE, T>,
 30{
 31    fn eval_bdd_2w_to_1w<R, A, B>(
 32        &self,
 33        module: &Module<BE>,
 34        out: &mut FheUintBlocks<R, T>,
 35        a: &FheUintBlocksPrep<A, BE, T>,
 36        b: &FheUintBlocksPrep<B, BE, T>,
 37        scratch: &mut Scratch<BE>,
 38    ) where
 39        R: DataMut,
 40        A: DataRef,
 41        B: DataRef,
 42    {
 43        eval_bdd_2w_to_1w(module, self.0, out, a, b, scratch);
 44    }
 45}
 46
 47pub fn eval_bdd_2w_to_1w<R: DataMut, A: DataRef, B: DataRef, T: UnsignedInteger, C: CircuitExecute<BE, T>, BE: Backend>(
 48    module: &Module<BE>,
 49    circuit: &C,
 50    out: &mut FheUintBlocks<R, T>,
 51    a: &FheUintBlocksPrep<A, BE, T>,
 52    b: &FheUintBlocksPrep<B, BE, T>,
 53    scratch: &mut Scratch<BE>,
 54) {
 55    #[cfg(debug_assertions)]
 56    {
 57        assert_eq!(out.blocks.len(), T::WORD_SIZE);
 58        assert_eq!(b.blocks.len(), T::WORD_SIZE);
 59        assert_eq!(b.blocks.len(), T::WORD_SIZE);
 60    }
 61
 62    // Collects inputs into a single array
 63    let inputs: Vec<&dyn GGSWCiphertextPreparedToRef<BE>> = a
 64        .blocks
 65        .iter()
 66        .map(|x| x as &dyn GGSWCiphertextPreparedToRef<BE>)
 67        .chain(
 68            b.blocks
 69                .iter()
 70                .map(|x| x as &dyn GGSWCiphertextPreparedToRef<BE>),
 71        )
 72        .collect_vec();
 73
 74    // Evaluates out[i] = circuit[i](a, b)
 75    circuit.execute(module, &mut out.blocks, &inputs, scratch);
 76}
 77
 78#[macro_export]
 79macro_rules! define_bdd_2w_to_1w_trait {
 80    ($(#[$meta:meta])* $vis:vis $trait_name:ident, $method_name:ident) => {
 81        $(#[$meta])*
 82        $vis trait $trait_name<T: UnsignedInteger, BE: Backend> {
 83            fn $method_name<A, B>(
 84                &mut self,
 85                module: &Module<BE>,
 86                a: &FheUintBlocksPrep<A, BE, T>,
 87                b: &FheUintBlocksPrep<B, BE, T>,
 88                scratch: &mut Scratch<BE>,
 89            ) where
 90                A: DataRef,
 91                B: DataRef;
 92        }
 93    };
 94}
 95
 96#[macro_export]
 97macro_rules! impl_bdd_2w_to_1w_trait {
 98    ($trait_name:ident, $method_name:ident, $ty:ty, $n:literal, $circuit_ty:ty, $output_circuits:path) => {
 99        impl<D: DataMut, BE: Backend> $trait_name<$ty, BE> for FheUintBlocks<D, $ty>
100        where
101            Circuits2WTo1W<$circuit_ty, $n>: EvalBDD2WTo1W<BE, $ty>,
102        {
103            fn $method_name<A, B>(
104                &mut self,
105                module: &Module<BE>,
106                a: &FheUintBlocksPrep<A, BE, $ty>,
107                b: &FheUintBlocksPrep<B, BE, $ty>,
108                scratch: &mut Scratch<BE>,
109            ) where
110                A: DataRef,
111                B: DataRef,
112            {
113                const OP: Circuits2WTo1W<$circuit_ty, $n> = Circuits2WTo1W::<$circuit_ty, $n>(&$output_circuits);
114
115                OP.eval_bdd_2w_to_1w(module, self, a, b, scratch);
116            }
117        }
118    };
119}
120
121define_bdd_2w_to_1w_trait!(pub Add, add);
122define_bdd_2w_to_1w_trait!(pub Sub, sub);
123define_bdd_2w_to_1w_trait!(pub Sll, sll);
124define_bdd_2w_to_1w_trait!(pub Sra, sra);
125define_bdd_2w_to_1w_trait!(pub Srl, srl);
126define_bdd_2w_to_1w_trait!(pub Slt, slt);
127define_bdd_2w_to_1w_trait!(pub Sltu, sltu);
128define_bdd_2w_to_1w_trait!(pub Or, or);
129define_bdd_2w_to_1w_trait!(pub And, and);
130define_bdd_2w_to_1w_trait!(pub Xor, xor);
131
132impl_bdd_2w_to_1w_trait!(
133    Add,
134    add,
135    u32,
136    32,
137    circuits::u32::add_codegen::AnyBitCircuit,
138    circuits::u32::add_codegen::OUTPUT_CIRCUITS
139);
140
141impl_bdd_2w_to_1w_trait!(
142    Sub,
143    sub,
144    u32,
145    32,
146    circuits::u32::sub_codegen::AnyBitCircuit,
147    circuits::u32::sub_codegen::OUTPUT_CIRCUITS
148);
149
150impl_bdd_2w_to_1w_trait!(
151    Sll,
152    sll,
153    u32,
154    32,
155    circuits::u32::sll_codegen::AnyBitCircuit,
156    circuits::u32::sll_codegen::OUTPUT_CIRCUITS
157);
158
159impl_bdd_2w_to_1w_trait!(
160    Sra,
161    sra,
162    u32,
163    32,
164    circuits::u32::sra_codegen::AnyBitCircuit,
165    circuits::u32::sra_codegen::OUTPUT_CIRCUITS
166);
167
168impl_bdd_2w_to_1w_trait!(
169    Srl,
170    srl,
171    u32,
172    32,
173    circuits::u32::srl_codegen::AnyBitCircuit,
174    circuits::u32::srl_codegen::OUTPUT_CIRCUITS
175);
176
177impl_bdd_2w_to_1w_trait!(
178    Slt,
179    slt,
180    u32,
181    1,
182    circuits::u32::slt_codegen::AnyBitCircuit,
183    circuits::u32::slt_codegen::OUTPUT_CIRCUITS
184);
185
186impl_bdd_2w_to_1w_trait!(
187    Sltu,
188    sltu,
189    u32,
190    1,
191    circuits::u32::sltu_codegen::AnyBitCircuit,
192    circuits::u32::sltu_codegen::OUTPUT_CIRCUITS
193);
194
195impl_bdd_2w_to_1w_trait!(
196    And,
197    and,
198    u32,
199    32,
200    circuits::u32::and_codegen::AnyBitCircuit,
201    circuits::u32::and_codegen::OUTPUT_CIRCUITS
202);
203
204impl_bdd_2w_to_1w_trait!(
205    Or,
206    or,
207    u32,
208    1,
209    circuits::u32::or_codegen::AnyBitCircuit,
210    circuits::u32::or_codegen::OUTPUT_CIRCUITS
211);
212
213impl_bdd_2w_to_1w_trait!(
214    Xor,
215    xor,
216    u32,
217    1,
218    circuits::u32::xor_codegen::AnyBitCircuit,
219    circuits::u32::xor_codegen::OUTPUT_CIRCUITS
220);