wip
Jean-Philippe Bossuat jeanphilippe.bossuat@gmail.com
Wed, 07 May 2025 10:23:18 +0200
5 files changed,
128 insertions(+),
44 deletions(-)
M
base2k/src/sampling.rs
→
base2k/src/sampling.rs
@@ -297,8 +297,6 @@ }
#[cfg(test)] mod tests { - use std::fmt::Display; - use super::{AddNormal, FillUniform}; use crate::vec_znx_ops::*; use crate::znx_base::*;
M
base2k/src/scalar_znx_dft_ops.rs
→
base2k/src/scalar_znx_dft_ops.rs
@@ -2,8 +2,8 @@ use crate::ffi::svp;
use crate::ffi::vec_znx_dft::vec_znx_dft_t; use crate::znx_base::{ZnxInfos, ZnxView, ZnxViewMut}; use crate::{ - Backend, FFT64, Module, ScalarToRef, ScalarZnxDft, ScalarZnxDftOwned, ScalarZnxDftToMut, ScalarZnxDftToRef, VecZnx, - VecZnxDft, VecZnxDftToMut, VecZnxDftToRef, VecZnxToRef, ZnxSliceSize, + Backend, FFT64, Module, ScalarToRef, ScalarZnxDft, ScalarZnxDftOwned, ScalarZnxDftToMut, ScalarZnxDftToRef, + VecZnxDft, VecZnxDftToMut, VecZnxDftToRef, }; pub trait ScalarZnxDftAlloc<B: Backend> {
M
rlwe/src/elem.rs
→
rlwe/src/elem.rs
@@ -1,13 +1,12 @@
use base2k::{ - Backend, DataView, DataViewMut, MatZnxDft, MatZnxDftAlloc, MatZnxDftToMut, MatZnxDftToRef, Module, VecZnx, VecZnxAlloc, - VecZnxDft, VecZnxDftAlloc, VecZnxDftToMut, VecZnxDftToRef, VecZnxToMut, VecZnxToRef, ZnxInfos, + Backend, DataView, DataViewMut, MatZnxDft, MatZnxDftAlloc, MatZnxDftToMut, MatZnxDftToRef, Module, ScalarZnxDftToRef, VecZnx, + VecZnxAlloc, VecZnxDft, VecZnxDftAlloc, VecZnxDftToMut, VecZnxDftToRef, VecZnxToMut, VecZnxToRef, ZnxInfos, }; -pub trait Infos<T> -where - T: ZnxInfos, -{ - fn inner(&self) -> &T; +pub trait Infos { + type Inner: ZnxInfos; + + fn inner(&self) -> &Self::Inner; /// Returns the ring degree of the polynomials. fn n(&self) -> usize {@@ -48,17 +47,16 @@ /// Returns the base 2 logarithm of the ciphertext modulus.
fn log_q(&self) -> usize; } -pub struct Ciphertext<T> { - data: T, +pub struct RLWECt<C>{ + data: VecZnx<C>, log_base2k: usize, log_q: usize, } -impl<T> Infos<T> for Ciphertext<T> -where - T: ZnxInfos, -{ - fn inner(&self) -> &T { +impl<T: ZnxInfos> Infos for RLWECt<T> { + type Inner = T; + + fn inner(&self) -> &Self::Inner { &self.data }@@ -90,11 +88,10 @@ log_base2k: usize,
log_q: usize, } -impl<T> Infos<T> for Plaintext<T> -where - T: ZnxInfos, -{ - fn inner(&self) -> &T { +impl<T: ZnxInfos> Infos for Plaintext<T> { + type Inner = T; + + fn inner(&self) -> &Self::Inner { &self.data }
M
rlwe/src/encryption.rs
→
rlwe/src/encryption.rs
@@ -6,13 +6,16 @@ };
use sampling::source::Source; -use crate::{elem::Infos, keys::SecretKey}; +use crate::{ + elem::{Ciphertext, Infos, Plaintext}, + keys::SecretKey, +}; -pub trait EncryptSk<B: Backend, D, P> { +pub trait EncryptSk<B: Backend, C, P> { fn encrypt<S>( module: &Module<B>, - res: &mut D, - pt: Option<&P>, + res: &mut Ciphertext<C>, + pt: Option<&Plaintext<P>>, sk: &SecretKey<S>, source_xa: &mut Source, source_xe: &mut Source,@@ -22,20 +25,18 @@ bound: f64,
) where S: ScalarZnxDftToRef<B>; - fn encrypt_tmp_bytes(module: &Module<B>, size: usize) -> usize { - (module.vec_znx_big_normalize_tmp_bytes() | module.bytes_of_vec_znx_dft(1, size)) + module.bytes_of_vec_znx_big(1, size) - } + fn encrypt_scratch_bytes(module: &Module<B>, size: usize) -> usize; } -impl<C, P> EncryptSk<FFT64, C, P> for C +impl<C, P> EncryptSk<FFT64, C, P> for Ciphertext<C> where - C: VecZnxToMut + ZnxInfos + Infos<C>, - P: VecZnxToRef, + C: VecZnxToMut + ZnxInfos, + P: VecZnxToRef + ZnxInfos, { fn encrypt<S>( module: &Module<FFT64>, - ct: &mut C, - pt: Option<&P>, + ct: &mut Ciphertext<C>, + pt: Option<&Plaintext<P>>, sk: &SecretKey<S>, source_xa: &mut Source, source_xe: &mut Source,@@ -76,6 +77,41 @@
// c0 = norm(c0_big = -as + m + e) module.vec_znx_big_normalize(log_base2k, &mut ct_mut, 0, &c0_big, 0, scratch_1); } + + fn encrypt_scratch_bytes(module: &Module<FFT64>, size: usize) -> usize { + (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> Ciphertext<C> +where + C: VecZnxToMut + ZnxInfos, +{ + pub fn encrypt_sk<P, S>( + &mut self, + module: &Module<FFT64>, + pt: Option<&Plaintext<P>>, + sk: &SecretKey<S>, + source_xa: &mut Source, + source_xe: &mut Source, + scratch: &mut Scratch, + sigma: f64, + bound: f64, + ) where + P: VecZnxToRef + ZnxInfos, + S: ScalarZnxDftToRef<FFT64>, + { + <Self as EncryptSk<FFT64, _, _>>::encrypt( + module, self, pt, sk, source_xa, source_xe, scratch, sigma, bound, + ); + } + + pub fn encrypt_sk_scratch_bytes<P>(module: &Module<FFT64>, size: usize) -> usize + where + Self: EncryptSk<FFT64, C, P>, + { + <Self as EncryptSk<FFT64, C, P>>::encrypt_scratch_bytes(module, size) + } } pub trait EncryptZeroSk<B: Backend, D> {@@ -91,17 +127,12 @@ 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() - } + fn encrypt_zero_scratch_bytes(module: &Module<B>, size: usize) -> usize; } impl<C> EncryptZeroSk<FFT64, C> for C where - C: VecZnxDftToMut<FFT64> + ZnxInfos + Infos<C>, + C: VecZnxDftToMut<FFT64> + ZnxInfos + Infos, { fn encrypt_zero<S>( module: &Module<FFT64>,@@ -145,5 +176,54 @@ 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); + } + + fn encrypt_zero_scratch_bytes(module: &Module<FFT64>, 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() + } +} + +#[cfg(test)] +mod tests { + use base2k::{FFT64, Module, ScratchOwned, VecZnx, Scalar}; + use sampling::source::Source; + + use crate::{elem::{Ciphertext, Infos, Plaintext}, keys::SecretKey}; + + #[test] + fn encrypt_sk_vec_znx_fft64() { + let module: Module<FFT64> = Module::<FFT64>::new(32); + let log_base2k: usize = 8; + let log_q: usize = 54; + + let sigma: f64 = 3.2; + let bound: f64 = sigma * 6; + + let mut ct: Ciphertext<VecZnx<Vec<u8>>> = Ciphertext::<VecZnx<Vec<u8>>>::new(&module, log_base2k, log_q, 2); + let mut pt: Plaintext<VecZnx<Vec<u8>>> = Plaintext::<VecZnx<Vec<u8>>>::new(&module, log_base2k, log_q); + + let mut source_xe = Source::new([0u8; 32]); + let mut source_xa: Source = Source::new([0u8; 32]); + + + let mut scratch: ScratchOwned = ScratchOwned::new(ct.encrypt_encsk_scratch_bytes(&module, ct.size())); + + let mut sk: SecretKey<Scalar<Vec<u8>>> = SecretKey::new(&module); + let mut sk_prep + sk.svp_prepare(&module, &mut sk_prep); + + ct.encrypt_sk( + &module, + Some(&pt), + &sk_prep, + &mut source_xa, + &mut source_xe, + scratch.borrow(), + sigma, + bound, + ); } }
M
rlwe/src/keys.rs
→
rlwe/src/keys.rs
@@ -1,6 +1,5 @@
use base2k::{ - Backend, FFT64, Module, Scalar, ScalarAlloc, ScalarZnxDft, ScalarZnxDftOps, ScalarZnxDftToMut, Scratch, VecZnxDft, - VecZnxDftAlloc, VecZnxDftToMut, + Backend, Module, Scalar, ScalarAlloc, ScalarZnxDft, ScalarZnxDftAlloc, ScalarZnxDftOps, ScalarZnxDftToMut, Scratch, VecZnxDft, VecZnxDftAlloc, VecZnxDftToMut, ZnxInfos, FFT64 }; use sampling::source::Source;@@ -40,6 +39,16 @@ where
ScalarZnxDft<D, base2k::FFT64>: ScalarZnxDftToMut<base2k::FFT64>, { module.svp_prepare(&mut sk_prep.data, 0, &self.data, 0) + } +} + +type SecretKeyPrep<C, B> = SecretKey<ScalarZnxDft<C, B>>; + +impl<B: Backend> SecretKey<ScalarZnxDft<Vec<u8>, B>> { + pub fn new(module: &Module<B>) -> Self{ + Self{ + data: module.new_scalar_znx_dft(1) + } } }