mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 13:16:44 +01:00
added grlwe sk encryption
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
use crate::ffi::vec_znx_big;
|
use crate::ffi::vec_znx_big;
|
||||||
use crate::znx_base::{ZnxInfos, ZnxView};
|
use crate::znx_base::{ZnxInfos, ZnxView};
|
||||||
use crate::{Backend, DataView, DataViewMut, FFT64, Module, VecZnxDft, ZnxSliceSize, alloc_aligned};
|
use crate::{Backend, DataView, DataViewMut, FFT64, Module, ZnxSliceSize, alloc_aligned};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
|||||||
261
rlwe/src/elem.rs
261
rlwe/src/elem.rs
@@ -1,7 +1,6 @@
|
|||||||
use base2k::{
|
use base2k::ZnxInfos;
|
||||||
Backend, MatZnxDft, MatZnxDftAlloc, MatZnxDftToMut, MatZnxDftToRef, Module, VecZnx, VecZnxAlloc, VecZnxDft, VecZnxDftAlloc,
|
|
||||||
VecZnxDftToMut, VecZnxDftToRef, VecZnxToMut, VecZnxToRef, ZnxInfos,
|
use crate::utils::derive_size;
|
||||||
};
|
|
||||||
|
|
||||||
pub trait Infos {
|
pub trait Infos {
|
||||||
type Inner: ZnxInfos;
|
type Inner: ZnxInfos;
|
||||||
@@ -46,257 +45,3 @@ pub trait Infos {
|
|||||||
/// Returns the bit precision of the ciphertext.
|
/// Returns the bit precision of the ciphertext.
|
||||||
fn log_k(&self) -> usize;
|
fn log_k(&self) -> usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RLWECt<C> {
|
|
||||||
pub data: VecZnx<C>,
|
|
||||||
pub log_base2k: usize,
|
|
||||||
pub log_k: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Infos for RLWECt<T> {
|
|
||||||
type Inner = VecZnx<T>;
|
|
||||||
|
|
||||||
fn inner(&self) -> &Self::Inner {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_base2k(&self) -> usize {
|
|
||||||
self.log_base2k
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_k(&self) -> usize {
|
|
||||||
self.log_k
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C> VecZnxToMut for RLWECt<C>
|
|
||||||
where
|
|
||||||
VecZnx<C>: VecZnxToMut,
|
|
||||||
{
|
|
||||||
fn to_mut(&mut self) -> VecZnx<&mut [u8]> {
|
|
||||||
self.data.to_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C> VecZnxToRef for RLWECt<C>
|
|
||||||
where
|
|
||||||
VecZnx<C>: VecZnxToRef,
|
|
||||||
{
|
|
||||||
fn to_ref(&self) -> VecZnx<&[u8]> {
|
|
||||||
self.data.to_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RLWEPt<C> {
|
|
||||||
pub data: VecZnx<C>,
|
|
||||||
pub log_base2k: usize,
|
|
||||||
pub log_k: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Infos for RLWEPt<T> {
|
|
||||||
type Inner = VecZnx<T>;
|
|
||||||
|
|
||||||
fn inner(&self) -> &Self::Inner {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_base2k(&self) -> usize {
|
|
||||||
self.log_base2k
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_k(&self) -> usize {
|
|
||||||
self.log_k
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C> VecZnxToMut for RLWEPt<C>
|
|
||||||
where
|
|
||||||
VecZnx<C>: VecZnxToMut,
|
|
||||||
{
|
|
||||||
fn to_mut(&mut self) -> VecZnx<&mut [u8]> {
|
|
||||||
self.data.to_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C> VecZnxToRef for RLWEPt<C>
|
|
||||||
where
|
|
||||||
VecZnx<C>: VecZnxToRef,
|
|
||||||
{
|
|
||||||
fn to_ref(&self) -> VecZnx<&[u8]> {
|
|
||||||
self.data.to_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RLWECt<Vec<u8>> {
|
|
||||||
pub fn new<B: Backend>(module: &Module<B>, log_base2k: usize, log_k: usize, cols: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
data: module.new_vec_znx(cols, derive_size(log_base2k, log_k)),
|
|
||||||
log_base2k: log_base2k,
|
|
||||||
log_k: log_k,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RLWEPt<Vec<u8>> {
|
|
||||||
pub fn new<B: Backend>(module: &Module<B>, log_base2k: usize, log_k: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
data: module.new_vec_znx(1, derive_size(log_base2k, log_k)),
|
|
||||||
log_base2k: log_base2k,
|
|
||||||
log_k: log_k,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RLWECtDft<C, B: Backend> {
|
|
||||||
pub data: VecZnxDft<C, B>,
|
|
||||||
pub log_base2k: usize,
|
|
||||||
pub log_k: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Backend> RLWECtDft<Vec<u8>, B> {
|
|
||||||
pub fn new(module: &Module<B>, log_base2k: usize, log_k: usize, cols: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
data: module.new_vec_znx_dft(cols, derive_size(log_base2k, log_k)),
|
|
||||||
log_base2k: log_base2k,
|
|
||||||
log_k: log_k,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, B: Backend> Infos for RLWECtDft<T, B> {
|
|
||||||
type Inner = VecZnxDft<T, B>;
|
|
||||||
|
|
||||||
fn inner(&self) -> &Self::Inner {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_base2k(&self) -> usize {
|
|
||||||
self.log_base2k
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_k(&self) -> usize {
|
|
||||||
self.log_k
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B: Backend> VecZnxDftToMut<B> for RLWECtDft<C, B>
|
|
||||||
where
|
|
||||||
VecZnxDft<C, B>: VecZnxDftToMut<B>,
|
|
||||||
{
|
|
||||||
fn to_mut(&mut self) -> VecZnxDft<&mut [u8], B> {
|
|
||||||
self.data.to_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B: Backend> VecZnxDftToRef<B> for RLWECtDft<C, B>
|
|
||||||
where
|
|
||||||
VecZnxDft<C, B>: VecZnxDftToRef<B>,
|
|
||||||
{
|
|
||||||
fn to_ref(&self) -> VecZnxDft<&[u8], B> {
|
|
||||||
self.data.to_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GRLWECt<C, B: Backend> {
|
|
||||||
pub data: MatZnxDft<C, B>,
|
|
||||||
pub log_base2k: usize,
|
|
||||||
pub log_k: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Backend> GRLWECt<Vec<u8>, B> {
|
|
||||||
pub fn new(module: &Module<B>, log_base2k: usize, log_k: usize, rows: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
data: module.new_mat_znx_dft(rows, 1, 2, derive_size(log_base2k, log_k)),
|
|
||||||
log_base2k: log_base2k,
|
|
||||||
log_k: log_k,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, B: Backend> Infos for GRLWECt<T, B> {
|
|
||||||
type Inner = MatZnxDft<T, B>;
|
|
||||||
|
|
||||||
fn inner(&self) -> &Self::Inner {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_base2k(&self) -> usize {
|
|
||||||
self.log_base2k
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_k(&self) -> usize {
|
|
||||||
self.log_k
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B: Backend> MatZnxDftToMut<B> for GRLWECt<C, B>
|
|
||||||
where
|
|
||||||
MatZnxDft<C, B>: MatZnxDftToMut<B>,
|
|
||||||
{
|
|
||||||
fn to_mut(&mut self) -> MatZnxDft<&mut [u8], B> {
|
|
||||||
self.data.to_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B: Backend> MatZnxDftToRef<B> for GRLWECt<C, B>
|
|
||||||
where
|
|
||||||
MatZnxDft<C, B>: MatZnxDftToRef<B>,
|
|
||||||
{
|
|
||||||
fn to_ref(&self) -> MatZnxDft<&[u8], B> {
|
|
||||||
self.data.to_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RGSWCt<C, B: Backend> {
|
|
||||||
pub data: MatZnxDft<C, B>,
|
|
||||||
pub log_base2k: usize,
|
|
||||||
pub log_k: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<B: Backend> RGSWCt<Vec<u8>, B> {
|
|
||||||
pub fn new(module: &Module<B>, log_base2k: usize, log_k: usize, rows: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
data: module.new_mat_znx_dft(rows, 2, 2, derive_size(log_base2k, log_k)),
|
|
||||||
log_base2k: log_base2k,
|
|
||||||
log_k: log_k,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, B: Backend> Infos for RGSWCt<T, B> {
|
|
||||||
type Inner = MatZnxDft<T, B>;
|
|
||||||
|
|
||||||
fn inner(&self) -> &Self::Inner {
|
|
||||||
&self.data
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_base2k(&self) -> usize {
|
|
||||||
self.log_base2k
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_k(&self) -> usize {
|
|
||||||
self.log_k
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B: Backend> MatZnxDftToMut<B> for RGSWCt<C, B>
|
|
||||||
where
|
|
||||||
MatZnxDft<C, B>: MatZnxDftToMut<B>,
|
|
||||||
{
|
|
||||||
fn to_mut(&mut self) -> MatZnxDft<&mut [u8], B> {
|
|
||||||
self.data.to_mut()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<C, B: Backend> MatZnxDftToRef<B> for RGSWCt<C, B>
|
|
||||||
where
|
|
||||||
MatZnxDft<C, B>: MatZnxDftToRef<B>,
|
|
||||||
{
|
|
||||||
fn to_ref(&self) -> MatZnxDft<&[u8], B> {
|
|
||||||
self.data.to_ref()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn derive_size(log_base2k: usize, log_k: usize) -> usize {
|
|
||||||
(log_k + log_base2k - 1) / log_base2k
|
|
||||||
}
|
|
||||||
|
|||||||
53
rlwe/src/elem_grlwe.rs
Normal file
53
rlwe/src/elem_grlwe.rs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
use base2k::{Backend, MatZnxDft, MatZnxDftAlloc, MatZnxDftToMut, MatZnxDftToRef, Module};
|
||||||
|
|
||||||
|
use crate::{elem::Infos, utils::derive_size};
|
||||||
|
|
||||||
|
pub struct GRLWECt<C, B: Backend> {
|
||||||
|
pub data: MatZnxDft<C, B>,
|
||||||
|
pub log_base2k: usize,
|
||||||
|
pub log_k: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> GRLWECt<Vec<u8>, B> {
|
||||||
|
pub fn new(module: &Module<B>, log_base2k: usize, log_k: usize, rows: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
data: module.new_mat_znx_dft(rows, 1, 2, derive_size(log_base2k, log_k)),
|
||||||
|
log_base2k: log_base2k,
|
||||||
|
log_k: log_k,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, B: Backend> Infos for GRLWECt<T, B> {
|
||||||
|
type Inner = MatZnxDft<T, B>;
|
||||||
|
|
||||||
|
fn inner(&self) -> &Self::Inner {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_base2k(&self) -> usize {
|
||||||
|
self.log_base2k
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_k(&self) -> usize {
|
||||||
|
self.log_k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, B: Backend> MatZnxDftToMut<B> for GRLWECt<C, B>
|
||||||
|
where
|
||||||
|
MatZnxDft<C, B>: MatZnxDftToMut<B>,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> MatZnxDft<&mut [u8], B> {
|
||||||
|
self.data.to_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, B: Backend> MatZnxDftToRef<B> for GRLWECt<C, B>
|
||||||
|
where
|
||||||
|
MatZnxDft<C, B>: MatZnxDftToRef<B>,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> MatZnxDft<&[u8], B> {
|
||||||
|
self.data.to_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
140
rlwe/src/elem_rgsw.rs
Normal file
140
rlwe/src/elem_rgsw.rs
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
use base2k::{
|
||||||
|
Backend, FFT64, MatZnxDft, MatZnxDftAlloc, MatZnxDftOps, MatZnxDftToMut, MatZnxDftToRef, Module, ScalarZnx, ScalarZnxDft,
|
||||||
|
ScalarZnxDftToRef, ScalarZnxToRef, Scratch, VecZnxAlloc, VecZnxDftAlloc, VecZnxDftOps, ZnxView, ZnxViewMut,
|
||||||
|
};
|
||||||
|
use sampling::source::Source;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
elem::Infos,
|
||||||
|
elem_grlwe::GRLWECt,
|
||||||
|
elem_rlwe::{RLWECt, RLWECtDft, RLWEPt},
|
||||||
|
keys::SecretKeyDft,
|
||||||
|
utils::derive_size,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct RGSWCt<C, B: Backend> {
|
||||||
|
pub data: MatZnxDft<C, B>,
|
||||||
|
pub log_base2k: usize,
|
||||||
|
pub log_k: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> RGSWCt<Vec<u8>, B> {
|
||||||
|
pub fn new(module: &Module<B>, log_base2k: usize, log_k: usize, rows: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
data: module.new_mat_znx_dft(rows, 2, 2, derive_size(log_base2k, log_k)),
|
||||||
|
log_base2k: log_base2k,
|
||||||
|
log_k: log_k,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, B: Backend> Infos for RGSWCt<T, B> {
|
||||||
|
type Inner = MatZnxDft<T, B>;
|
||||||
|
|
||||||
|
fn inner(&self) -> &Self::Inner {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_base2k(&self) -> usize {
|
||||||
|
self.log_base2k
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_k(&self) -> usize {
|
||||||
|
self.log_k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, B: Backend> MatZnxDftToMut<B> for RGSWCt<C, B>
|
||||||
|
where
|
||||||
|
MatZnxDft<C, B>: MatZnxDftToMut<B>,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> MatZnxDft<&mut [u8], B> {
|
||||||
|
self.data.to_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, B: Backend> MatZnxDftToRef<B> for RGSWCt<C, B>
|
||||||
|
where
|
||||||
|
MatZnxDft<C, B>: MatZnxDftToRef<B>,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> MatZnxDft<&[u8], B> {
|
||||||
|
self.data.to_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GRLWECt<Vec<u8>, FFT64> {
|
||||||
|
pub fn encrypt_sk_scratch_bytes(module: &Module<FFT64>, size: usize) -> usize {
|
||||||
|
RLWECt::encrypt_sk_scratch_bytes(module, size)
|
||||||
|
+ module.bytes_of_vec_znx(2, size)
|
||||||
|
+ module.bytes_of_vec_znx(1, size)
|
||||||
|
+ module.bytes_of_vec_znx_dft(2, size)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encrypt_pk_scratch_bytes(module: &Module<FFT64>, pk_size: usize) -> usize {
|
||||||
|
RLWECt::encrypt_pk_scratch_bytes(module, pk_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decrypt_scratch_bytes(module: &Module<FFT64>, size: usize) -> usize {
|
||||||
|
RLWECtDft::decrypt_scratch_bytes(module, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encrypt_grlwe_sk<C, P, S>(
|
||||||
|
module: &Module<FFT64>,
|
||||||
|
ct: &mut GRLWECt<C, FFT64>,
|
||||||
|
pt: &ScalarZnx<P>,
|
||||||
|
sk: &SecretKeyDft<S, FFT64>,
|
||||||
|
source_xa: &mut Source,
|
||||||
|
source_xe: &mut Source,
|
||||||
|
sigma: f64,
|
||||||
|
bound: f64,
|
||||||
|
scratch: &mut Scratch,
|
||||||
|
) where
|
||||||
|
MatZnxDft<C, FFT64>: MatZnxDftToMut<FFT64>,
|
||||||
|
ScalarZnx<P>: ScalarZnxToRef,
|
||||||
|
ScalarZnxDft<S, FFT64>: ScalarZnxDftToRef<FFT64>,
|
||||||
|
{
|
||||||
|
let rows: usize = ct.rows();
|
||||||
|
let size: usize = ct.size();
|
||||||
|
|
||||||
|
let (tmp_znx_pt, scrach_1) = scratch.tmp_vec_znx(module, 1, size);
|
||||||
|
let (tmp_znx_ct, scrach_2) = scrach_1.tmp_vec_znx(module, 2, size);
|
||||||
|
let (mut tmp_dft, scratch_3) = scrach_2.tmp_vec_znx_dft(module, 2, size);
|
||||||
|
|
||||||
|
let mut tmp_pt: RLWEPt<&mut [u8]> = RLWEPt {
|
||||||
|
data: tmp_znx_pt,
|
||||||
|
log_base2k: ct.log_base2k(),
|
||||||
|
log_k: ct.log_k(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut tmp_ct: RLWECt<&mut [u8]> = RLWECt {
|
||||||
|
data: tmp_znx_ct,
|
||||||
|
log_base2k: ct.log_base2k(),
|
||||||
|
log_k: ct.log_k(),
|
||||||
|
};
|
||||||
|
|
||||||
|
(0..rows).for_each(|row_i| {
|
||||||
|
tmp_pt
|
||||||
|
.data
|
||||||
|
.at_mut(0, row_i)
|
||||||
|
.copy_from_slice(&pt.to_ref().raw());
|
||||||
|
|
||||||
|
tmp_ct.encrypt_sk(
|
||||||
|
module,
|
||||||
|
Some(&tmp_pt),
|
||||||
|
sk,
|
||||||
|
source_xa,
|
||||||
|
source_xe,
|
||||||
|
sigma,
|
||||||
|
bound,
|
||||||
|
scratch_3,
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp_pt.data.at_mut(0, row_i).fill(0);
|
||||||
|
|
||||||
|
module.vec_znx_dft(&mut tmp_dft, 0, &tmp_ct, 0);
|
||||||
|
module.vec_znx_dft(&mut tmp_dft, 1, &tmp_ct, 1);
|
||||||
|
|
||||||
|
module.vmp_prepare_row(ct, row_i, 0, &tmp_dft);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,20 +1,180 @@
|
|||||||
use std::cmp::min;
|
|
||||||
|
|
||||||
use base2k::{
|
use base2k::{
|
||||||
AddNormal, Backend, FFT64, FillUniform, Module, ScalarZnxAlloc, ScalarZnxDft, ScalarZnxDftAlloc, ScalarZnxDftOps,
|
AddNormal, Backend, FFT64, FillUniform, Module, ScalarZnxAlloc, ScalarZnxDft, ScalarZnxDftAlloc, ScalarZnxDftOps,
|
||||||
ScalarZnxDftToRef, Scratch, VecZnx, VecZnxAlloc, VecZnxBigAlloc, VecZnxBigOps, VecZnxBigScratch, VecZnxDft, VecZnxDftAlloc,
|
ScalarZnxDftToRef, Scratch, VecZnx, VecZnxAlloc, VecZnxBigAlloc, VecZnxBigOps, VecZnxBigScratch, VecZnxDft, VecZnxDftAlloc,
|
||||||
VecZnxDftOps, VecZnxDftToMut, VecZnxDftToRef, VecZnxOps, VecZnxToMut, VecZnxToRef,
|
VecZnxDftOps, VecZnxDftToMut, VecZnxDftToRef, VecZnxOps, VecZnxToMut, VecZnxToRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
use sampling::source::Source;
|
use sampling::source::Source;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
elem::{Infos, RLWECt, RLWECtDft, RLWEPt},
|
elem::Infos,
|
||||||
keys::{PublicKey, SecretDistribution, SecretKeyDft},
|
keys::{PublicKey, SecretDistribution, SecretKeyDft},
|
||||||
|
utils::derive_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn encrypt_rlwe_sk_scratch_bytes<B: Backend>(module: &Module<B>, size: usize) -> usize {
|
pub struct RLWECt<C> {
|
||||||
(module.vec_znx_big_normalize_tmp_bytes() | module.bytes_of_vec_znx_dft(1, size)) + module.bytes_of_vec_znx_big(1, size)
|
pub data: VecZnx<C>,
|
||||||
|
pub log_base2k: usize,
|
||||||
|
pub log_k: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RLWECt<Vec<u8>> {
|
||||||
|
pub fn new<B: Backend>(module: &Module<B>, log_base2k: usize, log_k: usize, cols: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
data: module.new_vec_znx(cols, derive_size(log_base2k, log_k)),
|
||||||
|
log_base2k: log_base2k,
|
||||||
|
log_k: log_k,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Infos for RLWECt<T> {
|
||||||
|
type Inner = VecZnx<T>;
|
||||||
|
|
||||||
|
fn inner(&self) -> &Self::Inner {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_base2k(&self) -> usize {
|
||||||
|
self.log_base2k
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_k(&self) -> usize {
|
||||||
|
self.log_k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> VecZnxToMut for RLWECt<C>
|
||||||
|
where
|
||||||
|
VecZnx<C>: VecZnxToMut,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> VecZnx<&mut [u8]> {
|
||||||
|
self.data.to_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> VecZnxToRef for RLWECt<C>
|
||||||
|
where
|
||||||
|
VecZnx<C>: VecZnxToRef,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> VecZnx<&[u8]> {
|
||||||
|
self.data.to_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RLWEPt<C> {
|
||||||
|
pub data: VecZnx<C>,
|
||||||
|
pub log_base2k: usize,
|
||||||
|
pub log_k: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Infos for RLWEPt<T> {
|
||||||
|
type Inner = VecZnx<T>;
|
||||||
|
|
||||||
|
fn inner(&self) -> &Self::Inner {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_base2k(&self) -> usize {
|
||||||
|
self.log_base2k
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_k(&self) -> usize {
|
||||||
|
self.log_k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> VecZnxToMut for RLWEPt<C>
|
||||||
|
where
|
||||||
|
VecZnx<C>: VecZnxToMut,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> VecZnx<&mut [u8]> {
|
||||||
|
self.data.to_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C> VecZnxToRef for RLWEPt<C>
|
||||||
|
where
|
||||||
|
VecZnx<C>: VecZnxToRef,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> VecZnx<&[u8]> {
|
||||||
|
self.data.to_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RLWEPt<Vec<u8>> {
|
||||||
|
pub fn new<B: Backend>(module: &Module<B>, log_base2k: usize, log_k: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
data: module.new_vec_znx(1, derive_size(log_base2k, log_k)),
|
||||||
|
log_base2k: log_base2k,
|
||||||
|
log_k: log_k,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RLWECtDft<C, B: Backend> {
|
||||||
|
pub data: VecZnxDft<C, B>,
|
||||||
|
pub log_base2k: usize,
|
||||||
|
pub log_k: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> RLWECtDft<Vec<u8>, B> {
|
||||||
|
pub fn new(module: &Module<B>, log_base2k: usize, log_k: usize, cols: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
data: module.new_vec_znx_dft(cols, derive_size(log_base2k, log_k)),
|
||||||
|
log_base2k: log_base2k,
|
||||||
|
log_k: log_k,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, B: Backend> Infos for RLWECtDft<T, B> {
|
||||||
|
type Inner = VecZnxDft<T, B>;
|
||||||
|
|
||||||
|
fn inner(&self) -> &Self::Inner {
|
||||||
|
&self.data
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_base2k(&self) -> usize {
|
||||||
|
self.log_base2k
|
||||||
|
}
|
||||||
|
|
||||||
|
fn log_k(&self) -> usize {
|
||||||
|
self.log_k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, B: Backend> VecZnxDftToMut<B> for RLWECtDft<C, B>
|
||||||
|
where
|
||||||
|
VecZnxDft<C, B>: VecZnxDftToMut<B>,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> VecZnxDft<&mut [u8], B> {
|
||||||
|
self.data.to_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, B: Backend> VecZnxDftToRef<B> for RLWECtDft<C, B>
|
||||||
|
where
|
||||||
|
VecZnxDft<C, B>: VecZnxDftToRef<B>,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> VecZnxDft<&[u8], B> {
|
||||||
|
self.data.to_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RLWECt<Vec<u8>> {
|
||||||
|
pub fn encrypt_sk_scratch_bytes<B: Backend>(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encrypt_pk_scratch_bytes<B: Backend>(module: &Module<B>, pk_size: usize) -> usize {
|
||||||
|
((module.bytes_of_vec_znx_dft(1, pk_size) + module.bytes_of_vec_znx_big(1, pk_size)) | module.bytes_of_scalar_znx(1))
|
||||||
|
+ module.bytes_of_scalar_znx_dft(1)
|
||||||
|
+ module.vec_znx_big_normalize_tmp_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decrypt_scratch_bytes<B: Backend>(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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt_rlwe_sk<C, P, S>(
|
pub fn encrypt_rlwe_sk<C, P, S>(
|
||||||
@@ -94,11 +254,7 @@ pub fn decrypt_rlwe<P, C, S>(
|
|||||||
module.vec_znx_big_normalize(ct.log_base2k(), pt, 0, &mut c0_big, 0, scratch_1);
|
module.vec_znx_big_normalize(ct.log_base2k(), pt, 0, &mut c0_big, 0, scratch_1);
|
||||||
|
|
||||||
pt.log_base2k = ct.log_base2k();
|
pt.log_base2k = ct.log_base2k();
|
||||||
pt.log_k = min(pt.log_k(), ct.log_k());
|
pt.log_k = pt.log_k().min(ct.log_k());
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decrypt_rlwe_scratch_bytes<B: Backend>(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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> RLWECt<C> {
|
impl<C> RLWECt<C> {
|
||||||
@@ -207,11 +363,20 @@ pub(crate) fn encrypt_zero_rlwe_dft_sk<C, S>(
|
|||||||
module.vec_znx_dft(ct, 0, &tmp_znx, 0);
|
module.vec_znx_dft(ct, 0, &tmp_znx, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn encrypt_zero_rlwe_dft_scratch_bytes(module: &Module<FFT64>, size: usize) -> usize {
|
impl RLWECtDft<Vec<u8>, FFT64> {
|
||||||
(module.bytes_of_vec_znx(1, size) | module.bytes_of_vec_znx_dft(1, size))
|
pub fn encrypt_zero_sk_scratch_bytes(module: &Module<FFT64>, size: usize) -> usize {
|
||||||
+ module.bytes_of_vec_znx_big(1, size)
|
(module.bytes_of_vec_znx(1, size) | module.bytes_of_vec_znx_dft(1, size))
|
||||||
+ module.bytes_of_vec_znx(1, size)
|
+ module.bytes_of_vec_znx_big(1, size)
|
||||||
+ module.vec_znx_big_normalize_tmp_bytes()
|
+ module.bytes_of_vec_znx(1, size)
|
||||||
|
+ module.vec_znx_big_normalize_tmp_bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decrypt_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) + module.vec_znx_idft_tmp_bytes()))
|
||||||
|
+ module.bytes_of_vec_znx_big(1, size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decrypt_rlwe_dft<P, C, S>(
|
pub fn decrypt_rlwe_dft<P, C, S>(
|
||||||
@@ -246,14 +411,7 @@ pub fn decrypt_rlwe_dft<P, C, S>(
|
|||||||
module.vec_znx_big_normalize(ct.log_base2k(), pt, 0, &mut c0_big, 0, scratch_1);
|
module.vec_znx_big_normalize(ct.log_base2k(), pt, 0, &mut c0_big, 0, scratch_1);
|
||||||
|
|
||||||
pt.log_base2k = ct.log_base2k();
|
pt.log_base2k = ct.log_base2k();
|
||||||
pt.log_k = min(pt.log_k(), ct.log_k());
|
pt.log_k = pt.log_k().min(ct.log_k());
|
||||||
}
|
|
||||||
|
|
||||||
pub fn decrypt_rlwe_dft_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) + module.vec_znx_idft_tmp_bytes()))
|
|
||||||
+ module.bytes_of_vec_znx_big(1, size)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> RLWECtDft<C, FFT64> {
|
impl<C> RLWECtDft<C, FFT64> {
|
||||||
@@ -290,12 +448,6 @@ impl<C> RLWECtDft<C, FFT64> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt_rlwe_pk_scratch_bytes<B: Backend>(module: &Module<B>, pk_size: usize) -> usize {
|
|
||||||
((module.bytes_of_vec_znx_dft(1, pk_size) + module.bytes_of_vec_znx_big(1, pk_size)) | module.bytes_of_scalar_znx(1))
|
|
||||||
+ module.bytes_of_scalar_znx_dft(1)
|
|
||||||
+ module.vec_znx_big_normalize_tmp_bytes()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn encrypt_rlwe_pk<C, P, S>(
|
pub(crate) fn encrypt_rlwe_pk<C, P, S>(
|
||||||
module: &Module<FFT64>,
|
module: &Module<FFT64>,
|
||||||
ct: &mut RLWECt<C>,
|
ct: &mut RLWECt<C>,
|
||||||
@@ -369,13 +521,10 @@ mod tests {
|
|||||||
use sampling::source::Source;
|
use sampling::source::Source;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
elem::{Infos, RLWECt, RLWECtDft, RLWEPt},
|
elem_rlwe::{Infos, RLWECt, RLWECtDft, RLWEPt},
|
||||||
encryption::{decrypt_rlwe_dft_scratch_bytes, encrypt_zero_rlwe_dft_scratch_bytes},
|
|
||||||
keys::{PublicKey, SecretKey, SecretKeyDft},
|
keys::{PublicKey, SecretKey, SecretKeyDft},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{decrypt_rlwe_scratch_bytes, encrypt_rlwe_pk_scratch_bytes, encrypt_rlwe_sk_scratch_bytes};
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encrypt_sk_vec_znx_fft64() {
|
fn encrypt_sk_vec_znx_fft64() {
|
||||||
let module: Module<FFT64> = Module::<FFT64>::new(32);
|
let module: Module<FFT64> = Module::<FFT64>::new(32);
|
||||||
@@ -393,8 +542,9 @@ mod tests {
|
|||||||
let mut source_xe: Source = Source::new([0u8; 32]);
|
let mut source_xe: Source = Source::new([0u8; 32]);
|
||||||
let mut source_xa: Source = Source::new([0u8; 32]);
|
let mut source_xa: Source = Source::new([0u8; 32]);
|
||||||
|
|
||||||
let mut scratch: ScratchOwned =
|
let mut scratch: ScratchOwned = ScratchOwned::new(
|
||||||
ScratchOwned::new(encrypt_rlwe_sk_scratch_bytes(&module, ct.size()) | decrypt_rlwe_scratch_bytes(&module, ct.size()));
|
RLWECt::encrypt_sk_scratch_bytes(&module, ct.size()) | RLWECt::decrypt_scratch_bytes(&module, ct.size()),
|
||||||
|
);
|
||||||
|
|
||||||
let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module);
|
let mut sk: SecretKey<Vec<u8>> = SecretKey::new(&module);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
@@ -469,9 +619,8 @@ mod tests {
|
|||||||
let mut ct_dft: RLWECtDft<Vec<u8>, FFT64> = RLWECtDft::new(&module, log_base2k, log_k_ct, 2);
|
let mut ct_dft: RLWECtDft<Vec<u8>, FFT64> = RLWECtDft::new(&module, log_base2k, log_k_ct, 2);
|
||||||
|
|
||||||
let mut scratch: ScratchOwned = ScratchOwned::new(
|
let mut scratch: ScratchOwned = ScratchOwned::new(
|
||||||
encrypt_rlwe_sk_scratch_bytes(&module, ct_dft.size())
|
RLWECtDft::decrypt_scratch_bytes(&module, ct_dft.size())
|
||||||
| decrypt_rlwe_dft_scratch_bytes(&module, ct_dft.size())
|
| RLWECtDft::encrypt_zero_sk_scratch_bytes(&module, ct_dft.size()),
|
||||||
| encrypt_zero_rlwe_dft_scratch_bytes(&module, ct_dft.size()),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ct_dft.encrypt_zero_sk(
|
ct_dft.encrypt_zero_sk(
|
||||||
@@ -523,9 +672,9 @@ mod tests {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut scratch: ScratchOwned = ScratchOwned::new(
|
let mut scratch: ScratchOwned = ScratchOwned::new(
|
||||||
encrypt_rlwe_sk_scratch_bytes(&module, ct.size())
|
RLWECt::encrypt_sk_scratch_bytes(&module, ct.size())
|
||||||
| decrypt_rlwe_scratch_bytes(&module, ct.size())
|
| RLWECt::decrypt_scratch_bytes(&module, ct.size())
|
||||||
| encrypt_rlwe_pk_scratch_bytes(&module, pk.size()),
|
| RLWECt::encrypt_pk_scratch_bytes(&module, pk.size()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut data_want: Vec<i64> = vec![0i64; module.n()];
|
let mut data_want: Vec<i64> = vec![0i64; module.n()];
|
||||||
@@ -4,10 +4,7 @@ use base2k::{
|
|||||||
};
|
};
|
||||||
use sampling::source::Source;
|
use sampling::source::Source;
|
||||||
|
|
||||||
use crate::{
|
use crate::{elem::Infos, elem_rlwe::RLWECtDft};
|
||||||
elem::{Infos, RLWECtDft},
|
|
||||||
encryption::encrypt_zero_rlwe_dft_scratch_bytes,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum SecretDistribution {
|
pub enum SecretDistribution {
|
||||||
@@ -182,7 +179,10 @@ impl<C> PublicKey<C, FFT64> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Its ok to allocate scratch space here since pk is usually generated only once.
|
// Its ok to allocate scratch space here since pk is usually generated only once.
|
||||||
let mut scratch: ScratchOwned = ScratchOwned::new(encrypt_zero_rlwe_dft_scratch_bytes(module, self.size()));
|
let mut scratch: ScratchOwned = ScratchOwned::new(RLWECtDft::encrypt_zero_sk_scratch_bytes(
|
||||||
|
module,
|
||||||
|
self.size(),
|
||||||
|
));
|
||||||
self.data.encrypt_zero_sk(
|
self.data.encrypt_zero_sk(
|
||||||
module,
|
module,
|
||||||
sk_dft,
|
sk_dft,
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
pub mod elem;
|
pub mod elem;
|
||||||
pub mod encryption;
|
pub mod elem_grlwe;
|
||||||
|
pub mod elem_rgsw;
|
||||||
|
pub mod elem_rlwe;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
|
mod utils;
|
||||||
|
|||||||
3
rlwe/src/utils.rs
Normal file
3
rlwe/src/utils.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub(crate) fn derive_size(log_base2k: usize, log_k: usize) -> usize {
|
||||||
|
(log_k + log_base2k - 1) / log_base2k
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user