mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 05:06:44 +01:00
wip
This commit is contained in:
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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]>;
|
||||
}
|
||||
|
||||
@@ -33,21 +33,16 @@ pub use lwe_pt::*;
|
||||
pub use lwe_sk::*;
|
||||
pub use lwe_to_glwe_ksk::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BuildError {
|
||||
MissingData,
|
||||
MissingBase2K,
|
||||
MissingK,
|
||||
MissingDigits,
|
||||
ZeroDegree,
|
||||
NonPowerOfTwoDegree,
|
||||
ZeroBase2K,
|
||||
ZeroTorusPrecision,
|
||||
ZeroCols,
|
||||
ZeroLimbs,
|
||||
ZeroRank,
|
||||
ZeroDigits,
|
||||
VecZnxColsNotOne,
|
||||
use poulpy_hal::layouts::{Backend, Module};
|
||||
|
||||
pub trait GetDegree {
|
||||
fn n(&self) -> Degree;
|
||||
}
|
||||
|
||||
impl<B: Backend> GetDegree for Module<B> {
|
||||
fn n(&self) -> Degree {
|
||||
Self::n(&self).into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Newtype over `u32` with arithmetic and comparisons against same type and `u32`.
|
||||
|
||||
@@ -3,9 +3,8 @@ use 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>;
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user