This commit is contained in:
Pro7ech
2025-10-13 23:49:09 +02:00
parent d32b4738c3
commit 0533cdff8a
27 changed files with 776 additions and 2022 deletions

View File

@@ -25,7 +25,7 @@ impl GLWESwitchingKeyCompressed<Vec<u8>> {
{
(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())
}
}

View File

@@ -22,7 +22,7 @@ impl GLWESwitchingKey<Vec<u8>> {
{
(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

View File

@@ -23,7 +23,7 @@ impl TensorKey<Vec<u8>> {
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)

View File

@@ -22,7 +22,7 @@ impl GLWEToLWESwitchingKey<Vec<u8>> {
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()))
}

View File

@@ -39,7 +39,7 @@ impl LWESwitchingKey<Vec<u8>> {
"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)
}
}

View File

@@ -6,9 +6,7 @@ use poulpy_hal::{
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 @@ impl GLWECiphertextCompressed<Vec<u8>> {
}
}
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 @@ pub trait GLWECiphertextCompressedToRef {
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 @@ pub trait GLWECiphertextCompressedToMut {
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(),
}
}
}

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
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 @@ impl<D: Data> GGLWEInfos for GGLWE<D> {
}
}
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> fmt::Display for GGLWE<D> {
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),
}
}
}

View File

@@ -4,7 +4,7 @@ use poulpy_hal::{
};
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 @@ impl<D: Data> GGSWInfos for GGSW<D> {
}
}
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: DataMut> FillUniform for GGSW<D> {
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),
}
}
}

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
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;
@@ -86,86 +86,6 @@ impl<D: DataMut> GLWECiphertext<D> {
}
}
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 })
}
}
impl<D: Data> LWEInfos for GLWECiphertext<D> {
fn base2k(&self) -> Base2K {
self.base2k

View File

@@ -2,7 +2,7 @@ use poulpy_hal::layouts::{Data, DataMut, DataRef, ReaderFrom, VecZnx, VecZnxToMu
use crate::{
dist::Distribution,
layouts::{Base2K, BuildError, Degree, GLWEInfos, LWEInfos, Rank, TorusPrecision},
layouts::{Base2K, Degree, GLWEInfos, LWEInfos, Rank, TorusPrecision},
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@@ -22,6 +22,16 @@ pub struct GLWEPublicKeyLayout {
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> {
fn base2k(&self) -> Base2K {
self.base2k
@@ -70,91 +80,6 @@ impl GLWEInfos for GLWEPublicKeyLayout {
}
}
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,
})
}
}
impl GLWEPublicKey<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where

View File

@@ -3,8 +3,8 @@ use std::fmt;
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 @@ impl<D: Data> GLWEInfos for GLWEPlaintext<D> {
}
}
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 GLWEPlaintext<Vec<u8>> {
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(),
}
}
}

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
source::Source,
};
use crate::layouts::{Base2K, BuildError, Degree, TorusPrecision};
use crate::layouts::{Base2K, Degree, TorusPrecision};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
pub trait LWEInfos {
@@ -153,82 +153,6 @@ impl LWECiphertext<Vec<u8>> {
}
}
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 })
}
}
pub trait LWECiphertextToRef {
fn to_ref(&self) -> LWECiphertext<&[u8]>;
}

View File

@@ -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`.

View File

@@ -3,9 +3,8 @@ use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch};
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 @@ impl<D: Data, B: Backend> GGLWEInfos for AutomorphismKeyPrepared<D, B> {
}
}
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 @@ where
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 @@ where
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 @@ where
) -> 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 @@ where
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 @@ impl<B: Backend> AutomorphismKeyPrepared<Vec<u8>, B> {
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,28 +186,7 @@ where
{
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
where
Module<B>: AutomorphismKeyPrepareTmpBytes,
{
module.automorphism_key_prepare_tmp_bytes(self)
}
}
pub trait AutomorphismKeyPrepare<B: Backend> {
fn automorphism_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: AutomorphismKeyPreparedToMut<B> + SetAutomorphismGaloisElement,
O: AutomorphismKeyToRef + GetAutomorphismGaloisElement;
}
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>)
where
R: AutomorphismKeyPreparedToMut<B> + SetAutomorphismGaloisElement,
@@ -263,6 +197,27 @@ where
}
}
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
Module<B>: GLWESwitchingKeyPrepare<B>,
{
module.automorphism_key_prepare_tmp_bytes(self)
}
}
impl<D: DataMut, B: Backend> AutomorphismKeyPrepared<D, B> {
pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: AutomorphismKeyToRef + GetAutomorphismGaloisElement,
Module<B>: AutomorphismKeyPrepare<B>,
{
module.automorphism_key_prepare(self, other, scratch);
}
}
pub trait AutomorphismKeyPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> AutomorphismKeyPrepared<&mut [u8], B>;
}

View File

@@ -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 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWEPrepared<D, B> {
}
}
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 @@ where
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 @@ where
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 @@ where
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 @@ where
}
}
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 @@ impl<B: Backend> GGLWEPrepared<Vec<u8>, B> {
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 @@ impl<B: Backend> GGLWEPrepared<Vec<u8>, B> {
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 @@ where
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 @@ where
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,11 +228,13 @@ where
}
}
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,
{
@@ -424,6 +242,15 @@ where
}
}
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)
}
}
pub trait GGLWEPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], B>;
}

View File

@@ -3,10 +3,7 @@ use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch};
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 @@ impl<D: Data, B: Backend> GGLWEInfos for GLWESwitchingKeyPrepared<D, B> {
}
}
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 @@ where
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 @@ where
) -> 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 @@ impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> {
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 @@ impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> {
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 @@ where
{
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 @@ where
}
}
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
@@ -287,6 +215,15 @@ impl<D: DataMut, B: Backend> GLWESwitchingKeyPrepared<D, B> {
}
}
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)
}
}
pub trait GLWESwitchingKeyPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> GLWESwitchingKeyPrepared<&mut [u8], B>;
}

View File

@@ -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 @@ impl<D: Data, B: Backend> GGLWEInfos for TensorKeyPrepared<D, B> {
}
}
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 @@ impl<B: Backend> TensorKeyPrepared<Vec<u8>, B> {
)
}
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(),
)
}
}
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.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<A>(module: &Module<B>, infos: &A) -> usize
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_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>: VmpPMatAllocBytes,
{
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)
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,22 +170,38 @@ impl<D: DataRef, B: Backend> TensorKeyPrepared<D, B> {
}
}
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 {
fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
self.glwe_switching_key_prepare_tmp_bytes(infos)
}
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: TensorKeyPreparedToMut<B>,
O: TensorKeyToRef,
{
let mut res: TensorKeyPrepared<&mut [u8], B> = res.to_mut();
let other: TensorKey<&[u8]> = other.to_ref();
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);
}
}
}
impl<B: Backend> TensorKeyPrepare<B> for Module<B> where Module<B>: GLWESwitchingKeyPrepare<B> {}
impl<B: Backend> TensorKeyPrepared<Vec<u8>, B>
where
Module<B>: TensorKeyPrepareTmpBytes,
Module<B>: TensorKeyPrepare<B>,
{
fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) -> usize
where
@@ -180,33 +211,6 @@ where
}
}
pub trait TensorKeyPrepare<B: Backend> {
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
where
R: TensorKeyPreparedToMut<B>,
O: TensorKeyToRef;
}
impl<B: Backend> TensorKeyPrepare<B> for Module<B>
where
Module<B>: GLWESwitchingKeyPrepare<B>,
{
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
where
R: TensorKeyPreparedToMut<B>,
O: TensorKeyToRef,
{
let res = res.to_mut();
let other = other.to_ref();
assert_eq!(self.keys.len(), other.keys.len());
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
self.glwe_switching_prepare(a, b, scratch);
}
}
}
impl<D: DataMut, B: Backend> TensorKeyPrepared<D, B>
where
Module<B>: TensorKeyPrepare<B>,
@@ -219,35 +223,6 @@ where
}
}
pub trait TensorKeyPrepareAlloc<B: Backend> {
fn tensor_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: TensorKeyToRef;
}
impl<B: Backend> TensorKeyPrepareAlloc<B> for Module<B>
where
Module<B>: TensorKeyPrepare<B>,
{
fn tensor_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: TensorKeyToRef,
{
let mut ct_prepared: TensorKeyPrepared<Vec<u8>, B> = TensorKeyPrepared::alloc(self, other);
self.tensor_key_prepare(ct_prepared, other, scratch);
ct_prepared
}
}
impl<D: DataRef> TensorKey<D> {
pub fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &Scratch<B>)
where
Module<B>: TensorKeyPrepareAlloc<B>,
{
module.tensor_key_prepare_alloc(self, scratch);
}
}
pub trait TensorKeyPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> TensorKeyPrepared<&mut [u8], B>;
}

View File

@@ -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,143 +49,18 @@ impl<D: Data, B: Backend> GGSWInfos for GGSWPrepared<D, B> {
}
}
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>,
{
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(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,
base2k,
k,
dsize,
})
}
}
impl<B: Backend> GGSWPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGSWInfos,
Module<B>: VmpPMatAlloc<B>,
{
Self::alloc_with(
module,
infos.base2k(),
infos.k(),
infos.dnum(),
infos.dsize(),
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>,
{
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!(
size as u32 > dsize.0,
@@ -201,8 +75,8 @@ impl<B: Backend> GGSWPrepared<Vec<u8>, B> {
dsize.0,
);
Self {
data: module.vmp_pmat_alloc(
GGSWPrepared {
data: self.vmp_pmat_alloc(
dnum.into(),
(rank + 1).into(),
(rank + 1).into(),
@@ -214,13 +88,12 @@ impl<B: Backend> GGSWPrepared<Vec<u8>, B> {
}
}
pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize
fn ggsw_prepared_alloc_from_infos<A>(&self, infos: &A) -> GGSWPrepared<Vec<u8>, B>
where
A: GGSWInfos,
Module<B>: VmpPMatAllocBytes,
{
Self::alloc_bytes_with(
module,
assert_eq!(self.n(), infos.n());
self.ggsw_prepared_alloc(
infos.base2k(),
infos.k(),
infos.dnum(),
@@ -229,10 +102,7 @@ impl<B: Backend> GGSWPrepared<Vec<u8>, B> {
)
}
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> usize
where
Module<B>: VmpPMatAllocBytes,
{
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,
@@ -247,7 +117,57 @@ impl<B: Backend> GGSWPrepared<Vec<u8>, B> {
dsize.0,
);
module.vmp_pmat_alloc_bytes(dnum.into(), (rank + 1).into(), (rank + 1).into(), size)
self.vmp_pmat_alloc_bytes(dnum.into(), (rank + 1).into(), (rank + 1).into(), size)
}
fn ggsw_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
where
A: GGSWInfos,
{
assert_eq!(self.n(), infos.n());
self.ggsw_prepared_alloc_bytes(
infos.base2k(),
infos.k(),
infos.dnum(),
infos.dsize(),
infos.rank(),
)
}
}
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
A: GGSWInfos,
{
module.ggsw_prepared_alloc_from_infos(infos)
}
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)
}
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 @@ impl<D: DataRef, B: Backend> GGSWPrepared<D, B> {
}
}
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 @@ where
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 @@ where
{
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,6 +209,20 @@ where
}
}
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_tmp_bytes<A>(&self, module: Module<B>, infos: &A) -> usize
where
A: GGSWInfos,
{
module.ggsw_prepare_tmp_bytes(infos)
}
}
impl<D: DataMut, B: Backend> GGSWPrepared<D, B>
where
Module<B>: GGSWPrepare<B>,
@@ -329,35 +235,6 @@ where
}
}
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>
where
Module<B>: GGSWPrepare<B>,
{
fn ggsw_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: GGSWToRef,
{
let mut ct_prepared: GGSWPrepared<Vec<u8>, B> = GGSWPrepared::alloc(self, other);
self.ggsw_prepare(&mut ct_prepared, other, scratch);
ct_prepared
}
}
impl<D: DataRef> GGSW<D> {
fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &mut Scratch<B>)
where
Module<B>: GGSWPrepareAlloc<B>,
{
module.ggsw_prepare_alloc(self, scratch);
}
}
pub trait GGSWPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> GGSWPrepared<&mut [u8], B>;
}
@@ -383,7 +260,7 @@ impl<D: DataRef, B: Backend> GGSWCiphertextPreparedToRef<B> for GGSWPrepared<D,
base2k: self.base2k,
k: self.k,
dsize: self.dsize,
data: self.data.to_mut(),
data: self.data.to_ref(),
}
}
}

View File

@@ -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 @@ impl<D: Data, B: Backend> GLWEInfos for GLWEPublicKeyPrepared<D, B> {
}
}
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,
base2k,
k,
dist: Distribution::NONE,
})
}
}
impl<B: Backend> GLWEPublicKeyPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
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())
}
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,
}
}
pub fn alloc_bytes<A>(module: &Module<B>, 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)
}
}
pub trait GLWEPublicKeyPrepareTmpBytes {
fn glwe_public_key_prepare_tmp_bytes<A>(&self, infos: &A)
where
A: GLWEInfos;
}
impl<B: Backend> GLWEPublicKeyPrepareTmpBytes for Module<B> {
fn glwe_public_key_prepare_tmp_bytes<A>(&self, infos: &A)
where
A: GLWEInfos,
{
0
}
}
impl<B: Backend> GLWEPublicKeyPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A)
where
A: GLWEInfos,
Module<B>: GLWEPublicKeyPrepareTmpBytes,
{
module.glwe_public_key_prepare_tmp_bytes(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;
}
impl<B: Backend> GLWEPublicKeyPrepare<B> for Module<B>
pub trait GLWEPublicKeyPreparedAlloc<B: Backend>
where
Module<B>: VecZnxDftAlloc<B> + VecZnxDftApply<B>,
Self: GetDegree + VecZnxDftAlloc<B> + VecZnxDftAllocBytes,
{
fn glwe_public_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
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,
}
}
fn glwe_public_key_alloc_from_infos<A>(&self, infos: &A) -> GLWEPublicKeyPrepared<Vec<u8>, B>
where
A: GLWEInfos,
{
self.glwe_public_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank())
}
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)
}
fn glwe_public_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
where
A: GLWEInfos,
{
self.glwe_public_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.rank())
}
}
impl<B: Backend> GLWEPublicKeyPreparedAlloc<B> for Module<B> where Self: VecZnxDftAlloc<B> + VecZnxDftAllocBytes {}
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,
{
module.glwe_public_key_alloc_from_infos(infos)
}
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.glwe_public_key_prepared_alloc_bytes_from_infos(infos)
}
pub fn alloc_bytes(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
module.glwe_public_key_prepared_alloc_bytes(base2k, k, rank)
}
}
pub trait GLWEPublicKeyPrepare<B: Backend>
where
Self: GetDegree + VecZnxDftApply<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);
res.set_dist(other.get_dist());
}
}
impl<B: Backend> GLWEPublicKeyPrepare<B> for Module<B> where Self: GetDegree + VecZnxDftApply<B> {}
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>)
pub fn prepare<O>(&mut self, module: &Module<B>, other: &O)
where
O: GLWEPublicKeyToRef,
O: GLWEPublicKeyToRef + GetDist,
{
module.glwe_public_key_prepare(self, other, scratch);
}
}
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> GLWEPublicKeyPrepareAlloc<B> for Module<B>
where
Module<B>: GLWEPublicKeyPrepare<B>,
{
fn glwe_public_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: GLWEPublicKeyToRef,
{
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);
}
}

View File

@@ -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 @@ impl<D: Data, B: Backend> GLWEInfos for GLWESecretPrepared<D, B> {
Rank(self.data.cols() as u32)
}
}
impl<B: Backend> GLWESecretPrepared<Vec<u8>, B> {
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
where
A: GLWEInfos,
Module<B>: SvpPPolAlloc<B>,
{
assert_eq!(module.n() as u32, infos.n());
Self::alloc_with(module, infos.rank())
}
pub fn alloc_with(module: &Module<B>, rank: Rank) -> Self
where
Module<B>: SvpPPolAlloc<B>,
{
Self {
data: module.svp_ppol_alloc(rank.into()),
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,
}
}
pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize
fn glwe_secret_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWESecretPrepared<Vec<u8>, B>
where
A: GLWEInfos,
Module<B>: SvpPPolAllocBytes,
{
assert_eq!(module.n() as u32, infos.n());
Self::alloc_bytes_with(module, infos.rank())
assert_eq!(self.n(), infos.n());
self.glwe_secret_prepared_alloc(infos.rank())
}
pub fn alloc_bytes_with(module: &Module<B>, rank: Rank) -> usize
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>: SvpPPolAllocBytes,
A: GLWEInfos,
{
module.svp_ppol_alloc_bytes(rank.into())
assert_eq!(self.n(), infos.n());
self.glwe_secret_alloc_bytes(infos.rank())
}
}
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.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_from_infos<A>(module: &Module<B>, infos: &A) -> usize
where
A: GLWEInfos,
{
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 @@ impl<D: Data, B: Backend> GLWESecretPrepared<D, B> {
}
}
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>;

View File

@@ -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 @@ impl<D: Data, B: Backend> GGLWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
}
}
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 @@ impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
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,67 +107,73 @@ impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
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>,
{
pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGLWEInfos,
{
module.glwe_to_lwe_switching_key_prepared_alloc_from_infos(infos)
}
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: GGLWEInfos,
{
module.glwe_to_lwe_switching_key_prepared_alloc_bytes_from_infos(infos)
}
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)
}
}
pub trait GLWEToLWESwitchingKeyPrepare<B: Backend>
where
Self: GLWESwitchingKeyPrepare<B>,
{
fn glwe_to_lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A)
where
A: GGLWEInfos,
{
self.glwe_to_lwe_switching_key_prepare_tmp_bytes(infos);
self.glwe_switching_key_prepare_tmp_bytes(infos);
}
}
impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A)
where
A: GLWEInfos,
Module<B>: GLWEToLWESwitchingKeyPrepareTmpBytes,
{
module.glwe_secret_prepare_tmp_bytes(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;
}
impl<B: Backend> GLWEToLWESwitchingKeyPrepare<B> for Module<B>
where
Module<B>: 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<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GLWEToLWESwitchingKeyPreparedToMut<B>,
O: GLWEToLWESwitchingKeyToRef,
{
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<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
A: GGLWEInfos,
Module<B>: GLWEToLWESwitchingKeyPrepare<B>,
{
module.glwe_to_lwe_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 prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: GLWEToLWESwitchingKeyToRef,
Module<B>: GLWEToLWESwitchingKeyPrepare<B>,
@@ -175,26 +182,6 @@ impl<D: DataMut, B: Backend> GLWEToLWESwitchingKeyPrepared<D, B> {
}
}
pub trait GLWEToLWESwitchingKeyPrepareAlloc<B: Backend> {
fn glwe_to_lwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: GLWEToLWESwitchingKeyToRef;
}
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>)
where
O: GLWEToLWESwitchingKeyToRef,
{
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
}
}
pub trait GLWEToLWESwitchingKeyPreparedToRef<B: Backend> {
fn to_ref(&self) -> GLWEToLWESwitchingKeyPrepared<&[u8], B>;
}

View File

@@ -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 @@ impl<D: Data, B: Backend> GGLWEInfos for LWESwitchingKeyPrepared<D, B> {
}
}
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 @@ impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
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,67 +110,72 @@ impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
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>,
{
pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGLWEInfos,
{
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)
}
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWEInfos,
{
module.lwe_switching_key_prepared_alloc_bytes_from_infos(infos)
}
pub fn alloc_bytes(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
module.lwe_switching_key_prepared_alloc_bytes(base2k, k, dnum)
}
}
pub trait LWESwitchingKeyPrepare<B: Backend>
where
Self: GLWESwitchingKeyPrepare<B>,
{
fn lwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A)
where
A: GGLWEInfos,
{
self.lwe_switching_key_prepare_tmp_bytes(infos);
self.glwe_switching_key_prepare_tmp_bytes(infos);
}
}
impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A)
where
A: GLWEInfos,
Module<B>: LWESwitchingKeyPrepareTmpBytes,
{
module.glwe_secret_prepare_tmp_bytes(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;
}
impl<B: Backend> LWESwitchingKeyPrepare<B> for Module<B>
where
Module<B>: GLWESwitchingKeyPrepare<B>,
{
fn lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
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<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
A: GGLWEInfos,
Module<B>: LWESwitchingKeyPrepare<B>,
{
module.lwe_switching_key_prepare_tmp_bytes(infos);
}
}
impl<D: DataMut, B: Backend> LWESwitchingKeyPrepared<D, B> {
fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &Scratch<B>)
fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: LWESwitchingKeyToRef,
Module<B>: LWESwitchingKeyPrepare<B>,
@@ -180,26 +184,6 @@ impl<D: DataMut, B: Backend> LWESwitchingKeyPrepared<D, B> {
}
}
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>)
where
O: LWESwitchingKeyToRef,
{
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
}
}
pub trait LWESwitchingKeyPreparedToRef<B: Backend> {
fn to_ref(&self) -> LWESwitchingKeyPrepared<&[u8], B>;
}

View File

@@ -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 @@ impl<D: Data, B: Backend> GGLWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
}
}
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 @@ impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
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,67 +108,73 @@ impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
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>,
{
pub fn alloc_from_infos<A>(module: &Module<B>, infos: &A) -> Self
where
A: GGLWEInfos,
{
module.lwe_to_glwe_switching_key_prepared_alloc_from_infos(infos)
}
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: GGLWEInfos,
{
module.lwe_to_glwe_switching_key_prepared_alloc_bytes_from_infos(infos)
}
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)
}
}
pub trait LWEToGLWESwitchingKeyPrepare<B: Backend>
where
Self: GLWESwitchingKeyPrepare<B>,
{
fn lwe_to_glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A)
where
A: GGLWEInfos,
{
self.lwe_to_glwe_switching_key_prepare_tmp_bytes(infos);
self.glwe_switching_key_prepare_tmp_bytes(infos);
}
}
impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A)
where
A: GLWEInfos,
Module<B>: LWEToGLWESwitchingKeyPrepareTmpBytes,
{
module.glwe_secret_prepare_tmp_bytes(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;
}
impl<B: Backend> LWEToGLWESwitchingKeyPrepare<B> for Module<B>
where
Module<B>: 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<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: LWEToGLWESwitchingKeyPreparedToMut<B>,
O: LWEToGLWESwitchingKeyToRef,
{
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<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
A: GGLWEInfos,
Module<B>: LWEToGLWESwitchingKeyPrepare<B>,
{
module.lwe_to_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 prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
where
O: LWEToGLWESwitchingKeyToRef,
Module<B>: LWEToGLWESwitchingKeyPrepare<B>,
@@ -172,26 +183,6 @@ impl<D: DataMut, B: Backend> LWEToGLWESwitchingKeyPrepared<D, B> {
}
}
pub trait LWEToGLWESwitchingKeyPrepareAlloc<B: Backend> {
fn lwe_to_glwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
where
O: LWEToGLWESwitchingKeyToRef;
}
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>)
where
O: LWEToGLWESwitchingKeyToRef,
{
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
}
}
pub trait LWEToGLWESwitchingKeyPreparedToRef<B: Backend> {
fn to_ref(&self) -> LWEToGLWESwitchingKeyPrepared<&[u8], B>;
}

View File

@@ -129,12 +129,11 @@ where
{
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 @@ where
{
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 @@ where
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 @@ where
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 @@ where
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 @@ where
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 @@ where
{
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 @@ where
{
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,
)
}

View File

@@ -182,7 +182,7 @@ where
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 @@ where
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());

View File

@@ -101,7 +101,7 @@ where
{
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,

View File

@@ -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,