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

@@ -4,23 +4,25 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEAutomorphismKey, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
AutomorphismKeyToRef, Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
prepared::{
GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef,
},
};
#[derive(PartialEq, Eq)]
pub struct GGLWEAutomorphismKeyPrepared<D: Data, B: Backend> {
pub(crate) key: GGLWESwitchingKeyPrepared<D, B>,
pub struct AutomorphismKeyPrepared<D: Data, B: Backend> {
pub(crate) key: GLWESwitchingKeyPrepared<D, B>,
pub(crate) p: i64,
}
impl<D: Data, B: Backend> GGLWEAutomorphismKeyPrepared<D, B> {
impl<D: Data, B: Backend> AutomorphismKeyPrepared<D, B> {
pub fn p(&self) -> i64 {
self.p
}
}
impl<D: Data, B: Backend> LWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
impl<D: Data, B: Backend> LWEInfos for AutomorphismKeyPrepared<D, B> {
fn n(&self) -> Degree {
self.key.n()
}
@@ -38,13 +40,23 @@ impl<D: Data, B: Backend> LWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
}
}
impl<D: Data, B: Backend> GLWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
pub trait SetP {
fn set_p(&mut self, p: i64);
}
impl<D: Data, B: Backend> SetP for AutomorphismKeyPrepared<D, B> {
fn set_p(&mut self, p: i64) {
self.p = p
}
}
impl<D: Data, B: Backend> GLWEInfos for AutomorphismKeyPrepared<D, B> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data, B: Backend> GGLWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
impl<D: Data, B: Backend> GGLWEInfos for AutomorphismKeyPrepared<D, B> {
fn rank_in(&self) -> Rank {
self.key.rank_in()
}
@@ -62,7 +74,7 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
}
}
impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
impl<B: Backend> AutomorphismKeyPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGLWEInfos,
@@ -73,8 +85,8 @@ impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared"
);
GGLWEAutomorphismKeyPrepared::<Vec<u8>, B> {
key: GGLWESwitchingKeyPrepared::alloc(module, infos),
AutomorphismKeyPrepared::<Vec<u8>, B> {
key: GLWESwitchingKeyPrepared::alloc(module, infos),
p: 0,
}
}
@@ -83,8 +95,8 @@ impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
where
Module<B>: VmpPMatAlloc<B>,
{
GGLWEAutomorphismKeyPrepared {
key: GGLWESwitchingKeyPrepared::alloc_with(module, base2k, k, rank, rank, dnum, dsize),
AutomorphismKeyPrepared {
key: GLWESwitchingKeyPrepared::alloc_with(module, base2k, k, rank, rank, dnum, dsize),
p: 0,
}
}
@@ -99,43 +111,104 @@ impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared"
);
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
}
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize
where
Module<B>: VmpPMatAllocBytes,
{
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank, rank, dnum, dsize)
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank, rank, dnum, dsize)
}
}
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWEAutomorphismKeyPrepared<Vec<u8>, B>
pub trait AutomorphismKeyPrepareTmpBytes {
fn automorphism_key_prepare_tmp_bytes<A>(&self, infos: &A)
where
A: GGLWEInfos;
}
impl<B: Backend> AutomorphismKeyPrepareTmpBytes for Module<B>
where
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
Module<B>: GLWESwitchingKeyPrepareTmpBytes,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
fn automorphism_key_prepare_tmp_bytes<A>(&self, infos: &A)
where
A: GGLWEInfos,
{
self.glwe_switching_key_prepare_tmp_bytes(infos)
}
}
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWEAutomorphismKey<DR>> for GGLWEAutomorphismKeyPrepared<D, B>
where
Module<B>: VmpPrepare<B>,
{
fn prepare(&mut self, module: &Module<B>, other: &GGLWEAutomorphismKey<DR>, scratch: &mut Scratch<B>) {
self.key.prepare(module, &other.key, scratch);
impl<D: DataRef, B: Backend> AutomorphismKeyPrepared<D, B> {
pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize
where
Module<B>: AutomorphismKeyPrepareTmpBytes,
{
module.automorphism_key_prepare_tmp_bytes(self);
}
}
pub trait AutomorphismKeyPrepare<B: Backend> {
fn automorphism_key_prepare<R, O>(&self, res: &R, other: &O, scratch: &Scratch<B>)
where
R: AutomorphismKeyPreparedToMut<B>,
O: AutomorphismKeyToRef;
}
impl<B: Backend> AutomorphismKeyPrepare<B> for Module<B> {
fn automorphism_key_prepare<R, O>(&self, res: &R, other: &O, scratch: &Scratch<B>)
where
R: AutomorphismKeyPreparedToMut<B>,
O: AutomorphismKeyToRef,
{
self.key.prepare(self, &other.to_ref().key, scratch);
self.p = other.p;
}
}
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>> for GGLWEAutomorphismKey<D>
pub trait AutomorphismKeyPrepareAlloc<B: Backend> {
fn automorphism_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> AutomorphismKeyPrepared<Vec<u8>, B>
where
O: AutomorphismKeyToRef;
}
impl<B: Backend> AutomorphismKeyPrepareAlloc<B> for Module<B>
where
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
{
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
let mut atk_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> = GGLWEAutomorphismKeyPrepared::alloc(module, self);
atk_prepared.prepare(module, self, scratch);
fn automorphism_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> AutomorphismKeyPrepared<Vec<u8>, B>
where
O: AutomorphismKeyToRef,
{
let mut atk_prepared: AutomorphismKeyPrepared<Vec<u8>, B> = AutomorphismKeyPrepared::alloc(self, &other.to_ref());
atk_prepared.prepare(self, &other.to_ref(), scratch);
atk_prepared
}
}
pub trait AutomorphismKeyPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> AutomorphismKeyPrepared<&mut [u8], B>;
}
impl<D: DataMut, B: Backend> AutomorphismKeyPreparedToMut<B> for AutomorphismKeyPrepared<D, B> {
fn to_mut(&mut self) -> AutomorphismKeyPrepared<&mut [u8], B> {
AutomorphismKeyPrepared {
p: self.p,
key: self.key.to_mut(),
}
}
}
pub trait AutomorphismKeyPreparedToRef<B: Backend> {
fn to_ref(&self) -> AutomorphismKeyPrepared<&[u8], B>;
}
impl<D: DataRef, B: Backend> AutomorphismKeyPreparedToRef<B> for AutomorphismKeyPrepared<D, B> {
fn to_ref(&self) -> AutomorphismKeyPrepared<&[u8], B> {
AutomorphismKeyPrepared {
p: self.p,
key: self.key.to_ref(),
}
}
}

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(),
}
}
}

View File

@@ -1,21 +1,36 @@
use poulpy_hal::{
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
api::{VmpPMatAlloc, VmpPMatAllocBytes},
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
prepared::{GGLWECiphertextPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
prepared::{GGLWEPrepare, GGLWEPrepareTmpBytes, GGLWEPrepared, GGLWEPreparedToMut, GGLWEPreparedToRef},
};
#[derive(PartialEq, Eq)]
pub struct GGLWESwitchingKeyPrepared<D: Data, B: Backend> {
pub(crate) key: GGLWECiphertextPrepared<D, B>,
pub struct GLWESwitchingKeyPrepared<D: Data, B: Backend> {
pub(crate) key: GGLWEPrepared<D, B>,
pub(crate) sk_in_n: usize, // Degree of sk_in
pub(crate) sk_out_n: usize, // Degree of sk_out
}
impl<D: Data, B: Backend> LWEInfos for GGLWESwitchingKeyPrepared<D, B> {
pub(crate) trait GLWESwitchingKeyPreparedSetMetaData {
fn set_sk_in_n(&mut self, sk_in_n: usize);
fn set_sk_out_n(&mut self, sk_out_n: usize);
}
impl<D: DataMut, B: Backend> GLWESwitchingKeyPreparedSetMetaData for GLWESwitchingKeyPrepared<D, B> {
fn set_sk_in_n(&mut self, sk_in_n: usize) {
self.sk_in_n = sk_in_n
}
fn set_sk_out_n(&mut self, sk_out_n: usize) {
self.sk_out_n = self.sk_out_n
}
}
impl<D: Data, B: Backend> LWEInfos for GLWESwitchingKeyPrepared<D, B> {
fn n(&self) -> Degree {
self.key.n()
}
@@ -33,13 +48,13 @@ impl<D: Data, B: Backend> LWEInfos for GGLWESwitchingKeyPrepared<D, B> {
}
}
impl<D: Data, B: Backend> GLWEInfos for GGLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> GLWEInfos for GLWESwitchingKeyPrepared<D, B> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data, B: Backend> GGLWEInfos for GGLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> GGLWEInfos for GLWESwitchingKeyPrepared<D, B> {
fn rank_in(&self) -> Rank {
self.key.rank_in()
}
@@ -57,15 +72,15 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWESwitchingKeyPrepared<D, B> {
}
}
impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGLWEInfos,
Module<B>: VmpPMatAlloc<B>,
{
debug_assert_eq!(module.n() as u32, infos.n(), "module.n() != infos.n()");
GGLWESwitchingKeyPrepared::<Vec<u8>, B> {
key: GGLWECiphertextPrepared::alloc(module, infos),
GLWESwitchingKeyPrepared::<Vec<u8>, B> {
key: GGLWEPrepared::alloc(module, infos),
sk_in_n: 0,
sk_out_n: 0,
}
@@ -83,8 +98,8 @@ impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
where
Module<B>: VmpPMatAlloc<B>,
{
GGLWESwitchingKeyPrepared::<Vec<u8>, B> {
key: GGLWECiphertextPrepared::alloc_with(module, base2k, k, rank_in, rank_out, dnum, dsize),
GLWESwitchingKeyPrepared::<Vec<u8>, B> {
key: GGLWEPrepared::alloc_with(module, base2k, k, rank_in, rank_out, dnum, dsize),
sk_in_n: 0,
sk_out_n: 0,
}
@@ -96,7 +111,7 @@ impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
Module<B>: VmpPMatAllocBytes,
{
debug_assert_eq!(module.n() as u32, infos.n(), "module.n() != infos.n()");
GGLWECiphertextPrepared::alloc_bytes(module, infos)
GGLWEPrepared::alloc_bytes(module, infos)
}
pub fn alloc_bytes_with(
@@ -111,37 +126,122 @@ impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
where
Module<B>: VmpPMatAllocBytes,
{
GGLWECiphertextPrepared::alloc_bytes_with(module, base2k, k, rank_in, rank_out, dnum, dsize)
GGLWEPrepared::alloc_bytes_with(module, base2k, k, rank_in, rank_out, dnum, dsize)
}
}
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWESwitchingKeyPrepared<Vec<u8>, B>
pub trait GLWESwitchingKeyPrepareTmpBytes {
fn glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos;
}
impl<B: Backend> GLWESwitchingKeyPrepareTmpBytes for Module<B>
where
GGLWECiphertextPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
Module<B>: GGLWEPrepareTmpBytes,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
GGLWECiphertextPrepared::prepare_scratch_space(module, infos)
fn glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
self.gglwe_prepare_tmp_bytes(infos)
}
}
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWESwitchingKey<DR>> for GGLWESwitchingKeyPrepared<D, B>
impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B>
where
Module<B>: VmpPrepare<B>,
Module<B>: GGLWEPrepareTmpBytes,
{
fn prepare(&mut self, module: &Module<B>, other: &GGLWESwitchingKey<DR>, scratch: &mut Scratch<B>) {
self.key.prepare(module, &other.key, scratch);
self.sk_in_n = other.sk_in_n;
self.sk_out_n = other.sk_out_n;
pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize {
module.gglwe_prepare_tmp_bytes(self)
}
}
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWESwitchingKeyPrepared<Vec<u8>, B>> for GGLWESwitchingKey<D>
pub trait GLWESwitchingKeyPrepare<B: Backend> {
fn glwe_switching_prepare<R, O>(&self, res: &R, other: &O, scratch: &mut Scratch<B>)
where
R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeyPreparedSetMetaData,
O: GLWESwitchingKeyToRef;
}
impl<B: Backend> GLWESwitchingKeyPrepare<B> for Module<B>
where
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
Module<B>: GGLWEPrepare<B>,
{
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
let mut atk_prepared: GGLWESwitchingKeyPrepared<Vec<u8>, B> = GGLWESwitchingKeyPrepared::alloc(module, self);
atk_prepared.prepare(module, self, scratch);
atk_prepared
fn glwe_switching_prepare<R, O>(&self, res: &R, other: &O, scratch: &mut Scratch<B>)
where
R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeyPreparedSetMetaData,
O: GLWESwitchingKeyToRef,
{
self.gglwe_prepare(&res.to_mut(), other, scratch);
res.set_sk_in_n(other.sk_in_n);
res.set_sk_out_n(other.sk_out_n);
}
}
impl<D: DataMut, B: Backend> GLWESwitchingKeyPrepared<D, B> {
pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: GLWESwitchingKeyToRef,
Module<B>: GLWESwitchingKeyPrepare<B>,
{
module.glwe_switching_prepare(self, other, scratch);
}
}
pub trait GLWESwitchingKeyPrepareAlloc<B: Backend> {
fn glwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: GLWESwitchingKeyToRef;
}
impl<B: Backend> GLWESwitchingKeyPrepareAlloc<B> for Module<B>
where
Module<B>: GLWESwitchingKeyPrepare<B>,
{
fn glwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: GLWESwitchingKeyToRef,
{
let mut ct_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = GLWESwitchingKeyPrepared::alloc(self, self);
self.glwe_switching_prepare(&mut ct_prepared, other, scratch);
ct_prepared
}
}
impl<D: DataRef> GLWESwitchingKey<D> {
pub fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GLWESwitchingKeyPrepared<Vec<u8>, B>
where
Module<B>: GLWESwitchingKeyPrepareAlloc<B>,
{
module.glwe_switching_key_prepare_alloc(self, scratch);
}
}
pub trait GLWESwitchingKeyPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> GLWESwitchingKeyPrepared<&mut [u8], B>;
}
impl<D: DataMut, B: Backend> GLWESwitchingKeyPreparedToMut<B> for GLWESwitchingKeyPrepared<D, B> {
fn to_mut(&mut self) -> GLWESwitchingKeyPrepared<&mut [u8], B> {
GLWESwitchingKeyPrepared {
sk_in_n: self.sk_in_n,
sk_out_n: self.sk_out_n,
key: self.key.to_mut(),
}
}
}
pub trait GLWESwitchingKeyPreparedToRef<B: Backend> {
fn to_ref(&self) -> GLWESwitchingKeyPrepared<&[u8], B>;
}
impl<D: DataRef, B: Backend> GLWESwitchingKeyPreparedToRef<B> for GLWESwitchingKeyPrepared<D, B> {
fn to_ref(&self) -> GLWESwitchingKeyPrepared<&[u8], B> {
GLWESwitchingKeyPrepared {
sk_in_n: self.sk_in_n,
sk_out_n: self.sk_out_n,
key: self.key.to_ref(),
}
}
}

View File

@@ -1,19 +1,23 @@
use poulpy_hal::{
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
api::{VmpPMatAlloc, VmpPMatAllocBytes},
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWETensorKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TensorKey, TensorKeyToRef, TorusPrecision,
compressed::TensorKeyCompressedToMut,
prepared::{
GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut,
GLWESwitchingKeyPreparedToRef,
},
};
#[derive(PartialEq, Eq)]
pub struct GGLWETensorKeyPrepared<D: Data, B: Backend> {
pub(crate) keys: Vec<GGLWESwitchingKeyPrepared<D, B>>,
pub struct TensorKeyPrepared<D: Data, B: Backend> {
pub(crate) keys: Vec<GLWESwitchingKeyPrepared<D, B>>,
}
impl<D: Data, B: Backend> LWEInfos for GGLWETensorKeyPrepared<D, B> {
impl<D: Data, B: Backend> LWEInfos for TensorKeyPrepared<D, B> {
fn n(&self) -> Degree {
self.keys[0].n()
}
@@ -31,13 +35,13 @@ impl<D: Data, B: Backend> LWEInfos for GGLWETensorKeyPrepared<D, B> {
}
}
impl<D: Data, B: Backend> GLWEInfos for GGLWETensorKeyPrepared<D, B> {
impl<D: Data, B: Backend> GLWEInfos for TensorKeyPrepared<D, B> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data, B: Backend> GGLWEInfos for GGLWETensorKeyPrepared<D, B> {
impl<D: Data, B: Backend> GGLWEInfos for TensorKeyPrepared<D, B> {
fn rank_in(&self) -> Rank {
self.rank_out()
}
@@ -55,7 +59,7 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWETensorKeyPrepared<D, B> {
}
}
impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
impl<B: Backend> TensorKeyPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGLWEInfos,
@@ -80,10 +84,10 @@ impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
where
Module<B>: VmpPMatAlloc<B>,
{
let mut keys: Vec<GGLWESwitchingKeyPrepared<Vec<u8>, B>> = Vec::new();
let mut keys: Vec<GLWESwitchingKeyPrepared<Vec<u8>, B>> = Vec::new();
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
(0..pairs).for_each(|_| {
keys.push(GGLWESwitchingKeyPrepared::alloc_with(
keys.push(GLWESwitchingKeyPrepared::alloc_with(
module,
base2k,
k,
@@ -109,7 +113,7 @@ impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
let rank_out: usize = infos.rank_out().into();
let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1);
pairs
* GGLWESwitchingKeyPrepared::alloc_bytes_with(
* GLWESwitchingKeyPrepared::alloc_bytes_with(
module,
infos.base2k(),
infos.k(),
@@ -125,13 +129,13 @@ impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
Module<B>: VmpPMatAllocBytes,
{
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
pairs * GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank, dnum, dsize)
pairs * GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank, dnum, dsize)
}
}
impl<D: DataMut, B: Backend> GGLWETensorKeyPrepared<D, B> {
impl<D: DataMut, B: Backend> TensorKeyPrepared<D, B> {
// Returns a mutable reference to GLWESwitchingKey_{s}(s[i] * s[j])
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWESwitchingKeyPrepared<D, B> {
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GLWESwitchingKeyPrepared<D, B> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
@@ -140,9 +144,9 @@ impl<D: DataMut, B: Backend> GGLWETensorKeyPrepared<D, B> {
}
}
impl<D: DataRef, B: Backend> GGLWETensorKeyPrepared<D, B> {
impl<D: DataRef, B: Backend> TensorKeyPrepared<D, B> {
// Returns a reference to GLWESwitchingKey_{s}(s[i] * s[j])
pub fn at(&self, mut i: usize, mut j: usize) -> &GGLWESwitchingKeyPrepared<D, B> {
pub fn at(&self, mut i: usize, mut j: usize) -> &GLWESwitchingKeyPrepared<D, B> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
@@ -151,40 +155,125 @@ impl<D: DataRef, B: Backend> GGLWETensorKeyPrepared<D, B> {
}
}
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWETensorKeyPrepared<Vec<u8>, B>
pub trait TensorKeyPrepareTmpBytes {
fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize;
}
impl<B: Backend> TensorKeyPrepareTmpBytes for Module<B>
where
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
Module<B>: GLWESwitchingKeyPrepareTmpBytes,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize {
self.glwe_switching_key_prepare_tmp_bytes(infos)
}
}
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWETensorKey<DR>> for GGLWETensorKeyPrepared<D, B>
impl<B: Backend> TensorKeyPrepared<Vec<u8>, B>
where
Module<B>: VmpPrepare<B>,
Module<B>: TensorKeyPrepareTmpBytes,
{
fn prepare(&mut self, module: &Module<B>, other: &GGLWETensorKey<DR>, scratch: &mut Scratch<B>) {
#[cfg(debug_assertions)]
{
assert_eq!(self.keys.len(), other.keys.len());
fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) -> usize
where
A: GGLWEInfos,
{
module.tensor_key_prepare_tmp_bytes(infos)
}
}
pub trait TensorKeyPrepare<B: Backend> {
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
where
R: TensorKeyPreparedToMut<B>,
O: TensorKeyToRef;
}
impl<B: Backend> TensorKeyPrepare<B> for Module<B>
where
Module<B>: GLWESwitchingKeyPrepare<B>,
{
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
where
R: TensorKeyPreparedToMut<B>,
O: TensorKeyToRef,
{
let res = res.to_mut();
let other = other.to_ref();
assert_eq!(self.keys.len(), other.keys.len());
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
self.glwe_switching_prepare(a, b, scratch);
}
self.keys
.iter_mut()
.zip(other.keys.iter())
.for_each(|(a, b)| {
a.prepare(module, b, scratch);
});
}
}
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWETensorKeyPrepared<Vec<u8>, B>> for GGLWETensorKey<D>
impl<D: DataMut, B: Backend> TensorKeyPrepared<D, B>
where
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
Module<B>: TensorKeyPrepare<B>,
{
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWETensorKeyPrepared<Vec<u8>, B> {
let mut tsk_prepared: GGLWETensorKeyPrepared<Vec<u8>, B> = GGLWETensorKeyPrepared::alloc(module, self);
tsk_prepared.prepare(module, self, scratch);
tsk_prepared
fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: TensorKeyToRef,
{
module.tensor_key_prepare(self, other, scratch);
}
}
pub trait TensorKeyPrepareAlloc<B: Backend> {
fn tensor_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: TensorKeyToRef;
}
impl<B: Backend> TensorKeyPrepareAlloc<B> for Module<B>
where
Module<B>: TensorKeyPrepare<B>,
{
fn tensor_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: TensorKeyToRef,
{
let mut ct_prepared: TensorKeyPrepared<Vec<u8>, B> = TensorKeyPrepared::alloc(self, other);
self.tensor_key_prepare(ct_prepared, other, scratch);
ct_prepared
}
}
impl<D: DataRef> TensorKey<D> {
pub fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &Scratch<B>)
where
Module<B>: TensorKeyPrepareAlloc<B>,
{
module.tensor_key_prepare_alloc(self, scratch);
}
}
pub trait TensorKeyPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> TensorKeyPrepared<&mut [u8], B>;
}
impl<D: DataMut, B: Backend> TensorKeyPreparedToMut<B> for TensorKeyPrepared<D, B>
where
GLWESwitchingKeyPrepared<D, B>: GLWESwitchingKeyPreparedToMut<B>,
{
fn to_mut(&mut self) -> TensorKeyPrepared<&mut [u8], B> {
TensorKeyPrepared {
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
}
}
}
pub trait TensorKeyPreparedToRef<B: Backend> {
fn to_ref(&self) -> TensorKeyPrepared<&[u8], B>;
}
impl<D: DataRef, B: Backend> TensorKeyPreparedToRef<B> for TensorKeyPrepared<D, B>
where
GLWESwitchingKeyPrepared<D, B>: GLWESwitchingKeyPreparedToRef<B>,
{
fn to_ref(&self) -> TensorKeyPrepared<&[u8], B> {
TensorKeyPrepared {
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
}
}
}

View File

@@ -5,19 +5,18 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, BuildError, Degree, Dnum, Dsize, GGSWCiphertext, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
Base2K, BuildError, Degree, Dnum, Dsize, GGSW, GGSWInfos, GGSWToMut, GGSWToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
};
#[derive(PartialEq, Eq)]
pub struct GGSWCiphertextPrepared<D: Data, B: Backend> {
pub struct GGSWPrepared<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 GGSWCiphertextPrepared<D, B> {
impl<D: Data, B: Backend> LWEInfos for GGSWPrepared<D, B> {
fn n(&self) -> Degree {
Degree(self.data.n() as u32)
}
@@ -35,13 +34,13 @@ impl<D: Data, B: Backend> LWEInfos for GGSWCiphertextPrepared<D, B> {
}
}
impl<D: Data, B: Backend> GLWEInfos for GGSWCiphertextPrepared<D, B> {
impl<D: Data, B: Backend> GLWEInfos for GGSWPrepared<D, B> {
fn rank(&self) -> Rank {
Rank(self.data.cols_out() as u32 - 1)
}
}
impl<D: Data, B: Backend> GGSWInfos for GGSWCiphertextPrepared<D, B> {
impl<D: Data, B: Backend> GGSWInfos for GGSWPrepared<D, B> {
fn dsize(&self) -> Dsize {
self.dsize
}
@@ -58,7 +57,7 @@ pub struct GGSWCiphertextPreparedBuilder<D: Data, B: Backend> {
dsize: Option<Dsize>,
}
impl<D: Data, B: Backend> GGSWCiphertextPrepared<D, B> {
impl<D: Data, B: Backend> GGSWPrepared<D, B> {
#[inline]
pub fn builder() -> GGSWCiphertextPreparedBuilder<D, B> {
GGSWCiphertextPreparedBuilder {
@@ -129,7 +128,7 @@ impl<D: Data, B: Backend> GGSWCiphertextPreparedBuilder<D, B> {
self
}
pub fn build(self) -> Result<GGSWCiphertextPrepared<D, B>, BuildError> {
pub fn build(self) -> Result<GGSWPrepared<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)?;
@@ -159,7 +158,7 @@ impl<D: Data, B: Backend> GGSWCiphertextPreparedBuilder<D, B> {
return Err(BuildError::ZeroLimbs);
}
Ok(GGSWCiphertextPrepared {
Ok(GGSWPrepared {
data,
base2k,
k,
@@ -168,7 +167,7 @@ impl<D: Data, B: Backend> GGSWCiphertextPreparedBuilder<D, B> {
}
}
impl<B: Backend> GGSWCiphertextPrepared<Vec<u8>, B> {
impl<B: Backend> GGSWPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGSWInfos,
@@ -252,18 +251,27 @@ impl<B: Backend> GGSWCiphertextPrepared<Vec<u8>, B> {
}
}
impl<D: DataRef, B: Backend> GGSWCiphertextPrepared<D, B> {
impl<D: DataRef, B: Backend> GGSWPrepared<D, B> {
pub fn data(&self) -> &VmpPMat<D, B> {
&self.data
}
}
impl<B: Backend, A: GGSWInfos> PrepareScratchSpace<B, A> for GGSWCiphertextPrepared<Vec<u8>, B>
pub trait GGSWPrepareTmpBytes {
fn ggsw_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGSWInfos;
}
impl<B: Backend> GGSWPrepareTmpBytes for Module<B>
where
Module<B>: VmpPrepareTmpBytes,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
module.vmp_prepare_tmp_bytes(
fn ggsw_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGSWInfos,
{
self.vmp_prepare_tmp_bytes(
infos.dnum().into(),
(infos.rank() + 1).into(),
(infos.rank() + 1).into(),
@@ -272,57 +280,110 @@ where
}
}
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGSWCiphertext<DR>> for GGSWCiphertextPrepared<D, B>
impl<B: Backend> GGSWPrepared<Vec<u8>, B>
where
Module<B>: GGSWPrepareTmpBytes,
{
pub fn prepare_tmp_bytes<A>(&self, module: Module<B>, infos: &A) -> usize
where
A: GGSWInfos,
{
module.ggsw_prepare_tmp_bytes(self)
}
}
pub trait GGSWPrepare<B: Backend> {
fn ggsw_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GGSWPreparedToMut<B>,
O: GGSWToRef;
}
impl<B: Backend> GGSWPrepare<B> for Module<B>
where
Module<B>: VmpPrepare<B>,
{
fn prepare(&mut self, module: &Module<B>, other: &GGSWCiphertext<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;
fn ggsw_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GGSWPreparedToMut<B>,
O: GGSWToRef,
{
let mut res: GGSWPrepared<&mut [u8], B> = res.to_mut();
let other: GGSW<&[u8]> = other.to_ref();
assert_eq!(res.k, other.k);
assert_eq!(res.base2k, other.base2k);
assert_eq!(res.dsize, other.dsize);
self.vmp_prepare(&mut res.data, &other.data, scratch);
}
}
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGSWCiphertextPrepared<Vec<u8>, B>> for GGSWCiphertext<D>
impl<D: DataMut, B: Backend> GGSWPrepared<D, B>
where
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
Module<B>: GGSWPrepare<B>,
{
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGSWCiphertextPrepared<Vec<u8>, B> {
let mut ggsw_prepared: GGSWCiphertextPrepared<Vec<u8>, B> = GGSWCiphertextPrepared::alloc(module, self);
ggsw_prepared.prepare(module, self, scratch);
ggsw_prepared
pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: GGSWToRef,
{
module.ggsw_prepare(self, other, scratch);
}
}
pub trait GGSWCiphertextPreparedToMut<B: Backend> {
fn to_ref(&mut self) -> GGSWCiphertextPrepared<&mut [u8], B>;
pub trait GGSWPrepareAlloc<B: Backend> {
fn ggsw_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: GGSWToRef;
}
impl<D: DataMut, B: Backend> GGSWCiphertextPreparedToMut<B> for GGSWCiphertextPrepared<D, B> {
fn to_ref(&mut self) -> GGSWCiphertextPrepared<&mut [u8], B> {
GGSWCiphertextPrepared::builder()
.base2k(self.base2k())
.dsize(self.dsize())
.k(self.k())
.data(self.data.to_mut())
.build()
.unwrap()
impl<B: Backend> GGSWPrepareAlloc<B> for Module<B>
where
Module<B>: GGSWPrepare<B>,
{
fn ggsw_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: GGSWToRef,
{
let mut ct_prepared: GGSWPrepared<Vec<u8>, B> = GGSWPrepared::alloc(self, other);
self.ggsw_prepare(&mut ct_prepared, other, scratch);
ct_prepared
}
}
impl<D: DataRef> GGSW<D> {
fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &mut Scratch<B>)
where
Module<B>: GGSWPrepareAlloc<B>,
{
module.ggsw_prepare_alloc(self, scratch);
}
}
pub trait GGSWPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> GGSWPrepared<&mut [u8], B>;
}
impl<D: DataMut, B: Backend> GGSWPreparedToMut<B> for GGSWPrepared<D, B> {
fn to_mut(&mut self) -> GGSWPrepared<&mut [u8], B> {
GGSWPrepared {
base2k: self.base2k,
k: self.k,
dsize: self.dsize,
data: self.data.to_mut(),
}
}
}
pub trait GGSWCiphertextPreparedToRef<B: Backend> {
fn to_ref(&self) -> GGSWCiphertextPrepared<&[u8], B>;
fn to_ref(&self) -> GGSWPrepared<&[u8], B>;
}
impl<D: DataRef, B: Backend> GGSWCiphertextPreparedToRef<B> for GGSWCiphertextPrepared<D, B> {
fn to_ref(&self) -> GGSWCiphertextPrepared<&[u8], B> {
GGSWCiphertextPrepared::builder()
.base2k(self.base2k())
.dsize(self.dsize())
.k(self.k())
.data(self.data.to_ref())
.build()
.unwrap()
impl<D: DataRef, B: Backend> GGSWCiphertextPreparedToRef<B> for GGSWPrepared<D, B> {
fn to_ref(&self) -> GGSWPrepared<&[u8], B> {
GGSWPrepared {
base2k: self.base2k,
k: self.k,
dsize: self.dsize,
data: self.data.to_mut(),
}
}
}

View File

@@ -6,10 +6,7 @@ use poulpy_hal::{
use crate::{
dist::Distribution,
layouts::{
Base2K, BuildError, Degree, GLWEInfos, GLWEPublicKey, LWEInfos, Rank, TorusPrecision,
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
},
layouts::{Base2K, BuildError, Degree, GLWEInfos, GLWEPublicKey, LWEInfos, Rank, TorusPrecision},
};
#[derive(PartialEq, Eq)]

View File

@@ -5,10 +5,7 @@ use poulpy_hal::{
use crate::{
dist::Distribution,
layouts::{
Base2K, Degree, GLWEInfos, GLWESecret, LWEInfos, Rank, TorusPrecision,
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
},
layouts::{Base2K, Degree, GLWEInfos, GLWESecret, LWEInfos, Rank, TorusPrecision},
};
pub struct GLWESecretPrepared<D: Data, B: Backend> {
@@ -128,11 +125,11 @@ impl<D: DataRef, B: Backend> GLWESecretPreparedToRef<B> for GLWESecretPrepared<D
}
pub trait GLWESecretPreparedToMut<B: Backend> {
fn to_ref(&mut self) -> GLWESecretPrepared<&mut [u8], B>;
fn to_mut(&mut self) -> GLWESecretPrepared<&mut [u8], B>;
}
impl<D: DataMut, B: Backend> GLWESecretPreparedToMut<B> for GLWESecretPrepared<D, B> {
fn to_ref(&mut self) -> GLWESecretPrepared<&mut [u8], B> {
fn to_mut(&mut self) -> GLWESecretPrepared<&mut [u8], B> {
GLWESecretPrepared {
dist: self.dist,
data: self.data.to_mut(),

View File

@@ -4,12 +4,12 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWEKey, LWEInfos, Rank, TorusPrecision,
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWESwitchingKey, LWEInfos, Rank, TorusPrecision,
prepared::GLWESwitchingKeyPrepared,
};
#[derive(PartialEq, Eq)]
pub struct GLWEToLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
pub struct GLWEToLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
impl<D: Data, B: Backend> LWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
fn base2k(&self) -> Base2K {
@@ -69,14 +69,14 @@ impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
1,
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
);
Self(GGLWESwitchingKeyPrepared::alloc(module, infos))
Self(GLWESwitchingKeyPrepared::alloc(module, infos))
}
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self
where
Module<B>: VmpPMatAlloc<B>,
{
Self(GGLWESwitchingKeyPrepared::alloc_with(
Self(GLWESwitchingKeyPrepared::alloc_with(
module,
base2k,
k,
@@ -102,27 +102,27 @@ impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
1,
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
);
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
}
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize
where
Module<B>: VmpPMatAllocBytes,
{
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
}
}
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>
where
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
GLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
}
}
impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>> for GLWEToLWEKey<D>
impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>> for GLWEToLWESwitchingKey<D>
where
Module<B>: VmpPrepare<B> + VmpPMatAlloc<B>,
{
@@ -133,11 +133,11 @@ where
}
}
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWEToLWEKey<DR>> for GLWEToLWESwitchingKeyPrepared<DM, B>
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWEToLWESwitchingKey<DR>> for GLWEToLWESwitchingKeyPrepared<DM, B>
where
Module<B>: VmpPrepare<B>,
{
fn prepare(&mut self, module: &Module<B>, other: &GLWEToLWEKey<DR>, scratch: &mut Scratch<B>) {
fn prepare(&mut self, module: &Module<B>, other: &GLWEToLWESwitchingKey<DR>, scratch: &mut Scratch<B>) {
self.0.prepare(module, &other.0, scratch);
}
}

View File

@@ -5,11 +5,11 @@ use poulpy_hal::{
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, TorusPrecision,
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
prepared::GLWESwitchingKeyPrepared,
};
#[derive(PartialEq, Eq)]
pub struct LWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
pub struct LWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
impl<D: Data, B: Backend> LWEInfos for LWESwitchingKeyPrepared<D, B> {
fn base2k(&self) -> Base2K {
@@ -73,14 +73,14 @@ impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
1,
"rank_out > 1 is not supported for LWESwitchingKey"
);
Self(GGLWESwitchingKeyPrepared::alloc(module, infos))
Self(GLWESwitchingKeyPrepared::alloc(module, infos))
}
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self
where
Module<B>: VmpPMatAlloc<B>,
{
Self(GGLWESwitchingKeyPrepared::alloc_with(
Self(GLWESwitchingKeyPrepared::alloc_with(
module,
base2k,
k,
@@ -111,23 +111,23 @@ impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
1,
"rank_out > 1 is not supported for LWESwitchingKey"
);
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
}
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize
where
Module<B>: VmpPMatAllocBytes,
{
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
}
}
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for LWESwitchingKeyPrepared<Vec<u8>, B>
where
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
GLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
}
}

View File

@@ -5,12 +5,12 @@ use poulpy_hal::{
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, Rank, TorusPrecision,
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
prepared::GLWESwitchingKeyPrepared,
};
/// A special [GLWESwitchingKey] required to for the conversion from [LWECiphertext] to [GLWECiphertext].
#[derive(PartialEq, Eq)]
pub struct LWEToGLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
pub struct LWEToGLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
impl<D: Data, B: Backend> LWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
fn base2k(&self) -> Base2K {
@@ -70,14 +70,14 @@ impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
1,
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
);
Self(GGLWESwitchingKeyPrepared::alloc(module, infos))
Self(GLWESwitchingKeyPrepared::alloc(module, infos))
}
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self
where
Module<B>: VmpPMatAlloc<B>,
{
Self(GGLWESwitchingKeyPrepared::alloc_with(
Self(GLWESwitchingKeyPrepared::alloc_with(
module,
base2k,
k,
@@ -103,23 +103,23 @@ impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
1,
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
);
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
}
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize
where
Module<B>: VmpPMatAllocBytes,
{
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
}
}
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for LWEToGLWESwitchingKeyPrepared<Vec<u8>, B>
where
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
GLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
{
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
}
}

View File

@@ -19,16 +19,3 @@ pub use glwe_sk::*;
pub use glwe_to_lwe_ksk::*;
pub use lwe_ksk::*;
pub use lwe_to_glwe_ksk::*;
use poulpy_hal::layouts::{Backend, Module, Scratch};
pub trait PrepareScratchSpace<B: Backend, T> {
fn prepare_scratch_space(module: &Module<B>, infos: &T) -> usize;
}
pub trait PrepareAlloc<B: Backend, T> {
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> T;
}
pub trait Prepare<B: Backend, T> {
fn prepare(&mut self, module: &Module<B>, other: &T, scratch: &mut Scratch<B>);
}