wip
jump to
@@ -25,7 +25,7 @@ Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
{ (GGLWE::encrypt_sk_scratch_space(module, infos) | ScalarZnx::alloc_bytes(module.n(), 1)) + ScalarZnx::alloc_bytes(module.n(), infos.rank_in().into()) - + GLWESecretPrepared::alloc_bytes_with(module, infos.rank_out()) + + GLWESecretPrepared::alloc_bytes(module, infos.rank_out()) } }
@@ -22,7 +22,7 @@ Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{ (GGLWE::encrypt_sk_scratch_space(module, infos) | ScalarZnx::alloc_bytes(module.n(), 1)) + ScalarZnx::alloc_bytes(module.n(), infos.rank_in().into()) - + GLWESecretPrepared::alloc_bytes(module, &infos.glwe_layout()) + + GLWESecretPrepared::alloc_bytes_from_infos(module, &infos.glwe_layout()) } pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, _infos: &A) -> usize
@@ -23,7 +23,7 @@ A: GGLWEInfos,
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + VecZnxBigAllocBytes, { - GLWESecretPrepared::alloc_bytes_with(module, infos.rank_out()) + GLWESecretPrepared::alloc_bytes(module, infos.rank_out()) + module.vec_znx_dft_alloc_bytes(infos.rank_out().into(), 1) + module.vec_znx_big_alloc_bytes(1, 1) + module.vec_znx_dft_alloc_bytes(1, 1)
@@ -22,7 +22,7 @@ where
A: GGLWEInfos, Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes, { - GLWESecretPrepared::alloc_bytes_with(module, infos.rank_in()) + GLWESecretPrepared::alloc_bytes(module, infos.rank_in()) + (GLWESwitchingKey::encrypt_sk_scratch_space(module, infos) | GLWESecret::alloc_bytes_with(infos.n(), infos.rank_in())) }
@@ -39,7 +39,7 @@ 1,
"rank_out > 1 is not supported for LWESwitchingKey" ); GLWESecret::alloc_bytes_with(Degree(module.n() as u32), Rank(1)) - + GLWESecretPrepared::alloc_bytes_with(module, Rank(1)) + + GLWESecretPrepared::alloc_bytes(module, Rank(1)) + GLWESwitchingKey::encrypt_sk_scratch_space(module, infos) } }
@@ -6,9 +6,7 @@ },
source::Source, }; -use crate::layouts::{ - Base2K, BuildError, Degree, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::Decompress, -}; +use crate::layouts::{Base2K, Degree, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::Decompress}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use std::fmt;@@ -100,101 +98,6 @@ VecZnx::alloc_bytes(n.into(), 1, k.0.div_ceil(base2k.0) as usize)
} } -pub struct GLWECiphertextCompressedBuilder<D: Data> { - data: Option<VecZnx<D>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, - rank: Option<Rank>, -} - -impl<D: Data> GLWECiphertextCompressed<D> { - #[inline] - pub fn builder() -> GLWECiphertextCompressedBuilder<D> { - GLWECiphertextCompressedBuilder { - data: None, - base2k: None, - k: None, - rank: None, - } - } -} - -impl GLWECiphertextCompressedBuilder<Vec<u8>> { - #[inline] - pub fn layout<A>(mut self, layout: &A) -> Self - where - A: GLWEInfos, - { - self.data = Some(VecZnx::alloc(layout.n().into(), 1, layout.size())); - self.base2k = Some(layout.base2k()); - self.k = Some(layout.k()); - self.rank = Some(layout.rank()); - self - } -} - -impl<D: Data> GLWECiphertextCompressedBuilder<D> { - #[inline] - pub fn data(mut self, data: VecZnx<D>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - #[inline] - pub fn rank(mut self, rank: Rank) -> Self { - self.rank = Some(rank); - self - } - - pub fn build(self) -> Result<GLWECiphertextCompressed<D>, BuildError> { - let data: VecZnx<D> = self.data.ok_or(BuildError::MissingData)?; - let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?; - let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?; - let rank: Rank = self.rank.ok_or(BuildError::MissingK)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if rank == 0_u32 { - return Err(BuildError::ZeroRank); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() != 1 { - return Err(BuildError::VecZnxColsNotOne); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GLWECiphertextCompressed { - data, - base2k, - k, - rank, - seed: [0u8; 32], - }) - } -} - impl<D: DataMut> ReaderFrom for GLWECiphertextCompressed<D> { fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> { self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);@@ -282,13 +185,13 @@ }
impl<D: DataRef> GLWECiphertextCompressedToRef for GLWECiphertextCompressed<D> { fn to_ref(&self) -> GLWECiphertextCompressed<&[u8]> { - GLWECiphertextCompressed::builder() - .k(self.k()) - .base2k(self.base2k()) - .rank(self.rank()) - .data(self.data.to_ref()) - .build() - .unwrap() + GLWECiphertextCompressed { + seed: self.seed.clone(), + base2k: self.base2k, + k: self.k, + rank: self.rank, + data: self.data.to_ref(), + } } }@@ -298,12 +201,12 @@ }
impl<D: DataMut> GLWECiphertextCompressedToMut for GLWECiphertextCompressed<D> { fn to_mut(&mut self) -> GLWECiphertextCompressed<&mut [u8]> { - GLWECiphertextCompressed::builder() - .k(self.k()) - .base2k(self.base2k()) - .rank(self.rank()) - .data(self.data.to_mut()) - .build() - .unwrap() + GLWECiphertextCompressed { + seed: self.seed.clone(), + base2k: self.base2k, + k: self.k, + rank: self.rank, + data: self.data.to_mut(), + } } }
@@ -3,7 +3,7 @@ layouts::{Data, DataMut, DataRef, FillUniform, MatZnx, MatZnxToMut, MatZnxToRef, ReaderFrom, WriterTo, ZnxInfos},
source::Source, }; -use crate::layouts::{Base2K, BuildError, Degree, Dnum, Dsize, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision}; +use crate::layouts::{Base2K, Degree, Dnum, Dsize, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use std::fmt;@@ -132,107 +132,6 @@ Dnum(self.data.rows() as u32)
} } -pub struct GGLWECiphertextBuilder<D: Data> { - data: Option<MatZnx<D>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, - dsize: Option<Dsize>, -} - -impl<D: Data> GGLWE<D> { - #[inline] - pub fn builder() -> GGLWECiphertextBuilder<D> { - GGLWECiphertextBuilder { - data: None, - base2k: None, - k: None, - dsize: None, - } - } -} - -impl GGLWECiphertextBuilder<Vec<u8>> { - #[inline] - pub fn layout<A>(mut self, infos: &A) -> Self - where - A: GGLWEInfos, - { - self.data = Some(MatZnx::alloc( - infos.n().into(), - infos.dnum().into(), - infos.rank_in().into(), - (infos.rank_out() + 1).into(), - infos.size(), - )); - self.base2k = Some(infos.base2k()); - self.k = Some(infos.k()); - self.dsize = Some(infos.dsize()); - self - } -} - -impl<D: Data> GGLWECiphertextBuilder<D> { - #[inline] - pub fn data(mut self, data: MatZnx<D>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - #[inline] - pub fn dsize(mut self, dsize: Dsize) -> Self { - self.dsize = Some(dsize); - self - } - - pub fn build(self) -> Result<GGLWE<D>, BuildError> { - let data: MatZnx<D> = self.data.ok_or(BuildError::MissingData)?; - let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?; - let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?; - let dsize: Dsize = self.dsize.ok_or(BuildError::MissingDigits)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if dsize == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GGLWE { - data, - base2k, - k, - dsize, - }) - } -} - impl<D: DataRef> GGLWE<D> { pub fn data(&self) -> &MatZnx<D> { &self.data@@ -272,23 +171,21 @@ }
impl<D: DataRef> GGLWE<D> { pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> { - GLWECiphertext::builder() - .data(self.data.at(row, col)) - .base2k(self.base2k()) - .k(self.k()) - .build() - .unwrap() + GLWECiphertext { + k: self.k, + base2k: self.base2k, + data: self.data.at(row, col), + } } } impl<D: DataMut> GGLWE<D> { pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> { - GLWECiphertext::builder() - .base2k(self.base2k()) - .k(self.k()) - .data(self.data.at_mut(row, col)) - .build() - .unwrap() + GLWECiphertext { + k: self.k, + base2k: self.base2k, + data: self.data.at_mut(row, col), + } } }
@@ -4,7 +4,7 @@ source::Source,
}; use std::fmt; -use crate::layouts::{Base2K, BuildError, Degree, Dnum, Dsize, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision}; +use crate::layouts::{Base2K, Degree, Dnum, Dsize, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision}; pub trait GGSWInfos where@@ -105,122 +105,6 @@ Dnum(self.data.rows() as u32)
} } -pub struct GGSWCiphertextBuilder<D: Data> { - data: Option<MatZnx<D>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, - dsize: Option<Dsize>, -} - -impl<D: Data> GGSW<D> { - #[inline] - pub fn builder() -> GGSWCiphertextBuilder<D> { - GGSWCiphertextBuilder { - data: None, - base2k: None, - k: None, - dsize: None, - } - } -} - -impl GGSWCiphertextBuilder<Vec<u8>> { - #[inline] - pub fn layout<A>(mut self, infos: &A) -> Self - where - A: GGSWInfos, - { - debug_assert!( - infos.size() as u32 > infos.dsize().0, - "invalid ggsw: ceil(k/base2k): {} <= dsize: {}", - infos.size(), - infos.dsize() - ); - - assert!( - infos.dnum().0 * infos.dsize().0 <= infos.size() as u32, - "invalid ggsw: dnum: {} * dsize:{} > ceil(k/base2k): {}", - infos.dnum(), - infos.dsize(), - infos.size(), - ); - - self.data = Some(MatZnx::alloc( - infos.n().into(), - infos.dnum().into(), - (infos.rank() + 1).into(), - (infos.rank() + 1).into(), - infos.size(), - )); - self.base2k = Some(infos.base2k()); - self.k = Some(infos.k()); - self.dsize = Some(infos.dsize()); - self - } -} - -impl<D: Data> GGSWCiphertextBuilder<D> { - #[inline] - pub fn data(mut self, data: MatZnx<D>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - #[inline] - pub fn dsize(mut self, dsize: Dsize) -> Self { - self.dsize = Some(dsize); - self - } - - pub fn build(self) -> Result<GGSW<D>, BuildError> { - let data: MatZnx<D> = self.data.ok_or(BuildError::MissingData)?; - let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?; - let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?; - let dsize: Dsize = self.dsize.ok_or(BuildError::MissingDigits)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if dsize == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GGSW { - data, - base2k, - k, - dsize, - }) - } -} - impl<D: DataRef> fmt::Debug for GGSW<D> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.data)@@ -248,23 +132,21 @@ }
impl<D: DataRef> GGSW<D> { pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> { - GLWECiphertext::builder() - .data(self.data.at(row, col)) - .base2k(self.base2k()) - .k(self.k()) - .build() - .unwrap() + GLWECiphertext { + k: self.k, + base2k: self.base2k, + data: self.data.at(row, col), + } } } impl<D: DataMut> GGSW<D> { pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> { - GLWECiphertext::builder() - .base2k(self.base2k()) - .k(self.k()) - .data(self.data.at_mut(row, col)) - .build() - .unwrap() + GLWECiphertext { + k: self.k, + base2k: self.base2k, + data: self.data.at_mut(row, col), + } } }
@@ -5,7 +5,7 @@ },
source::Source, }; -use crate::layouts::{Base2K, BuildError, Degree, LWEInfos, Rank, TorusPrecision}; +use crate::layouts::{Base2K, Degree, LWEInfos, Rank, TorusPrecision}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; use std::fmt;@@ -83,86 +83,6 @@
impl<D: DataMut> GLWECiphertext<D> { pub fn data_mut(&mut self) -> &mut VecZnx<D> { &mut self.data - } -} - -pub struct GLWECiphertextBuilder<D: Data> { - data: Option<VecZnx<D>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, -} - -impl<D: Data> GLWECiphertext<D> { - #[inline] - pub fn builder() -> GLWECiphertextBuilder<D> { - GLWECiphertextBuilder { - data: None, - base2k: None, - k: None, - } - } -} - -impl GLWECiphertextBuilder<Vec<u8>> { - #[inline] - pub fn layout<A>(mut self, layout: &A) -> Self - where - A: GLWEInfos, - { - self.data = Some(VecZnx::alloc( - layout.n().into(), - (layout.rank() + 1).into(), - layout.size(), - )); - self.base2k = Some(layout.base2k()); - self.k = Some(layout.k()); - self - } -} - -impl<D: Data> GLWECiphertextBuilder<D> { - #[inline] - pub fn data(mut self, data: VecZnx<D>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - pub fn build(self) -> Result<GLWECiphertext<D>, BuildError> { - let data: VecZnx<D> = self.data.ok_or(BuildError::MissingData)?; - let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?; - let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GLWECiphertext { data, base2k, k }) } }
@@ -2,7 +2,7 @@ use poulpy_hal::layouts::{Data, DataMut, DataRef, ReaderFrom, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo, ZnxInfos};
use crate::{ dist::Distribution, - layouts::{Base2K, BuildError, Degree, GLWEInfos, LWEInfos, Rank, TorusPrecision}, + layouts::{Base2K, Degree, GLWEInfos, LWEInfos, Rank, TorusPrecision}, }; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};@@ -20,6 +20,16 @@ pub n: Degree,
pub base2k: Base2K, pub k: TorusPrecision, pub rank: Rank, +} + +pub trait GetDist { + fn get_dist(&self) -> Distribution; +} + +impl<D: DataRef> GetDist for GLWEPublicKey<D> { + fn get_dist(&self) -> Distribution { + self.dist + } } impl<D: Data> LWEInfos for GLWEPublicKey<D> {@@ -67,91 +77,6 @@
impl GLWEInfos for GLWEPublicKeyLayout { fn rank(&self) -> Rank { self.rank - } -} - -pub struct GLWEPublicKeyBuilder<D: Data> { - data: Option<VecZnx<D>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, -} - -impl<D: Data> GLWEPublicKey<D> { - #[inline] - pub fn builder() -> GLWEPublicKeyBuilder<D> { - GLWEPublicKeyBuilder { - data: None, - base2k: None, - k: None, - } - } -} - -impl GLWEPublicKeyBuilder<Vec<u8>> { - #[inline] - pub fn layout<A>(mut self, layout: &A) -> Self - where - A: GLWEInfos, - { - self.data = Some(VecZnx::alloc( - layout.n().into(), - (layout.rank() + 1).into(), - layout.size(), - )); - self.base2k = Some(layout.base2k()); - self.k = Some(layout.k()); - self - } -} - -impl<D: Data> GLWEPublicKeyBuilder<D> { - #[inline] - pub fn data(mut self, data: VecZnx<D>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - pub fn build(self) -> Result<GLWEPublicKey<D>, BuildError> { - let data: VecZnx<D> = self.data.ok_or(BuildError::MissingData)?; - let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?; - let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GLWEPublicKey { - data, - base2k, - k, - dist: Distribution::NONE, - }) } }
@@ -3,8 +3,8 @@
use poulpy_hal::layouts::{Data, DataMut, DataRef, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos}; use crate::layouts::{ - Base2K, BuildError, Degree, GLWECiphertext, GLWECiphertextToMut, GLWECiphertextToRef, GLWEInfos, GLWELayoutSet, LWEInfos, - Rank, TorusPrecision, + Base2K, Degree, GLWECiphertext, GLWECiphertextToMut, GLWECiphertextToRef, GLWEInfos, GLWELayoutSet, LWEInfos, Rank, + TorusPrecision, }; #[derive(PartialEq, Eq, Copy, Clone, Debug)]@@ -74,69 +74,6 @@ Rank(self.data.cols() as u32 - 1)
} } -pub struct GLWEPlaintextBuilder<D: Data> { - data: Option<VecZnx<D>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, -} - -impl<D: Data> GLWEPlaintext<D> { - #[inline] - pub fn builder() -> GLWEPlaintextBuilder<D> { - GLWEPlaintextBuilder { - data: None, - base2k: None, - k: None, - } - } -} - -impl<D: Data> GLWEPlaintextBuilder<D> { - #[inline] - pub fn data(mut self, data: VecZnx<D>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - pub fn build(self) -> Result<GLWEPlaintext<D>, BuildError> { - let data: VecZnx<D> = self.data.ok_or(BuildError::MissingData)?; - let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?; - let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?; - - if base2k.0 == 0 { - return Err(BuildError::ZeroBase2K); - } - - if k.0 == 0 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() != 1 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GLWEPlaintext { data, base2k, k }) - } -} - impl<D: DataRef> fmt::Display for GLWEPlaintext<D> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(@@ -181,23 +118,21 @@ }
impl<D: DataRef> GLWECiphertextToRef for GLWEPlaintext<D> { fn to_ref(&self) -> GLWECiphertext<&[u8]> { - GLWECiphertext::builder() - .data(self.data.to_ref()) - .k(self.k()) - .base2k(self.base2k()) - .build() - .unwrap() + GLWECiphertext { + k: self.k, + base2k: self.base2k, + data: self.data.to_ref(), + } } } impl<D: DataMut> GLWECiphertextToMut for GLWEPlaintext<D> { fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]> { - GLWECiphertext::builder() - .k(self.k()) - .base2k(self.base2k()) - .data(self.data.to_mut()) - .build() - .unwrap() + GLWECiphertext { + k: self.k, + base2k: self.base2k, + data: self.data.to_mut(), + } } }
@@ -5,7 +5,7 @@ layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo, Zn, ZnToMut, ZnToRef, ZnxInfos},
source::Source, }; -use crate::layouts::{Base2K, BuildError, Degree, TorusPrecision}; +use crate::layouts::{Base2K, Degree, TorusPrecision}; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; pub trait LWEInfos {@@ -150,82 +150,6 @@ }
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision) -> usize { Zn::alloc_bytes((n + 1).into(), 1, k.0.div_ceil(base2k.0) as usize) - } -} - -impl LWECiphertextBuilder<Vec<u8>> { - #[inline] - pub fn layout<A>(mut self, layout: A) -> Self - where - A: LWEInfos, - { - self.data = Some(Zn::alloc((layout.n() + 1).into(), 1, layout.size())); - self.base2k = Some(layout.base2k()); - self.k = Some(layout.k()); - self - } -} - -pub struct LWECiphertextBuilder<D: Data> { - data: Option<Zn<D>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, -} - -impl<D: Data> LWECiphertext<D> { - #[inline] - pub fn builder() -> LWECiphertextBuilder<D> { - LWECiphertextBuilder { - data: None, - base2k: None, - k: None, - } - } -} - -impl<D: Data> LWECiphertextBuilder<D> { - #[inline] - pub fn data(mut self, data: Zn<D>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - pub fn build(self) -> Result<LWECiphertext<D>, BuildError> { - let data: Zn<D> = self.data.ok_or(BuildError::MissingData)?; - let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?; - let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?; - - if base2k.0 == 0 { - return Err(BuildError::ZeroBase2K); - } - - if k.0 == 0 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(LWECiphertext { data, base2k, k }) } }
@@ -33,21 +33,16 @@ pub use lwe_pt::*;
pub use lwe_sk::*; pub use lwe_to_glwe_ksk::*; -#[derive(Debug)] -pub enum BuildError { - MissingData, - MissingBase2K, - MissingK, - MissingDigits, - ZeroDegree, - NonPowerOfTwoDegree, - ZeroBase2K, - ZeroTorusPrecision, - ZeroCols, - ZeroLimbs, - ZeroRank, - ZeroDigits, - VecZnxColsNotOne, +use poulpy_hal::layouts::{Backend, Module}; + +pub trait GetDegree { + fn n(&self) -> Degree; +} + +impl<B: Backend> GetDegree for Module<B> { + fn n(&self) -> Degree { + Self::n(&self).into() + } } /// Newtype over `u32` with arithmetic and comparisons against same type and `u32`.
@@ -3,9 +3,8 @@
use crate::layouts::{ AutomorphismKeyToRef, Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, prepared::{ - GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, - GLWESwitchingKeyPreparedAllocBytes, GLWESwitchingKeyPreparedAllocBytesFromInfos, GLWESwitchingKeyPreparedAllocFromInfos, - GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef, + GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, GLWESwitchingKeyPreparedToMut, + GLWESwitchingKeyPreparedToRef, }, };@@ -77,20 +76,9 @@ self.key.dnum()
} } -pub trait AutomorphismKeyPreparedAlloc<B: Backend> { - fn automorphism_key_prepared_alloc( - &self, - base2k: Base2K, - k: TorusPrecision, - rank: Rank, - dnum: Dnum, - dsize: Dsize, - ) -> AutomorphismKeyPrepared<Vec<u8>, B>; -} - -impl<B: Backend> AutomorphismKeyPreparedAlloc<B> for Module<B> +pub trait AutomorphismKeyPreparedAlloc<B: Backend> where - Module<B>: GLWESwitchingKeyPreparedAlloc<B>, + Self: GLWESwitchingKeyPreparedAlloc<B>, { fn automorphism_key_prepared_alloc( &self,@@ -105,18 +93,7 @@ key: self.glwe_switching_key_prepared_alloc(base2k, k, rank, rank, dnum, dsize),
p: 0, } } -} -pub trait AutomorphismKeyPreparedAllocFromInfos<B: Backend> { - fn automorphism_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> AutomorphismKeyPrepared<Vec<u8>, B> - where - A: GGLWEInfos; -} - -impl<B: Backend> AutomorphismKeyPreparedAllocFromInfos<B> for Module<B> -where - Module<B>: GLWESwitchingKeyPreparedAllocFromInfos<B>, -{ fn automorphism_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> AutomorphismKeyPrepared<Vec<u8>, B> where A: GGLWEInfos,@@ -126,28 +103,15 @@ infos.rank_in(),
infos.rank_out(), "rank_in != rank_out is not supported for AutomorphismKeyPrepared" ); - AutomorphismKeyPrepared { - key: self.glwe_switching_key_prepared_alloc_from_infos(infos), - p: 0, - } + self.automorphism_key_prepared_alloc( + infos.base2k(), + infos.k(), + infos.rank(), + infos.dnum(), + infos.dsize(), + ) } -} -pub trait AutomorphismKeyPreparedAllocBytes<B: Backend> { - fn automorphism_key_prepared_alloc_bytes( - &self, - base2k: Base2K, - k: TorusPrecision, - rank: Rank, - dnum: Dnum, - dsize: Dsize, - ) -> usize; -} - -impl<B: Backend> AutomorphismKeyPreparedAllocBytes<B> for Module<B> -where - Module<B>: GLWESwitchingKeyPreparedAllocBytes<B>, -{ fn automorphism_key_prepared_alloc_bytes( &self, base2k: Base2K,@@ -158,18 +122,7 @@ dsize: Dsize,
) -> usize { self.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank, rank, dnum, dsize) } -} -pub trait AutomorphismKeyPreparedAllocBytesFromInfos<B: Backend> { - fn automorphism_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos; -} - -impl<B: Backend> AutomorphismKeyPreparedAllocBytesFromInfos<B> for Module<B> -where - Module<B>: GLWESwitchingKeyPreparedAllocBytesFromInfos<B>, -{ fn automorphism_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GGLWEInfos,@@ -179,15 +132,23 @@ infos.rank_in(),
infos.rank_out(), "rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared" ); - self.glwe_switching_key_prepared_alloc_bytes_from_infos(infos) + self.automorphism_key_prepared_alloc_bytes( + infos.base2k(), + infos.k(), + infos.rank(), + infos.dnum(), + infos.dsize(), + ) } } +impl<B: Backend> AutomorphismKeyPreparedAlloc<B> for Module<B> where Module<B>: GLWESwitchingKeyPreparedAlloc<B> {} + impl<B: Backend> AutomorphismKeyPrepared<Vec<u8>, B> { pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GGLWEInfos, - Module<B>: AutomorphismKeyPreparedAllocFromInfos<B>, + Module<B>: AutomorphismKeyPreparedAlloc<B>, { module.automorphism_key_prepared_alloc_from_infos(infos) }@@ -202,28 +163,22 @@
pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: AutomorphismKeyPreparedAllocBytesFromInfos<B>, + Module<B>: AutomorphismKeyPreparedAlloc<B>, { module.automorphism_key_prepared_alloc_bytes_from_infos(infos) } pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize where - Module<B>: AutomorphismKeyPreparedAllocBytes<B>, + Module<B>: AutomorphismKeyPreparedAlloc<B>, { module.automorphism_key_prepared_alloc_bytes(base2k, k, rank, dnum, dsize) } } -pub trait AutomorphismKeyPrepareTmpBytes { - fn automorphism_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos; -} - -impl<B: Backend> AutomorphismKeyPrepareTmpBytes for Module<B> +pub trait AutomorphismKeyPrepare<B: Backend> where - Module<B>: GLWESwitchingKeyPrepareTmpBytes, + Self: GLWESwitchingKeyPrepare<B>, { fn automorphism_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize where@@ -231,35 +186,35 @@ A: GGLWEInfos,
{ self.glwe_switching_key_prepare_tmp_bytes(infos) } -} -impl<D: DataRef, B: Backend> AutomorphismKeyPrepared<D, B> { - pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize + fn automorphism_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) where - Module<B>: AutomorphismKeyPrepareTmpBytes, + R: AutomorphismKeyPreparedToMut<B> + SetAutomorphismGaloisElement, + O: AutomorphismKeyToRef + GetAutomorphismGaloisElement, { - module.automorphism_key_prepare_tmp_bytes(self) + self.glwe_switching_prepare(&mut res.to_mut().key, &other.to_ref().key, scratch); + res.set_p(other.p()); } } -pub trait AutomorphismKeyPrepare<B: Backend> { - fn automorphism_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) +impl<B: Backend> AutomorphismKeyPrepare<B> for Module<B> where Module<B>: GLWESwitchingKeyPrepare<B> {} + +impl<B: Backend> AutomorphismKeyPrepared<Vec<u8>, B> { + pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize where - R: AutomorphismKeyPreparedToMut<B> + SetAutomorphismGaloisElement, - O: AutomorphismKeyToRef + GetAutomorphismGaloisElement; + Module<B>: GLWESwitchingKeyPrepare<B>, + { + module.automorphism_key_prepare_tmp_bytes(self) + } } -impl<B: Backend> AutomorphismKeyPrepare<B> for Module<B> -where - Module<B>: GLWESwitchingKeyPrepare<B>, -{ - fn automorphism_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) +impl<D: DataMut, B: Backend> AutomorphismKeyPrepared<D, B> { + pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) where - R: AutomorphismKeyPreparedToMut<B> + SetAutomorphismGaloisElement, O: AutomorphismKeyToRef + GetAutomorphismGaloisElement, + Module<B>: AutomorphismKeyPrepare<B>, { - self.glwe_switching_prepare(&mut res.to_mut().key, &other.to_ref().key, scratch); - res.set_p(other.p()); + module.automorphism_key_prepare(self, other, scratch); } }
@@ -1,11 +1,10 @@
use poulpy_hal::{ api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare, VmpPrepareTmpBytes}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat, VmpPMatToMut, VmpPMatToRef, ZnxInfos}, - oep::VmpPMatAllocBytesImpl, }; use crate::layouts::{ - Base2K, BuildError, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GGLWEToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision, + Base2K, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GGLWEToRef, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision, }; #[derive(PartialEq, Eq)]@@ -58,123 +57,9 @@ Dnum(self.data.rows() as u32)
} } -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> GGLWEPrepared<D, B> { - #[inline] - pub fn builder() -> GGLWEPreparedBuilder<D, B> { - GGLWEPreparedBuilder { - data: None, - base2k: None, - k: None, - dsize: None, - } - } -} - -impl<B: Backend> GGLWEPreparedBuilder<Vec<u8>, B> { - #[inline] - pub fn layout<A>(mut self, infos: &A) -> Self - where - A: GGLWEInfos, - B: VmpPMatAllocBytesImpl<B>, - { - self.data = Some(VmpPMat::alloc( - infos.n().into(), - infos.dnum().into(), - infos.rank_in().into(), - (infos.rank_out() + 1).into(), - infos.size(), - )); - self.base2k = Some(infos.base2k()); - self.k = Some(infos.k()); - self.dsize = Some(infos.dsize()); - self - } -} - -impl<D: Data, B: Backend> GGLWEPreparedBuilder<D, B> { - #[inline] - pub fn data(mut self, data: VmpPMat<D, B>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - #[inline] - pub fn dsize(mut self, dsize: Dsize) -> Self { - self.dsize = Some(dsize); - self - } - - 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)?; - let dsize: Dsize = self.dsize.ok_or(BuildError::MissingDigits)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if dsize == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GGLWEPrepared { - data, - base2k, - k, - dsize, - }) - } -} - -pub trait GGLWEPreparedAlloc<B: Backend> { - fn gglwe_prepared_alloc( - &self, - base2k: Base2K, - k: TorusPrecision, - rank_in: Rank, - rank_out: Rank, - dnum: Dnum, - dsize: Dsize, - ) -> GGLWEPrepared<Vec<u8>, B>; -} - -impl<B: Backend> GGLWEPreparedAlloc<B> for Module<B> +pub trait GGLWEPreparedAlloc<B: Backend> where - Module<B>: VmpPMatAlloc<B>, + Self: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes, { fn gglwe_prepared_alloc( &self,@@ -206,23 +91,12 @@ base2k,
dsize, } } -} -pub trait GGLWEPreparedAllocFromInfos<B: Backend> { - fn gglwe_prepared_alloc_from_infos<A>(&self, infos: &A) -> GGLWEPrepared<Vec<u8>, B> - where - A: GGLWEInfos; -} - -impl<B: Backend> GGLWEPreparedAllocFromInfos<B> for Module<B> -where - Module<B>: GGLWEPreparedAlloc<B>, -{ fn gglwe_prepared_alloc_from_infos<A>(&self, infos: &A) -> GGLWEPrepared<Vec<u8>, B> where A: GGLWEInfos, { - assert_eq!(self.n() as u32, infos.n(), "module.n() != infos.n()"); + assert_eq!(self.n(), infos.n()); self.gglwe_prepared_alloc( infos.base2k(), infos.k(),@@ -232,24 +106,7 @@ infos.dnum(),
infos.dsize(), ) } -} -pub trait GGLWEPreparedAllocBytes<B: Backend> { - fn gglwe_prepared_alloc_bytes( - &self, - base2k: Base2K, - k: TorusPrecision, - rank_in: Rank, - rank_out: Rank, - dnum: Dnum, - dsize: Dsize, - ) -> usize; -} - -impl<B: Backend> GGLWEPreparedAllocBytes<B> for Module<B> -where - Module<B>: VmpPMatAllocBytes, -{ fn gglwe_prepared_alloc_bytes( &self, base2k: Base2K,@@ -275,23 +132,12 @@ );
self.vmp_pmat_alloc_bytes(dnum.into(), rank_in.into(), (rank_out + 1).into(), size) } -} -pub trait GGLWEPreparedAllocBytesFromInfos<B: Backend> { - fn gglwe_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos; -} - -impl<B: Backend> GGLWEPreparedAllocBytesFromInfos<B> for Module<B> -where - Module<B>: GGLWEPreparedAllocBytes<B>, -{ fn gglwe_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GGLWEInfos, { - assert_eq!(self.n() as u32, infos.n(), "module.n() != infos.n()"); + assert_eq!(self.n(), infos.n()); self.gglwe_prepared_alloc_bytes( infos.base2k(), infos.k(),@@ -303,11 +149,15 @@ )
} } -impl<B: Backend> GGLWEPrepared<Vec<u8>, B> { +impl<B: Backend> GGLWEPreparedAlloc<B> for Module<B> where Module<B>: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes {} + +impl<B: Backend> GGLWEPrepared<Vec<u8>, B> +where + Module<B>: GGLWEPreparedAlloc<B>, +{ pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GGLWEInfos, - Module<B>: GGLWEPreparedAllocFromInfos<B>, { module.gglwe_prepared_alloc_from_infos(infos) }@@ -320,17 +170,13 @@ rank_in: Rank,
rank_out: Rank, dnum: Dnum, dsize: Dsize, - ) -> Self - where - Module<B>: GGLWEPreparedAlloc<B>, - { + ) -> Self { module.gglwe_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize) } pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: GGLWEPreparedAllocBytesFromInfos<B>, { module.gglwe_prepared_alloc_bytes_from_infos(infos) }@@ -343,23 +189,14 @@ rank_in: Rank,
rank_out: Rank, dnum: Dnum, dsize: Dsize, - ) -> usize - where - Module<B>: GGLWEPreparedAllocBytes<B>, - { + ) -> usize { module.gglwe_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize) } } -pub trait GGLWEPrepareTmpBytes { - fn gglwe_prepare_tmp_bytes<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos; -} - -impl<B: Backend> GGLWEPrepareTmpBytes for Module<B> +pub trait GGLWEPrepare<B: Backend> where - Module<B>: VmpPrepareTmpBytes, + Self: GetDegree + VmpPrepareTmpBytes + VmpPrepare<B>, { fn gglwe_prepare_tmp_bytes<A>(&self, infos: &A) -> usize where@@ -372,28 +209,7 @@ (infos.rank() + 1).into(),
infos.size(), ) } -} - -impl<B: Backend> GGLWEPrepared<Vec<u8>, B> { - pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize - where - Module<B>: GGLWEPrepareTmpBytes, - { - module.gglwe_prepare_tmp_bytes(self) - } -} -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>,@@ -402,8 +218,8 @@ {
let mut res: GGLWEPrepared<&mut [u8], B> = res.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.n(), self.n()); + assert_eq!(other.n(), self.n()); assert_eq!(res.base2k, other.base2k); assert_eq!(res.k, other.k); assert_eq!(res.dsize, other.dsize);@@ -412,15 +228,26 @@ self.vmp_prepare(&mut res.data, &other.data, scratch);
} } +impl<B: Backend> GGLWEPrepare<B> for Module<B> where Self: GetDegree + VmpPrepareTmpBytes + VmpPrepare<B> {} + 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>) + pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) where O: GGLWEToRef, { module.gglwe_prepare(self, other, scratch); + } +} + +impl<B: Backend> GGLWEPrepared<Vec<u8>, B> { + pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize + where + Module<B>: GGLWEPrepare<B>, + { + module.gglwe_prepare_tmp_bytes(self) } }
@@ -3,10 +3,7 @@
use crate::layouts::{ Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKeySetMetaData, GLWESwitchingKeyToRef, GLWESwtichingKeyGetMetaData, LWEInfos, Rank, TorusPrecision, - prepared::{ - GGLWEPrepare, GGLWEPrepareTmpBytes, GGLWEPrepared, GGLWEPreparedAlloc, GGLWEPreparedAllocBytes, - GGLWEPreparedAllocBytesFromInfos, GGLWEPreparedAllocFromInfos, GGLWEPreparedToMut, GGLWEPreparedToRef, - }, + prepared::{GGLWEPrepare, GGLWEPrepared, GGLWEPreparedAlloc, GGLWEPreparedToMut, GGLWEPreparedToRef}, }; #[derive(PartialEq, Eq)]@@ -78,21 +75,9 @@ self.key.dnum()
} } -pub trait GLWESwitchingKeyPreparedAlloc<B: Backend> { - fn glwe_switching_key_prepared_alloc( - &self, - base2k: Base2K, - k: TorusPrecision, - rank_in: Rank, - rank_out: Rank, - dnum: Dnum, - dsize: Dsize, - ) -> GLWESwitchingKeyPrepared<Vec<u8>, B>; -} - -impl<B: Backend> GLWESwitchingKeyPreparedAlloc<B> for Module<B> +pub trait GLWESwitchingKeyPreparedAlloc<B: Backend> where - Module<B>: GGLWEPreparedAlloc<B>, + Self: GGLWEPreparedAlloc<B>, { fn glwe_switching_key_prepared_alloc( &self,@@ -109,46 +94,21 @@ sk_in_n: 0,
sk_out_n: 0, } } -} -pub trait GLWESwitchingKeyPreparedAllocFromInfos<B: Backend> { - fn glwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWESwitchingKeyPrepared<Vec<u8>, B> - where - A: GGLWEInfos; -} - -impl<B: Backend> GLWESwitchingKeyPreparedAllocFromInfos<B> for Module<B> -where - Module<B>: GGLWEPreparedAllocFromInfos<B>, -{ fn glwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWESwitchingKeyPrepared<Vec<u8>, B> where A: GGLWEInfos, { - GLWESwitchingKeyPrepared::<Vec<u8>, B> { - key: self.gglwe_prepared_alloc_from_infos(infos), - sk_in_n: 0, - sk_out_n: 0, - } + self.glwe_switching_key_prepared_alloc( + infos.base2k(), + infos.k(), + infos.rank_in(), + infos.rank_out(), + infos.dnum(), + infos.dsize(), + ) } -} -pub trait GLWESwitchingKeyPreparedAllocBytes<B: Backend> { - fn glwe_switching_key_prepared_alloc_bytes( - &self, - base2k: Base2K, - k: TorusPrecision, - rank_in: Rank, - rank_out: Rank, - dnum: Dnum, - dsize: Dsize, - ) -> usize; -} - -impl<B: Backend> GLWESwitchingKeyPreparedAllocBytes<B> for Module<B> -where - Module<B>: GGLWEPreparedAllocBytes<B>, -{ fn glwe_switching_key_prepared_alloc_bytes( &self, base2k: Base2K,@@ -160,31 +120,31 @@ dsize: Dsize,
) -> usize { self.gglwe_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize) } -} -pub trait GLWESwitchingKeyPreparedAllocBytesFromInfos<B: Backend> { - fn glwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize - where - A: GGLWEInfos; -} - -impl<B: Backend> GLWESwitchingKeyPreparedAllocBytesFromInfos<B> for Module<B> -where - Module<B>: GGLWEPreparedAllocBytesFromInfos<B>, -{ fn glwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GGLWEInfos, { - self.gglwe_prepared_alloc_bytes_from_infos(infos) + self.glwe_switching_key_prepared_alloc_bytes( + infos.base2k(), + infos.k(), + infos.rank_in(), + infos.rank_out(), + infos.dnum(), + infos.dsize(), + ) } } -impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> { +impl<B: Backend> GLWESwitchingKeyPreparedAlloc<B> for Module<B> where Module<B>: GGLWEPreparedAlloc<B> {} + +impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> +where + Module<B>: GLWESwitchingKeyPreparedAlloc<B>, +{ pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GGLWEInfos, - Module<B>: GLWESwitchingKeyPreparedAllocFromInfos<B>, { module.glwe_switching_key_prepared_alloc_from_infos(infos) }@@ -197,17 +157,13 @@ rank_in: Rank,
rank_out: Rank, dnum: Dnum, dsize: Dsize, - ) -> Self - where - Module<B>: GLWESwitchingKeyPreparedAlloc<B>, - { + ) -> Self { module.glwe_switching_key_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize) } pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: GLWESwitchingKeyPreparedAllocBytesFromInfos<B>, { module.glwe_switching_key_prepared_alloc_bytes_from_infos(infos) }@@ -220,23 +176,14 @@ rank_in: Rank,
rank_out: Rank, dnum: Dnum, dsize: Dsize, - ) -> usize - where - Module<B>: GLWESwitchingKeyPreparedAllocBytes<B>, - { + ) -> usize { module.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize) } } -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> +pub trait GLWESwitchingKeyPrepare<B: Backend> where - Module<B>: GGLWEPrepareTmpBytes, + Self: GGLWEPrepare<B>, { fn glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize where@@ -244,28 +191,7 @@ A: GGLWEInfos,
{ self.gglwe_prepare_tmp_bytes(infos) } -} -impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> -where - Module<B>: GGLWEPrepareTmpBytes, -{ - pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize { - module.gglwe_prepare_tmp_bytes(self) - } -} - -pub trait GLWESwitchingKeyPrepare<B: Backend> { - fn glwe_switching_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) - where - R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeySetMetaData, - O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData; -} - -impl<B: Backend> GLWESwitchingKeyPrepare<B> for Module<B> -where - Module<B>: GGLWEPrepare<B>, -{ fn glwe_switching_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) where R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeySetMetaData,@@ -277,6 +203,8 @@ res.set_sk_out_n(other.sk_out_n());
} } +impl<B: Backend> GLWESwitchingKeyPrepare<B> for Module<B> where Self: GGLWEPrepare<B> {} + impl<D: DataMut, B: Backend> GLWESwitchingKeyPrepared<D, B> { pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) where@@ -284,6 +212,15 @@ O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData,
Module<B>: GLWESwitchingKeyPrepare<B>, { module.glwe_switching_prepare(self, other, scratch); + } +} + +impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> +where + Module<B>: GLWESwitchingKeyPrepare<B>, +{ + pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize { + module.gglwe_prepare_tmp_bytes(self) } }
@@ -1,13 +1,9 @@
-use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, -}; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; use crate::layouts::{ Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TensorKey, TensorKeyToRef, TorusPrecision, - compressed::TensorKeyCompressedToMut, prepared::{ - GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, + GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef, }, };@@ -59,19 +55,36 @@ self.keys[0].dnum()
} } -impl<B: Backend> TensorKeyPrepared<Vec<u8>, B> { - pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self +pub trait TensorKeyPreparedAlloc<B: Backend> +where + Self: GLWESwitchingKeyPreparedAlloc<B>, +{ + fn tensor_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + dnum: Dnum, + dsize: Dsize, + rank: Rank, + ) -> TensorKeyPrepared<Vec<u8>, B> { + let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1); + TensorKeyPrepared { + keys: (0..pairs) + .map(|_| self.glwe_switching_key_prepared_alloc(base2k, k, Rank(1), rank, dnum, dsize)) + .collect(), + } + } + + fn tensor_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> TensorKeyPrepared<Vec<u8>, B> where A: GGLWEInfos, - Module<B>: VmpPMatAlloc<B>, { assert_eq!( infos.rank_in(), infos.rank_out(), "rank_in != rank_out is not supported for GGLWETensorKeyPrepared" ); - Self::alloc_with( - module, + self.tensor_key_prepared_alloc( infos.base2k(), infos.k(), infos.dnum(),@@ -80,56 +93,58 @@ infos.rank_out(),
) } - pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self + fn tensor_key_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize { + let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize; + pairs * self.glwe_switching_key_prepared_alloc_bytes(base2k, k, Rank(1), rank, dnum, dsize) + } + + fn tensor_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where - Module<B>: VmpPMatAlloc<B>, + A: GGLWEInfos, { - 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(GLWESwitchingKeyPrepared::alloc( - module, - base2k, - k, - Rank(1), - rank, - dnum, - dsize, - )); - }); - Self { keys } + self.tensor_key_prepared_alloc_bytes( + infos.base2k(), + infos.k(), + infos.rank(), + infos.dnum(), + infos.dsize(), + ) } +} - pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize +impl<B: Backend> TensorKeyPreparedAlloc<B> for Module<B> where Module<B>: GLWESwitchingKeyPreparedAlloc<B> {} + +impl<B: Backend> TensorKeyPrepared<Vec<u8>, B> +where + Module<B>: TensorKeyPreparedAlloc<B>, +{ + pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GGLWEInfos, - Module<B>: VmpPMatAllocBytes, { - assert_eq!( - infos.rank_in(), - infos.rank_out(), - "rank_in != rank_out is not supported for GGLWETensorKey" - ); - let rank_out: usize = infos.rank_out().into(); - let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1); - pairs - * GLWESwitchingKeyPrepared::alloc_bytes( - module, - infos.base2k(), - infos.k(), - Rank(1), - infos.rank_out(), - infos.dnum(), - infos.dsize(), - ) + module.tensor_key_prepared_alloc_from_infos(infos) + } + + pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self { + module.tensor_key_prepared_alloc(base2k, k, dnum, dsize, rank) } - pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize + pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize where - Module<B>: VmpPMatAllocBytes, + A: GGLWEInfos, { - let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize; - pairs * GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, Rank(1), rank, dnum, dsize) + module.tensor_key_prepared_alloc_bytes_from_infos(infos) + } + + pub fn alloc_bytes_with( + module: &Module<B>, + base2k: Base2K, + k: TorusPrecision, + rank: Rank, + dnum: Dnum, + dsize: Dsize, + ) -> usize { + module.tensor_key_prepared_alloc_bytes(base2k, k, rank, dnum, dsize) } }@@ -155,51 +170,26 @@ &self.keys[i * rank + j - (i * (i + 1) / 2)]
} } -pub trait TensorKeyPrepareTmpBytes { - fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize; -} - -impl<B: Backend> TensorKeyPrepareTmpBytes for Module<B> +pub trait TensorKeyPrepare<B: Backend> where - Module<B>: GLWESwitchingKeyPrepareTmpBytes, + Self: GLWESwitchingKeyPrepare<B>, { - fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize { - self.glwe_switching_key_prepare_tmp_bytes(infos) - } -} - -impl<B: Backend> TensorKeyPrepared<Vec<u8>, B> -where - Module<B>: TensorKeyPrepareTmpBytes, -{ - fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) -> usize + fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGLWEInfos, { - module.tensor_key_prepare_tmp_bytes(infos) + self.glwe_switching_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>) + fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) where R: TensorKeyPreparedToMut<B>, O: TensorKeyToRef, { - let res = res.to_mut(); - let other = other.to_ref(); + let mut res: TensorKeyPrepared<&mut [u8], B> = res.to_mut(); + let other: TensorKey<&[u8]> = other.to_ref(); - assert_eq!(self.keys.len(), other.keys.len()); + assert_eq!(res.keys.len(), other.keys.len()); for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) { self.glwe_switching_prepare(a, b, scratch);@@ -207,44 +197,29 @@ }
} } -impl<D: DataMut, B: Backend> TensorKeyPrepared<D, B> +impl<B: Backend> TensorKeyPrepare<B> for Module<B> where Module<B>: GLWESwitchingKeyPrepare<B> {} + +impl<B: Backend> TensorKeyPrepared<Vec<u8>, B> where Module<B>: TensorKeyPrepare<B>, { - fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) + fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) -> usize where - O: TensorKeyToRef, + A: GGLWEInfos, { - module.tensor_key_prepare(self, other, scratch); + module.tensor_key_prepare_tmp_bytes(infos) } } -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> +impl<D: DataMut, B: Backend> TensorKeyPrepared<D, B> where Module<B>: TensorKeyPrepare<B>, { - fn tensor_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) + fn prepare<O>(&mut self, module: &Module<B>, 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); + module.tensor_key_prepare(self, other, scratch); } }
@@ -1,11 +1,10 @@
use poulpy_hal::{ api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare, VmpPrepareTmpBytes}, layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat, VmpPMatToMut, VmpPMatToRef, ZnxInfos}, - oep::VmpPMatAllocBytesImpl, }; use crate::layouts::{ - Base2K, BuildError, Degree, Dnum, Dsize, GGSW, GGSWInfos, GGSWToMut, GGSWToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision, + Base2K, Degree, Dnum, Dsize, GGSW, GGSWInfos, GGSWToRef, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision, }; #[derive(PartialEq, Eq)]@@ -50,131 +49,51 @@ Dnum(self.data.rows() as u32)
} } -pub struct GGSWCiphertextPreparedBuilder<D: Data, B: Backend> { - data: Option<VmpPMat<D, B>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, - dsize: Option<Dsize>, -} - -impl<D: Data, B: Backend> GGSWPrepared<D, B> { - #[inline] - pub fn builder() -> GGSWCiphertextPreparedBuilder<D, B> { - GGSWCiphertextPreparedBuilder { - data: None, - base2k: None, - k: None, - dsize: None, - } - } -} - -impl<B: Backend> GGSWCiphertextPreparedBuilder<Vec<u8>, B> { - #[inline] - pub fn layout<A>(mut self, infos: &A) -> Self - where - A: GGSWInfos, - B: VmpPMatAllocBytesImpl<B>, - { +pub trait GGSWPreparedAlloc<B: Backend> +where + Self: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes, +{ + fn ggsw_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + dnum: Dnum, + dsize: Dsize, + rank: Rank, + ) -> GGSWPrepared<Vec<u8>, B> { + let size: usize = k.0.div_ceil(base2k.0) as usize; debug_assert!( - infos.size() as u32 > infos.dsize().0, - "invalid ggsw: ceil(k/base2k): {} <= dsize: {}", - infos.size(), - infos.dsize() + size as u32 > dsize.0, + "invalid ggsw: ceil(k/base2k): {size} <= dsize: {}", + dsize.0 ); assert!( - infos.dnum().0 * infos.dsize().0 <= infos.size() as u32, - "invalid ggsw: dnum: {} * dsize:{} > ceil(k/base2k): {}", - infos.dnum(), - infos.dsize(), - infos.size(), + dnum.0 * dsize.0 <= size as u32, + "invalid ggsw: dnum: {} * dsize:{} > ceil(k/base2k): {size}", + dnum.0, + dsize.0, ); - self.data = Some(VmpPMat::alloc( - infos.n().into(), - infos.dnum().into(), - (infos.rank() + 1).into(), - (infos.rank() + 1).into(), - infos.size(), - )); - self.base2k = Some(infos.base2k()); - self.k = Some(infos.k()); - self.dsize = Some(infos.dsize()); - self - } -} - -impl<D: Data, B: Backend> GGSWCiphertextPreparedBuilder<D, B> { - #[inline] - pub fn data(mut self, data: VmpPMat<D, B>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - #[inline] - pub fn dsize(mut self, dsize: Dsize) -> Self { - self.dsize = Some(dsize); - self - } - - 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)?; - let dsize: Dsize = self.dsize.ok_or(BuildError::MissingDigits)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if dsize == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GGSWPrepared { - data, + GGSWPrepared { + data: self.vmp_pmat_alloc( + dnum.into(), + (rank + 1).into(), + (rank + 1).into(), + k.0.div_ceil(base2k.0) as usize, + ), + k, base2k, - k, dsize, - }) + } } -} -impl<B: Backend> GGSWPrepared<Vec<u8>, B> { - pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self + fn ggsw_prepared_alloc_from_infos<A>(&self, infos: &A) -> GGSWPrepared<Vec<u8>, B> where A: GGSWInfos, - Module<B>: VmpPMatAlloc<B>, { - Self::alloc_with( - module, + assert_eq!(self.n(), infos.n()); + self.ggsw_prepared_alloc( infos.base2k(), infos.k(), infos.dnum(),@@ -183,10 +102,7 @@ infos.rank(),
) } - pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self - where - Module<B>: VmpPMatAlloc<B>, - { + fn ggsw_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> usize { let size: usize = k.0.div_ceil(base2k.0) as usize; debug_assert!( size as u32 > dsize.0,@@ -201,26 +117,15 @@ dnum.0,
dsize.0, ); - Self { - data: module.vmp_pmat_alloc( - dnum.into(), - (rank + 1).into(), - (rank + 1).into(), - k.0.div_ceil(base2k.0) as usize, - ), - k, - base2k, - dsize, - } + self.vmp_pmat_alloc_bytes(dnum.into(), (rank + 1).into(), (rank + 1).into(), size) } - pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize + fn ggsw_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GGSWInfos, - Module<B>: VmpPMatAllocBytes, { - Self::alloc_bytes_with( - module, + assert_eq!(self.n(), infos.n()); + self.ggsw_prepared_alloc_bytes( infos.base2k(), infos.k(), infos.dnum(),@@ -228,26 +133,41 @@ infos.dsize(),
infos.rank(), ) } +} - pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> usize +impl<B: Backend> GGSWPreparedAlloc<B> for Module<B> where Module<B>: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes {} + +impl<B: Backend> GGSWPrepared<Vec<u8>, B> +where + Module<B>: GGSWPreparedAlloc<B>, +{ + pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where - Module<B>: VmpPMatAllocBytes, + A: GGSWInfos, { - let size: usize = k.0.div_ceil(base2k.0) as usize; - debug_assert!( - size as u32 > dsize.0, - "invalid ggsw: ceil(k/base2k): {size} <= dsize: {}", - dsize.0 - ); + module.ggsw_prepared_alloc_from_infos(infos) + } - assert!( - dnum.0 * dsize.0 <= size as u32, - "invalid ggsw: dnum: {} * dsize:{} > ceil(k/base2k): {size}", - dnum.0, - dsize.0, - ); + pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self { + module.ggsw_prepared_alloc(base2k, k, dnum, dsize, rank) + } - module.vmp_pmat_alloc_bytes(dnum.into(), (rank + 1).into(), (rank + 1).into(), size) + pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize + where + A: GGSWInfos, + { + module.ggsw_prepared_alloc_bytes_from_infos(infos) + } + + pub fn alloc_bytes_with( + module: &Module<B>, + base2k: Base2K, + k: TorusPrecision, + dnum: Dnum, + dsize: Dsize, + rank: Rank, + ) -> usize { + module.ggsw_prepared_alloc_bytes(base2k, k, dnum, dsize, rank) } }@@ -257,20 +177,15 @@ &self.data
} } -pub trait GGSWPrepareTmpBytes { - fn ggsw_prepare_tmp_bytes<A>(&self, infos: &A) -> usize - where - A: GGSWInfos; -} - -impl<B: Backend> GGSWPrepareTmpBytes for Module<B> +pub trait GGSWPrepare<B: Backend> where - Module<B>: VmpPrepareTmpBytes, + Self: GetDegree + VmpPrepareTmpBytes + VmpPrepare<B>, { fn ggsw_prepare_tmp_bytes<A>(&self, infos: &A) -> usize where A: GGSWInfos, { + assert_eq!(self.n(), infos.n()); self.vmp_prepare_tmp_bytes( infos.dnum().into(), (infos.rank() + 1).into(),@@ -278,31 +193,6 @@ (infos.rank() + 1).into(),
infos.size(), ) } -} - -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 ggsw_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) where R: GGSWPreparedToMut<B>,@@ -310,6 +200,8 @@ O: GGSWToRef,
{ let mut res: GGSWPrepared<&mut [u8], B> = res.to_mut(); let other: GGSW<&[u8]> = other.to_ref(); + assert_eq!(res.n(), self.n()); + assert_eq!(other.n(), self.n()); assert_eq!(res.k, other.k); assert_eq!(res.base2k, other.base2k); assert_eq!(res.dsize, other.dsize);@@ -317,44 +209,29 @@ self.vmp_prepare(&mut res.data, &other.data, scratch);
} } -impl<D: DataMut, B: Backend> GGSWPrepared<D, B> +impl<B: Backend> GGSWPrepare<B> for Module<B> where Self: GetDegree + VmpPrepareTmpBytes + VmpPrepare<B> {} + +impl<B: Backend> GGSWPrepared<Vec<u8>, B> where Module<B>: GGSWPrepare<B>, { - pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) + pub fn prepare_tmp_bytes<A>(&self, module: Module<B>, infos: &A) -> usize where - O: GGSWToRef, + A: GGSWInfos, { - module.ggsw_prepare(self, other, scratch); + module.ggsw_prepare_tmp_bytes(infos) } } -pub trait GGSWPrepareAlloc<B: Backend> { - fn ggsw_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) - where - O: GGSWToRef; -} - -impl<B: Backend> GGSWPrepareAlloc<B> for Module<B> +impl<D: DataMut, B: Backend> GGSWPrepared<D, B> where Module<B>: GGSWPrepare<B>, { - fn ggsw_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) + pub fn prepare<O>(&mut self, module: &Module<B>, 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); + module.ggsw_prepare(self, other, scratch); } }@@ -383,7 +260,7 @@ GGSWPrepared {
base2k: self.base2k, k: self.k, dsize: self.dsize, - data: self.data.to_mut(), + data: self.data.to_ref(), } } }
@@ -1,12 +1,11 @@
use poulpy_hal::{ api::{VecZnxDftAlloc, VecZnxDftAllocBytes, VecZnxDftApply}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VecZnxDft, VecZnxDftToMut, VecZnxDftToRef, ZnxInfos}, - oep::VecZnxDftAllocBytesImpl, + layouts::{Backend, Data, DataMut, DataRef, Module, VecZnxDft, VecZnxDftToMut, VecZnxDftToRef, ZnxInfos}, }; use crate::{ dist::Distribution, - layouts::{Base2K, BuildError, Degree, GLWEInfos, GLWEPublicKey, GLWEPublicKeyToRef, LWEInfos, Rank, TorusPrecision}, + layouts::{Base2K, Degree, GLWEInfos, GLWEPublicKey, GLWEPublicKeyToRef, GetDegree, GetDist, LWEInfos, Rank, TorusPrecision}, }; #[derive(PartialEq, Eq)]@@ -51,229 +50,106 @@ Rank(self.data.cols() as u32 - 1)
} } -pub struct GLWEPublicKeyPreparedBuilder<D: Data, B: Backend> { - data: Option<VecZnxDft<D, B>>, - base2k: Option<Base2K>, - k: Option<TorusPrecision>, -} - -impl<D: Data, B: Backend> GLWEPublicKeyPrepared<D, B> { - #[inline] - pub fn builder() -> GLWEPublicKeyPreparedBuilder<D, B> { - GLWEPublicKeyPreparedBuilder { - data: None, - base2k: None, - k: None, - } - } -} - -impl<B: Backend> GLWEPublicKeyPreparedBuilder<Vec<u8>, B> { - #[inline] - pub fn layout<A>(mut self, layout: &A) -> Self - where - A: GLWEInfos, - B: VecZnxDftAllocBytesImpl<B>, - { - self.data = Some(VecZnxDft::alloc( - layout.n().into(), - (layout.rank() + 1).into(), - layout.size(), - )); - self.base2k = Some(layout.base2k()); - self.k = Some(layout.k()); - self - } -} - -impl<D: Data, B: Backend> GLWEPublicKeyPreparedBuilder<D, B> { - #[inline] - pub fn data(mut self, data: VecZnxDft<D, B>) -> Self { - self.data = Some(data); - self - } - #[inline] - pub fn base2k(mut self, base2k: Base2K) -> Self { - self.base2k = Some(base2k); - self - } - #[inline] - pub fn k(mut self, k: TorusPrecision) -> Self { - self.k = Some(k); - self - } - - pub fn build(self) -> Result<GLWEPublicKeyPrepared<D, B>, BuildError> { - let data: VecZnxDft<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)?; - - if base2k == 0_u32 { - return Err(BuildError::ZeroBase2K); - } - - if k == 0_u32 { - return Err(BuildError::ZeroTorusPrecision); - } - - if data.n() == 0 { - return Err(BuildError::ZeroDegree); - } - - if data.cols() == 0 { - return Err(BuildError::ZeroCols); - } - - if data.size() == 0 { - return Err(BuildError::ZeroLimbs); - } - - Ok(GLWEPublicKeyPrepared { - data, +pub trait GLWEPublicKeyPreparedAlloc<B: Backend> +where + Self: GetDegree + VecZnxDftAlloc<B> + VecZnxDftAllocBytes, +{ + fn glwe_public_key_prepared_alloc(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> GLWEPublicKeyPrepared<Vec<u8>, B> { + GLWEPublicKeyPrepared { + data: self.vec_znx_dft_alloc((rank + 1).into(), k.0.div_ceil(base2k.0) as usize), base2k, k, dist: Distribution::NONE, - }) + } } -} -impl<B: Backend> GLWEPublicKeyPrepared<Vec<u8>, B> { - pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self + fn glwe_public_key_alloc_from_infos<A>(&self, infos: &A) -> GLWEPublicKeyPrepared<Vec<u8>, B> where A: GLWEInfos, - Module<B>: VecZnxDftAlloc<B>, { - debug_assert_eq!(module.n(), infos.n().0 as usize, "module.n() != infos.n()"); - Self::alloc_with(module, infos.base2k(), infos.k(), infos.rank()) + self.glwe_public_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank()) } - pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self - where - Module<B>: VecZnxDftAlloc<B>, - { - Self { - data: module.vec_znx_dft_alloc((rank + 1).into(), k.0.div_ceil(base2k.0) as usize), - base2k, - k, - dist: Distribution::NONE, - } + fn glwe_public_key_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize { + self.vec_znx_dft_alloc_bytes((rank + 1).into(), k.0.div_ceil(base2k.0) as usize) } - pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize + fn glwe_public_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GLWEInfos, - Module<B>: VecZnxDftAllocBytes, { - debug_assert_eq!(module.n(), infos.n().0 as usize, "module.n() != infos.n()"); - Self::alloc_bytes_with(module, infos.base2k(), infos.k(), infos.rank()) - } - - pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize - where - Module<B>: VecZnxDftAllocBytes, - { - module.vec_znx_dft_alloc_bytes((rank + 1).into(), k.0.div_ceil(base2k.0) as usize) + self.glwe_public_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.rank()) } } -pub trait GLWEPublicKeyPrepareTmpBytes { - fn glwe_public_key_prepare_tmp_bytes<A>(&self, infos: &A) - where - A: GLWEInfos; -} +impl<B: Backend> GLWEPublicKeyPreparedAlloc<B> for Module<B> where Self: VecZnxDftAlloc<B> + VecZnxDftAllocBytes {} -impl<B: Backend> GLWEPublicKeyPrepareTmpBytes for Module<B> { - fn glwe_public_key_prepare_tmp_bytes<A>(&self, infos: &A) +impl<B: Backend> GLWEPublicKeyPrepared<Vec<u8>, B> +where + Module<B>: GLWEPublicKeyPreparedAlloc<B>, +{ + pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GLWEInfos, { - 0 + module.glwe_public_key_alloc_from_infos(infos) } -} -impl<B: Backend> GLWEPublicKeyPrepared<Vec<u8>, B> { - pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) + pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self { + module.glwe_public_key_prepared_alloc(base2k, k, rank) + } + + pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize where A: GLWEInfos, - Module<B>: GLWEPublicKeyPrepareTmpBytes, { - module.glwe_public_key_prepare_tmp_bytes(infos); + module.glwe_public_key_prepared_alloc_bytes_from_infos(infos) } -} -pub trait GLWEPublicKeyPrepare<B: Backend> { - fn glwe_public_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) - where - R: GLWEPublicKeyPreparedToMut<B> + SetDist, - O: GLWEPublicKeyToRef; + pub fn alloc_bytes(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize { + module.glwe_public_key_prepared_alloc_bytes(base2k, k, rank) + } } -impl<B: Backend> GLWEPublicKeyPrepare<B> for Module<B> +pub trait GLWEPublicKeyPrepare<B: Backend> where - Module<B>: VecZnxDftAlloc<B> + VecZnxDftApply<B>, + Self: GetDegree + VecZnxDftApply<B>, { - fn glwe_public_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) + fn glwe_public_key_prepare<R, O>(&self, res: &mut R, other: &O) where R: GLWEPublicKeyPreparedToMut<B> + SetDist, - O: GLWEPublicKeyToRef, + O: GLWEPublicKeyToRef + GetDist, { { - let res: GLWEPublicKeyPrepared<&mut [u8], B> = res.to_mut(); + let mut res: GLWEPublicKeyPrepared<&mut [u8], B> = res.to_mut(); let other: GLWEPublicKey<&[u8]> = other.to_ref(); - assert_eq!(res.n(), self.n() as u32); - assert_eq!(other.n(), self.n() as u32); + assert_eq!(res.n(), self.n()); + assert_eq!(other.n(), self.n()); assert_eq!(res.size(), other.size()); assert_eq!(res.k(), other.k()); assert_eq!(res.base2k(), other.base2k()); - for i in 0..(self.rank() + 1).into() { - self.vec_znx_dft_apply(1, 0, &mut self.data, i, &other.data, i); + for i in 0..(res.rank() + 1).into() { + self.vec_znx_dft_apply(1, 0, &mut res.data, i, &other.data, i); } } - res.set_dist(other.dist); - } -} - -impl<D: DataMut, B: Backend> GLWEPublicKeyPrepared<D, B> -where - Module<B>: GLWEPublicKeyPrepare<B>, -{ - pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) - where - O: GLWEPublicKeyToRef, - { - module.glwe_public_key_prepare(self, other, scratch); + res.set_dist(other.get_dist()); } } -pub trait GLWEPublicKeyPrepareAlloc<B: Backend> { - fn glwe_public_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) - where - O: GLWEPublicKeyToRef; -} +impl<B: Backend> GLWEPublicKeyPrepare<B> for Module<B> where Self: GetDegree + VecZnxDftApply<B> {} -impl<B: Backend> GLWEPublicKeyPrepareAlloc<B> for Module<B> +impl<D: DataMut, B: Backend> GLWEPublicKeyPrepared<D, B> where Module<B>: GLWEPublicKeyPrepare<B>, { - fn glwe_public_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) + pub fn prepare<O>(&mut self, module: &Module<B>, other: &O) where - O: GLWEPublicKeyToRef, + O: GLWEPublicKeyToRef + GetDist, { - let mut ct_prepared: GLWEPublicKeyPrepared<Vec<u8>, B> = GLWEPublicKeyPrepared::alloc(self, other); - self.glwe_public_key_prepare(&mut ct_prepared, ct_prepared, scratch); - ct_prepared - } -} - -impl<D: DataRef> GLWEPublicKey<D> { - pub fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &mut Scratch<B>) - where - Module<B>: GLWEPublicKeyPrepareAlloc<B>, - { - module.glwe_public_key_prepare_alloc(self, scratch); + module.glwe_public_key_prepare(self, other); } }
@@ -1,12 +1,12 @@
use poulpy_hal::{ api::{SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, SvpPPol, SvpPPolToMut, SvpPPolToRef, ZnxInfos}, + layouts::{Backend, Data, DataMut, DataRef, Module, SvpPPol, SvpPPolToMut, SvpPPolToRef, ZnxInfos}, }; use crate::{ dist::Distribution, layouts::{ - Base2K, Degree, GLWEInfos, GLWESecret, GLWESecretToMut, GLWESecretToRef, LWEInfos, Rank, TorusPrecision, + Base2K, Degree, GLWEInfos, GLWESecret, GLWESecretToRef, GetDegree, GetDist, LWEInfos, Rank, TorusPrecision, prepared::SetDist, }, };@@ -44,40 +44,63 @@ fn rank(&self) -> Rank {
Rank(self.data.cols() as u32) } } -impl<B: Backend> GLWESecretPrepared<Vec<u8>, B> { - pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self + +pub trait GLWESecretPreparedAlloc<B: Backend> +where + Self: GetDegree + SvpPPolAllocBytes + SvpPPolAlloc<B>, +{ + fn glwe_secret_prepared_alloc(&self, rank: Rank) -> GLWESecretPrepared<Vec<u8>, B> { + GLWESecretPrepared { + data: self.svp_ppol_alloc(rank.into()), + dist: Distribution::NONE, + } + } + fn glwe_secret_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWESecretPrepared<Vec<u8>, B> where A: GLWEInfos, - Module<B>: SvpPPolAlloc<B>, { - assert_eq!(module.n() as u32, infos.n()); - Self::alloc_with(module, infos.rank()) + assert_eq!(self.n(), infos.n()); + self.glwe_secret_prepared_alloc(infos.rank()) } - pub fn alloc_with(module: &Module<B>, rank: Rank) -> Self + fn glwe_secret_alloc_bytes(&self, rank: Rank) -> usize { + self.svp_ppol_alloc_bytes(rank.into()) + } + fn glwe_secret_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where - Module<B>: SvpPPolAlloc<B>, + A: GLWEInfos, { - Self { - data: module.svp_ppol_alloc(rank.into()), - dist: Distribution::NONE, - } + assert_eq!(self.n(), infos.n()); + self.glwe_secret_alloc_bytes(infos.rank()) } +} - pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize +impl<B: Backend> GLWESecretPreparedAlloc<B> for Module<B> where Self: GetDegree + SvpPPolAllocBytes + SvpPPolAlloc<B> {} + +impl<B: Backend> GLWESecretPrepared<Vec<u8>, B> +where + Module<B>: GLWESecretPreparedAlloc<B>, +{ + pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GLWEInfos, - Module<B>: SvpPPolAllocBytes, { - assert_eq!(module.n() as u32, infos.n()); - Self::alloc_bytes_with(module, infos.rank()) + module.glwe_secret_prepared_alloc_from_infos(infos) + } + + pub fn alloc(module: &Module<B>, rank: Rank) -> Self { + module.glwe_secret_prepared_alloc(rank) } - pub fn alloc_bytes_with(module: &Module<B>, rank: Rank) -> usize + pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize where - Module<B>: SvpPPolAllocBytes, + A: GLWEInfos, { - module.svp_ppol_alloc_bytes(rank.into()) + module.glwe_secret_alloc_bytes_from_infos(infos) + } + + pub fn alloc_bytes(module: &Module<B>, rank: Rank) -> usize { + module.glwe_secret_alloc_bytes(rank) } }@@ -91,81 +114,29 @@ Rank(self.data.cols() as u32)
} } -pub trait GLWESecretPrepareTmpBytes { - fn glwe_secret_prepare_tmp_bytes<A>(&self, infos: &A) - where - A: GLWEInfos; -} - -impl<B: Backend> GLWESecretPrepareTmpBytes for Module<B> { - fn glwe_secret_prepare_tmp_bytes<A>(&self, infos: &A) - where - A: GLWEInfos, - { - 0 - } -} - -impl<B: Backend> GLWESecretPrepared<Vec<u8>, B> +pub trait GLWESecretPrepare<B: Backend> where - Module<B>: GLWESecretPrepareTmpBytes, + Self: SvpPrepare<B>, { - fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) -> usize - where - A: GLWEInfos, - { - 0 - } -} - -pub trait GLWESecretPrepare<B: Backend> { - fn glwe_secret_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) + fn glwe_secret_prepare<R, O>(&self, res: &mut R, other: &O) where R: GLWESecretPreparedToMut<B> + SetDist, - O: GLWESecretToRef; -} - -impl<B: Backend> GLWESecretPrepare<B> for Module<B> -where - Module<B>: SvpPrepare<B>, -{ - fn glwe_secret_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) - where - R: GLWESecretPreparedToMut<B> + SetDist, - O: GLWESecretToRef, + O: GLWESecretToRef + GetDist, { { - let res: GLWESecretPrepared<&mut [u8], _> = res.to_mut(); + let mut res: GLWESecretPrepared<&mut [u8], _> = res.to_mut(); let other: GLWESecret<&[u8]> = other.to_ref(); - for i in 0..self.rank().into() { + for i in 0..res.rank().into() { self.svp_prepare(&mut res.data, i, &other.data, i); } } - res.set_dist(other.dist); + res.set_dist(other.get_dist()); } } -pub trait GLWESecretPrepareAlloc<B: Backend> { - fn glwe_secret_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) - where - O: GLWESecretToMut; -} - -impl<B: Backend> GLWESecretPrepareAlloc<B> for Module<B> -where - Module<B>: GLWESecretPrepare<B>, -{ - fn glwe_secret_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) - where - O: GLWESecretToMut, - { - let mut ct_prep: GLWESecretPrepared<Vec<u8>, B> = GLWESecretPrepared::alloc(self, self); - self.glwe_secret_prepare(&mut ct_prep, other, scratch); - ct_prep - } -} +impl<B: Backend> GLWESecretPrepare<B> for Module<B> where Self: SvpPrepare<B> {} pub trait GLWESecretPreparedToRef<B: Backend> { fn to_ref(&self) -> GLWESecretPrepared<&[u8], B>;
@@ -1,13 +1,9 @@
-use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, -}; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; use crate::layouts::{ - Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWESwitchingKeyToMut, GLWEToLWESwitchingKeyToRef, LWEInfos, Rank, - TorusPrecision, + Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision, prepared::{ - GLWESecretPrepareTmpBytes, GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, + GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef, }, };@@ -57,11 +53,22 @@ self.0.dnum()
} } -impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> { - pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self +pub trait GLWEToLWESwitchingKeyPreparedAlloc<B: Backend> +where + Self: GLWESwitchingKeyPreparedAlloc<B>, +{ + fn glwe_to_lwe_switching_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + dnum: Dnum, + ) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> { + GLWEToLWESwitchingKeyPrepared(self.glwe_switching_key_prepared_alloc(base2k, k, rank_in, Rank(1), dnum, Dsize(1))) + } + fn glwe_to_lwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> where A: GGLWEInfos, - Module<B>: VmpPMatAlloc<B>, { debug_assert_eq!( infos.rank_out().0,@@ -73,28 +80,22 @@ infos.dsize().0,
1, "dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared" ); - Self(GLWESwitchingKeyPrepared::alloc_from_infos(module, infos)) + self.glwe_to_lwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum()) } - pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self - where - Module<B>: VmpPMatAlloc<B>, - { - Self(GLWESwitchingKeyPrepared::alloc( - module, - base2k, - k, - rank_in, - Rank(1), - dnum, - Dsize(1), - )) + fn glwe_to_lwe_switching_key_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_in: Rank, + dnum: Dnum, + ) -> usize { + self.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank_in, Rank(1), dnum, Dsize(1)) } - pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize + fn glwe_to_lwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: VmpPMatAllocBytes, { debug_assert_eq!( infos.rank_out().0,@@ -106,92 +107,78 @@ infos.dsize().0,
1, "dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared" ); - GLWESwitchingKeyPrepared::alloc_bytes_from_infos(module, infos) - } - - pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize - where - Module<B>: VmpPMatAllocBytes, - { - GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1)) + self.glwe_to_lwe_switching_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum()) } } -pub trait GLWEToLWESwitchingKeyPrepareTmpBytes { - fn glwe_to_lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) - where - A: GGLWEInfos; -} +impl<B: Backend> GLWEToLWESwitchingKeyPreparedAlloc<B> for Module<B> where Module<B>: GLWESwitchingKeyPreparedAlloc<B> {} -impl<B: Backend> GLWEToLWESwitchingKeyPrepareTmpBytes for Module<B> +impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> where - Module<B>: GLWEToLWESwitchingKeyPrepareTmpBytes, + Module<B>: GLWEToLWESwitchingKeyPreparedAlloc<B>, { - fn glwe_to_lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) + pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GGLWEInfos, { - self.glwe_to_lwe_switching_key_prepare_tmp_bytes(infos); + module.glwe_to_lwe_switching_key_prepared_alloc_from_infos(infos) } -} -impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> { - pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) + pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self { + module.glwe_to_lwe_switching_key_prepared_alloc(base2k, k, rank_in, dnum) + } + + pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize where - A: GLWEInfos, - Module<B>: GLWEToLWESwitchingKeyPrepareTmpBytes, + A: GGLWEInfos, { - module.glwe_secret_prepare_tmp_bytes(infos); + module.glwe_to_lwe_switching_key_prepared_alloc_bytes_from_infos(infos) } -} -pub trait GLWEToLWESwitchingKeyPrepare<B: Backend> { - fn glwe_to_lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) - where - R: GLWEToLWESwitchingKeyPreparedToMut<B>, - O: GLWEToLWESwitchingKeyToRef; + pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize { + module.glwe_to_lwe_switching_key_prepared_alloc_bytes(base2k, k, rank_in, dnum) + } } -impl<B: Backend> GLWEToLWESwitchingKeyPrepare<B> for Module<B> +pub trait GLWEToLWESwitchingKeyPrepare<B: Backend> where - Module<B>: GLWESwitchingKeyPrepare<B>, + Self: GLWESwitchingKeyPrepare<B>, { - fn glwe_to_lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) + fn glwe_to_lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) where - R: GLWEToLWESwitchingKeyPreparedToMut<B>, - O: GLWEToLWESwitchingKeyToRef, + A: GGLWEInfos, { - self.glwe_switching_prepare(&mut res.to_mut().0, other, scratch); + self.glwe_switching_key_prepare_tmp_bytes(infos); } -} -impl<D: DataMut, B: Backend> GLWEToLWESwitchingKeyPrepared<D, B> { - fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &Scratch<B>) + fn glwe_to_lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) where + R: GLWEToLWESwitchingKeyPreparedToMut<B>, O: GLWEToLWESwitchingKeyToRef, - Module<B>: GLWEToLWESwitchingKeyPrepare<B>, { - module.glwe_to_lwe_switching_key_prepare(self, other, scratch); + self.glwe_switching_prepare(&mut res.to_mut().0, &other.to_ref().0, scratch); } } -pub trait GLWEToLWESwitchingKeyPrepareAlloc<B: Backend> { - fn glwe_to_lwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) +impl<B: Backend> GLWEToLWESwitchingKeyPrepare<B> for Module<B> where Self: GLWESwitchingKeyPrepare<B> {} + +impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> { + pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) where - O: GLWEToLWESwitchingKeyToRef; + A: GGLWEInfos, + Module<B>: GLWEToLWESwitchingKeyPrepare<B>, + { + module.glwe_to_lwe_switching_key_prepare_tmp_bytes(infos); + } } -impl<B: Backend> GLWEToLWESwitchingKeyPrepareAlloc<B> for Module<B> -where - Module<B>: GLWEToLWESwitchingKeyPrepare<B>, -{ - fn glwe_to_lwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) +impl<D: DataMut, B: Backend> GLWEToLWESwitchingKeyPrepared<D, B> { + fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) where O: GLWEToLWESwitchingKeyToRef, + Module<B>: GLWEToLWESwitchingKeyPrepare<B>, { - let mut ct_prep: GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> = GLWEToLWESwitchingKeyPrepared::alloc(self, &other.to_ref()); - self.glwe_to_lwe_switching_key_prepare(&mut ct_prep, other, scratch); - ct_prep + module.glwe_to_lwe_switching_key_prepare(self, other, scratch); } }
@@ -1,11 +1,11 @@
-use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, -}; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; use crate::layouts::{ Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKeyToRef, Rank, TorusPrecision, - prepared::{GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef}, + prepared::{ + GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, GLWESwitchingKeyPreparedToMut, + GLWESwitchingKeyPreparedToRef, + }, }; #[derive(PartialEq, Eq)]@@ -52,11 +52,22 @@ self.0.dnum()
} } -impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> { - pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self +pub trait LWESwitchingKeyPreparedAlloc<B: Backend> +where + Self: GLWESwitchingKeyPreparedAlloc<B>, +{ + fn lwe_switching_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + dnum: Dnum, + ) -> LWESwitchingKeyPrepared<Vec<u8>, B> { + LWESwitchingKeyPrepared(self.glwe_switching_key_prepared_alloc(base2k, k, Rank(1), Rank(1), dnum, Dsize(1))) + } + + fn lwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> LWESwitchingKeyPrepared<Vec<u8>, B> where A: GGLWEInfos, - Module<B>: VmpPMatAlloc<B>, { debug_assert_eq!( infos.dsize().0,@@ -73,28 +84,16 @@ infos.rank_out().0,
1, "rank_out > 1 is not supported for LWESwitchingKey" ); - Self(GLWESwitchingKeyPrepared::alloc_from_infos(module, infos)) + self.lwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.dnum()) } - pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self - where - Module<B>: VmpPMatAlloc<B>, - { - Self(GLWESwitchingKeyPrepared::alloc( - module, - base2k, - k, - Rank(1), - Rank(1), - dnum, - Dsize(1), - )) + fn lwe_switching_key_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize { + self.glwe_switching_key_prepared_alloc_bytes(base2k, k, Rank(1), Rank(1), dnum, Dsize(1)) } - pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize + fn lwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: VmpPMatAllocBytes, { debug_assert_eq!( infos.dsize().0,@@ -111,92 +110,77 @@ infos.rank_out().0,
1, "rank_out > 1 is not supported for LWESwitchingKey" ); - GLWESwitchingKeyPrepared::alloc_bytes_from_infos(module, infos) - } - - pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize - where - Module<B>: VmpPMatAllocBytes, - { - GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1)) + self.lwe_switching_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.dnum()) } } -pub trait LWESwitchingKeyPrepareTmpBytes { - fn lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) - where - A: GGLWEInfos; -} +impl<B: Backend> LWESwitchingKeyPreparedAlloc<B> for Module<B> where Self: GLWESwitchingKeyPreparedAlloc<B> {} -impl<B: Backend> LWESwitchingKeyPrepareTmpBytes for Module<B> +impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> where - Module<B>: LWESwitchingKeyPrepareTmpBytes, + Module<B>: LWESwitchingKeyPreparedAlloc<B>, { - fn lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) + pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GGLWEInfos, { - self.lwe_switching_key_prepare_tmp_bytes(infos); + module.lwe_switching_key_prepared_alloc_from_infos(infos) + } + + pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self { + module.lwe_switching_key_prepared_alloc(base2k, k, dnum) } -} -impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> { - pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) + pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize where - A: GLWEInfos, - Module<B>: LWESwitchingKeyPrepareTmpBytes, + A: GGLWEInfos, { - module.glwe_secret_prepare_tmp_bytes(infos); + module.lwe_switching_key_prepared_alloc_bytes_from_infos(infos) } -} -pub trait LWESwitchingKeyPrepare<B: Backend> { - fn lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) - where - R: LWESwitchingKeyPreparedToMut<B>, - O: LWESwitchingKeyToRef; + pub fn alloc_bytes(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize { + module.lwe_switching_key_prepared_alloc_bytes(base2k, k, dnum) + } } -impl<B: Backend> LWESwitchingKeyPrepare<B> for Module<B> +pub trait LWESwitchingKeyPrepare<B: Backend> where - Module<B>: GLWESwitchingKeyPrepare<B>, + Self: GLWESwitchingKeyPrepare<B>, { - fn lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) + fn lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) + where + A: GGLWEInfos, + { + self.glwe_switching_key_prepare_tmp_bytes(infos); + } + fn lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) where R: LWESwitchingKeyPreparedToMut<B>, O: LWESwitchingKeyToRef, { - self.glwe_switching_prepare(&mut res.to_mut().0, other, scratch); + self.glwe_switching_prepare(&mut res.to_mut().0, &other.to_ref().0, scratch); } } -impl<D: DataMut, B: Backend> LWESwitchingKeyPrepared<D, B> { - fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &Scratch<B>) +impl<B: Backend> LWESwitchingKeyPrepare<B> for Module<B> where Self: GLWESwitchingKeyPrepare<B> {} + +impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> { + pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) where - O: LWESwitchingKeyToRef, + A: GGLWEInfos, Module<B>: LWESwitchingKeyPrepare<B>, { - module.lwe_switching_key_prepare(self, other, scratch); + module.lwe_switching_key_prepare_tmp_bytes(infos); } } -pub trait LWESwitchingKeyPrepareAlloc<B: Backend> { - fn lwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) - where - O: LWESwitchingKeyToRef; -} - -impl<B: Backend> LWESwitchingKeyPrepareAlloc<B> for Module<B> -where - Module<B>: LWESwitchingKeyPrepare<B>, -{ - fn lwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) +impl<D: DataMut, B: Backend> LWESwitchingKeyPrepared<D, B> { + fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) where O: LWESwitchingKeyToRef, + Module<B>: LWESwitchingKeyPrepare<B>, { - let mut ct_prep: LWESwitchingKeyPrepared<Vec<u8>, B> = LWESwitchingKeyPrepared::alloc(self, &other.to_ref()); - self.lwe_switching_key_prepare(&mut ct_prep, other, scratch); - ct_prep + module.lwe_switching_key_prepare(self, other, scratch); } }
@@ -1,11 +1,11 @@
-use poulpy_hal::{ - api::{VmpPMatAlloc, VmpPMatAllocBytes}, - layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}, -}; +use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch}; use crate::layouts::{ Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKeyToRef, Rank, TorusPrecision, - prepared::{GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef}, + prepared::{ + GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedAlloc, GLWESwitchingKeyPreparedToMut, + GLWESwitchingKeyPreparedToRef, + }, }; /// A special [GLWESwitchingKey] required to for the conversion from [LWECiphertext] to [GLWECiphertext].@@ -54,11 +54,22 @@ self.0.dnum()
} } -impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> { - pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self +pub trait LWEToGLWESwitchingKeyPreparedAlloc<B: Backend> +where + Self: GLWESwitchingKeyPreparedAlloc<B>, +{ + fn lwe_to_glwe_switching_key_prepared_alloc( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_out: Rank, + dnum: Dnum, + ) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> { + LWEToGLWESwitchingKeyPrepared(self.glwe_switching_key_prepared_alloc(base2k, k, Rank(1), rank_out, dnum, Dsize(1))) + } + fn lwe_to_glwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> where A: GGLWEInfos, - Module<B>: VmpPMatAlloc<B>, { debug_assert_eq!( infos.rank_in().0,@@ -70,28 +81,22 @@ infos.dsize().0,
1, "dsize > 1 is not supported for LWEToGLWESwitchingKey" ); - Self(GLWESwitchingKeyPrepared::alloc_from_infos(module, infos)) + self.lwe_to_glwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum()) } - pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self - where - Module<B>: VmpPMatAlloc<B>, - { - Self(GLWESwitchingKeyPrepared::alloc( - module, - base2k, - k, - Rank(1), - rank_out, - dnum, - Dsize(1), - )) + fn lwe_to_glwe_switching_key_prepared_alloc_bytes( + &self, + base2k: Base2K, + k: TorusPrecision, + rank_out: Rank, + dnum: Dnum, + ) -> usize { + self.glwe_switching_key_prepared_alloc_bytes(base2k, k, Rank(1), rank_out, dnum, Dsize(1)) } - pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize + fn lwe_to_glwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize where A: GGLWEInfos, - Module<B>: VmpPMatAllocBytes, { debug_assert_eq!( infos.rank_in().0,@@ -103,92 +108,78 @@ infos.dsize().0,
1, "dsize > 1 is not supported for LWEToGLWESwitchingKey" ); - GLWESwitchingKeyPrepared::alloc_bytes_from_infos(module, infos) - } - - pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize - where - Module<B>: VmpPMatAllocBytes, - { - GLWESwitchingKeyPrepared::alloc_bytes(module, base2k, k, Rank(1), rank_out, dnum, Dsize(1)) + self.lwe_to_glwe_switching_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum()) } } -pub trait LWEToGLWESwitchingKeyPrepareTmpBytes { - fn lwe_to_glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) - where - A: GGLWEInfos; -} +impl<B: Backend> LWEToGLWESwitchingKeyPreparedAlloc<B> for Module<B> where Self: GLWESwitchingKeyPreparedAlloc<B> {} -impl<B: Backend> LWEToGLWESwitchingKeyPrepareTmpBytes for Module<B> +impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> where - Module<B>: LWEToGLWESwitchingKeyPrepareTmpBytes, + Module<B>: LWEToGLWESwitchingKeyPreparedAlloc<B>, { - fn lwe_to_glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) + pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self where A: GGLWEInfos, { - self.lwe_to_glwe_switching_key_prepare_tmp_bytes(infos); + module.lwe_to_glwe_switching_key_prepared_alloc_from_infos(infos) } -} -impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> { - pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) + pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self { + module.lwe_to_glwe_switching_key_prepared_alloc(base2k, k, rank_out, dnum) + } + + pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize where - A: GLWEInfos, - Module<B>: LWEToGLWESwitchingKeyPrepareTmpBytes, + A: GGLWEInfos, { - module.glwe_secret_prepare_tmp_bytes(infos); + module.lwe_to_glwe_switching_key_prepared_alloc_bytes_from_infos(infos) } -} -pub trait LWEToGLWESwitchingKeyPrepare<B: Backend> { - fn lwe_to_glwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) - where - R: LWEToGLWESwitchingKeyPreparedToMut<B>, - O: LWEToGLWESwitchingKeyToRef; + pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> usize { + module.lwe_to_glwe_switching_key_prepared_alloc_bytes(base2k, k, rank_out, dnum) + } } -impl<B: Backend> LWEToGLWESwitchingKeyPrepare<B> for Module<B> +pub trait LWEToGLWESwitchingKeyPrepare<B: Backend> where - Module<B>: GLWESwitchingKeyPrepare<B>, + Self: GLWESwitchingKeyPrepare<B>, { - fn lwe_to_glwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>) + fn lwe_to_glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) where - R: LWEToGLWESwitchingKeyPreparedToMut<B>, - O: LWEToGLWESwitchingKeyToRef, + A: GGLWEInfos, { - self.glwe_switching_prepare(&mut res.to_mut().0, other, scratch); + self.glwe_switching_key_prepare_tmp_bytes(infos); } -} -impl<D: DataMut, B: Backend> LWEToGLWESwitchingKeyPrepared<D, B> { - fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &Scratch<B>) + fn lwe_to_glwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>) where + R: LWEToGLWESwitchingKeyPreparedToMut<B>, O: LWEToGLWESwitchingKeyToRef, - Module<B>: LWEToGLWESwitchingKeyPrepare<B>, { - module.lwe_to_glwe_switching_key_prepare(self, other, scratch); + self.glwe_switching_prepare(&mut res.to_mut().0, &other.to_ref().0, scratch); } } -pub trait LWEToGLWESwitchingKeyPrepareAlloc<B: Backend> { - fn lwe_to_glwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) +impl<B: Backend> LWEToGLWESwitchingKeyPrepare<B> for Module<B> where Self: GLWESwitchingKeyPrepare<B> {} + +impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> { + pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) where - O: LWEToGLWESwitchingKeyToRef; + A: GGLWEInfos, + Module<B>: LWEToGLWESwitchingKeyPrepare<B>, + { + module.lwe_to_glwe_switching_key_prepare_tmp_bytes(infos); + } } -impl<B: Backend> LWEToGLWESwitchingKeyPrepareAlloc<B> for Module<B> -where - Module<B>: LWEToGLWESwitchingKeyPrepare<B>, -{ - fn lwe_to_glwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) +impl<D: DataMut, B: Backend> LWEToGLWESwitchingKeyPrepared<D, B> { + fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>) where O: LWEToGLWESwitchingKeyToRef, + Module<B>: LWEToGLWESwitchingKeyPrepare<B>, { - let mut ct_prep: LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> = LWEToGLWESwitchingKeyPrepared::alloc(self, &other.to_ref()); - self.lwe_to_glwe_switching_key_prepare(&mut ct_prep, other, scratch); - ct_prep + module.lwe_to_glwe_switching_key_prepare(self, other, scratch); } }
@@ -129,12 +129,11 @@ A: GLWEInfos,
{ let (data, scratch) = self.take_vec_znx(infos.n().into(), (infos.rank() + 1).into(), infos.size()); ( - GLWECiphertext::builder() - .base2k(infos.base2k()) - .k(infos.k()) - .data(data) - .build() - .unwrap(), + GLWECiphertext { + k: infos.k(), + base2k: infos.base2k(), + data, + }, scratch, ) }@@ -169,12 +168,11 @@ A: GLWEInfos,
{ let (data, scratch) = self.take_vec_znx(infos.n().into(), 1, infos.size()); ( - GLWEPlaintext::builder() - .base2k(infos.base2k()) - .k(infos.k()) - .data(data) - .build() - .unwrap(), + GLWEPlaintext { + k: infos.k(), + base2k: infos.base2k(), + data, + }, scratch, ) }@@ -196,13 +194,12 @@ (infos.rank_out() + 1).into(),
infos.size(), ); ( - GGLWE::builder() - .base2k(infos.base2k()) - .k(infos.k()) - .dsize(infos.dsize()) - .data(data) - .build() - .unwrap(), + GGLWE { + k: infos.k(), + base2k: infos.base2k(), + dsize: infos.dsize(), + data, + }, scratch, ) }@@ -224,13 +221,12 @@ (infos.rank_out() + 1).into(),
infos.size(), ); ( - GGLWEPrepared::builder() - .base2k(infos.base2k()) - .dsize(infos.dsize()) - .k(infos.k()) - .data(data) - .build() - .unwrap(), + GGLWEPrepared { + k: infos.k(), + base2k: infos.base2k(), + dsize: infos.dsize(), + data, + }, scratch, ) }@@ -252,13 +248,12 @@ (infos.rank() + 1).into(),
infos.size(), ); ( - GGSW::builder() - .base2k(infos.base2k()) - .dsize(infos.dsize()) - .k(infos.k()) - .data(data) - .build() - .unwrap(), + GGSW { + k: infos.k(), + base2k: infos.base2k(), + dsize: infos.dsize(), + data, + }, scratch, ) }@@ -280,13 +275,12 @@ (infos.rank() + 1).into(),
infos.size(), ); ( - GGSWPrepared::builder() - .base2k(infos.base2k()) - .dsize(infos.dsize()) - .k(infos.k()) - .data(data) - .build() - .unwrap(), + GGSWPrepared { + k: infos.k(), + base2k: infos.base2k(), + dsize: infos.dsize(), + data, + }, scratch, ) }@@ -321,13 +315,12 @@ A: GLWEInfos,
{ let (data, scratch) = self.take_vec_znx(infos.n().into(), (infos.rank() + 1).into(), infos.size()); ( - GLWEPublicKey::builder() - .base2k(infos.base2k()) - .k(infos.k()) - .base2k(infos.base2k()) - .data(data) - .build() - .unwrap(), + GLWEPublicKey { + k: infos.k(), + dist: Distribution::NONE, + base2k: infos.base2k(), + data, + }, scratch, ) }@@ -343,12 +336,12 @@ A: GLWEInfos,
{ let (data, scratch) = self.take_vec_znx_dft(infos.n().into(), (infos.rank() + 1).into(), infos.size()); ( - GLWEPublicKeyPrepared::builder() - .base2k(infos.base2k()) - .k(infos.k()) - .data(data) - .build() - .unwrap(), + GLWEPublicKeyPrepared { + k: infos.k(), + dist: Distribution::NONE, + base2k: infos.base2k(), + data, + }, scratch, ) }
@@ -182,7 +182,7 @@ let mut auto_key_prepared: AutomorphismKeyPrepared<Vec<u8>, B> =
AutomorphismKeyPrepared::alloc_from_infos(module, &auto_key_layout); auto_key_prepared.prepare(module, &auto_key, scratch.borrow()); - let mut tsk_prepared: TensorKeyPrepared<Vec<u8>, B> = TensorKeyPrepared::alloc(module, &tensor_key_layout); + let mut tsk_prepared: TensorKeyPrepared<Vec<u8>, B> = TensorKeyPrepared::alloc_from_infos(module, &tensor_key_layout); tsk_prepared.prepare(module, &tensor_key, scratch.borrow()); ct_out.automorphism(@@ -362,7 +362,7 @@ let mut auto_key_prepared: AutomorphismKeyPrepared<Vec<u8>, B> =
AutomorphismKeyPrepared::alloc_from_infos(module, &auto_key_layout); auto_key_prepared.prepare(module, &auto_key, scratch.borrow()); - let mut tsk_prepared: TensorKeyPrepared<Vec<u8>, B> = TensorKeyPrepared::alloc(module, &tensor_key_layout); + let mut tsk_prepared: TensorKeyPrepared<Vec<u8>, B> = TensorKeyPrepared::alloc_from_infos(module, &tensor_key_layout); tsk_prepared.prepare(module, &tensor_key, scratch.borrow()); ct.automorphism_inplace(module, &auto_key_prepared, &tsk_prepared, scratch.borrow());
@@ -101,7 +101,7 @@ Module<BE>: VmpPMatAlloc<BE>,
{ Self { blocks: (0..T::WORD_SIZE) - .map(|_| GGSWPrepared::alloc_with(module, base2k, k, dnum, dsize, rank)) + .map(|_| GGSWPrepared::alloc(module, base2k, k, dnum, dsize, rank)) .collect(), _base: 1, _phantom: PhantomData,
@@ -122,7 +122,7 @@ where
A: BlindRotationKeyInfos, { let mut data: Vec<GGSWPrepared<Vec<u8>, B>> = Vec::with_capacity(infos.n_lwe().into()); - (0..infos.n_lwe().as_usize()).for_each(|_| data.push(GGSWPrepared::alloc(module, infos))); + (0..infos.n_lwe().as_usize()).for_each(|_| data.push(GGSWPrepared::alloc_from_infos(module, infos))); Self { data, dist: Distribution::NONE,