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::GGSWPreparedToRef;
  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 GGSWPreparedToRef<BE>> = a
 64        .blocks
 65        .iter()
 66        .map(|x| x as &dyn GGSWPreparedToRef<BE>)
 67        .chain(b.blocks.iter().map(|x| x as &dyn GGSWPreparedToRef<BE>))
 68        .collect_vec();
 69
 70    // Evaluates out[i] = circuit[i](a, b)
 71    circuit.execute(module, &mut out.blocks, &inputs, scratch);
 72}
 73
 74#[macro_export]
 75macro_rules! define_bdd_2w_to_1w_trait {
 76    ($(#[$meta:meta])* $vis:vis $trait_name:ident, $method_name:ident) => {
 77        $(#[$meta])*
 78        $vis trait $trait_name<T: UnsignedInteger, BE: Backend> {
 79            fn $method_name<A, B>(
 80                &mut self,
 81                module: &Module<BE>,
 82                a: &FheUintBlocksPrep<A, BE, T>,
 83                b: &FheUintBlocksPrep<B, BE, T>,
 84                scratch: &mut Scratch<BE>,
 85            ) where
 86                A: DataRef,
 87                B: DataRef;
 88        }
 89    };
 90}
 91
 92#[macro_export]
 93macro_rules! impl_bdd_2w_to_1w_trait {
 94    ($trait_name:ident, $method_name:ident, $ty:ty, $n:literal, $circuit_ty:ty, $output_circuits:path) => {
 95        impl<D: DataMut, BE: Backend> $trait_name<$ty, BE> for FheUintBlocks<D, $ty>
 96        where
 97            Circuits2WTo1W<$circuit_ty, $n>: EvalBDD2WTo1W<BE, $ty>,
 98        {
 99            fn $method_name<A, B>(
100                &mut self,
101                module: &Module<BE>,
102                a: &FheUintBlocksPrep<A, BE, $ty>,
103                b: &FheUintBlocksPrep<B, BE, $ty>,
104                scratch: &mut Scratch<BE>,
105            ) where
106                A: DataRef,
107                B: DataRef,
108            {
109                const OP: Circuits2WTo1W<$circuit_ty, $n> = Circuits2WTo1W::<$circuit_ty, $n>(&$output_circuits);
110
111                OP.eval_bdd_2w_to_1w(module, self, a, b, scratch);
112            }
113        }
114    };
115}
116
117define_bdd_2w_to_1w_trait!(pub Add, add);
118define_bdd_2w_to_1w_trait!(pub Sub, sub);
119define_bdd_2w_to_1w_trait!(pub Sll, sll);
120define_bdd_2w_to_1w_trait!(pub Sra, sra);
121define_bdd_2w_to_1w_trait!(pub Srl, srl);
122define_bdd_2w_to_1w_trait!(pub Slt, slt);
123define_bdd_2w_to_1w_trait!(pub Sltu, sltu);
124define_bdd_2w_to_1w_trait!(pub Or, or);
125define_bdd_2w_to_1w_trait!(pub And, and);
126define_bdd_2w_to_1w_trait!(pub Xor, xor);
127
128impl_bdd_2w_to_1w_trait!(
129    Add,
130    add,
131    u32,
132    32,
133    circuits::u32::add_codegen::AnyBitCircuit,
134    circuits::u32::add_codegen::OUTPUT_CIRCUITS
135);
136
137impl_bdd_2w_to_1w_trait!(
138    Sub,
139    sub,
140    u32,
141    32,
142    circuits::u32::sub_codegen::AnyBitCircuit,
143    circuits::u32::sub_codegen::OUTPUT_CIRCUITS
144);
145
146impl_bdd_2w_to_1w_trait!(
147    Sll,
148    sll,
149    u32,
150    32,
151    circuits::u32::sll_codegen::AnyBitCircuit,
152    circuits::u32::sll_codegen::OUTPUT_CIRCUITS
153);
154
155impl_bdd_2w_to_1w_trait!(
156    Sra,
157    sra,
158    u32,
159    32,
160    circuits::u32::sra_codegen::AnyBitCircuit,
161    circuits::u32::sra_codegen::OUTPUT_CIRCUITS
162);
163
164impl_bdd_2w_to_1w_trait!(
165    Srl,
166    srl,
167    u32,
168    32,
169    circuits::u32::srl_codegen::AnyBitCircuit,
170    circuits::u32::srl_codegen::OUTPUT_CIRCUITS
171);
172
173impl_bdd_2w_to_1w_trait!(
174    Slt,
175    slt,
176    u32,
177    1,
178    circuits::u32::slt_codegen::AnyBitCircuit,
179    circuits::u32::slt_codegen::OUTPUT_CIRCUITS
180);
181
182impl_bdd_2w_to_1w_trait!(
183    Sltu,
184    sltu,
185    u32,
186    1,
187    circuits::u32::sltu_codegen::AnyBitCircuit,
188    circuits::u32::sltu_codegen::OUTPUT_CIRCUITS
189);
190
191impl_bdd_2w_to_1w_trait!(
192    And,
193    and,
194    u32,
195    32,
196    circuits::u32::and_codegen::AnyBitCircuit,
197    circuits::u32::and_codegen::OUTPUT_CIRCUITS
198);
199
200impl_bdd_2w_to_1w_trait!(
201    Or,
202    or,
203    u32,
204    32,
205    circuits::u32::or_codegen::AnyBitCircuit,
206    circuits::u32::or_codegen::OUTPUT_CIRCUITS
207);
208
209impl_bdd_2w_to_1w_trait!(
210    Xor,
211    xor,
212    u32,
213    32,
214    circuits::u32::xor_codegen::AnyBitCircuit,
215    circuits::u32::xor_codegen::OUTPUT_CIRCUITS
216);