added rlwe basic sk encryption
Jean-Philippe Bossuat jeanphilippe.bossuat@gmail.com
Tue, 06 May 2025 16:43:17 +0200
3 files changed,
102 insertions(+),
16 deletions(-)
M
rlwe/src/elem.rs
→
rlwe/src/elem.rs
@@ -1,4 +1,4 @@
-use base2k::{Backend, FFT64, MatZnxDft, MatZnxDftAlloc, Module, VecZnx, VecZnxAlloc}; +use base2k::{Backend, FFT64, MatZnxDft, MatZnxDftAlloc, Module, VecZnx, VecZnxAlloc, VecZnxDft, VecZnxDftAlloc}; pub struct Ciphertext<T> { data: T,@@ -48,7 +48,12 @@ &mut self.data
} } -pub(crate) type CipherVecZnx<C> = Ciphertext<VecZnx<C>>; +pub(crate) type CtVecZnx<C> = Ciphertext<VecZnx<C>>; +pub(crate) type CtVecZnxDft<C, B: Backend> = Ciphertext<VecZnxDft<C, B>>; +pub(crate) type CtMatZnxDft<C, B: Backend> = Ciphertext<MatZnxDft<C, B>>; +pub(crate) type PtVecZnx<C> = Plaintext<VecZnx<C>>; +pub(crate) type PtVecZnxDft<C, B: Backend> = Plaintext<VecZnxDft<C, B>>; +pub(crate) type PtMatZnxDft<C, B: Backend> = Plaintext<MatZnxDft<C, B>>; impl Ciphertext<VecZnx<Vec<u8>>> { pub fn new<B: Backend>(module: &Module<B>, log_base2k: usize, log_q: usize, cols: usize) -> Self {@@ -64,6 +69,16 @@ impl Plaintext<VecZnx<Vec<u8>>> {
pub fn new<B: Backend>(module: &Module<B>, log_base2k: usize, log_q: usize) -> Self { Self { data: module.new_vec_znx(1, derive_size(log_base2k, log_q)), + log_base2k: log_base2k, + log_q: log_q, + } + } +} + +impl<B: Backend> Ciphertext<VecZnxDft<Vec<u8>, B>> { + pub fn new(module: &Module<B>, log_base2k: usize, log_q: usize, cols: usize) -> Self { + Self { + data: module.new_vec_znx_dft(cols, derive_size(log_base2k, log_q)), log_base2k: log_base2k, log_q: log_q, }
M
rlwe/src/encryption.rs
→
rlwe/src/encryption.rs
@@ -1,20 +1,21 @@
use base2k::{ - AddNormal, Backend, FFT64, FillUniform, Module, ScalarZnxDftOps, ScalarZnxDftToRef, Scratch, VecZnx, VecZnxBigAlloc, - VecZnxBigOps, VecZnxBigScratch, VecZnxDftAlloc, VecZnxDftOps, VecZnxToMut, VecZnxToRef, ZnxInfos, + AddNormal, Backend, FFT64, FillUniform, Module, ScalarZnxDftOps, ScalarZnxDftToRef, Scratch, VecZnx, VecZnxAlloc, + VecZnxBigAlloc, VecZnxBigOps, VecZnxBigScratch, VecZnxDft, VecZnxDftAlloc, VecZnxDftOps, VecZnxDftToMut, VecZnxDftToRef, + VecZnxToMut, VecZnxToRef, ZnxInfos, }; use sampling::source::Source; use crate::{ - elem::{CipherVecZnx, Plaintext}, + elem::{CtVecZnx, CtVecZnxDft, PtVecZnx}, keys::SecretKey, }; -pub trait EncryptSk<B: Backend, D> { - fn encrypt<P, S>( +pub trait EncryptSk<B: Backend, D, P> { + fn encrypt<S>( module: &Module<B>, res: &mut D, - pt: Option<&Plaintext<P>>, + pt: Option<&P>, sk: &SecretKey<S>, source_xa: &mut Source, source_xe: &mut Source,@@ -22,7 +23,6 @@ scratch: &mut Scratch,
sigma: f64, bound: f64, ) where - P: VecZnxToRef, S: ScalarZnxDftToRef<B>; fn encrypt_tmp_bytes(module: &Module<B>, size: usize) -> usize {@@ -30,14 +30,15 @@ (module.vec_znx_big_normalize_tmp_bytes() | module.bytes_of_vec_znx_dft(1, size)) + module.bytes_of_vec_znx_big(1, size)
} } -impl<C> EncryptSk<FFT64, CipherVecZnx<C>> for CipherVecZnx<C> +impl<C, P> EncryptSk<FFT64, CtVecZnx<C>, PtVecZnx<P>> for CtVecZnx<C> where VecZnx<C>: VecZnxToMut + VecZnxToRef, + VecZnx<P>: VecZnxToRef, { - fn encrypt<P, S>( + fn encrypt<S>( module: &Module<FFT64>, - ct: &mut CipherVecZnx<C>, - pt: Option<&Plaintext<P>>, + ct: &mut CtVecZnx<C>, + pt: Option<&PtVecZnx<P>>, sk: &SecretKey<S>, source_xa: &mut Source, source_xe: &mut Source,@@ -45,7 +46,6 @@ scratch: &mut Scratch,
sigma: f64, bound: f64, ) where - P: VecZnxToRef, S: ScalarZnxDftToRef<FFT64>, { let log_base2k: usize = ct.log_base2k();@@ -60,9 +60,10 @@ let (mut c0_big, scratch_1) = scratch.tmp_vec_znx_big(module, 1, size);
{ let (mut c0_dft, _) = scratch_1.tmp_vec_znx_dft(module, 1, size); + module.vec_znx_dft(&mut c0_dft, 0, &ct_mut, 1); // c0_dft = DFT(a) * DFT(s) - module.svp_apply(&mut c0_dft, 0, &sk.data().to_ref(), 0, &ct_mut, 1); + module.svp_apply_inplace(&mut c0_dft, 0, &sk.data().to_ref(), 0); // c0_big = IDFT(c0_dft) module.vec_znx_idft_tmp_a(&mut c0_big, 0, &mut c0_dft, 0);@@ -79,3 +80,73 @@ // c0 = norm(c0_big = -as + m + e)
module.vec_znx_big_normalize(log_base2k, &mut ct_mut, 0, &c0_big, 0, scratch_1); } } + +pub trait EncryptZeroSk<B: Backend, D> { + fn encrypt_zero<S>( + module: &Module<B>, + res: &mut D, + sk: &SecretKey<S>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + sigma: f64, + bound: f64, + ) where + S: ScalarZnxDftToRef<B>; + + fn encrypt_zero_tmp_bytes(module: &Module<B>, size: usize) -> usize { + (module.bytes_of_vec_znx(1, size) | module.bytes_of_vec_znx_dft(1, size)) + + module.bytes_of_vec_znx_big(1, size) + + module.bytes_of_vec_znx(1, size) + + module.vec_znx_big_normalize_tmp_bytes() + } +} + +impl<C> EncryptZeroSk<FFT64, CtVecZnxDft<C, FFT64>> for CtVecZnxDft<C, FFT64> +where + VecZnxDft<C, FFT64>: VecZnxDftToMut<FFT64> + VecZnxDftToRef<FFT64>, +{ + fn encrypt_zero<S>( + module: &Module<FFT64>, + ct: &mut CtVecZnxDft<C, FFT64>, + sk: &SecretKey<S>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + sigma: f64, + bound: f64, + ) where + S: ScalarZnxDftToRef<FFT64>, + { + let log_base2k: usize = ct.log_base2k(); + let log_q: usize = ct.log_q(); + let mut ct_mut: VecZnxDft<&mut [u8], FFT64> = ct.data_mut().to_mut(); + let size: usize = ct_mut.size(); + + // ct[1] = DFT(a) + { + let (mut tmp_znx, _) = scratch.tmp_vec_znx(module, 1, size); + tmp_znx.fill_uniform(log_base2k, 1, size, source_xa); + module.vec_znx_dft(&mut ct_mut, 1, &tmp_znx, 0); + } + + let (mut c0_big, scratch_1) = scratch.tmp_vec_znx_big(module, 1, size); + + { + let (mut tmp_dft, _) = scratch_1.tmp_vec_znx_dft(module, 1, size); + // c0_dft = DFT(a) * DFT(s) + module.svp_apply(&mut tmp_dft, 0, &sk.data().to_ref(), 0, &ct_mut, 1); + // c0_big = IDFT(c0_dft) + module.vec_znx_idft_tmp_a(&mut c0_big, 0, &mut tmp_dft, 0); + } + + // c0_big += e + c0_big.add_normal(log_base2k, 0, log_q, source_xe, sigma, bound); + + // c0 = norm(c0_big = -as + e) + let (mut tmp_znx, scratch_2) = scratch_1.tmp_vec_znx(module, 1, size); + module.vec_znx_big_normalize(log_base2k, &mut tmp_znx, 0, &c0_big, 0, scratch_2); + // ct[0] = DFT(-as + e) + module.vec_znx_dft(&mut ct_mut, 0, &tmp_znx, 0); + } +}
M
rlwe/src/keys.rs
→
rlwe/src/keys.rs
@@ -15,7 +15,7 @@ pub fn data(&self) -> &T {
&self.data } - pub fn data_mut(&self) -> &mut T { + pub fn data_mut(&mut self) -> &mut T { &mut self.data } }