mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 13:16:44 +01:00
Distinguish between gglwe_to_ggsw key and tensor_key + update key repreentation
This commit is contained in:
124
poulpy-core/src/encryption/compressed/gglwe_to_ggsw_key.rs
Normal file
124
poulpy-core/src/encryption/compressed/gglwe_to_ggsw_key.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
use poulpy_hal::{
|
||||
api::{ModuleN, ScratchTakeBasic, VecZnxCopy},
|
||||
layouts::{Backend, DataMut, Module, Scratch},
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
GGLWECompressedEncryptSk, GetDistribution, ScratchTakeCore,
|
||||
layouts::{
|
||||
GGLWEInfos, GGLWEToGGSWKeyCompressed, GGLWEToGGSWKeyCompressedToMut, GLWEInfos, GLWESecret, GLWESecretTensor,
|
||||
GLWESecretTensorFactory, GLWESecretToRef,
|
||||
prepared::{GLWESecretPrepared, GLWESecretPreparedFactory},
|
||||
},
|
||||
};
|
||||
|
||||
impl GGLWEToGGSWKeyCompressed<Vec<u8>> {
|
||||
pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
M: GGLWEToGGSWKeyCompressedEncryptSk<BE>,
|
||||
{
|
||||
module.gglwe_to_ggsw_key_encrypt_sk_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<DataSelf: DataMut> GGLWEToGGSWKeyCompressed<DataSelf> {
|
||||
pub fn encrypt_sk<M, S, BE: Backend>(
|
||||
&mut self,
|
||||
module: &M,
|
||||
sk: &S,
|
||||
seed_xa: [u8; 32],
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
M: GGLWEToGGSWKeyCompressedEncryptSk<BE>,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
module.gglwe_to_ggsw_key_encrypt_sk(self, sk, seed_xa, source_xe, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEToGGSWKeyCompressedEncryptSk<BE: Backend> {
|
||||
fn gglwe_to_ggsw_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
|
||||
fn gglwe_to_ggsw_key_encrypt_sk<R, S>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk: &S,
|
||||
seed_xa: [u8; 32],
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
R: GGLWEToGGSWKeyCompressedToMut + GGLWEInfos,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos;
|
||||
}
|
||||
|
||||
impl<BE: Backend> GGLWEToGGSWKeyCompressedEncryptSk<BE> for Module<BE>
|
||||
where
|
||||
Self: ModuleN + GGLWECompressedEncryptSk<BE> + GLWESecretTensorFactory<BE> + GLWESecretPreparedFactory<BE> + VecZnxCopy,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
fn gglwe_to_ggsw_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
let sk_prepared: usize = GLWESecretPrepared::bytes_of(self, infos.rank());
|
||||
let sk_tensor: usize = GLWESecretTensor::bytes_of_from_infos(infos);
|
||||
let gglwe_encrypt: usize = self.gglwe_compressed_encrypt_sk_tmp_bytes(infos);
|
||||
let sk_ij = GLWESecret::bytes_of(self.n().into(), infos.rank());
|
||||
(sk_prepared + sk_tensor + sk_ij) + gglwe_encrypt.max(self.glwe_secret_tensor_prepare_tmp_bytes(infos.rank()))
|
||||
}
|
||||
|
||||
fn gglwe_to_ggsw_key_encrypt_sk<R, S>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk: &S,
|
||||
seed_xa: [u8; 32],
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
R: GGLWEToGGSWKeyCompressedToMut + GGLWEInfos,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||
{
|
||||
assert_eq!(res.rank(), sk.rank());
|
||||
assert_eq!(res.n(), sk.n());
|
||||
|
||||
let res: &mut GGLWEToGGSWKeyCompressed<&mut [u8]> = &mut res.to_mut();
|
||||
let rank: usize = res.rank_out().as_usize();
|
||||
|
||||
let (mut sk_prepared, scratch_1) = scratch.take_glwe_secret_prepared(self, res.rank());
|
||||
let (mut sk_tensor, scratch_2) = scratch_1.take_glwe_secret_tensor(self.n().into(), res.rank());
|
||||
sk_prepared.prepare(self, sk);
|
||||
sk_tensor.prepare(self, sk, scratch_2);
|
||||
|
||||
let (mut sk_ij, scratch_3) = scratch_2.take_scalar_znx(self.n(), rank);
|
||||
|
||||
let mut source_xa = Source::new(seed_xa);
|
||||
|
||||
for i in 0..rank {
|
||||
for j in 0..rank {
|
||||
self.vec_znx_copy(
|
||||
&mut sk_ij.as_vec_znx_mut(),
|
||||
j,
|
||||
&sk_tensor.at(i, j).as_vec_znx(),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
let (seed_xa_tmp, _) = source_xa.branch();
|
||||
|
||||
res.at_mut(i).encrypt_sk(
|
||||
self,
|
||||
&sk_ij,
|
||||
&sk_prepared,
|
||||
seed_xa_tmp,
|
||||
source_xe,
|
||||
scratch_3,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
use poulpy_hal::{
|
||||
api::{
|
||||
ModuleN, ScratchTakeBasic, SvpApplyDftToDft, SvpPPolBytesOf, SvpPrepare, VecZnxBigBytesOf, VecZnxBigNormalize,
|
||||
VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyTmpA,
|
||||
},
|
||||
api::ScratchTakeBasic,
|
||||
layouts::{Backend, DataMut, Module, Scratch},
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
GGLWECompressedEncryptSk, GLWETensorKeyEncryptSk, GetDistribution, ScratchTakeCore,
|
||||
GGLWECompressedEncryptSk, GetDistribution, ScratchTakeCore,
|
||||
layouts::{
|
||||
GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretPrepared, GLWESecretPreparedFactory, GLWESecretToRef,
|
||||
GLWETensorKeyCompressedAtMut, LWEInfos, Rank, compressed::GLWETensorKeyCompressed,
|
||||
GGLWECompressedSeedMut, GGLWECompressedToMut, GGLWEInfos, GGLWELayout, GLWEInfos, GLWESecretPrepared,
|
||||
GLWESecretPreparedFactory, GLWESecretTensor, GLWESecretTensorFactory, GLWESecretToRef,
|
||||
compressed::GLWETensorKeyCompressed,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -34,7 +32,7 @@ impl<DataSelf: DataMut> GLWETensorKeyCompressed<DataSelf> {
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
S: GLWESecretToRef + GetDistribution,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||
M: GLWETensorKeyCompressedEncryptSk<BE>,
|
||||
{
|
||||
module.glwe_tensor_key_compressed_encrypt_sk(self, sk, seed_xa, source_xe, scratch);
|
||||
@@ -46,7 +44,7 @@ pub trait GLWETensorKeyCompressedEncryptSk<BE: Backend> {
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
|
||||
fn glwe_tensor_key_compressed_encrypt_sk<R, S, D>(
|
||||
fn glwe_tensor_key_compressed_encrypt_sk<R, S>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk: &S,
|
||||
@@ -54,40 +52,38 @@ pub trait GLWETensorKeyCompressedEncryptSk<BE: Backend> {
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
D: DataMut,
|
||||
R: GLWETensorKeyCompressedAtMut<D> + GGLWEInfos,
|
||||
S: GLWESecretToRef + GetDistribution;
|
||||
R: GGLWECompressedToMut + GGLWEInfos + GGLWECompressedSeedMut,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos;
|
||||
}
|
||||
|
||||
impl<BE: Backend> GLWETensorKeyCompressedEncryptSk<BE> for Module<BE>
|
||||
where
|
||||
Self: ModuleN
|
||||
+ GGLWECompressedEncryptSk<BE>
|
||||
+ GLWETensorKeyEncryptSk<BE>
|
||||
+ VecZnxDftApply<BE>
|
||||
+ SvpApplyDftToDft<BE>
|
||||
+ VecZnxIdftApplyTmpA<BE>
|
||||
+ VecZnxBigNormalize<BE>
|
||||
+ SvpPrepare<BE>
|
||||
+ SvpPPolBytesOf
|
||||
+ VecZnxDftBytesOf
|
||||
+ VecZnxBigBytesOf
|
||||
+ GLWESecretPreparedFactory<BE>,
|
||||
Self: GGLWECompressedEncryptSk<BE> + GLWESecretPreparedFactory<BE> + GLWESecretTensorFactory<BE>,
|
||||
Scratch<BE>: ScratchTakeBasic + ScratchTakeCore<BE>,
|
||||
{
|
||||
fn glwe_tensor_key_compressed_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
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)
|
||||
let sk_prepared: usize = GLWESecretPrepared::bytes_of(self, infos.rank_out());
|
||||
let sk_tensor: usize = GLWESecretTensor::bytes_of_from_infos(infos);
|
||||
|
||||
let tensor_infos: GGLWELayout = GGLWELayout {
|
||||
n: infos.n(),
|
||||
base2k: infos.base2k(),
|
||||
k: infos.k(),
|
||||
rank_in: GLWESecretTensor::pairs(infos.rank().into()).into(),
|
||||
rank_out: infos.rank_out(),
|
||||
dnum: infos.dnum(),
|
||||
dsize: infos.dsize(),
|
||||
};
|
||||
|
||||
let gglwe_encrypt: usize = self.gglwe_compressed_encrypt_sk_tmp_bytes(&tensor_infos);
|
||||
|
||||
(sk_prepared + sk_tensor) + gglwe_encrypt.max(self.glwe_secret_tensor_prepare_tmp_bytes(infos.rank()))
|
||||
}
|
||||
|
||||
fn glwe_tensor_key_compressed_encrypt_sk<R, S, D>(
|
||||
fn glwe_tensor_key_compressed_encrypt_sk<R, S>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk: &S,
|
||||
@@ -95,62 +91,24 @@ where
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
D: DataMut,
|
||||
R: GGLWEInfos + GLWETensorKeyCompressedAtMut<D>,
|
||||
S: GLWESecretToRef + GetDistribution,
|
||||
R: GGLWEInfos + GGLWECompressedToMut + GGLWECompressedSeedMut,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||
{
|
||||
let (mut sk_dft_prep, scratch_1) = scratch.take_glwe_secret_prepared(self, res.rank());
|
||||
sk_dft_prep.prepare(self, sk);
|
||||
assert_eq!(res.rank_out(), sk.rank());
|
||||
assert_eq!(res.n(), sk.n());
|
||||
|
||||
let sk: &GLWESecret<&[u8]> = &sk.to_ref();
|
||||
let (mut sk_prepared, scratch_1) = scratch.take_glwe_secret_prepared(self, res.rank());
|
||||
let (mut sk_tensor, scratch_2) = scratch_1.take_glwe_secret_tensor(self.n().into(), res.rank());
|
||||
sk_prepared.prepare(self, sk);
|
||||
sk_tensor.prepare(self, sk, scratch_2);
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
assert_eq!(res.rank_out(), sk.rank());
|
||||
assert_eq!(res.n(), sk.n());
|
||||
}
|
||||
|
||||
// let n: usize = sk.n().into();
|
||||
let rank: usize = res.rank_out().into();
|
||||
|
||||
let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(self, rank, 1);
|
||||
|
||||
for i in 0..rank {
|
||||
self.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(self, 1, 1);
|
||||
let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(self.n().into(), Rank(1));
|
||||
let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(self, 1, 1);
|
||||
|
||||
let mut source_xa: Source = Source::new(seed_xa);
|
||||
|
||||
for i in 0..rank {
|
||||
for j in i..rank {
|
||||
self.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_dft_prep.data, j, &sk_dft, i);
|
||||
|
||||
self.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
|
||||
self.vec_znx_big_normalize(
|
||||
res.base2k().into(),
|
||||
&mut sk_ij.data.as_vec_znx_mut(),
|
||||
0,
|
||||
res.base2k().into(),
|
||||
&sk_ij_big,
|
||||
0,
|
||||
scratch_5,
|
||||
);
|
||||
|
||||
let (seed_xa_tmp, _) = source_xa.branch();
|
||||
|
||||
self.gglwe_compressed_encrypt_sk(
|
||||
res.at_mut(i, j),
|
||||
&sk_ij.data,
|
||||
&sk_dft_prep,
|
||||
seed_xa_tmp,
|
||||
source_xe,
|
||||
scratch_5,
|
||||
);
|
||||
}
|
||||
}
|
||||
self.gglwe_compressed_encrypt_sk(
|
||||
res,
|
||||
&sk_tensor.data,
|
||||
&sk_prepared,
|
||||
seed_xa,
|
||||
source_xe,
|
||||
scratch_2,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
mod gglwe;
|
||||
mod gglwe_to_ggsw_key;
|
||||
mod ggsw;
|
||||
mod glwe_automorphism_key;
|
||||
mod glwe_ct;
|
||||
@@ -6,6 +7,7 @@ mod glwe_switching_key;
|
||||
mod glwe_tensor_key;
|
||||
|
||||
pub use gglwe::*;
|
||||
pub use gglwe_to_ggsw_key::*;
|
||||
pub use ggsw::*;
|
||||
pub use glwe_automorphism_key::*;
|
||||
pub use glwe_ct::*;
|
||||
|
||||
@@ -148,7 +148,7 @@ where
|
||||
// Example for ksk rank 2 to rank 3:
|
||||
//
|
||||
// (-(a0*s0 + a1*s1 + a2*s2) + s0', a0, a1, a2)
|
||||
// (-(b0*s0 + b1*s1 + b2*s2) + s0', b0, b1, b2)
|
||||
// (-(b0*s0 + b1*s1 + b2*s2) + s1', b0, b1, b2)
|
||||
//
|
||||
// Example ksk rank 2 to rank 1
|
||||
//
|
||||
|
||||
112
poulpy-core/src/encryption/gglwe_to_ggsw_key.rs
Normal file
112
poulpy-core/src/encryption/gglwe_to_ggsw_key.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
use poulpy_hal::{
|
||||
api::{ModuleN, ScratchTakeBasic, VecZnxCopy},
|
||||
layouts::{Backend, DataMut, Module, Scratch},
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
GGLWEEncryptSk, GetDistribution, ScratchTakeCore,
|
||||
layouts::{
|
||||
GGLWEInfos, GGLWEToGGSWKey, GGLWEToGGSWKeyToMut, GLWEInfos, GLWESecret, GLWESecretTensor, GLWESecretTensorFactory,
|
||||
GLWESecretToRef,
|
||||
prepared::{GLWESecretPrepared, GLWESecretPreparedFactory},
|
||||
},
|
||||
};
|
||||
|
||||
impl GGLWEToGGSWKey<Vec<u8>> {
|
||||
pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
M: GGLWEToGGSWKeyEncryptSk<BE>,
|
||||
{
|
||||
module.gglwe_to_ggsw_key_encrypt_sk_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<DataSelf: DataMut> GGLWEToGGSWKey<DataSelf> {
|
||||
pub fn encrypt_sk<M, S, BE: Backend>(
|
||||
&mut self,
|
||||
module: &M,
|
||||
sk: &S,
|
||||
source_xa: &mut Source,
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
M: GGLWEToGGSWKeyEncryptSk<BE>,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
module.gglwe_to_ggsw_key_encrypt_sk(self, sk, source_xa, source_xe, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEToGGSWKeyEncryptSk<BE: Backend> {
|
||||
fn gglwe_to_ggsw_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
|
||||
fn gglwe_to_ggsw_key_encrypt_sk<R, S>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk: &S,
|
||||
source_xa: &mut Source,
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
R: GGLWEToGGSWKeyToMut,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos;
|
||||
}
|
||||
|
||||
impl<BE: Backend> GGLWEToGGSWKeyEncryptSk<BE> for Module<BE>
|
||||
where
|
||||
Self: ModuleN + GGLWEEncryptSk<BE> + GLWESecretTensorFactory<BE> + GLWESecretPreparedFactory<BE> + VecZnxCopy,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
fn gglwe_to_ggsw_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
let sk_prepared: usize = GLWESecretPrepared::bytes_of(self, infos.rank());
|
||||
let sk_tensor: usize = GLWESecretTensor::bytes_of_from_infos(infos);
|
||||
let gglwe_encrypt: usize = self.gglwe_encrypt_sk_tmp_bytes(infos);
|
||||
let sk_ij = GLWESecret::bytes_of(self.n().into(), infos.rank());
|
||||
(sk_prepared + sk_tensor + sk_ij) + gglwe_encrypt.max(self.glwe_secret_tensor_prepare_tmp_bytes(infos.rank()))
|
||||
}
|
||||
|
||||
fn gglwe_to_ggsw_key_encrypt_sk<R, S>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk: &S,
|
||||
source_xa: &mut Source,
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
R: GGLWEToGGSWKeyToMut,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||
{
|
||||
let res: &mut GGLWEToGGSWKey<&mut [u8]> = &mut res.to_mut();
|
||||
|
||||
let rank: usize = res.rank_out().as_usize();
|
||||
|
||||
let (mut sk_prepared, scratch_1) = scratch.take_glwe_secret_prepared(self, res.rank());
|
||||
let (mut sk_tensor, scratch_2) = scratch_1.take_glwe_secret_tensor(self.n().into(), res.rank());
|
||||
sk_prepared.prepare(self, sk);
|
||||
sk_tensor.prepare(self, sk, scratch_2);
|
||||
|
||||
let (mut sk_ij, scratch_3) = scratch_2.take_scalar_znx(self.n(), rank);
|
||||
|
||||
for i in 0..rank {
|
||||
for j in 0..rank {
|
||||
self.vec_znx_copy(
|
||||
&mut sk_ij.as_vec_znx_mut(),
|
||||
j,
|
||||
&sk_tensor.at(i, j).as_vec_znx(),
|
||||
0,
|
||||
);
|
||||
}
|
||||
|
||||
res.at_mut(i)
|
||||
.encrypt_sk(self, &sk_ij, &sk_prepared, source_xa, source_xe, scratch_3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
use poulpy_hal::{
|
||||
api::{
|
||||
ModuleN, ScratchTakeBasic, SvpApplyDftToDft, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxDftApply, VecZnxDftBytesOf,
|
||||
VecZnxIdftApplyTmpA,
|
||||
},
|
||||
api::ModuleN,
|
||||
layouts::{Backend, DataMut, Module, Scratch},
|
||||
source::Source,
|
||||
};
|
||||
@@ -10,7 +7,8 @@ use poulpy_hal::{
|
||||
use crate::{
|
||||
GGLWEEncryptSk, GetDistribution, ScratchTakeCore,
|
||||
layouts::{
|
||||
GGLWE, GGLWEInfos, GLWEInfos, GLWESecret, GLWESecretToRef, GLWETensorKey, GLWETensorKeyToMut, LWEInfos, Rank,
|
||||
GGLWEInfos, GGLWELayout, GGLWEToMut, GLWEInfos, GLWESecretTensor, GLWESecretTensorFactory, GLWESecretToRef,
|
||||
GLWETensorKey,
|
||||
prepared::{GLWESecretPrepared, GLWESecretPreparedFactory},
|
||||
},
|
||||
};
|
||||
@@ -55,33 +53,35 @@ pub trait GLWETensorKeyEncryptSk<BE: Backend> {
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
R: GLWETensorKeyToMut,
|
||||
R: GGLWEToMut + GGLWEInfos,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos;
|
||||
}
|
||||
|
||||
impl<BE: Backend> GLWETensorKeyEncryptSk<BE> for Module<BE>
|
||||
where
|
||||
Self: ModuleN
|
||||
+ GGLWEEncryptSk<BE>
|
||||
+ VecZnxDftBytesOf
|
||||
+ VecZnxBigBytesOf
|
||||
+ GLWESecretPreparedFactory<BE>
|
||||
+ VecZnxDftApply<BE>
|
||||
+ SvpApplyDftToDft<BE>
|
||||
+ VecZnxIdftApplyTmpA<BE>
|
||||
+ VecZnxBigNormalize<BE>,
|
||||
Self: ModuleN + GGLWEEncryptSk<BE> + GLWESecretPreparedFactory<BE> + GLWESecretTensorFactory<BE>,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
fn glwe_tensor_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
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))
|
||||
+ GGLWE::encrypt_sk_tmp_bytes(self, infos)
|
||||
let sk_prepared: usize = GLWESecretPrepared::bytes_of(self, infos.rank_out());
|
||||
let sk_tensor: usize = GLWESecretTensor::bytes_of_from_infos(infos);
|
||||
|
||||
let tensor_infos: GGLWELayout = GGLWELayout {
|
||||
n: infos.n(),
|
||||
base2k: infos.base2k(),
|
||||
k: infos.k(),
|
||||
rank_in: GLWESecretTensor::pairs(infos.rank().into()).into(),
|
||||
rank_out: infos.rank_out(),
|
||||
dnum: infos.dnum(),
|
||||
dsize: infos.dsize(),
|
||||
};
|
||||
|
||||
let gglwe_encrypt: usize = self.gglwe_encrypt_sk_tmp_bytes(&tensor_infos);
|
||||
|
||||
(sk_prepared + sk_tensor) + gglwe_encrypt.max(self.glwe_secret_tensor_prepare_tmp_bytes(infos.rank()))
|
||||
}
|
||||
|
||||
fn glwe_tensor_key_encrypt_sk<R, S>(
|
||||
@@ -92,56 +92,24 @@ where
|
||||
source_xe: &mut Source,
|
||||
scratch: &mut Scratch<BE>,
|
||||
) where
|
||||
R: GLWETensorKeyToMut,
|
||||
R: GGLWEToMut + GGLWEInfos,
|
||||
S: GLWESecretToRef + GetDistribution + GLWEInfos,
|
||||
{
|
||||
let res: &mut GLWETensorKey<&mut [u8]> = &mut res.to_mut();
|
||||
|
||||
// let n: RingDegree = sk.n();
|
||||
let rank: Rank = res.rank_out();
|
||||
|
||||
let (mut sk_prepared, scratch_1) = scratch.take_glwe_secret_prepared(self, sk.rank());
|
||||
sk_prepared.prepare(self, sk);
|
||||
|
||||
let sk: &GLWESecret<&[u8]> = &sk.to_ref();
|
||||
|
||||
assert_eq!(res.rank_out(), sk.rank());
|
||||
assert_eq!(res.n(), sk.n());
|
||||
|
||||
let (mut sk_dft, scratch_2) = scratch_1.take_vec_znx_dft(self, rank.into(), 1);
|
||||
let (mut sk_prepared, scratch_1) = scratch.take_glwe_secret_prepared(self, res.rank());
|
||||
let (mut sk_tensor, scratch_2) = scratch_1.take_glwe_secret_tensor(self.n().into(), res.rank());
|
||||
sk_prepared.prepare(self, sk);
|
||||
sk_tensor.prepare(self, sk, scratch_2);
|
||||
|
||||
(0..rank.into()).for_each(|i| {
|
||||
self.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(self, 1, 1);
|
||||
let (mut sk_ij, scratch_4) = scratch_3.take_glwe_secret(self.n().into(), Rank(1));
|
||||
let (mut sk_ij_dft, scratch_5) = scratch_4.take_vec_znx_dft(self, 1, 1);
|
||||
|
||||
(0..rank.into()).for_each(|i| {
|
||||
(i..rank.into()).for_each(|j| {
|
||||
self.svp_apply_dft_to_dft(&mut sk_ij_dft, 0, &sk_prepared.data, j, &sk_dft, i);
|
||||
|
||||
self.vec_znx_idft_apply_tmpa(&mut sk_ij_big, 0, &mut sk_ij_dft, 0);
|
||||
self.vec_znx_big_normalize(
|
||||
res.base2k().into(),
|
||||
&mut sk_ij.data.as_vec_znx_mut(),
|
||||
0,
|
||||
res.base2k().into(),
|
||||
&sk_ij_big,
|
||||
0,
|
||||
scratch_5,
|
||||
);
|
||||
|
||||
res.at_mut(i, j).encrypt_sk(
|
||||
self,
|
||||
&sk_ij.data,
|
||||
&sk_prepared,
|
||||
source_xa,
|
||||
source_xe,
|
||||
scratch_5,
|
||||
);
|
||||
});
|
||||
})
|
||||
self.gglwe_encrypt_sk(
|
||||
res,
|
||||
&sk_tensor.data,
|
||||
&sk_prepared,
|
||||
source_xa,
|
||||
source_xe,
|
||||
scratch_2,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,23 +7,22 @@ use poulpy_hal::{
|
||||
use crate::{
|
||||
GGLWEEncryptSk, ScratchTakeCore,
|
||||
layouts::{
|
||||
GGLWE, GGLWEInfos, GGLWEToMut, GLWESecret, GLWESecretToRef, GLWEToLWESwitchingKey, LWEInfos, LWESecret, LWESecretToRef,
|
||||
Rank,
|
||||
GGLWE, GGLWEInfos, GGLWEToMut, GLWESecret, GLWESecretToRef, GLWEToLWEKey, LWEInfos, LWESecret, LWESecretToRef, Rank,
|
||||
prepared::{GLWESecretPrepared, GLWESecretPreparedFactory},
|
||||
},
|
||||
};
|
||||
|
||||
impl GLWEToLWESwitchingKey<Vec<u8>> {
|
||||
impl GLWEToLWEKey<Vec<u8>> {
|
||||
pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
M: GLWEToLWESwitchingKeyEncryptSk<BE>,
|
||||
{
|
||||
module.glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes(infos)
|
||||
module.glwe_to_lwe_key_encrypt_sk_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GLWEToLWESwitchingKey<D> {
|
||||
impl<D: DataMut> GLWEToLWEKey<D> {
|
||||
pub fn encrypt_sk<M, S1, S2, BE: Backend>(
|
||||
&mut self,
|
||||
module: &M,
|
||||
@@ -38,16 +37,16 @@ impl<D: DataMut> GLWEToLWESwitchingKey<D> {
|
||||
S2: GLWESecretToRef,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
module.glwe_to_lwe_switching_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
||||
module.glwe_to_lwe_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWEToLWESwitchingKeyEncryptSk<BE: Backend> {
|
||||
fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
fn glwe_to_lwe_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
|
||||
fn glwe_to_lwe_switching_key_encrypt_sk<R, S1, S2>(
|
||||
fn glwe_to_lwe_key_encrypt_sk<R, S1, S2>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk_lwe: &S1,
|
||||
@@ -70,7 +69,7 @@ where
|
||||
+ VecZnxAutomorphismInplaceTmpBytes,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
fn glwe_to_lwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
fn glwe_to_lwe_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
@@ -79,7 +78,7 @@ where
|
||||
.max(GLWESecret::bytes_of(self.n().into(), infos.rank_in()) + self.vec_znx_automorphism_inplace_tmp_bytes())
|
||||
}
|
||||
|
||||
fn glwe_to_lwe_switching_key_encrypt_sk<R, S1, S2>(
|
||||
fn glwe_to_lwe_key_encrypt_sk<R, S1, S2>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk_lwe: &S1,
|
||||
@@ -8,21 +8,21 @@ use crate::{
|
||||
GGLWEEncryptSk, ScratchTakeCore,
|
||||
layouts::{
|
||||
GGLWE, GGLWEInfos, GGLWEToMut, GLWESecret, GLWESecretPreparedFactory, GLWESecretPreparedToRef, LWEInfos, LWESecret,
|
||||
LWESecretToRef, LWEToGLWESwitchingKey, Rank,
|
||||
LWESecretToRef, LWEToGLWEKey, Rank,
|
||||
},
|
||||
};
|
||||
|
||||
impl LWEToGLWESwitchingKey<Vec<u8>> {
|
||||
impl LWEToGLWEKey<Vec<u8>> {
|
||||
pub fn encrypt_sk_tmp_bytes<M, A, BE: Backend>(module: &M, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
M: LWEToGLWESwitchingKeyEncryptSk<BE>,
|
||||
{
|
||||
module.lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes(infos)
|
||||
module.lwe_to_glwe_key_encrypt_sk_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> LWEToGLWESwitchingKey<D> {
|
||||
impl<D: DataMut> LWEToGLWEKey<D> {
|
||||
pub fn encrypt_sk<S1, S2, M, BE: Backend>(
|
||||
&mut self,
|
||||
module: &M,
|
||||
@@ -37,16 +37,16 @@ impl<D: DataMut> LWEToGLWESwitchingKey<D> {
|
||||
M: LWEToGLWESwitchingKeyEncryptSk<BE>,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
module.lwe_to_glwe_switching_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
||||
module.lwe_to_glwe_key_encrypt_sk(self, sk_lwe, sk_glwe, source_xa, source_xe, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LWEToGLWESwitchingKeyEncryptSk<BE: Backend> {
|
||||
fn lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
fn lwe_to_glwe_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
|
||||
fn lwe_to_glwe_switching_key_encrypt_sk<R, S1, S2>(
|
||||
fn lwe_to_glwe_key_encrypt_sk<R, S1, S2>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk_lwe: &S1,
|
||||
@@ -69,20 +69,20 @@ where
|
||||
+ VecZnxAutomorphismInplaceTmpBytes,
|
||||
Scratch<BE>: ScratchTakeCore<BE>,
|
||||
{
|
||||
fn lwe_to_glwe_switching_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
fn lwe_to_glwe_key_encrypt_sk_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
debug_assert_eq!(
|
||||
infos.rank_in(),
|
||||
Rank(1),
|
||||
"rank_in != 1 is not supported for LWEToGLWESwitchingKey"
|
||||
"rank_in != 1 is not supported for LWEToGLWEKeyPrepared"
|
||||
);
|
||||
GLWESecret::bytes_of(self.n().into(), infos.rank_in())
|
||||
+ GGLWE::encrypt_sk_tmp_bytes(self, infos).max(self.vec_znx_automorphism_inplace_tmp_bytes())
|
||||
}
|
||||
|
||||
fn lwe_to_glwe_switching_key_encrypt_sk<R, S1, S2>(
|
||||
fn lwe_to_glwe_key_encrypt_sk<R, S1, S2>(
|
||||
&self,
|
||||
res: &mut R,
|
||||
sk_lwe: &S1,
|
||||
@@ -1,28 +1,30 @@
|
||||
mod compressed;
|
||||
mod gglwe;
|
||||
mod gglwe_to_ggsw_key;
|
||||
mod ggsw;
|
||||
mod glwe;
|
||||
mod glwe_automorphism_key;
|
||||
mod glwe_public_key;
|
||||
mod glwe_switching_key;
|
||||
mod glwe_tensor_key;
|
||||
mod glwe_to_lwe_switching_key;
|
||||
mod glwe_to_lwe_key;
|
||||
mod lwe;
|
||||
mod lwe_switching_key;
|
||||
mod lwe_to_glwe_switching_key;
|
||||
mod lwe_to_glwe_key;
|
||||
|
||||
pub use compressed::*;
|
||||
pub use gglwe::*;
|
||||
pub use gglwe_to_ggsw_key::*;
|
||||
pub use ggsw::*;
|
||||
pub use glwe::*;
|
||||
pub use glwe_automorphism_key::*;
|
||||
pub use glwe_public_key::*;
|
||||
pub use glwe_switching_key::*;
|
||||
pub use glwe_tensor_key::*;
|
||||
pub use glwe_to_lwe_switching_key::*;
|
||||
pub use glwe_to_lwe_key::*;
|
||||
pub use lwe::*;
|
||||
pub use lwe_switching_key::*;
|
||||
pub use lwe_to_glwe_switching_key::*;
|
||||
pub use lwe_to_glwe_key::*;
|
||||
|
||||
pub const SIGMA: f64 = 3.2;
|
||||
pub(crate) const SIGMA_BOUND: f64 = 6.0 * SIGMA;
|
||||
|
||||
Reference in New Issue
Block a user