mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 05:06:44 +01:00
* Added some circuit, evaluation + some layouts * Refactor + memory reduction * Rows -> Dnum, Digits -> Dsize * fix #96 + glwe_packing (indirectly CBT) * clippy
107 lines
3.4 KiB
Rust
107 lines
3.4 KiB
Rust
use poulpy_hal::{
|
|
api::{
|
|
ScratchAvailable, TakeVecZnx, TakeVecZnxDft, VecZnxBigAddSmallInplace, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes,
|
|
VecZnxDftAllocBytes, VecZnxDftApply, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeTmpBytes, VmpApplyDftToDft,
|
|
VmpApplyDftToDftAdd, VmpApplyDftToDftTmpBytes,
|
|
},
|
|
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut, ZnxZero},
|
|
};
|
|
|
|
use crate::{
|
|
TakeGLWECt,
|
|
layouts::{
|
|
GGLWEInfos, GLWECiphertext, GLWECiphertextLayout, GLWEInfos, LWECiphertext, LWEInfos, Rank,
|
|
prepared::GLWEToLWESwitchingKeyPrepared,
|
|
},
|
|
};
|
|
|
|
impl LWECiphertext<Vec<u8>> {
|
|
pub fn from_glwe_scratch_space<B: Backend, OUT, IN, KEY>(
|
|
module: &Module<B>,
|
|
lwe_infos: &OUT,
|
|
glwe_infos: &IN,
|
|
key_infos: &KEY,
|
|
) -> usize
|
|
where
|
|
OUT: LWEInfos,
|
|
IN: GLWEInfos,
|
|
KEY: GGLWEInfos,
|
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
|
{
|
|
let glwe_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
|
n: module.n().into(),
|
|
base2k: lwe_infos.base2k(),
|
|
k: lwe_infos.k(),
|
|
rank: Rank(1),
|
|
};
|
|
|
|
GLWECiphertext::alloc_bytes_with(
|
|
module.n().into(),
|
|
lwe_infos.base2k(),
|
|
lwe_infos.k(),
|
|
1u32.into(),
|
|
) + GLWECiphertext::keyswitch_scratch_space(module, &glwe_layout, glwe_infos, key_infos)
|
|
}
|
|
}
|
|
|
|
impl<DLwe: DataMut> LWECiphertext<DLwe> {
|
|
pub fn sample_extract<DGlwe: DataRef>(&mut self, a: &GLWECiphertext<DGlwe>) {
|
|
#[cfg(debug_assertions)]
|
|
{
|
|
assert!(self.n() <= a.n());
|
|
assert!(self.base2k() == a.base2k());
|
|
}
|
|
|
|
let min_size: usize = self.size().min(a.size());
|
|
let n: usize = self.n().into();
|
|
|
|
self.data.zero();
|
|
(0..min_size).for_each(|i| {
|
|
let data_lwe: &mut [i64] = self.data.at_mut(0, i);
|
|
data_lwe[0] = a.data.at(0, i)[0];
|
|
data_lwe[1..].copy_from_slice(&a.data.at(1, i)[..n]);
|
|
});
|
|
}
|
|
|
|
pub fn from_glwe<DGlwe, DKs, B: Backend>(
|
|
&mut self,
|
|
module: &Module<B>,
|
|
a: &GLWECiphertext<DGlwe>,
|
|
ks: &GLWEToLWESwitchingKeyPrepared<DKs, B>,
|
|
scratch: &mut Scratch<B>,
|
|
) where
|
|
DGlwe: DataRef,
|
|
DKs: DataRef,
|
|
Module<B>: VecZnxDftAllocBytes
|
|
+ VmpApplyDftToDftTmpBytes
|
|
+ VecZnxBigNormalizeTmpBytes
|
|
+ VmpApplyDftToDft<B>
|
|
+ VmpApplyDftToDftAdd<B>
|
|
+ VecZnxDftApply<B>
|
|
+ VecZnxIdftApplyConsume<B>
|
|
+ VecZnxBigAddSmallInplace<B>
|
|
+ VecZnxBigNormalize<B>
|
|
+ VecZnxNormalize<B>
|
|
+ VecZnxNormalizeTmpBytes,
|
|
Scratch<B>: ScratchAvailable + TakeVecZnxDft<B> + TakeGLWECt + TakeVecZnx,
|
|
{
|
|
#[cfg(debug_assertions)]
|
|
{
|
|
assert_eq!(a.n(), module.n() as u32);
|
|
assert_eq!(ks.n(), module.n() as u32);
|
|
assert!(self.n() <= module.n() as u32);
|
|
}
|
|
|
|
let glwe_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
|
n: module.n().into(),
|
|
base2k: self.base2k(),
|
|
k: self.k(),
|
|
rank: Rank(1),
|
|
};
|
|
|
|
let (mut tmp_glwe, scratch_1) = scratch.take_glwe_ct(&glwe_layout);
|
|
tmp_glwe.keyswitch(module, a, &ks.0, scratch_1);
|
|
self.sample_extract(&tmp_glwe);
|
|
}
|
|
}
|