mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 05:06:44 +01:00
fix cross-base2k vec_znx_normalize wrong early carry
This commit is contained in:
@@ -1,20 +1,88 @@
|
||||
use poulpy_hal::{
|
||||
api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow},
|
||||
layouts::{Backend, Module, Scratch, ScratchOwned, ZnxView},
|
||||
api::{ScratchAvailable, ScratchOwnedAlloc, ScratchOwnedBorrow, VecZnxFillUniform},
|
||||
layouts::{Backend, FillUniform, Module, Scratch, ScratchOwned, ZnxView},
|
||||
source::Source,
|
||||
};
|
||||
use rug::Float;
|
||||
|
||||
use crate::{
|
||||
GLWEDecrypt, GLWEEncryptSk, GLWEFromLWE, GLWEToLWESwitchingKeyEncryptSk, LWEDecrypt, LWEEncryptSk, LWEFromGLWE,
|
||||
LWEToGLWESwitchingKeyEncryptSk, ScratchTakeCore,
|
||||
layouts::{
|
||||
Base2K, Degree, Dnum, GLWE, GLWELayout, GLWEPlaintext, GLWESecret, GLWESecretPreparedFactory, GLWEToLWEKey,
|
||||
GLWEToLWEKeyLayout, GLWEToLWEKeyPrepared, GLWEToLWEKeyPreparedFactory, LWE, LWELayout, LWEPlaintext, LWESecret,
|
||||
LWEToGLWEKey, LWEToGLWEKeyLayout, LWEToGLWEKeyPrepared, LWEToGLWEKeyPreparedFactory, Rank, TorusPrecision,
|
||||
prepared::GLWESecretPrepared,
|
||||
},
|
||||
GLWEDecrypt, GLWEEncryptSk, GLWEFromLWE, GLWENoise, GLWENormalize, GLWEToLWESwitchingKeyEncryptSk, LWEDecrypt, LWEEncryptSk, LWEFromGLWE, LWEToGLWESwitchingKeyEncryptSk, SIGMA, ScratchTakeCore, layouts::{
|
||||
Base2K, Degree, Dnum, GLWE, GLWELayout, GLWEPlaintext, GLWESecret, GLWESecretPreparedFactory, GLWEToLWEKey, GLWEToLWEKeyLayout, GLWEToLWEKeyPrepared, GLWEToLWEKeyPreparedFactory, LWE, LWEInfos, LWELayout, LWEPlaintext, LWESecret, LWEToGLWEKey, LWEToGLWEKeyLayout, LWEToGLWEKeyPrepared, LWEToGLWEKeyPreparedFactory, Rank, TorusPrecision, prepared::GLWESecretPrepared
|
||||
}
|
||||
};
|
||||
|
||||
pub fn test_glwe_base2k_conversion<BE: Backend>(module: &Module<BE>)
|
||||
where
|
||||
Module<BE>: GLWEEncryptSk<BE>
|
||||
+ GLWEDecrypt<BE>
|
||||
+ GLWENormalize<BE>
|
||||
+ VecZnxFillUniform
|
||||
+ GLWESecretPreparedFactory<BE>
|
||||
+ GLWENoise<BE>,
|
||||
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
|
||||
Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
|
||||
{
|
||||
let n_glwe: Degree = Degree(module.n() as u32);
|
||||
|
||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||
let mut source_xa: Source = Source::new([0u8; 32]);
|
||||
let mut source_xe: Source = Source::new([0u8; 32]);
|
||||
|
||||
for rank in 1_usize..3 {
|
||||
for bases in [[12, 8], [8, 12]] {
|
||||
let glwe_infos_in: GLWELayout = GLWELayout {
|
||||
n: n_glwe,
|
||||
base2k: Base2K(bases[0]),
|
||||
k: TorusPrecision(34),
|
||||
rank: Rank(rank as u32),
|
||||
};
|
||||
|
||||
let glwe_infos_out: GLWELayout = GLWELayout {
|
||||
n: n_glwe,
|
||||
base2k: Base2K(bases[1]),
|
||||
k: TorusPrecision(34),
|
||||
rank: Rank(rank as u32),
|
||||
};
|
||||
|
||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(module.n().into(), rank.into());
|
||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||
|
||||
let mut sk_prep: GLWESecretPrepared<Vec<u8>, BE> = GLWESecretPrepared::alloc_from_infos(module, &sk);
|
||||
sk_prep.prepare(module, &sk);
|
||||
|
||||
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(
|
||||
GLWE::encrypt_sk_tmp_bytes(module, &glwe_infos_in).max(GLWE::decrypt_tmp_bytes(module, &glwe_infos_out)),
|
||||
);
|
||||
|
||||
let mut ct_in: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos_in);
|
||||
let mut ct_out: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos_out);
|
||||
|
||||
let pt_in: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos_in);
|
||||
let pt_out: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos_in);
|
||||
|
||||
ct_in.encrypt_sk(
|
||||
module,
|
||||
&pt_in,
|
||||
&sk_prep,
|
||||
&mut source_xa,
|
||||
&mut source_xe,
|
||||
scratch.borrow(),
|
||||
);
|
||||
|
||||
let mut data: Vec<Float> = (0..module.n()).map(|_| Float::with_val(128, 0)).collect();
|
||||
ct_in.data().decode_vec_float(ct_in.base2k().into(), 0, &mut data);
|
||||
|
||||
ct_out.fill_uniform(ct_out.base2k().into(),&mut source_xa);
|
||||
module.glwe_normalize(&mut ct_out, &ct_in, scratch.borrow());
|
||||
|
||||
let mut data_conv: Vec<Float> = (0..module.n()).map(|_| Float::with_val(128, 0)).collect();
|
||||
ct_out.data().decode_vec_float(ct_out.base2k().into(), 0, &mut data_conv);
|
||||
|
||||
ct_out.assert_noise(module, &sk_prep, &pt_out, -(ct_out.k().as_u32() as f64) + SIGMA.log2() + 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn test_lwe_to_glwe<BE: Backend>(module: &Module<BE>)
|
||||
where
|
||||
Module<BE>: GLWEFromLWE<BE>
|
||||
|
||||
@@ -79,8 +79,6 @@ where
|
||||
);
|
||||
}
|
||||
|
||||
println!("pt_want: {}", pt_want.as_vec_znx());
|
||||
|
||||
module.gglwe_assert_noise(key.at(i), &sk_prepared, &pt_want, max_noise);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ where
|
||||
let k_pt: usize = 30;
|
||||
|
||||
for rank in 1_usize..3 {
|
||||
// println!("rank: {}", rank);
|
||||
|
||||
let n: usize = module.n();
|
||||
|
||||
let glwe_infos: GLWELayout = GLWELayout {
|
||||
|
||||
@@ -28,36 +28,37 @@ where
|
||||
ScratchOwned<BE>: ScratchOwnedAlloc<BE> + ScratchOwnedBorrow<BE>,
|
||||
Scratch<BE>: ScratchAvailable + ScratchTakeCore<BE>,
|
||||
{
|
||||
let base2k: usize = 12;
|
||||
let base2k_glwe: usize = 12;
|
||||
let base2k_gglwe: usize = 8;
|
||||
let k_in: usize = 45;
|
||||
let dsize: usize = k_in.div_ceil(base2k);
|
||||
let dsize: usize = k_in.div_ceil(base2k_gglwe);
|
||||
|
||||
for rank_in in 1_usize..3 {
|
||||
for rank_out in 1_usize..3 {
|
||||
for di in 1_usize..dsize + 1 {
|
||||
let k_ksk: usize = k_in + base2k * di;
|
||||
for di in 1_usize..dsize+1 {
|
||||
let k_ksk: usize = k_in + base2k_gglwe * di;
|
||||
let k_out: usize = k_ksk; // better capture noise
|
||||
|
||||
let n: usize = module.n();
|
||||
let dnum: usize = k_in.div_ceil(base2k * dsize);
|
||||
let dnum: usize = k_in.div_ceil(base2k_gglwe * dsize);
|
||||
|
||||
let glwe_in_infos: GLWELayout = GLWELayout {
|
||||
n: n.into(),
|
||||
base2k: base2k.into(),
|
||||
base2k: base2k_glwe.into(),
|
||||
k: k_in.into(),
|
||||
rank: rank_in.into(),
|
||||
};
|
||||
|
||||
let glwe_out_infos: GLWELayout = GLWELayout {
|
||||
n: n.into(),
|
||||
base2k: base2k.into(),
|
||||
base2k: base2k_glwe.into(),
|
||||
k: k_out.into(),
|
||||
rank: rank_out.into(),
|
||||
};
|
||||
|
||||
let ksk: GLWESwitchingKeyLayout = GLWESwitchingKeyLayout {
|
||||
n: n.into(),
|
||||
base2k: base2k.into(),
|
||||
base2k: base2k_gglwe.into(),
|
||||
k: k_ksk.into(),
|
||||
dnum: dnum.into(),
|
||||
dsize: di.into(),
|
||||
@@ -74,7 +75,7 @@ where
|
||||
let mut source_xe: Source = Source::new([0u8; 32]);
|
||||
let mut source_xa: Source = Source::new([0u8; 32]);
|
||||
|
||||
module.vec_znx_fill_uniform(base2k, &mut pt_want.data, 0, &mut source_xa);
|
||||
module.vec_znx_fill_uniform(base2k_glwe, &mut pt_want.data, 0, &mut source_xa);
|
||||
|
||||
let mut scratch: ScratchOwned<BE> = ScratchOwned::alloc(
|
||||
GLWESwitchingKey::encrypt_sk_tmp_bytes(module, &ksk)
|
||||
@@ -120,7 +121,7 @@ where
|
||||
|
||||
let max_noise: f64 = log2_std_noise_gglwe_product(
|
||||
module.n() as f64,
|
||||
base2k * dsize,
|
||||
base2k_gglwe * dsize,
|
||||
0.5,
|
||||
0.5,
|
||||
0f64,
|
||||
|
||||
Reference in New Issue
Block a user