Added LWE-GLWE conversion & LWE Keyswitch, improved LUT generation

This commit is contained in:
Jean-Philippe Bossuat
2025-07-07 11:09:04 +02:00
parent c4a517e9c3
commit 5234c3fc63
28 changed files with 979 additions and 782 deletions

View File

@@ -87,8 +87,20 @@ impl<DataSelf: AsRef<[u8]> + AsMut<[u8]>> GLWECiphertext<DataSelf> {
#[cfg(debug_assertions)]
{
assert_eq!(lhs.rank(), rhs.rank_in());
assert_eq!(self.rank(), rhs.rank_out());
assert_eq!(
lhs.rank(),
rhs.rank_in(),
"lhs.rank(): {} != rhs.rank_in(): {}",
lhs.rank(),
rhs.rank_in()
);
assert_eq!(
self.rank(),
rhs.rank_out(),
"self.rank(): {} != rhs.rank_out(): {}",
self.rank(),
rhs.rank_out()
);
assert_eq!(self.basek(), basek);
assert_eq!(lhs.basek(), basek);
assert_eq!(rhs.n(), module.n());
@@ -141,9 +153,9 @@ impl<DataSelf: AsRef<[u8]> + AsMut<[u8]>> GLWECiphertext<DataSelf> {
});
if di == 0 {
module.vmp_apply(&mut res_dft, &ai_dft, &rhs.0.data, scratch2);
module.vmp_apply(&mut res_dft, &ai_dft, &rhs.key.data, scratch2);
} else {
module.vmp_apply_add(&mut res_dft, &ai_dft, &rhs.0.data, di, scratch2);
module.vmp_apply_add(&mut res_dft, &ai_dft, &rhs.key.data, di, scratch2);
}
});
}
@@ -225,9 +237,9 @@ impl<DataSelf: AsRef<[u8]> + AsMut<[u8]>> GLWECiphertext<DataSelf> {
});
if di == 0 {
module.vmp_apply(&mut res_dft, &ai_dft, &rhs.0.data, scratch2);
module.vmp_apply(&mut res_dft, &ai_dft, &rhs.key.data, scratch2);
} else {
module.vmp_apply_add(&mut res_dft, &ai_dft, &rhs.0.data, di, scratch2);
module.vmp_apply_add(&mut res_dft, &ai_dft, &rhs.key.data, di, scratch2);
}
});
}

View File

@@ -67,7 +67,7 @@ fn test_automorphism(
.fill_uniform(basek, 0, pt_want.size(), &mut source_xa);
let mut scratch: ScratchOwned = ScratchOwned::new(
GLWEAutomorphismKey::generate_from_sk_scratch_space(&module, basek, autokey.k(), rank)
GLWEAutomorphismKey::encrypt_sk_scratch_space(&module, basek, autokey.k(), rank)
| GLWECiphertext::decrypt_scratch_space(&module, basek, ct_out.k())
| GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_in.k())
| GLWECiphertext::automorphism_scratch_space(
@@ -85,7 +85,7 @@ fn test_automorphism(
sk.fill_ternary_prob(0.5, &mut source_xs);
let sk_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::from(&module, &sk);
autokey.generate_from_sk(
autokey.encrypt_sk(
&module,
p,
&sk,
@@ -164,7 +164,7 @@ fn test_automorphism_inplace(
.fill_uniform(basek, 0, pt_want.size(), &mut source_xa);
let mut scratch: ScratchOwned = ScratchOwned::new(
GLWEAutomorphismKey::generate_from_sk_scratch_space(&module, basek, autokey.k(), rank)
GLWEAutomorphismKey::encrypt_sk_scratch_space(&module, basek, autokey.k(), rank)
| GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k())
| GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k())
| GLWECiphertext::automorphism_inplace_scratch_space(&module, basek, ct.k(), autokey.k(), digits, rank),
@@ -174,7 +174,7 @@ fn test_automorphism_inplace(
sk.fill_ternary_prob(0.5, &mut source_xs);
let sk_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::from(&module, &sk);
autokey.generate_from_sk(
autokey.encrypt_sk(
&module,
p,
&sk,

View File

@@ -72,7 +72,7 @@ fn test_keyswitch(
.fill_uniform(basek, 0, pt_want.size(), &mut source_xa);
let mut scratch: ScratchOwned = ScratchOwned::new(
GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), rank_out)
GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ksk.k(), rank_in, rank_out)
| GLWECiphertext::decrypt_scratch_space(&module, basek, ct_out.k())
| GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_in.k())
| GLWECiphertext::keyswitch_scratch_space(
@@ -95,7 +95,7 @@ fn test_keyswitch(
sk_out.fill_ternary_prob(0.5, &mut source_xs);
let sk_out_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::from(&module, &sk_out);
ksk.generate_from_sk(
ksk.encrypt_sk(
&module,
&sk_in,
&sk_out_dft,
@@ -163,7 +163,7 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ct: usize, k_ksk: usize,
.fill_uniform(basek, 0, pt_want.size(), &mut source_xa);
let mut scratch: ScratchOwned = ScratchOwned::new(
GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ct_grlwe.k(), rank)
GLWESwitchingKey::encrypt_sk_scratch_space(&module, basek, ct_grlwe.k(), rank, rank)
| GLWECiphertext::decrypt_scratch_space(&module, basek, ct_glwe.k())
| GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct_glwe.k())
| GLWECiphertext::keyswitch_inplace_scratch_space(&module, basek, ct_glwe.k(), ct_grlwe.k(), digits, rank),
@@ -177,7 +177,7 @@ fn test_keyswitch_inplace(log_n: usize, basek: usize, k_ct: usize, k_ksk: usize,
sk_out.fill_ternary_prob(0.5, &mut source_xs);
let sk_out_dft: FourierGLWESecret<Vec<u8>, FFT64> = FourierGLWESecret::from(&module, &sk_out);
ct_grlwe.generate_from_sk(
ct_grlwe.encrypt_sk(
&module,
&sk_in,
&sk_out_dft,

View File

@@ -26,7 +26,7 @@ fn apply() {
let mut scratch: ScratchOwned = ScratchOwned::new(
GLWECiphertext::encrypt_sk_scratch_space(&module, basek, k_ct)
| GLWECiphertext::decrypt_scratch_space(&module, basek, k_ct)
| GLWEAutomorphismKey::generate_from_sk_scratch_space(&module, basek, k_ksk, rank)
| GLWEAutomorphismKey::encrypt_sk_scratch_space(&module, basek, k_ksk, rank)
| GLWEPacker::scratch_space(&module, basek, k_ct, k_ksk, digits, rank),
);
@@ -46,7 +46,7 @@ fn apply() {
let mut auto_keys: HashMap<i64, GLWEAutomorphismKey<Vec<u8>, FFT64>> = HashMap::new();
gal_els.iter().for_each(|gal_el| {
let mut key: GLWEAutomorphismKey<Vec<u8>, FFT64> = GLWEAutomorphismKey::alloc(&module, basek, k_ksk, rows, digits, rank);
key.generate_from_sk(
key.encrypt_sk(
&module,
*gal_el,
&sk,

View File

@@ -35,7 +35,7 @@ fn test_trace_inplace(log_n: usize, basek: usize, k: usize, sigma: f64, rank: us
let mut scratch: ScratchOwned = ScratchOwned::new(
GLWECiphertext::encrypt_sk_scratch_space(&module, basek, ct.k())
| GLWECiphertext::decrypt_scratch_space(&module, basek, ct.k())
| GLWEAutomorphismKey::generate_from_sk_scratch_space(&module, basek, k_autokey, rank)
| GLWEAutomorphismKey::encrypt_sk_scratch_space(&module, basek, k_autokey, rank)
| GLWECiphertext::trace_inplace_scratch_space(&module, basek, ct.k(), k_autokey, digits, rank),
);
@@ -68,7 +68,7 @@ fn test_trace_inplace(log_n: usize, basek: usize, k: usize, sigma: f64, rank: us
gal_els.iter().for_each(|gal_el| {
let mut key: GLWEAutomorphismKey<Vec<u8>, FFT64> =
GLWEAutomorphismKey::alloc(&module, basek, k_autokey, rows, digits, rank);
key.generate_from_sk(
key.encrypt_sk(
&module,
*gal_el,
&sk,