This commit is contained in:
Pro7ech
2025-10-13 12:14:11 +02:00
parent 662e533eac
commit cf377ff243
94 changed files with 1892 additions and 1235 deletions

View File

@@ -1,23 +1,22 @@
use poulpy_hal::{
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare, VmpPrepareTmpBytes},
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat, ZnxInfos},
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat, VmpPMatToMut, VmpPMatToRef, ZnxInfos},
oep::VmpPMatAllocBytesImpl,
};
use crate::layouts::{
Base2K, BuildError, Degree, Dnum, Dsize, GGLWECiphertext, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
Base2K, BuildError, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GGLWEToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
};
#[derive(PartialEq, Eq)]
pub struct GGLWECiphertextPrepared<D: Data, B: Backend> {
pub struct GGLWEPrepared<D: Data, B: Backend> {
pub(crate) data: VmpPMat<D, B>,
pub(crate) k: TorusPrecision,
pub(crate) base2k: Base2K,
pub(crate) dsize: Dsize,
}
impl<D: Data, B: Backend> LWEInfos for GGLWECiphertextPrepared<D, B> {
impl<D: Data, B: Backend> LWEInfos for GGLWEPrepared<D, B> {
fn n(&self) -> Degree {
Degree(self.data.n() as u32)
}
@@ -35,13 +34,13 @@ impl<D: Data, B: Backend> LWEInfos for GGLWECiphertextPrepared<D, B> {
}
}
impl<D: Data, B: Backend> GLWEInfos for GGLWECiphertextPrepared<D, B> {
impl<D: Data, B: Backend> GLWEInfos for GGLWEPrepared<D, B> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data, B: Backend> GGLWEInfos for GGLWECiphertextPrepared<D, B> {
impl<D: Data, B: Backend> GGLWEInfos for GGLWEPrepared<D, B> {
fn rank_in(&self) -> Rank {
Rank(self.data.cols_in() as u32)
}
@@ -59,17 +58,17 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWECiphertextPrepared<D, B> {
}
}
pub struct GGLWECiphertextPreparedBuilder<D: Data, B: Backend> {
pub struct GGLWEPreparedBuilder<D: Data, B: Backend> {
data: Option<VmpPMat<D, B>>,
base2k: Option<Base2K>,
k: Option<TorusPrecision>,
dsize: Option<Dsize>,
}
impl<D: Data, B: Backend> GGLWECiphertextPrepared<D, B> {
impl<D: Data, B: Backend> GGLWEPrepared<D, B> {
#[inline]
pub fn builder() -> GGLWECiphertextPreparedBuilder<D, B> {
GGLWECiphertextPreparedBuilder {
pub fn builder() -> GGLWEPreparedBuilder<D, B> {
GGLWEPreparedBuilder {
data: None,
base2k: None,
k: None,
@@ -78,7 +77,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPrepared<D, B> {
}
}
impl<B: Backend> GGLWECiphertextPreparedBuilder<Vec<u8>, B> {
impl<B: Backend> GGLWEPreparedBuilder<Vec<u8>, B> {
#[inline]
pub fn layout<A>(mut self, infos: &A) -> Self
where
@@ -99,7 +98,7 @@ impl<B: Backend> GGLWECiphertextPreparedBuilder<Vec<u8>, B> {
}
}
impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
impl<D: Data, B: Backend> GGLWEPreparedBuilder<D, B> {
#[inline]
pub fn data(mut self, data: VmpPMat<D, B>) -> Self {
self.data = Some(data);
@@ -122,7 +121,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
self
}
pub fn build(self) -> Result<GGLWECiphertextPrepared<D, B>, BuildError> {
pub fn build(self) -> Result<GGLWEPrepared<D, B>, BuildError> {
let data: VmpPMat<D, B> = self.data.ok_or(BuildError::MissingData)?;
let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?;
let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?;
@@ -152,7 +151,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
return Err(BuildError::ZeroLimbs);
}
Ok(GGLWECiphertextPrepared {
Ok(GGLWEPrepared {
data,
base2k,
k,
@@ -161,7 +160,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
}
}
impl<B: Backend> GGLWECiphertextPrepared<Vec<u8>, B> {
impl<B: Backend> GGLWEPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGLWEInfos,
@@ -260,12 +259,21 @@ impl<B: Backend> GGLWECiphertextPrepared<Vec<u8>, B> {
}
}
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWECiphertextPrepared<Vec<u8>, B>
pub trait GGLWEPrepareTmpBytes {
fn gglwe_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos;
}
impl<B: Backend> GGLWEPrepareTmpBytes for Module<B>
where
Module<B>: VmpPrepareTmpBytes,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
module.vmp_prepare_tmp_bytes(
fn gglwe_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
self.vmp_prepare_tmp_bytes(
infos.dnum().into(),
infos.rank_in().into(),
(infos.rank() + 1).into(),
@@ -274,25 +282,106 @@ where
}
}
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWECiphertext<DR>> for GGLWECiphertextPrepared<D, B>
where
Module<B>: VmpPrepare<B>,
{
fn prepare(&mut self, module: &Module<B>, other: &GGLWECiphertext<DR>, scratch: &mut Scratch<B>) {
module.vmp_prepare(&mut self.data, &other.data, scratch);
self.k = other.k;
self.base2k = other.base2k;
self.dsize = other.dsize;
impl<B: Backend> GGLWEPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes(&self, module: &Module<B>)
where
Module<B>: GGLWEPrepareTmpBytes,
{
module.gglwe_prepare_tmp_bytes(self)
}
}
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWECiphertextPrepared<Vec<u8>, B>> for GGLWECiphertext<D>
pub trait GGLWEPrepare<B: Backend> {
fn gglwe_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GGLWEPreparedToMut<B>,
O: GGLWEToRef;
}
impl<B: Backend> GGLWEPrepare<B> for Module<B>
where
Module<B>: VmpPrepare<B>,
{
fn gglwe_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GGLWEPreparedToMut<B>,
O: GGLWEToRef,
{
let mut res: GGLWEPrepared<&mut [u8], B> = self.to_mut();
let other: GGLWE<&[u8]> = other.to_ref();
assert_eq!(res.n(), self.n() as u32);
assert_eq!(other.n(), self.n() as u32);
assert_eq!(res.base2k, other.base2k);
assert_eq!(res.k, other.k);
assert_eq!(res.dsize, other.dsize);
self.vmp_prepare(&mut res.data, &other.data, scratch);
}
}
impl<D: DataMut, B: Backend> GGLWEPrepared<D, B>
where
Module<B>: GGLWEPrepare<B>,
{
fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: GGLWEToRef,
{
module.gglwe_prepare(self, other, scratch);
}
}
pub trait GGLWEPrepareAlloc<B: Backend> {
fn gglwe_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> GGLWEPrepared<Vec<u8>, B>;
}
impl<B: Backend> GGLWEPrepareAlloc<B> for Module<B>
where
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
{
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWECiphertextPrepared<Vec<u8>, B> {
let mut atk_prepared: GGLWECiphertextPrepared<Vec<u8>, B> = GGLWECiphertextPrepared::alloc(module, self);
atk_prepared.prepare(module, self, scratch);
atk_prepared
fn gglwe_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> GGLWEPrepared<Vec<u8>, B> {
let mut ct_prepared: GGLWEPrepared<Vec<u8>, B> = GGLWEPrepared::alloc(self, &other.to_ref());
ct_prepared.prepare(self, &other.to_ref(), scratch);
ct_prepared
}
}
impl<D: DataRef> GGLWE<D> {
fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &Scratch<B>) -> GGLWEPrepared<Vec<u8>, B>
where
Module<B>: GGLWEPrepareAlloc<B>,
{
module.gglwe_prepare_alloc(self, scratch)
}
}
pub trait GGLWEPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], B>;
}
impl<D: DataMut, B: Backend> GGLWEPreparedToMut<B> for GGLWEPrepared<D, B> {
fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], B> {
GGLWEPrepared {
k: self.k,
base2k: self.base2k,
dsize: self.dsize,
data: self.data.to_mut(),
}
}
}
pub trait GGLWEPreparedToRef<B: Backend> {
fn to_ref(&self) -> GGLWEPrepared<&[u8], B>;
}
impl<D: DataRef, B: Backend> GGLWEPreparedToRef<B> for GGLWEPrepared<D, B> {
fn to_ref(&self) -> GGLWEPrepared<&[u8], B> {
GGLWEPrepared {
k: self.k,
base2k: self.base2k,
dsize: self.dsize,
data: self.data.to_ref(),
}
}
}