gadget product working
Jean-Philippe Bossuat jeanphilippe.bossuat@gmail.com
Wed, 12 Feb 2025 09:19:22 +0100
8 files changed,
56 insertions(+),
33 deletions(-)
M
base2k/examples/rlwe_encrypt.rs
→
base2k/examples/rlwe_encrypt.rs
@@ -25,7 +25,7 @@ let mut s: Scalar = Scalar::new(n);
s.fill_ternary_prob(0.5, &mut source); // Buffer to store s in the DFT domain - let mut s_ppol: SvpPPol = module.svp_new_ppol(); + let mut s_ppol: SvpPPol = module.new_svp_ppol(); // s_ppol <- DFT(s) module.svp_prepare(&mut s_ppol, &s);
M
base2k/src/svp.rs
→
base2k/src/svp.rs
@@ -80,7 +80,7 @@ }
pub trait SvpPPolOps { /// Allocates a new [SvpPPol]. - fn svp_new_ppol(&self) -> SvpPPol; + fn new_svp_ppol(&self) -> SvpPPol; /// Returns the minimum number of bytes necessary to allocate /// a new [SvpPPol] through [SvpPPol::from_bytes].@@ -95,7 +95,7 @@ fn svp_apply_dft(&self, c: &mut VecZnxDft, a: &SvpPPol, b: &VecZnx, b_limbs: usize);
} impl SvpPPolOps for Module { - fn svp_new_ppol(&self) -> SvpPPol { + fn new_svp_ppol(&self) -> SvpPPol { unsafe { SvpPPol(svp::new_svp_ppol(self.0), self.n()) } }
M
rlwe/examples/encryption.rs
→
rlwe/examples/encryption.rs
@@ -55,7 +55,7 @@
let mut source_xe: Source = Source::new([1; 32]); let mut source_xa: Source = Source::new([2; 32]); - let mut sk_svp_ppol: base2k::SvpPPol = params.module().svp_new_ppol(); + let mut sk_svp_ppol: base2k::SvpPPol = params.module().new_svp_ppol(); params.module().svp_prepare(&mut sk_svp_ppol, &sk.0); params.encrypt_rlwe_sk_thread_safe(
M
rlwe/examples/gadget_product.rs
→
rlwe/examples/gadget_product.rs
@@ -3,7 +3,9 @@ use rlwe::{
ciphertext::Ciphertext, decryptor::{Decryptor, decrypt_rlwe_thread_safe_tmp_byte}, encryptor::{EncryptorSk, encrypt_rlwe_sk_tmp_bytes}, - keys::SecretKey, + evaluator::{gadget_product_inplace, gadget_product_tmp_bytes}, + key_generator::{gen_switching_key_thread_safe, gen_switching_key_thread_safe_tmp_bytes}, + keys::{SecretKey, SwitchingKey}, parameters::{Parameters, ParametersLiteral}, plaintext::Plaintext, };@@ -13,7 +15,7 @@ fn main() {
let params_lit: ParametersLiteral = ParametersLiteral { log_n: 10, log_q: 54, - log_p: 0, + log_p: 17, log_base2k: 17, log_scale: 20, xe: 3.2,@@ -26,6 +28,20 @@ let mut tmp_bytes: Vec<u8> = vec![
0u8; params.decrypt_rlwe_thread_safe_tmp_byte(params.log_q()) | params.encrypt_rlwe_sk_tmp_bytes(params.log_q()) + | gen_switching_key_thread_safe_tmp_bytes( + params.module(), + params.log_base2k(), + params.limbs_q(), + params.log_q() + ) + | gadget_product_tmp_bytes( + params.module(), + params.log_base2k(), + params.log_q(), + params.log_q(), + params.limbs_q(), + params.limbs_qp() + ) ]; let mut source: Source = Source::new([0; 32]);@@ -54,22 +70,45 @@ pt.0.value[0].print_limbs(pt.limbs(), 16);
let mut ct: Ciphertext = params.new_ciphertext(params.log_q()); - let mut source_xe: Source = Source::new(new_seed()); - let mut source_xa: Source = Source::new(new_seed()); + let mut source_xe: Source = Source::new([1; 32]); + let mut source_xa: Source = Source::new([2; 32]); - let mut sk_svp_ppol: base2k::SvpPPol = params.module().svp_new_ppol(); - params.module().svp_prepare(&mut sk_svp_ppol, &sk0.0); + let mut sk0_svp_ppol: base2k::SvpPPol = params.module().new_svp_ppol(); + params.module().svp_prepare(&mut sk0_svp_ppol, &sk0.0); + + let mut sk1_svp_ppol: base2k::SvpPPol = params.module().new_svp_ppol(); + params.module().svp_prepare(&mut sk1_svp_ppol, &sk1.0); params.encrypt_rlwe_sk_thread_safe( &mut ct, Some(&pt), - &sk_svp_ppol, + &sk0_svp_ppol, + &mut source_xa, + &mut source_xe, + &mut tmp_bytes, + ); + + let mut swk: SwitchingKey = SwitchingKey::new( + params.module(), + params.log_base2k(), + params.limbs_q(), + params.log_qp(), + ); + + gen_switching_key_thread_safe( + params.module(), + &mut swk, + &sk0, + &sk1_svp_ppol, &mut source_xa, &mut source_xe, + params.xe(), &mut tmp_bytes, ); - params.decrypt_rlwe_thread_safe(&mut pt, &ct, &sk_svp_ppol, &mut tmp_bytes); + gadget_product_inplace(params.module(), &mut ct, &swk.0, &mut tmp_bytes); + + params.decrypt_rlwe_thread_safe(&mut pt, &ct, &sk1_svp_ppol, &mut tmp_bytes); pt.0.value[0].print_limbs(pt.limbs(), 16);
M
rlwe/src/ciphertext.rs
→
rlwe/src/ciphertext.rs
@@ -63,17 +63,10 @@ pub struct GadgetCiphertext {
pub value: Vec<VmpPMat>, pub log_base2k: usize, pub log_q: usize, - pub log_scale: usize, } impl GadgetCiphertext { - pub fn new( - module: &Module, - log_base2k: usize, - rows: usize, - log_q: usize, - log_scale: usize, - ) -> Self { + pub fn new(module: &Module, log_base2k: usize, rows: usize, log_q: usize) -> Self { let cols: usize = (log_q + log_base2k - 1) / log_base2k; let mut value: Vec<VmpPMat> = Vec::new(); (0..rows).for_each(|_| value.push(module.new_vmp_pmat(rows, cols)));@@ -81,7 +74,6 @@ Self {
value, log_base2k, log_q, - log_scale, } }
M
rlwe/src/decryptor.rs
→
rlwe/src/decryptor.rs
@@ -10,7 +10,7 @@ }
impl Decryptor { pub fn new(params: &Parameters, sk: &SecretKey) -> Self { - let mut sk_svp_ppol: SvpPPol = params.module().svp_new_ppol(); + let mut sk_svp_ppol: SvpPPol = params.module().new_svp_ppol(); sk.prepare(params.module(), &mut sk_svp_ppol); Self { sk: sk_svp_ppol } }
M
rlwe/src/encryptor.rs
→
rlwe/src/encryptor.rs
@@ -20,7 +20,7 @@ }
impl EncryptorSk { pub fn new(params: &Parameters, sk: Option<&SecretKey>) -> Self { - let mut sk_svp_ppol: SvpPPol = params.module().svp_new_ppol(); + let mut sk_svp_ppol: SvpPPol = params.module().new_svp_ppol(); let mut initialized: bool = false; if let Some(sk) = sk { sk.prepare(params.module(), &mut sk_svp_ppol);
M
rlwe/src/keys.rs
→
rlwe/src/keys.rs
@@ -61,16 +61,8 @@
pub struct SwitchingKey(pub GadgetCiphertext); impl SwitchingKey { - pub fn new( - module: &Module, - log_base2k: usize, - rows: usize, - log_q: usize, - log_scale: usize, - ) -> SwitchingKey { - SwitchingKey(GadgetCiphertext::new( - module, log_base2k, rows, log_q, log_scale, - )) + pub fn new(module: &Module, log_base2k: usize, rows: usize, log_q: usize) -> SwitchingKey { + SwitchingKey(GadgetCiphertext::new(module, log_base2k, rows, log_q)) } pub fn gen_thread_safe(