This commit is contained in:
Jean-Philippe Bossuat
2025-05-25 11:15:59 +02:00
parent 43c7f21033
commit cb284a4c4c
6 changed files with 83 additions and 24 deletions

View File

@@ -71,7 +71,7 @@ impl<D: AsRef<[u8]>> ZnxView for VecZnx<D> {
type Scalar = i64; type Scalar = i64;
} }
impl<D: AsRef<[u8]>> VecZnx<D> { impl VecZnx<Vec<u8>> {
pub fn rsh_scratch_space(n: usize) -> usize { pub fn rsh_scratch_space(n: usize) -> usize {
n * std::mem::size_of::<i64>() n * std::mem::size_of::<i64>()
} }

View File

@@ -334,7 +334,7 @@ where
VecZnx<DataLhs>: VecZnxToRef, VecZnx<DataLhs>: VecZnxToRef,
MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>, MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>,
{ {
Self::keyswitch_private(self, true, rhs.p(), module, lhs, &rhs.key, scratch); Self::keyswitch_private::<_, _, 1>(self, rhs.p(), module, lhs, &rhs.key, scratch);
} }
pub fn automorphism_add_inplace<DataRhs>( pub fn automorphism_add_inplace<DataRhs>(
@@ -347,7 +347,61 @@ where
{ {
unsafe { unsafe {
let self_ptr: *mut GLWECiphertext<DataSelf> = self as *mut GLWECiphertext<DataSelf>; let self_ptr: *mut GLWECiphertext<DataSelf> = self as *mut GLWECiphertext<DataSelf>;
Self::keyswitch_private(self, true, rhs.p(), module, &*self_ptr, &rhs.key, scratch); Self::keyswitch_private::<_, _, 1>(self, rhs.p(), module, &*self_ptr, &rhs.key, scratch);
}
}
pub fn automorphism_sub_ab<DataLhs, DataRhs>(
&mut self,
module: &Module<FFT64>,
lhs: &GLWECiphertext<DataLhs>,
rhs: &AutomorphismKey<DataRhs, FFT64>,
scratch: &mut Scratch,
) where
VecZnx<DataLhs>: VecZnxToRef,
MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>,
{
Self::keyswitch_private::<_, _, 2>(self, rhs.p(), module, lhs, &rhs.key, scratch);
}
pub fn automorphism_sub_ab_inplace<DataRhs>(
&mut self,
module: &Module<FFT64>,
rhs: &AutomorphismKey<DataRhs, FFT64>,
scratch: &mut Scratch,
) where
MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>,
{
unsafe {
let self_ptr: *mut GLWECiphertext<DataSelf> = self as *mut GLWECiphertext<DataSelf>;
Self::keyswitch_private::<_, _, 2>(self, rhs.p(), module, &*self_ptr, &rhs.key, scratch);
}
}
pub fn automorphism_sub_ba<DataLhs, DataRhs>(
&mut self,
module: &Module<FFT64>,
lhs: &GLWECiphertext<DataLhs>,
rhs: &AutomorphismKey<DataRhs, FFT64>,
scratch: &mut Scratch,
) where
VecZnx<DataLhs>: VecZnxToRef,
MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>,
{
Self::keyswitch_private::<_, _, 3>(self, rhs.p(), module, lhs, &rhs.key, scratch);
}
pub fn automorphism_sub_ba_inplace<DataRhs>(
&mut self,
module: &Module<FFT64>,
rhs: &AutomorphismKey<DataRhs, FFT64>,
scratch: &mut Scratch,
) where
MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>,
{
unsafe {
let self_ptr: *mut GLWECiphertext<DataSelf> = self as *mut GLWECiphertext<DataSelf>;
Self::keyswitch_private::<_, _, 3>(self, rhs.p(), module, &*self_ptr, &rhs.key, scratch);
} }
} }
@@ -420,12 +474,11 @@ where
VecZnx<DataLhs>: VecZnxToRef, VecZnx<DataLhs>: VecZnxToRef,
MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>, MatZnxDft<DataRhs, FFT64>: MatZnxDftToRef<FFT64>,
{ {
Self::keyswitch_private(self, false, 0, module, lhs, rhs, scratch); Self::keyswitch_private::<_, _, 0>(self, 0, module, lhs, rhs, scratch);
} }
pub(crate) fn keyswitch_private<DataLhs, DataRhs>( pub(crate) fn keyswitch_private<DataLhs, DataRhs, const OP: u8>(
&mut self, &mut self,
add_self: bool,
apply_auto: i64, apply_auto: i64,
module: &Module<FFT64>, module: &Module<FFT64>,
lhs: &GLWECiphertext<DataLhs>, lhs: &GLWECiphertext<DataLhs>,
@@ -481,8 +534,11 @@ where
module.vec_znx_big_automorphism_inplace(apply_auto, &mut res_big, i); module.vec_znx_big_automorphism_inplace(apply_auto, &mut res_big, i);
} }
if add_self { match OP{
module.vec_znx_big_add_small_inplace(&mut res_big, i, lhs, i); 1=> module.vec_znx_big_add_small_inplace(&mut res_big, i, lhs, i),
2=> module.vec_znx_big_sub_small_a_inplace(&mut res_big, i, lhs, i),
3=> module.vec_znx_big_sub_small_b_inplace(&mut res_big, i, lhs, i),
_=>{},
} }
module.vec_znx_big_normalize(basek, self, i, &res_big, i, scratch1); module.vec_znx_big_normalize(basek, self, i, &res_big, i, scratch1);
}); });

View File

@@ -175,10 +175,7 @@ where
self.set_k(a.k()); self.set_k(a.k());
} }
pub fn rotate_inplace<A>(&mut self, module: &Module<FFT64>, k: i64) pub fn rotate_inplace(&mut self, module: &Module<FFT64>, k: i64){
where
A: VecZnxToRef + Infos,
{
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
assert_eq!(self.n(), module.n()); assert_eq!(self.n(), module.n());
@@ -242,3 +239,9 @@ where
}); });
} }
} }
impl GLWECiphertext<Vec<u8>>{
pub fn rsh_scratch_space(module: &Module<FFT64>) -> usize{
VecZnx::rsh_scratch_space(module.n())
}
}

View File

@@ -56,7 +56,7 @@ impl<T, B: Backend> TensorKey<T, B> {
} }
impl TensorKey<Vec<u8>, FFT64> { impl TensorKey<Vec<u8>, FFT64> {
pub fn encrypt_sk_scratch_space(module: &Module<FFT64>, rank: usize, size: usize) -> usize { pub fn generate_from_sk_scratch_space(module: &Module<FFT64>, rank: usize, size: usize) -> usize {
module.bytes_of_scalar_znx_dft(1) + GLWESwitchingKey::encrypt_sk_scratch_space(module, rank, size) module.bytes_of_scalar_znx_dft(1) + GLWESwitchingKey::encrypt_sk_scratch_space(module, rank, size)
} }
} }
@@ -65,7 +65,7 @@ impl<DataSelf> TensorKey<DataSelf, FFT64>
where where
MatZnxDft<DataSelf, FFT64>: MatZnxDftToMut<FFT64>, MatZnxDft<DataSelf, FFT64>: MatZnxDftToMut<FFT64>,
{ {
pub fn encrypt_sk<DataSk>( pub fn generate_from_sk<DataSk>(
&mut self, &mut self,
module: &Module<FFT64>, module: &Module<FFT64>,
sk_dft: &SecretKeyFourier<DataSk, FFT64>, sk_dft: &SecretKeyFourier<DataSk, FFT64>,

View File

@@ -160,7 +160,7 @@ fn test_keyswitch(log_n: usize, basek: usize, k: usize, rank: usize, sigma: f64)
GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_in.size()) GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_in.size())
| GLWECiphertextFourier::decrypt_scratch_space(&module, ct_out.size()) | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_out.size())
| GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) | GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size())
| TensorKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) | TensorKey::generate_from_sk_scratch_space(&module, rank, ksk.size())
| GGSWCiphertext::keyswitch_scratch_space( | GGSWCiphertext::keyswitch_scratch_space(
&module, &module,
ct_out.size(), ct_out.size(),
@@ -194,7 +194,7 @@ fn test_keyswitch(log_n: usize, basek: usize, k: usize, rank: usize, sigma: f64)
sigma, sigma,
scratch.borrow(), scratch.borrow(),
); );
tsk.encrypt_sk( tsk.generate_from_sk(
&module, &module,
&sk_out_dft, &sk_out_dft,
&mut source_xa, &mut source_xa,
@@ -286,7 +286,7 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k: usize, rank: usize, sig
GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct.size()) GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct.size())
| GLWECiphertextFourier::decrypt_scratch_space(&module, ct.size()) | GLWECiphertextFourier::decrypt_scratch_space(&module, ct.size())
| GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) | GLWESwitchingKey::encrypt_sk_scratch_space(&module, rank, ksk.size())
| TensorKey::encrypt_sk_scratch_space(&module, rank, ksk.size()) | TensorKey::generate_from_sk_scratch_space(&module, rank, ksk.size())
| GGSWCiphertext::keyswitch_inplace_scratch_space(&module, ct.size(), ksk.size(), tsk.size(), rank), | GGSWCiphertext::keyswitch_inplace_scratch_space(&module, ct.size(), ksk.size(), tsk.size(), rank),
); );
@@ -313,7 +313,7 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k: usize, rank: usize, sig
sigma, sigma,
scratch.borrow(), scratch.borrow(),
); );
tsk.encrypt_sk( tsk.generate_from_sk(
&module, &module,
&sk_out_dft, &sk_out_dft,
&mut source_xa, &mut source_xa,
@@ -455,7 +455,7 @@ fn test_automorphism(p: i64, log_n: usize, basek: usize, k: usize, rank: usize,
GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_in.size()) GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct_in.size())
| GLWECiphertextFourier::decrypt_scratch_space(&module, ct_out.size()) | GLWECiphertextFourier::decrypt_scratch_space(&module, ct_out.size())
| AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key.size()) | AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key.size())
| TensorKey::encrypt_sk_scratch_space(&module, rank, tensor_key.size()) | TensorKey::generate_from_sk_scratch_space(&module, rank, tensor_key.size())
| GGSWCiphertext::automorphism_scratch_space( | GGSWCiphertext::automorphism_scratch_space(
&module, &module,
ct_out.size(), ct_out.size(),
@@ -483,7 +483,7 @@ fn test_automorphism(p: i64, log_n: usize, basek: usize, k: usize, rank: usize,
sigma, sigma,
scratch.borrow(), scratch.borrow(),
); );
tensor_key.encrypt_sk( tensor_key.generate_from_sk(
&module, &module,
&sk_dft, &sk_dft,
&mut source_xa, &mut source_xa,
@@ -575,7 +575,7 @@ fn test_automorphism_inplace(p: i64, log_n: usize, basek: usize, k: usize, rank:
GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct.size()) GGSWCiphertext::encrypt_sk_scratch_space(&module, rank, ct.size())
| GLWECiphertextFourier::decrypt_scratch_space(&module, ct.size()) | GLWECiphertextFourier::decrypt_scratch_space(&module, ct.size())
| AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key.size()) | AutomorphismKey::generate_from_sk_scratch_space(&module, rank, auto_key.size())
| TensorKey::encrypt_sk_scratch_space(&module, rank, tensor_key.size()) | TensorKey::generate_from_sk_scratch_space(&module, rank, tensor_key.size())
| GGSWCiphertext::automorphism_inplace_scratch_space(&module, ct.size(), auto_key.size(), tensor_key.size(), rank), | GGSWCiphertext::automorphism_inplace_scratch_space(&module, ct.size(), auto_key.size(), tensor_key.size(), rank),
); );
@@ -596,7 +596,7 @@ fn test_automorphism_inplace(p: i64, log_n: usize, basek: usize, k: usize, rank:
sigma, sigma,
scratch.borrow(), scratch.borrow(),
); );
tensor_key.encrypt_sk( tensor_key.generate_from_sk(
&module, &module,
&sk_dft, &sk_dft,
&mut source_xa, &mut source_xa,

View File

@@ -30,7 +30,7 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k: usize, sigma: f64, rank: usize
let mut source_xe: Source = Source::new([0u8; 32]); let mut source_xe: Source = Source::new([0u8; 32]);
let mut source_xa: Source = Source::new([0u8; 32]); let mut source_xa: Source = Source::new([0u8; 32]);
let mut scratch: ScratchOwned = ScratchOwned::new(TensorKey::encrypt_sk_scratch_space( let mut scratch: ScratchOwned = ScratchOwned::new(TensorKey::generate_from_sk_scratch_space(
&module, &module,
rank, rank,
tensor_key.size(), tensor_key.size(),
@@ -40,7 +40,7 @@ fn test_encrypt_sk(log_n: usize, basek: usize, k: usize, sigma: f64, rank: usize
sk.fill_ternary_prob(0.5, &mut source_xs); sk.fill_ternary_prob(0.5, &mut source_xs);
let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank); let mut sk_dft: SecretKeyFourier<Vec<u8>, FFT64> = SecretKeyFourier::alloc(&module, rank);
sk_dft.dft(&module, &sk); sk_dft.dft(generate_from_sksk);
tensor_key.encrypt_sk( tensor_key.encrypt_sk(
&module, &module,