Add cross-basek normalization (#90)

* added cross_basek_normalization

* updated method signatures to take layouts

* fixed cross-base normalization

fix #91
fix #93
This commit is contained in:
Jean-Philippe Bossuat
2025-09-30 14:40:10 +02:00
committed by GitHub
parent 4da790ea6a
commit 37e13b965c
216 changed files with 12481 additions and 7745 deletions

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxBigNormalize, VecZnxDftAllocBytes,
VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch},
source::Source,
@@ -12,18 +12,20 @@ use poulpy_hal::{
use crate::{
TakeGLWESecret, TakeGLWESecretPrepared,
layouts::{
GLWESecret,
GGLWELayoutInfos, GLWEInfos, GLWESecret, LWEInfos,
compressed::{GGLWEAutomorphismKeyCompressed, GGLWESwitchingKeyCompressed},
},
};
impl GGLWEAutomorphismKeyCompressed<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
{
GGLWESwitchingKeyCompressed::encrypt_sk_scratch_space(module, basek, k, rank, rank)
+ GLWESecret::bytes_of(module.n(), rank)
assert_eq!(module.n() as u32, infos.n());
GGLWESwitchingKeyCompressed::encrypt_sk_scratch_space(module, infos)
+ GLWESecret::alloc_bytes_with(infos.n(), infos.rank_out())
}
}
@@ -49,7 +51,7 @@ impl<DataSelf: DataMut> GGLWEAutomorphismKeyCompressed<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -60,26 +62,21 @@ impl<DataSelf: DataMut> GGLWEAutomorphismKeyCompressed<DataSelf> {
{
#[cfg(debug_assertions)]
{
use crate::layouts::Infos;
assert_eq!(self.n(), sk.n());
assert_eq!(self.rank_out(), self.rank_in());
assert_eq!(sk.rank(), self.rank());
assert_eq!(sk.rank(), self.rank_out());
assert!(
scratch.available()
>= GGLWEAutomorphismKeyCompressed::encrypt_sk_scratch_space(module, self.basek(), self.k(), self.rank()),
"scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space(module, self.rank()={}, self.size()={}): {}",
scratch.available() >= GGLWEAutomorphismKeyCompressed::encrypt_sk_scratch_space(module, self),
"scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space: {}",
scratch.available(),
self.rank(),
self.size(),
GGLWEAutomorphismKeyCompressed::encrypt_sk_scratch_space(module, self.basek(), self.k(), self.rank())
GGLWEAutomorphismKeyCompressed::encrypt_sk_scratch_space(module, self)
)
}
let (mut sk_out, scratch_1) = scratch.take_glwe_secret(sk.n(), sk.rank());
{
(0..self.rank()).for_each(|i| {
(0..self.rank_out().into()).for_each(|i| {
module.vec_znx_automorphism(
module.galois_element_inv(p),
&mut sk_out.data.as_vec_znx_mut(),

View File

@@ -2,7 +2,7 @@ use poulpy_hal::{
api::{
ScratchAvailable, SvpApplyDftToDftInplace, TakeVecZnx, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal,
VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
},
layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch, ZnxZero},
source::Source,
@@ -11,15 +11,16 @@ use poulpy_hal::{
use crate::{
TakeGLWEPt,
encryption::{SIGMA, glwe_encrypt_sk_internal},
layouts::{GGLWECiphertext, Infos, compressed::GGLWECiphertextCompressed, prepared::GLWESecretPrepared},
layouts::{GGLWECiphertext, GGLWELayoutInfos, LWEInfos, compressed::GGLWECiphertextCompressed, prepared::GLWESecretPrepared},
};
impl GGLWECiphertextCompressed<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{
GGLWECiphertext::encrypt_sk_scratch_space(module, basek, k)
GGLWECiphertext::encrypt_sk_scratch_space(module, infos)
}
}
@@ -42,7 +43,7 @@ impl<D: DataMut> GGLWECiphertextCompressed<D> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -56,7 +57,7 @@ impl<D: DataMut> GGLWECiphertextCompressed<D> {
assert_eq!(
self.rank_in(),
pt.cols(),
pt.cols() as u32,
"self.rank_in(): {} != pt.cols(): {}",
self.rank_in(),
pt.cols()
@@ -69,36 +70,33 @@ impl<D: DataMut> GGLWECiphertextCompressed<D> {
sk.rank()
);
assert_eq!(self.n(), sk.n());
assert_eq!(pt.n(), sk.n());
assert_eq!(pt.n() as u32, sk.n());
assert!(
scratch.available() >= GGLWECiphertextCompressed::encrypt_sk_scratch_space(module, self.basek(), self.k()),
"scratch.available: {} < GGLWECiphertext::encrypt_sk_scratch_space(module, self.rank()={}, self.size()={}): {}",
scratch.available() >= GGLWECiphertextCompressed::encrypt_sk_scratch_space(module, self),
"scratch.available: {} < GGLWECiphertext::encrypt_sk_scratch_space: {}",
scratch.available(),
self.rank(),
self.size(),
GGLWECiphertextCompressed::encrypt_sk_scratch_space(module, self.basek(), self.k())
GGLWECiphertextCompressed::encrypt_sk_scratch_space(module, self)
);
assert!(
self.rows() * self.digits() * self.basek() <= self.k(),
"self.rows() : {} * self.digits() : {} * self.basek() : {} = {} >= self.k() = {}",
self.rows().0 * self.digits().0 * self.base2k().0 <= self.k().0,
"self.rows() : {} * self.digits() : {} * self.base2k() : {} = {} >= self.k() = {}",
self.rows(),
self.digits(),
self.basek(),
self.rows() * self.digits() * self.basek(),
self.base2k(),
self.rows().0 * self.digits().0 * self.base2k().0,
self.k()
);
}
let rows: usize = self.rows();
let digits: usize = self.digits();
let basek: usize = self.basek();
let k: usize = self.k();
let rank_in: usize = self.rank_in();
let cols: usize = self.rank_out() + 1;
let rows: usize = self.rows().into();
let digits: usize = self.digits().into();
let base2k: usize = self.base2k().into();
let rank_in: usize = self.rank_in().into();
let cols: usize = (self.rank_out() + 1).into();
let mut source_xa = Source::new(seed);
let (mut tmp_pt, scrach_1) = scratch.take_glwe_pt(sk.n(), basek, k);
let (mut tmp_pt, scrach_1) = scratch.take_glwe_pt(self);
(0..rank_in).for_each(|col_i| {
(0..rows).for_each(|row_i| {
// Adds the scalar_znx_pt to the i-th limb of the vec_znx_pt
@@ -110,15 +108,15 @@ impl<D: DataMut> GGLWECiphertextCompressed<D> {
pt,
col_i,
);
module.vec_znx_normalize_inplace(basek, &mut tmp_pt.data, 0, scrach_1);
module.vec_znx_normalize_inplace(base2k, &mut tmp_pt.data, 0, scrach_1);
let (seed, mut source_xa_tmp) = source_xa.branch();
self.seed[col_i * rows + row_i] = seed;
glwe_encrypt_sk_internal(
module,
self.basek(),
self.k(),
self.base2k().into(),
self.k().into(),
&mut self.at_mut(row_i, col_i).data,
cols,
true,

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply,
VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub,
VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch},
source::Source,
@@ -11,23 +11,21 @@ use poulpy_hal::{
use crate::{
TakeGLWESecretPrepared,
layouts::{GGLWECiphertext, GLWESecret, compressed::GGLWESwitchingKeyCompressed, prepared::GLWESecretPrepared},
layouts::{
Degree, GGLWECiphertext, GGLWELayoutInfos, GLWEInfos, GLWESecret, LWEInfos, compressed::GGLWESwitchingKeyCompressed,
prepared::GLWESecretPrepared,
},
};
impl GGLWESwitchingKeyCompressed<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(
module: &Module<B>,
basek: usize,
k: usize,
rank_in: usize,
rank_out: usize,
) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
{
(GGLWECiphertext::encrypt_sk_scratch_space(module, basek, k) | ScalarZnx::alloc_bytes(module.n(), 1))
+ ScalarZnx::alloc_bytes(module.n(), rank_in)
+ GLWESecretPrepared::bytes_of(module, rank_out)
(GGLWECiphertext::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())
}
}
@@ -52,7 +50,7 @@ impl<DataSelf: DataMut> GGLWESwitchingKeyCompressed<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -63,35 +61,22 @@ impl<DataSelf: DataMut> GGLWESwitchingKeyCompressed<DataSelf> {
{
#[cfg(debug_assertions)]
{
use crate::layouts::{GGLWESwitchingKey, Infos};
use crate::layouts::GGLWESwitchingKey;
assert!(sk_in.n() <= module.n());
assert!(sk_out.n() <= module.n());
assert!(sk_in.n().0 <= module.n() as u32);
assert!(sk_out.n().0 <= module.n() as u32);
assert!(
scratch.available()
>= GGLWESwitchingKey::encrypt_sk_scratch_space(
module,
self.basek(),
self.k(),
self.rank_in(),
self.rank_out()
),
scratch.available() >= GGLWESwitchingKey::encrypt_sk_scratch_space(module, self),
"scratch.available()={} < GLWESwitchingKey::encrypt_sk_scratch_space={}",
scratch.available(),
GGLWESwitchingKey::encrypt_sk_scratch_space(
module,
self.basek(),
self.k(),
self.rank_in(),
self.rank_out()
)
GGLWESwitchingKey::encrypt_sk_scratch_space(module, self)
)
}
let n: usize = sk_in.n().max(sk_out.n());
let n: usize = sk_in.n().max(sk_out.n()).into();
let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(n, sk_in.rank());
(0..sk_in.rank()).for_each(|i| {
let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(n, sk_in.rank().into());
(0..sk_in.rank().into()).for_each(|i| {
module.vec_znx_switch_ring(
&mut sk_in_tmp.as_vec_znx_mut(),
i,
@@ -100,10 +85,10 @@ impl<DataSelf: DataMut> GGLWESwitchingKeyCompressed<DataSelf> {
);
});
let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(n, sk_out.rank());
let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(Degree(n as u32), sk_out.rank());
{
let (mut tmp, _) = scratch_2.take_scalar_znx(n, 1);
(0..sk_out.rank()).for_each(|i| {
(0..sk_out.rank().into()).for_each(|i| {
module.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i);
module.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0);
});
@@ -117,7 +102,7 @@ impl<DataSelf: DataMut> GGLWESwitchingKeyCompressed<DataSelf> {
source_xe,
scratch_2,
);
self.sk_in_n = sk_in.n();
self.sk_out_n = sk_out.n();
self.sk_in_n = sk_in.n().into();
self.sk_out_n = sk_out.n().into();
}
}

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx,
TakeVecZnx, TakeVecZnxBig, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigAllocBytes,
VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA,
VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch},
source::Source,
@@ -11,16 +11,20 @@ use poulpy_hal::{
use crate::{
TakeGLWESecret, TakeGLWESecretPrepared,
layouts::{GGLWETensorKey, GLWESecret, Infos, compressed::GGLWETensorKeyCompressed, prepared::Prepare},
layouts::{
GGLWELayoutInfos, GGLWETensorKey, GLWEInfos, GLWESecret, LWEInfos, Rank, compressed::GGLWETensorKeyCompressed,
prepared::Prepare,
},
};
impl GGLWETensorKeyCompressed<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>:
SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + VecZnxBigAllocBytes,
{
GGLWETensorKey::encrypt_sk_scratch_space(module, basek, k, rank)
GGLWETensorKey::encrypt_sk_scratch_space(module, infos)
}
}
@@ -42,7 +46,7 @@ impl<DataSelf: DataMut> GGLWETensorKeyCompressed<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -63,37 +67,38 @@ impl<DataSelf: DataMut> GGLWETensorKeyCompressed<DataSelf> {
{
#[cfg(debug_assertions)]
{
assert_eq!(self.rank(), sk.rank());
assert_eq!(self.rank_out(), sk.rank());
assert_eq!(self.n(), sk.n());
}
let n: usize = sk.n();
let rank: usize = self.rank();
let n: usize = sk.n().into();
let rank: usize = self.rank_out().into();
let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(n, rank);
let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(sk.n(), self.rank_out());
sk_dft_prep.prepare(module, sk, scratch_1);
let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(n, rank, 1);
(0..rank).for_each(|i| {
for i in 0..rank {
module.vec_znx_dft_apply(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i);
});
}
let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(n, 1, 1);
let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(n, 1);
let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(sk.n(), Rank(1));
let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(n, 1, 1);
let mut source_xa: Source = Source::new(seed_xa);
(0..rank).for_each(|i| {
(i..rank).for_each(|j| {
for i in 0..rank {
for j in i..rank {
module.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i);
module.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
module.vec_znx_big_normalize(
self.basek(),
self.base2k().into(),
&mut sk_ij.data.as_vec_znx_mut(),
0,
self.base2k().into(),
&sk_ij_big,
0,
scratch_5,
@@ -103,7 +108,7 @@ impl<DataSelf: DataMut> GGLWETensorKeyCompressed<DataSelf> {
self.at_mut(i, j)
.encrypt_sk(module, &sk_ij, sk, seed_xa_tmp, source_xe, scratch_5);
});
})
}
}
}
}

View File

@@ -2,7 +2,7 @@ use poulpy_hal::{
api::{
ScratchAvailable, SvpApplyDftToDftInplace, TakeVecZnx, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal,
VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
},
layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch, ZnxZero},
source::Source,
@@ -11,15 +11,18 @@ use poulpy_hal::{
use crate::{
TakeGLWEPt,
encryption::{SIGMA, glwe_encrypt_sk_internal},
layouts::{GGSWCiphertext, Infos, compressed::GGSWCiphertextCompressed, prepared::GLWESecretPrepared},
layouts::{
GGSWCiphertext, GGSWInfos, GLWEInfos, LWEInfos, compressed::GGSWCiphertextCompressed, prepared::GLWESecretPrepared,
},
};
impl GGSWCiphertextCompressed<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGSWInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
{
GGSWCiphertext::encrypt_sk_scratch_space(module, basek, k, rank)
GGSWCiphertext::encrypt_sk_scratch_space(module, infos)
}
}
@@ -42,7 +45,7 @@ impl<DataSelf: DataMut> GGSWCiphertextCompressed<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -56,27 +59,26 @@ impl<DataSelf: DataMut> GGSWCiphertextCompressed<DataSelf> {
assert_eq!(self.rank(), sk.rank());
assert_eq!(self.n(), sk.n());
assert_eq!(pt.n(), sk.n());
assert_eq!(pt.n() as u32, sk.n());
}
let basek: usize = self.basek();
let k: usize = self.k();
let rank: usize = self.rank();
let base2k: usize = self.base2k().into();
let rank: usize = self.rank().into();
let cols: usize = rank + 1;
let digits: usize = self.digits();
let digits: usize = self.digits().into();
let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(self.n(), basek, k);
let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(&self.glwe_layout());
let mut source = Source::new(seed_xa);
self.seed = vec![[0u8; 32]; self.rows() * cols];
self.seed = vec![[0u8; 32]; self.rows().0 as usize * cols];
(0..self.rows()).for_each(|row_i| {
(0..self.rows().into()).for_each(|row_i| {
tmp_pt.data.zero();
// Adds the scalar_znx_pt to the i-th limb of the vec_znx_pt
module.vec_znx_add_scalar_inplace(&mut tmp_pt.data, 0, (digits - 1) + row_i * digits, pt, 0);
module.vec_znx_normalize_inplace(basek, &mut tmp_pt.data, 0, scratch_1);
module.vec_znx_normalize_inplace(base2k, &mut tmp_pt.data, 0, scratch_1);
(0..rank + 1).for_each(|col_j| {
// rlwe encrypt of vec_znx_pt into vec_znx_ct
@@ -87,8 +89,8 @@ impl<DataSelf: DataMut> GGSWCiphertextCompressed<DataSelf> {
glwe_encrypt_sk_internal(
module,
self.basek(),
self.k(),
self.base2k().into(),
self.k().into(),
&mut self.at_mut(row_i, col_j).data,
cols,
true,

View File

@@ -2,7 +2,7 @@ use poulpy_hal::{
api::{
ScratchAvailable, SvpApplyDftToDftInplace, TakeVecZnx, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal,
VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize,
VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch},
source::Source,
@@ -10,15 +10,18 @@ use poulpy_hal::{
use crate::{
encryption::{SIGMA, glwe_ct::glwe_encrypt_sk_internal},
layouts::{GLWECiphertext, GLWEPlaintext, Infos, compressed::GLWECiphertextCompressed, prepared::GLWESecretPrepared},
layouts::{
GLWECiphertext, GLWEInfos, GLWEPlaintext, LWEInfos, compressed::GLWECiphertextCompressed, prepared::GLWESecretPrepared,
},
};
impl GLWECiphertextCompressed<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GLWEInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
{
GLWECiphertext::encrypt_sk_scratch_space(module, basek, k)
GLWECiphertext::encrypt_sk_scratch_space(module, infos)
}
}
@@ -40,7 +43,7 @@ impl<D: DataMut> GLWECiphertextCompressed<D> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -68,7 +71,7 @@ impl<D: DataMut> GLWECiphertextCompressed<D> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -77,11 +80,11 @@ impl<D: DataMut> GLWECiphertextCompressed<D> {
Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx,
{
let mut source_xa = Source::new(seed_xa);
let cols: usize = self.rank() + 1;
let cols: usize = (self.rank() + 1).into();
glwe_encrypt_sk_internal(
module,
self.basek(),
self.k(),
self.base2k().into(),
self.k().into(),
&mut self.data,
cols,
true,

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphism, VecZnxBigNormalize, VecZnxDftAllocBytes,
VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch},
source::Source,
@@ -11,19 +11,33 @@ use poulpy_hal::{
use crate::{
TakeGLWESecret, TakeGLWESecretPrepared,
layouts::{GGLWEAutomorphismKey, GGLWESwitchingKey, GLWESecret},
layouts::{GGLWEAutomorphismKey, GGLWELayoutInfos, GGLWESwitchingKey, GLWEInfos, GLWESecret, LWEInfos},
};
impl GGLWEAutomorphismKey<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{
GGLWESwitchingKey::encrypt_sk_scratch_space(module, basek, k, rank, rank) + GLWESecret::bytes_of(module.n(), rank)
assert_eq!(
infos.rank_in(),
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
);
GGLWESwitchingKey::encrypt_sk_scratch_space(module, infos) + GLWESecret::alloc_bytes(&infos.glwe_layout())
}
pub fn encrypt_pk_scratch_space<B: Backend>(module: &Module<B>, _basek: usize, _k: usize, _rank: usize) -> usize {
GGLWESwitchingKey::encrypt_pk_scratch_space(module, _basek, _k, _rank, _rank)
pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, _infos: &A) -> usize
where
A: GGLWELayoutInfos,
{
assert_eq!(
_infos.rank_in(),
_infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
);
GGLWESwitchingKey::encrypt_pk_scratch_space(module, _infos)
}
}
@@ -46,7 +60,7 @@ impl<DataSelf: DataMut> GGLWEAutomorphismKey<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -60,26 +74,23 @@ impl<DataSelf: DataMut> GGLWEAutomorphismKey<DataSelf> {
{
#[cfg(debug_assertions)]
{
use crate::layouts::Infos;
use crate::layouts::{GLWEInfos, LWEInfos};
assert_eq!(self.n(), sk.n());
assert_eq!(self.rank_out(), self.rank_in());
assert_eq!(sk.rank(), self.rank());
assert_eq!(sk.rank(), self.rank_out());
assert!(
scratch.available()
>= GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, self.basek(), self.k(), self.rank()),
"scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space(module, self.rank()={}, self.size()={}): {}",
scratch.available() >= GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, self),
"scratch.available(): {} < AutomorphismKey::encrypt_sk_scratch_space: {:?}",
scratch.available(),
self.rank(),
self.size(),
GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, self.basek(), self.k(), self.rank())
GGLWEAutomorphismKey::encrypt_sk_scratch_space(module, self)
)
}
let (mut sk_out, scratch_1) = scratch.take_glwe_secret(sk.n(), sk.rank());
{
(0..self.rank()).for_each(|i| {
(0..self.rank_out().into()).for_each(|i| {
module.vec_znx_automorphism(
module.galois_element_inv(p),
&mut sk_out.data.as_vec_znx_mut(),

View File

@@ -2,7 +2,7 @@ use poulpy_hal::{
api::{
ScratchAvailable, SvpApplyDftToDftInplace, TakeVecZnx, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal,
VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
},
layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch, ZnxZero},
source::Source,
@@ -10,19 +10,23 @@ use poulpy_hal::{
use crate::{
TakeGLWEPt,
layouts::{GGLWECiphertext, GLWECiphertext, GLWEPlaintext, Infos, prepared::GLWESecretPrepared},
layouts::{GGLWECiphertext, GGLWELayoutInfos, GLWECiphertext, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared},
};
impl GGLWECiphertext<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{
GLWECiphertext::encrypt_sk_scratch_space(module, basek, k)
+ (GLWEPlaintext::byte_of(module.n(), basek, k) | module.vec_znx_normalize_tmp_bytes())
GLWECiphertext::encrypt_sk_scratch_space(module, &infos.glwe_layout())
+ (GLWEPlaintext::alloc_bytes(&infos.glwe_layout()) | module.vec_znx_normalize_tmp_bytes())
}
pub fn encrypt_pk_scratch_space<B: Backend>(_module: &Module<B>, _basek: usize, _k: usize, _rank: usize) -> usize {
pub fn encrypt_pk_scratch_space<B: Backend, A>(_module: &Module<B>, _infos: &A) -> usize
where
A: GGLWELayoutInfos,
{
unimplemented!()
}
}
@@ -46,7 +50,7 @@ impl<DataSelf: DataMut> GGLWECiphertext<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -60,7 +64,7 @@ impl<DataSelf: DataMut> GGLWECiphertext<DataSelf> {
assert_eq!(
self.rank_in(),
pt.cols(),
pt.cols() as u32,
"self.rank_in(): {} != pt.cols(): {}",
self.rank_in(),
pt.cols()
@@ -73,33 +77,32 @@ impl<DataSelf: DataMut> GGLWECiphertext<DataSelf> {
sk.rank()
);
assert_eq!(self.n(), sk.n());
assert_eq!(pt.n(), sk.n());
assert_eq!(pt.n() as u32, sk.n());
assert!(
scratch.available() >= GGLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k()),
scratch.available() >= GGLWECiphertext::encrypt_sk_scratch_space(module, self),
"scratch.available: {} < GGLWECiphertext::encrypt_sk_scratch_space(module, self.rank()={}, self.size()={}): {}",
scratch.available(),
self.rank(),
self.rank_out(),
self.size(),
GGLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k())
GGLWECiphertext::encrypt_sk_scratch_space(module, self)
);
assert!(
self.rows() * self.digits() * self.basek() <= self.k(),
"self.rows() : {} * self.digits() : {} * self.basek() : {} = {} >= self.k() = {}",
self.rows().0 * self.digits().0 * self.base2k().0 <= self.k().0,
"self.rows() : {} * self.digits() : {} * self.base2k() : {} = {} >= self.k() = {}",
self.rows(),
self.digits(),
self.basek(),
self.rows() * self.digits() * self.basek(),
self.base2k(),
self.rows().0 * self.digits().0 * self.base2k().0,
self.k()
);
}
let rows: usize = self.rows();
let digits: usize = self.digits();
let basek: usize = self.basek();
let k: usize = self.k();
let rank_in: usize = self.rank_in();
let rows: usize = self.rows().into();
let digits: usize = self.digits().into();
let base2k: usize = self.base2k().into();
let rank_in: usize = self.rank_in().into();
let (mut tmp_pt, scrach_1) = scratch.take_glwe_pt(sk.n(), basek, k);
let (mut tmp_pt, scrach_1) = scratch.take_glwe_pt(self);
// For each input column (i.e. rank) produces a GGLWE ciphertext of rank_out+1 columns
//
// Example for ksk rank 2 to rank 3:
@@ -122,7 +125,7 @@ impl<DataSelf: DataMut> GGLWECiphertext<DataSelf> {
pt,
col_i,
);
module.vec_znx_normalize_inplace(basek, &mut tmp_pt.data, 0, scrach_1);
module.vec_znx_normalize_inplace(base2k, &mut tmp_pt.data, 0, scrach_1);
// rlwe encrypt of vec_znx_pt into vec_znx_ct
self.at_mut(row_i, col_i)

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply,
VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub,
VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch},
source::Source,
@@ -11,33 +11,28 @@ use poulpy_hal::{
use crate::{
TakeGLWESecretPrepared,
layouts::{GGLWECiphertext, GGLWESwitchingKey, GLWESecret, prepared::GLWESecretPrepared},
layouts::{
Degree, GGLWECiphertext, GGLWELayoutInfos, GGLWESwitchingKey, GLWEInfos, GLWESecret, LWEInfos,
prepared::GLWESecretPrepared,
},
};
impl GGLWESwitchingKey<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(
module: &Module<B>,
basek: usize,
k: usize,
rank_in: usize,
rank_out: usize,
) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{
(GGLWECiphertext::encrypt_sk_scratch_space(module, basek, k) | ScalarZnx::alloc_bytes(module.n(), 1))
+ ScalarZnx::alloc_bytes(module.n(), rank_in)
+ GLWESecretPrepared::bytes_of(module, rank_out)
(GGLWECiphertext::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())
}
pub fn encrypt_pk_scratch_space<B: Backend>(
module: &Module<B>,
_basek: usize,
_k: usize,
_rank_in: usize,
_rank_out: usize,
) -> usize {
GGLWECiphertext::encrypt_pk_scratch_space(module, _basek, _k, _rank_out)
pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, _infos: &A) -> usize
where
A: GGLWELayoutInfos,
{
GGLWECiphertext::encrypt_pk_scratch_space(module, _infos)
}
}
@@ -60,7 +55,7 @@ impl<DataSelf: DataMut> GGLWESwitchingKey<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -73,35 +68,20 @@ impl<DataSelf: DataMut> GGLWESwitchingKey<DataSelf> {
{
#[cfg(debug_assertions)]
{
use crate::layouts::Infos;
assert!(sk_in.n() <= module.n());
assert!(sk_out.n() <= module.n());
assert!(sk_in.n().0 <= module.n() as u32);
assert!(sk_out.n().0 <= module.n() as u32);
assert!(
scratch.available()
>= GGLWESwitchingKey::encrypt_sk_scratch_space(
module,
self.basek(),
self.k(),
self.rank_in(),
self.rank_out()
),
scratch.available() >= GGLWESwitchingKey::encrypt_sk_scratch_space(module, self),
"scratch.available()={} < GLWESwitchingKey::encrypt_sk_scratch_space={}",
scratch.available(),
GGLWESwitchingKey::encrypt_sk_scratch_space(
module,
self.basek(),
self.k(),
self.rank_in(),
self.rank_out()
)
GGLWESwitchingKey::encrypt_sk_scratch_space(module, self)
)
}
let n: usize = sk_in.n().max(sk_out.n());
let n: usize = sk_in.n().max(sk_out.n()).into();
let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(n, sk_in.rank());
(0..sk_in.rank()).for_each(|i| {
let (mut sk_in_tmp, scratch_1) = scratch.take_scalar_znx(n, sk_in.rank().into());
(0..sk_in.rank().into()).for_each(|i| {
module.vec_znx_switch_ring(
&mut sk_in_tmp.as_vec_znx_mut(),
i,
@@ -110,10 +90,10 @@ impl<DataSelf: DataMut> GGLWESwitchingKey<DataSelf> {
);
});
let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(n, sk_out.rank());
let (mut sk_out_tmp, scratch_2) = scratch_1.take_glwe_secret_prepared(Degree(n as u32), sk_out.rank());
{
let (mut tmp, _) = scratch_2.take_scalar_znx(n, 1);
(0..sk_out.rank()).for_each(|i| {
(0..sk_out.rank().into()).for_each(|i| {
module.vec_znx_switch_ring(&mut tmp.as_vec_znx_mut(), 0, &sk_out.data.as_vec_znx(), i);
module.svp_prepare(&mut sk_out_tmp.data, i, &tmp, 0);
});
@@ -127,7 +107,7 @@ impl<DataSelf: DataMut> GGLWESwitchingKey<DataSelf> {
source_xe,
scratch_2,
);
self.sk_in_n = sk_in.n();
self.sk_out_n = sk_out.n();
self.sk_in_n = sk_in.n().into();
self.sk_out_n = sk_out.n().into();
}
}

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx,
TakeVecZnxBig, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxBigAllocBytes,
VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxIdftApplyTmpA,
VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch},
source::Source,
@@ -12,23 +12,24 @@ use poulpy_hal::{
use crate::{
TakeGLWESecret, TakeGLWESecretPrepared,
layouts::{
GGLWESwitchingKey, GGLWETensorKey, GLWESecret, Infos,
Degree, GGLWELayoutInfos, GGLWESwitchingKey, GGLWETensorKey, GLWEInfos, GLWESecret, LWEInfos, Rank,
prepared::{GLWESecretPrepared, Prepare},
},
};
impl GGLWETensorKey<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>:
SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + VecZnxBigAllocBytes,
{
GLWESecretPrepared::bytes_of(module, rank)
+ module.vec_znx_dft_alloc_bytes(rank, 1)
GLWESecretPrepared::alloc_bytes_with(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)
+ GLWESecret::bytes_of(module.n(), 1)
+ GGLWESwitchingKey::encrypt_sk_scratch_space(module, basek, k, rank, rank)
+ GLWESecret::alloc_bytes_with(Degree(module.n() as u32), Rank(1))
+ GGLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
}
}
@@ -51,7 +52,7 @@ impl<DataSelf: DataMut> GGLWETensorKey<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -65,36 +66,36 @@ impl<DataSelf: DataMut> GGLWETensorKey<DataSelf> {
{
#[cfg(debug_assertions)]
{
assert_eq!(self.rank(), sk.rank());
assert_eq!(self.rank_out(), sk.rank());
assert_eq!(self.n(), sk.n());
}
let n: usize = sk.n();
let rank: usize = self.rank();
let n: Degree = sk.n();
let rank: Rank = self.rank_out();
let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(n, rank);
sk_dft_prep.prepare(module, sk, scratch_1);
let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(n, rank, 1);
let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(n.into(), rank.into(), 1);
(0..rank).for_each(|i| {
(0..rank.into()).for_each(|i| {
module.vec_znx_dft_apply(1, 0, &mut sk_dft, i, &sk.data.as_vec_znx(), i);
});
let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(n, 1, 1);
let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(n, 1);
let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(n, 1, 1);
let (mut sk_ij_big, scratch_3) = scratch_2.take_vec_znx_big(n.into(), 1, 1);
let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(n, Rank(1));
let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(n.into(), 1, 1);
(0..rank).for_each(|i| {
(i..rank).for_each(|j| {
(0..rank.into()).for_each(|i| {
(i..rank.into()).for_each(|j| {
module.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i);
module.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
module.vec_znx_big_normalize(
self.basek(),
self.base2k().into(),
&mut sk_ij.data.as_vec_znx_mut(),
0,
self.base2k().into(),
&sk_ij_big,
0,
scratch_5,

View File

@@ -2,7 +2,7 @@ use poulpy_hal::{
api::{
ScratchAvailable, SvpApplyDftToDftInplace, TakeVecZnx, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal,
VecZnxAddScalarInplace, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
},
layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch, VecZnx, ZnxZero},
source::Source,
@@ -10,19 +10,20 @@ use poulpy_hal::{
use crate::{
TakeGLWEPt,
layouts::{GGSWCiphertext, GLWECiphertext, Infos, prepared::GLWESecretPrepared},
layouts::{GGSWCiphertext, GGSWInfos, GLWECiphertext, GLWEInfos, LWEInfos, prepared::GLWESecretPrepared},
};
impl GGSWCiphertext<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGSWInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
{
let size = k.div_ceil(basek);
GLWECiphertext::encrypt_sk_scratch_space(module, basek, k)
+ VecZnx::alloc_bytes(module.n(), rank + 1, size)
let size = infos.size();
GLWECiphertext::encrypt_sk_scratch_space(module, &infos.glwe_layout())
+ VecZnx::alloc_bytes(module.n(), (infos.rank() + 1).into(), size)
+ VecZnx::alloc_bytes(module.n(), 1, size)
+ module.vec_znx_dft_alloc_bytes(rank + 1, size)
+ module.vec_znx_dft_alloc_bytes((infos.rank() + 1).into(), size)
}
}
@@ -45,7 +46,7 @@ impl<DataSelf: DataMut> GGSWCiphertext<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -59,22 +60,21 @@ impl<DataSelf: DataMut> GGSWCiphertext<DataSelf> {
assert_eq!(self.rank(), sk.rank());
assert_eq!(self.n(), sk.n());
assert_eq!(pt.n(), sk.n());
assert_eq!(pt.n() as u32, sk.n());
}
let basek: usize = self.basek();
let k: usize = self.k();
let rank: usize = self.rank();
let digits: usize = self.digits();
let base2k: usize = self.base2k().into();
let rank: usize = self.rank().into();
let digits: usize = self.digits().into();
let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(self.n(), basek, k);
let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(&self.glwe_layout());
(0..self.rows()).for_each(|row_i| {
(0..self.rows().into()).for_each(|row_i| {
tmp_pt.data.zero();
// Adds the scalar_znx_pt to the i-th limb of the vec_znx_pt
module.vec_znx_add_scalar_inplace(&mut tmp_pt.data, 0, (digits - 1) + row_i * digits, pt, 0);
module.vec_znx_normalize_inplace(basek, &mut tmp_pt.data, 0, scratch_1);
module.vec_znx_normalize_inplace(base2k, &mut tmp_pt.data, 0, scratch_1);
(0..rank + 1).for_each(|col_j| {
// rlwe encrypt of vec_znx_pt into vec_znx_ct

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDft, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeSvpPPol,
TakeVecZnx, TakeVecZnxDft, VecZnxAddInplace, VecZnxAddNormal, VecZnxBigAddNormal, VecZnxBigAddSmallInplace,
VecZnxBigAllocBytes, VecZnxBigNormalize, VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume,
VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
VecZnxNormalize, VecZnxNormalizeInplace, VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
},
layouts::{Backend, DataMut, DataRef, Module, ScalarZnx, Scratch, VecZnx, VecZnxBig, ZnxInfos, ZnxZero},
source::Source,
@@ -13,26 +13,30 @@ use crate::{
dist::Distribution,
encryption::{SIGMA, SIGMA_BOUND},
layouts::{
GLWECiphertext, GLWEPlaintext, Infos,
GLWECiphertext, GLWEInfos, GLWEPlaintext, LWEInfos,
prepared::{GLWEPublicKeyPrepared, GLWESecretPrepared},
},
};
impl GLWECiphertext<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GLWEInfos,
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
{
let size: usize = k.div_ceil(basek);
let size: usize = infos.size();
assert_eq!(module.n() as u32, infos.n());
module.vec_znx_normalize_tmp_bytes()
+ 2 * VecZnx::alloc_bytes(module.n(), 1, size)
+ module.vec_znx_dft_alloc_bytes(1, size)
}
pub fn encrypt_pk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize) -> usize
pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GLWEInfos,
Module<B>: VecZnxDftAllocBytes + SvpPPolAllocBytes + VecZnxBigAllocBytes + VecZnxNormalizeTmpBytes,
{
let size: usize = k.div_ceil(basek);
let size: usize = infos.size();
assert_eq!(module.n() as u32, infos.n());
((module.vec_znx_dft_alloc_bytes(1, size) + module.vec_znx_big_alloc_bytes(1, size))
| ScalarZnx::alloc_bytes(module.n(), 1))
+ module.svp_ppol_alloc_bytes(1)
@@ -58,7 +62,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -72,10 +76,10 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
assert_eq!(sk.n(), self.n());
assert_eq!(pt.n(), self.n());
assert!(
scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k()),
scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(module, self),
"scratch.available(): {} < GLWECiphertext::encrypt_sk_scratch_space: {}",
scratch.available(),
GLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k())
GLWECiphertext::encrypt_sk_scratch_space(module, self)
)
}
@@ -97,7 +101,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -110,10 +114,10 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
assert_eq!(self.rank(), sk.rank());
assert_eq!(sk.n(), self.n());
assert!(
scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k()),
scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(module, self),
"scratch.available(): {} < GLWECiphertext::encrypt_sk_scratch_space: {}",
scratch.available(),
GLWECiphertext::encrypt_sk_scratch_space(module, self.basek(), self.k())
GLWECiphertext::encrypt_sk_scratch_space(module, self)
)
}
self.encrypt_sk_internal(
@@ -143,7 +147,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -151,11 +155,11 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
+ VecZnxSub,
Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx,
{
let cols: usize = self.rank() + 1;
let cols: usize = (self.rank() + 1).into();
glwe_encrypt_sk_internal(
module,
self.basek(),
self.k(),
self.base2k().into(),
self.k().into(),
&mut self.data,
cols,
false,
@@ -235,24 +239,24 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
{
#[cfg(debug_assertions)]
{
assert_eq!(self.basek(), pk.basek());
assert_eq!(self.base2k(), pk.base2k());
assert_eq!(self.n(), pk.n());
assert_eq!(self.rank(), pk.rank());
if let Some((pt, _)) = pt {
assert_eq!(pt.basek(), pk.basek());
assert_eq!(pt.base2k(), pk.base2k());
assert_eq!(pt.n(), pk.n());
}
}
let basek: usize = pk.basek();
let base2k: usize = pk.base2k().into();
let size_pk: usize = pk.size();
let cols: usize = self.rank() + 1;
let cols: usize = (self.rank() + 1).into();
// Generates u according to the underlying secret distribution.
let (mut u_dft, scratch_1) = scratch.take_svp_ppol(self.n(), 1);
let (mut u_dft, scratch_1) = scratch.take_svp_ppol(self.n().into(), 1);
{
let (mut u, _) = scratch_1.take_scalar_znx(self.n(), 1);
let (mut u, _) = scratch_1.take_scalar_znx(self.n().into(), 1);
match pk.dist {
Distribution::NONE => panic!(
"invalid public key: SecretDistribution::NONE, ensure it has been correctly intialized through \
@@ -271,7 +275,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
// ct[i] = pk[i] * u + ei (+ m if col = i)
(0..cols).for_each(|i| {
let (mut ci_dft, scratch_2) = scratch_1.take_vec_znx_dft(self.n(), 1, size_pk);
let (mut ci_dft, scratch_2) = scratch_1.take_vec_znx_dft(self.n().into(), 1, size_pk);
// ci_dft = DFT(u) * DFT(pk[i])
module.svp_apply_dft_to_dft(&mut ci_dft, 0, &u_dft, 0, &pk.data, i);
@@ -279,7 +283,15 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
let mut ci_big = module.vec_znx_idft_apply_consume(ci_dft);
// ci_big = u * pk[i] + e
module.vec_znx_big_add_normal(basek, &mut ci_big, 0, pk.k(), source_xe, SIGMA, SIGMA_BOUND);
module.vec_znx_big_add_normal(
base2k,
&mut ci_big,
0,
pk.k().into(),
source_xe,
SIGMA,
SIGMA_BOUND,
);
// ci_big = u * pk[i] + e + m (if col = i)
if let Some((pt, col)) = pt
@@ -289,7 +301,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
}
// ct[i] = norm(ci_big)
module.vec_znx_big_normalize(basek, &mut self.data, i, &ci_big, 0, scratch_2);
module.vec_znx_big_normalize(base2k, &mut self.data, i, base2k, &ci_big, 0, scratch_2);
});
}
}
@@ -297,7 +309,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
#[allow(clippy::too_many_arguments)]
pub(crate) fn glwe_encrypt_sk_internal<DataCt: DataMut, DataPt: DataRef, DataSk: DataRef, B: Backend>(
module: &Module<B>,
basek: usize,
base2k: usize,
k: usize,
ct: &mut VecZnx<DataCt>,
cols: usize,
@@ -316,7 +328,7 @@ pub(crate) fn glwe_encrypt_sk_internal<DataCt: DataMut, DataPt: DataRef, DataSk:
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -350,7 +362,7 @@ pub(crate) fn glwe_encrypt_sk_internal<DataCt: DataMut, DataPt: DataRef, DataSk:
let col_ct: usize = if compressed { 0 } else { i };
// ct[i] = uniform (+ pt)
module.vec_znx_fill_uniform(basek, ct, col_ct, source_xa);
module.vec_znx_fill_uniform(base2k, ct, col_ct, source_xa);
let (mut ci_dft, scratch_3) = scratch_2.take_vec_znx_dft(ct.n(), 1, size);
@@ -360,7 +372,7 @@ pub(crate) fn glwe_encrypt_sk_internal<DataCt: DataMut, DataPt: DataRef, DataSk:
if let Some((pt, col)) = pt {
if i == col {
module.vec_znx_sub(&mut ci, 0, ct, col_ct, &pt.data, 0);
module.vec_znx_normalize_inplace(basek, &mut ci, 0, scratch_3);
module.vec_znx_normalize_inplace(base2k, &mut ci, 0, scratch_3);
module.vec_znx_dft_apply(1, 0, &mut ci_dft, 0, &ci, 0);
} else {
module.vec_znx_dft_apply(1, 0, &mut ci_dft, 0, ct, col_ct);
@@ -373,15 +385,15 @@ pub(crate) fn glwe_encrypt_sk_internal<DataCt: DataMut, DataPt: DataRef, DataSk:
let ci_big: VecZnxBig<&mut [u8], B> = module.vec_znx_idft_apply_consume(ci_dft);
// use c[0] as buffer, which is overwritten later by the normalization step
module.vec_znx_big_normalize(basek, &mut ci, 0, &ci_big, 0, scratch_3);
module.vec_znx_big_normalize(base2k, &mut ci, 0, base2k, &ci_big, 0, scratch_3);
// c0_tmp = -c[i] * s[i] (use c[0] as buffer)
module.vec_znx_sub_ab_inplace(&mut c0, 0, &ci, 0);
module.vec_znx_sub_inplace(&mut c0, 0, &ci, 0);
});
}
// c[0] += e
module.vec_znx_add_normal(basek, &mut c0, 0, k, source_xe, sigma, SIGMA_BOUND);
module.vec_znx_add_normal(base2k, &mut c0, 0, k, source_xe, sigma, SIGMA_BOUND);
// c[0] += m if col = 0
if let Some((pt, col)) = pt
@@ -391,5 +403,5 @@ pub(crate) fn glwe_encrypt_sk_internal<DataCt: DataMut, DataPt: DataRef, DataSk:
}
// c[0] = norm(c[0])
module.vec_znx_normalize(basek, ct, 0, &c0, 0, scratch_1);
module.vec_znx_normalize(base2k, ct, 0, base2k, &c0, 0, scratch_1);
}

View File

@@ -2,14 +2,14 @@ use poulpy_hal::{
api::{
ScratchOwnedAlloc, ScratchOwnedBorrow, SvpApplyDftToDftInplace, VecZnxAddInplace, VecZnxAddNormal, VecZnxBigNormalize,
VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace,
},
layouts::{Backend, DataMut, DataRef, Module, ScratchOwned},
oep::{ScratchAvailableImpl, ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeVecZnxDftImpl, TakeVecZnxImpl},
source::Source,
};
use crate::layouts::{GLWECiphertext, GLWEPublicKey, Infos, prepared::GLWESecretPrepared};
use crate::layouts::{GLWECiphertext, GLWEPublicKey, prepared::GLWESecretPrepared};
impl<D: DataMut> GLWEPublicKey<D> {
pub fn generate_from_sk<S: DataRef, B>(
@@ -27,7 +27,7 @@ impl<D: DataMut> GLWEPublicKey<D> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -42,7 +42,7 @@ impl<D: DataMut> GLWEPublicKey<D> {
{
#[cfg(debug_assertions)]
{
use crate::Distribution;
use crate::{Distribution, layouts::LWEInfos};
assert_eq!(self.n(), sk.n());
@@ -52,13 +52,9 @@ impl<D: DataMut> GLWEPublicKey<D> {
}
// Its ok to allocate scratch space here since pk is usually generated only once.
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWECiphertext::encrypt_sk_scratch_space(
module,
self.basek(),
self.k(),
));
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWECiphertext::encrypt_sk_scratch_space(module, self));
let mut tmp: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(self.n(), self.basek(), self.k(), self.rank());
let mut tmp: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(self);
tmp.encrypt_zero_sk(module, sk, source_xa, source_xe, scratch.borrow());
self.dist = sk.dist;
}

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigNormalize,
VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut, ZnxZero},
source::Source,
@@ -11,17 +11,21 @@ use poulpy_hal::{
use crate::{
TakeGLWESecret, TakeGLWESecretPrepared,
layouts::{GGLWESwitchingKey, GLWESecret, GLWEToLWESwitchingKey, LWESecret, prepared::GLWESecretPrepared},
layouts::{
GGLWELayoutInfos, GGLWESwitchingKey, GLWESecret, GLWEToLWESwitchingKey, LWEInfos, LWESecret, Rank,
prepared::GLWESecretPrepared,
},
};
impl GLWEToLWESwitchingKey<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank_in: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{
GLWESecretPrepared::bytes_of(module, rank_in)
+ (GGLWESwitchingKey::encrypt_sk_scratch_space(module, basek, k, rank_in, 1)
| GLWESecret::bytes_of(module.n(), rank_in))
GLWESecretPrepared::alloc_bytes_with(module, infos.rank_in())
+ (GGLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
| GLWESecret::alloc_bytes_with(infos.n(), infos.rank_in()))
}
}
@@ -47,7 +51,7 @@ impl<D: DataMut> GLWEToLWESwitchingKey<D> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -60,12 +64,12 @@ impl<D: DataMut> GLWEToLWESwitchingKey<D> {
{
#[cfg(debug_assertions)]
{
assert!(sk_lwe.n() <= module.n());
assert!(sk_lwe.n().0 <= module.n() as u32);
}
let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(sk_glwe.n(), 1);
let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(sk_glwe.n(), Rank(1));
sk_lwe_as_glwe.data.zero();
sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n()].copy_from_slice(sk_lwe.data.at(0, 0));
sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n().into()].copy_from_slice(sk_lwe.data.at(0, 0));
module.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1);
self.0.encrypt_sk(

View File

@@ -7,7 +7,7 @@ use poulpy_hal::{
use crate::{
encryption::{SIGMA, SIGMA_BOUND},
layouts::{Infos, LWECiphertext, LWEPlaintext, LWESecret},
layouts::{LWECiphertext, LWEInfos, LWEPlaintext, LWESecret},
};
impl<DataSelf: DataMut> LWECiphertext<DataSelf> {
@@ -29,10 +29,10 @@ impl<DataSelf: DataMut> LWECiphertext<DataSelf> {
assert_eq!(self.n(), sk.n())
}
let basek: usize = self.basek();
let k: usize = self.k();
let base2k: usize = self.base2k().into();
let k: usize = self.k().into();
module.zn_fill_uniform(self.n() + 1, basek, &mut self.data, 0, source_xa);
module.zn_fill_uniform((self.n() + 1).into(), base2k, &mut self.data, 0, source_xa);
let mut tmp_znx: Zn<Vec<u8>> = Zn::alloc(1, 1, self.size());
@@ -57,7 +57,7 @@ impl<DataSelf: DataMut> LWECiphertext<DataSelf> {
module.zn_add_normal(
1,
basek,
base2k,
&mut self.data,
0,
k,
@@ -68,7 +68,7 @@ impl<DataSelf: DataMut> LWECiphertext<DataSelf> {
module.zn_normalize_inplace(
1,
basek,
base2k,
&mut tmp_znx,
0,
ScratchOwned::alloc(size_of::<i64>()).borrow(),

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigNormalize,
VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut},
source::Source,
@@ -11,17 +11,36 @@ use poulpy_hal::{
use crate::{
TakeGLWESecret, TakeGLWESecretPrepared,
layouts::{GGLWESwitchingKey, GLWESecret, Infos, LWESecret, LWESwitchingKey, prepared::GLWESecretPrepared},
layouts::{
Degree, GGLWELayoutInfos, GGLWESwitchingKey, GLWESecret, LWEInfos, LWESecret, LWESwitchingKey, Rank,
prepared::GLWESecretPrepared,
},
};
impl LWESwitchingKey<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{
GLWESecret::bytes_of(module.n(), 1)
+ GLWESecretPrepared::bytes_of(module, 1)
+ GGLWESwitchingKey::encrypt_sk_scratch_space(module, basek, k, 1, 1)
debug_assert_eq!(
infos.digits().0,
1,
"digits > 1 is not supported for LWESwitchingKey"
);
debug_assert_eq!(
infos.rank_in().0,
1,
"rank_in > 1 is not supported for LWESwitchingKey"
);
debug_assert_eq!(
infos.rank_out().0,
1,
"rank_out > 1 is not supported for LWESwitchingKey"
);
GLWESecret::alloc_bytes_with(Degree(module.n() as u32), Rank(1))
+ GLWESecretPrepared::alloc_bytes_with(module, Rank(1))
+ GGLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
}
}
@@ -47,7 +66,7 @@ impl<D: DataMut> LWESwitchingKey<D> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -60,20 +79,20 @@ impl<D: DataMut> LWESwitchingKey<D> {
{
#[cfg(debug_assertions)]
{
assert!(sk_lwe_in.n() <= self.n());
assert!(sk_lwe_out.n() <= self.n());
assert!(self.n() <= module.n());
assert!(sk_lwe_in.n().0 <= self.n().0);
assert!(sk_lwe_out.n().0 <= self.n().0);
assert!(self.n().0 <= module.n() as u32);
}
let (mut sk_in_glwe, scratch_1) = scratch.take_glwe_secret(self.n(), 1);
let (mut sk_out_glwe, scratch_2) = scratch_1.take_glwe_secret(self.n(), 1);
let (mut sk_in_glwe, scratch_1) = scratch.take_glwe_secret(self.n(), Rank(1));
let (mut sk_out_glwe, scratch_2) = scratch_1.take_glwe_secret(self.n(), Rank(1));
sk_out_glwe.data.at_mut(0, 0)[..sk_lwe_out.n()].copy_from_slice(sk_lwe_out.data.at(0, 0));
sk_out_glwe.data.at_mut(0, 0)[sk_lwe_out.n()..].fill(0);
sk_out_glwe.data.at_mut(0, 0)[..sk_lwe_out.n().into()].copy_from_slice(sk_lwe_out.data.at(0, 0));
sk_out_glwe.data.at_mut(0, 0)[sk_lwe_out.n().into()..].fill(0);
module.vec_znx_automorphism_inplace(-1, &mut sk_out_glwe.data.as_vec_znx_mut(), 0, scratch_2);
sk_in_glwe.data.at_mut(0, 0)[..sk_lwe_in.n()].copy_from_slice(sk_lwe_in.data.at(0, 0));
sk_in_glwe.data.at_mut(0, 0)[sk_lwe_in.n()..].fill(0);
sk_in_glwe.data.at_mut(0, 0)[..sk_lwe_in.n().into()].copy_from_slice(sk_lwe_in.data.at(0, 0));
sk_in_glwe.data.at_mut(0, 0)[sk_lwe_in.n().into()..].fill(0);
module.vec_znx_automorphism_inplace(-1, &mut sk_in_glwe.data.as_vec_znx_mut(), 0, scratch_2);
self.0.encrypt_sk(

View File

@@ -3,7 +3,7 @@ use poulpy_hal::{
ScratchAvailable, SvpApplyDftToDftInplace, SvpPPolAllocBytes, SvpPrepare, TakeScalarZnx, TakeVecZnx, TakeVecZnxDft,
VecZnxAddInplace, VecZnxAddNormal, VecZnxAddScalarInplace, VecZnxAutomorphismInplace, VecZnxBigNormalize,
VecZnxDftAllocBytes, VecZnxDftApply, VecZnxFillUniform, VecZnxIdftApplyConsume, VecZnxNormalize, VecZnxNormalizeInplace,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubABInplace, VecZnxSwitchRing,
VecZnxNormalizeTmpBytes, VecZnxSub, VecZnxSubInplace, VecZnxSwitchRing,
},
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxView, ZnxViewMut},
source::Source,
@@ -11,15 +11,22 @@ use poulpy_hal::{
use crate::{
TakeGLWESecret, TakeGLWESecretPrepared,
layouts::{GGLWESwitchingKey, GLWESecret, LWESecret, LWEToGLWESwitchingKey},
layouts::{Degree, GGLWELayoutInfos, GGLWESwitchingKey, GLWESecret, LWEInfos, LWESecret, LWEToGLWESwitchingKey, Rank},
};
impl LWEToGLWESwitchingKey<Vec<u8>> {
pub fn encrypt_sk_scratch_space<B: Backend>(module: &Module<B>, basek: usize, k: usize, rank_out: usize) -> usize
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
where
A: GGLWELayoutInfos,
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
{
GGLWESwitchingKey::encrypt_sk_scratch_space(module, basek, k, 1, rank_out) + GLWESecret::bytes_of(module.n(), 1)
debug_assert_eq!(
infos.rank_in(),
Rank(1),
"rank_in != 1 is not supported for LWEToGLWESwitchingKey"
);
GGLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
+ GLWESecret::alloc_bytes_with(Degree(module.n() as u32), infos.rank_in())
}
}
@@ -45,7 +52,7 @@ impl<D: DataMut> LWEToGLWESwitchingKey<D> {
+ VecZnxIdftApplyConsume<B>
+ VecZnxNormalizeTmpBytes
+ VecZnxFillUniform
+ VecZnxSubABInplace
+ VecZnxSubInplace
+ VecZnxAddInplace
+ VecZnxNormalizeInplace<B>
+ VecZnxAddNormal
@@ -58,12 +65,14 @@ impl<D: DataMut> LWEToGLWESwitchingKey<D> {
{
#[cfg(debug_assertions)]
{
assert!(sk_lwe.n() <= module.n());
use crate::layouts::LWEInfos;
assert!(sk_lwe.n().0 <= module.n() as u32);
}
let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(sk_glwe.n(), 1);
sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n()].copy_from_slice(sk_lwe.data.at(0, 0));
sk_lwe_as_glwe.data.at_mut(0, 0)[sk_lwe.n()..].fill(0);
let (mut sk_lwe_as_glwe, scratch_1) = scratch.take_glwe_secret(sk_glwe.n(), Rank(1));
sk_lwe_as_glwe.data.at_mut(0, 0)[..sk_lwe.n().into()].copy_from_slice(sk_lwe.data.at(0, 0));
sk_lwe_as_glwe.data.at_mut(0, 0)[sk_lwe.n().into()..].fill(0);
module.vec_znx_automorphism_inplace(-1, &mut sk_lwe_as_glwe.data.as_vec_znx_mut(), 0, scratch_1);
self.0.encrypt_sk(