keyswitch tests

This commit is contained in:
Pro7ech
2025-10-20 15:32:52 +02:00
parent 0c894c19db
commit 252eda36fe
60 changed files with 918 additions and 945 deletions

View File

@@ -5,11 +5,10 @@ use poulpy_hal::{
};
use crate::{
ScratchTakeCore,
encryption::compressed::gglwe_ksk::GLWESwitchingKeyCompressedEncryptSk,
GGLWECompressedEncryptSk, ScratchTakeCore,
layouts::{
GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, LWEInfos,
compressed::{AutomorphismKeyCompressed, AutomorphismKeyCompressedToMut},
GGLWECompressedSeedMut, GGLWECompressedToMut, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretPrepare, GLWESecretPrepared,
GLWESecretPreparedAlloc, GLWESecretToRef, LWEInfos, SetAutomorphismGaloisElement, compressed::AutomorphismKeyCompressed,
},
};
@@ -34,7 +33,7 @@ impl<DataSelf: DataMut> AutomorphismKeyCompressed<DataSelf> {
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
S: GLWESecretToRef,
S: GLWESecretToRef + GLWEInfos,
M: AutomorphismKeyCompressedEncryptSk<BE>,
{
module.automorphism_key_compressed_encrypt_sk(self, p, sk, seed_xa, source_xe, scratch);
@@ -55,20 +54,28 @@ pub trait AutomorphismKeyCompressedEncryptSk<BE: Backend> {
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: AutomorphismKeyCompressedToMut,
S: GLWESecretToRef;
R: GGLWECompressedToMut + GGLWECompressedSeedMut + SetAutomorphismGaloisElement + GGLWEInfos,
S: GLWESecretToRef + GLWEInfos;
}
impl<BE: Backend> AutomorphismKeyCompressedEncryptSk<BE> for Module<BE>
where
Self: ModuleN + GaloisElement + VecZnxAutomorphism + GLWESwitchingKeyCompressedEncryptSk<BE>,
Self: ModuleN
+ GaloisElement
+ VecZnxAutomorphism
+ GGLWECompressedEncryptSk<BE>
+ GLWESecretPreparedAlloc<BE>
+ GLWESecretPrepare<BE>,
Scratch<BE>: ScratchTakeCore<BE>,
{
fn automorphism_key_compressed_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
self.glwe_switching_key_compressed_encrypt_sk_tmp_bytes(infos) + GLWESecret::bytes_of(self.n().into(), infos.rank())
assert_eq!(self.n() as u32, infos.n());
self.gglwe_compressed_encrypt_sk_tmp_bytes(infos)
.max(GLWESecret::bytes_of_from_infos(infos))
+ GLWESecretPrepared::bytes_of_from_infos(self, infos)
}
fn automorphism_key_compressed_encrypt_sk<R, S>(
@@ -80,12 +87,10 @@ where
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: AutomorphismKeyCompressedToMut,
S: GLWESecretToRef,
R: GGLWECompressedToMut + GGLWECompressedSeedMut + SetAutomorphismGaloisElement + GGLWEInfos,
S: GLWESecretToRef + GLWEInfos,
{
let res: &mut AutomorphismKeyCompressed<&mut [u8]> = &mut res.to_mut();
let sk: &GLWESecret<&[u8]> = &sk.to_ref();
assert_eq!(res.n(), sk.n());
assert_eq!(res.rank_out(), res.rank_in());
assert_eq!(sk.rank(), res.rank_out());
@@ -96,9 +101,9 @@ where
AutomorphismKeyCompressed::encrypt_sk_tmp_bytes(self, res)
);
let (mut sk_out, scratch_1) = scratch.take_glwe_secret(self, sk.rank());
let (mut sk_out_prepared, scratch_1) = scratch.take_glwe_secret_prepared(self, sk.rank());
{
let (mut sk_out, _) = scratch_1.take_glwe_secret(self, sk.rank());
for i in 0..res.rank_out().into() {
self.vec_znx_automorphism(
self.galois_element_inv(p),
@@ -108,10 +113,18 @@ where
i,
);
}
sk_out_prepared.prepare(self, &sk_out);
}
self.glwe_switching_key_compressed_encrypt_sk(&mut res.key, sk, &sk_out, seed_xa, source_xe, scratch_1);
self.gglwe_compressed_encrypt_sk(
res,
&sk.data,
&sk_out_prepared,
seed_xa,
source_xe,
scratch_1,
);
res.p = p;
res.set_p(p);
}
}

View File

@@ -8,8 +8,9 @@ use crate::{
ScratchTakeCore,
encryption::compressed::gglwe_ct::GGLWECompressedEncryptSk,
layouts::{
GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, LWEInfos,
compressed::{GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedToMut},
GGLWECompressedSeedMut, GGLWECompressedToMut, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef,
GLWESwitchingKeyDegreesMut, LWEInfos,
compressed::GLWESwitchingKeyCompressed,
prepared::{GLWESecretPrepare, GLWESecretPrepared, GLWESecretPreparedAlloc},
},
};
@@ -57,7 +58,7 @@ pub trait GLWESwitchingKeyCompressedEncryptSk<BE: Backend> {
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: GLWESwitchingKeyCompressedToMut,
R: GGLWECompressedToMut + GGLWECompressedSeedMut + GLWESwitchingKeyDegreesMut + GGLWEInfos,
S1: GLWESecretToRef,
S2: GLWESecretToRef;
}
@@ -86,11 +87,10 @@ where
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: GLWESwitchingKeyCompressedToMut,
R: GGLWECompressedToMut + GGLWECompressedSeedMut + GLWESwitchingKeyDegreesMut + GGLWEInfos,
S1: GLWESecretToRef,
S2: GLWESecretToRef,
{
let res: &mut GLWESwitchingKeyCompressed<&mut [u8]> = &mut res.to_mut();
let sk_in: &GLWESecret<&[u8]> = &sk_in.to_ref();
let sk_out: &GLWESecret<&[u8]> = &sk_out.to_ref();
@@ -122,15 +122,9 @@ where
}
}
self.gglwe_compressed_encrypt_sk(
&mut res.key,
&sk_in_tmp,
&sk_out_tmp,
seed_xa,
source_xe,
scratch_2,
);
res.sk_in_n = sk_in.n().into();
res.sk_out_n = sk_out.n().into();
self.gglwe_compressed_encrypt_sk(res, &sk_in_tmp, &sk_out_tmp, seed_xa, source_xe, scratch_2);
*res.input_degree() = sk_in.n();
*res.output_degree() = sk_out.n();
}
}

View File

@@ -4,16 +4,15 @@ use poulpy_hal::{
VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyTmpA,
},
layouts::{Backend, DataMut, Module, Scratch},
oep::{SvpPPolAllocBytesImpl, VecZnxBigAllocBytesImpl, VecZnxDftAllocBytesImpl},
source::Source,
};
use crate::{
GetDistribution, ScratchTakeCore,
encryption::{compressed::gglwe_ksk::GLWESwitchingKeyCompressedEncryptSk, gglwe_tsk::TensorKeyEncryptSk},
GGLWECompressedEncryptSk, GetDistribution, ScratchTakeCore,
encryption::gglwe_tsk::TensorKeyEncryptSk,
layouts::{
GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, LWEInfos, Rank,
compressed::{TensorKeyCompressed, TensorKeyCompressedToMut},
GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretPrepared, GLWESecretPreparedAlloc, GLWESecretToRef, LWEInfos, Rank,
TensorKeyCompressedAtMut, compressed::TensorKeyCompressed,
},
};
@@ -23,7 +22,7 @@ impl TensorKeyCompressed<Vec<u8>> {
A: GGLWEInfos,
M: GGLWETensorKeyCompressedEncryptSk<BE>,
{
module.gglwe_tensor_key_compressed_encrypt_sk_tmp_bytes(infos)
module.tensor_key_compressed_encrypt_sk_tmp_bytes(infos)
}
}
@@ -39,16 +38,16 @@ impl<DataSelf: DataMut> TensorKeyCompressed<DataSelf> {
S: GLWESecretToRef + GetDistribution,
M: GGLWETensorKeyCompressedEncryptSk<BE>,
{
module.gglwe_tensor_key_encrypt_sk(self, sk, seed_xa, source_xe, scratch);
module.tensor_key_compressed_encrypt_sk(self, sk, seed_xa, source_xe, scratch);
}
}
pub trait GGLWETensorKeyCompressedEncryptSk<BE: Backend> {
fn gglwe_tensor_key_compressed_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
fn tensor_key_compressed_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos;
fn gglwe_tensor_key_encrypt_sk<R, S>(
fn tensor_key_compressed_encrypt_sk<R, S, D>(
&self,
res: &mut R,
sk: &S,
@@ -56,36 +55,40 @@ pub trait GGLWETensorKeyCompressedEncryptSk<BE: Backend> {
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: TensorKeyCompressedToMut,
D: DataMut,
R: TensorKeyCompressedAtMut<D> + GGLWEInfos,
S: GLWESecretToRef + GetDistribution;
}
impl<BE: Backend> GGLWETensorKeyCompressedEncryptSk<BE> for Module<BE>
where
Self: ModuleN
+ GLWESwitchingKeyCompressedEncryptSk<BE>
+ GGLWECompressedEncryptSk<BE>
+ TensorKeyEncryptSk<BE>
+ VecZnxDftApply<BE>
+ SvpApplyDftToDft<BE>
+ VecZnxIdftApplyTmpA<BE>
+ VecZnxBigNormalize<BE>
+ SvpPrepare<BE>
+ SvpPPolAllocBytesImpl<BE>
+ SvpPPolBytesOf
+ VecZnxDftAllocBytesImpl<BE>
+ VecZnxBigAllocBytesImpl<BE>
+ VecZnxDftBytesOf
+ VecZnxBigBytesOf,
+ VecZnxBigBytesOf
+ GLWESecretPreparedAlloc<BE>,
Scratch<BE>: ScratchTakeBasic + ScratchTakeCore<BE>,
{
fn gglwe_tensor_key_compressed_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
fn tensor_key_compressed_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
self.tensor_key_encrypt_sk_tmp_bytes(infos)
GLWESecretPrepared::bytes_of(self, infos.rank_out())
+ self.bytes_of_vec_znx_dft(infos.rank_out().into(), 1)
+ self.bytes_of_vec_znx_big(1, 1)
+ self.bytes_of_vec_znx_dft(1, 1)
+ GLWESecret::bytes_of(self.n().into(), Rank(1))
+ self.gglwe_compressed_encrypt_sk_tmp_bytes(infos)
}
fn gglwe_tensor_key_encrypt_sk<R, S>(
fn tensor_key_compressed_encrypt_sk<R, S, D>(
&self,
res: &mut R,
sk: &S,
@@ -93,11 +96,10 @@ where
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: TensorKeyCompressedToMut,
D: DataMut,
R: GGLWEInfos + TensorKeyCompressedAtMut<D>,
S: GLWESecretToRef + GetDistribution,
{
let res: &mut TensorKeyCompressed<&mut [u8]> = &mut res.to_mut();
let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(self, res.rank_out());
sk_dft_prep.prepare(self, sk);
@@ -141,10 +143,10 @@ where
let (seed_xa_tmp, _) = source_xa.branch();
self.glwe_switching_key_compressed_encrypt_sk(
self.gglwe_compressed_encrypt_sk(
res.at_mut(i, j),
&sk_ij,
sk,
&sk_ij.data,
&sk_dft_prep,
seed_xa_tmp,
source_xe,
scratch_5,

View File

@@ -1,6 +1,6 @@
use poulpy_hal::{
api::{ModuleN, VecZnxAddScalarInplace, VecZnxNormalizeInplace},
layouts::{Backend, DataMut, Module, ScalarZnx, ScalarZnxToRef, Scratch, ZnxZero},
layouts::{Backend, DataMut, Module, ScalarZnx, ScalarZnxToRef, Scratch, ZnxInfos, ZnxZero},
source::Source,
};
@@ -57,7 +57,7 @@ pub trait GGSWCompressedEncryptSk<BE: Backend> {
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: GGSWCompressedToMut + GGSWCompressedSeedMut,
R: GGSWCompressedToMut + GGSWCompressedSeedMut + GGSWInfos,
P: ScalarZnxToRef,
S: GLWESecretPreparedToRef<BE>;
}
@@ -83,30 +83,29 @@ where
source_xe: &mut Source,
scratch: &mut Scratch<BE>,
) where
R: GGSWCompressedToMut + GGSWCompressedSeedMut,
R: GGSWCompressedToMut + GGSWCompressedSeedMut + GGSWInfos,
P: ScalarZnxToRef,
S: GLWESecretPreparedToRef<BE>,
{
let mut seeds: Vec<[u8; 32]> = vec![[0u8; 32]; res.seed_mut().len()];
let base2k: usize = res.base2k().into();
let rank: usize = res.rank().into();
let cols: usize = rank + 1;
let dsize: usize = res.dsize().into();
let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref();
let pt: &ScalarZnx<&[u8]> = &pt.to_ref();
assert_eq!(res.rank(), sk.rank());
assert_eq!(pt.n(), self.n());
assert_eq!(res.n(), self.n() as u32);
assert_eq!(sk.n(), self.n() as u32);
let mut seeds: Vec<[u8; 32]> = vec![[0u8; 32]; res.dnum().as_usize() * (res.rank().as_usize() + 1)];
{
let res: &mut GGSWCompressed<&mut [u8]> = &mut res.to_mut();
let sk: &GLWESecretPrepared<&[u8], BE> = &sk.to_ref();
let pt: &ScalarZnx<&[u8]> = &pt.to_ref();
#[cfg(debug_assertions)]
{
use poulpy_hal::layouts::ZnxInfos;
assert_eq!(res.rank(), sk.rank());
assert_eq!(res.n(), sk.n());
assert_eq!(pt.n() as u32, sk.n());
}
let base2k: usize = res.base2k().into();
let rank: usize = res.rank().into();
let cols: usize = rank + 1;
let dsize: usize = res.dsize().into();
println!("res.seed: {:?}", res.seed);
let (mut tmp_pt, scratch_1) = scratch.take_glwe_pt(self, &res.glwe_layout());