mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 05:06:44 +01:00
wip
This commit is contained in:
@@ -69,7 +69,7 @@ where
|
|||||||
B: ScratchFromBytesImpl<B>,
|
B: ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_scalar_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Scratch<B>) {
|
fn take_scalar_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, ScalarZnx::alloc_bytes(n, cols));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, ScalarZnx::bytes_of(n, cols));
|
||||||
(
|
(
|
||||||
ScalarZnx::from_data(take_slice, n, cols),
|
ScalarZnx::from_data(take_slice, n, cols),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -82,7 +82,7 @@ where
|
|||||||
B: SvpPPolAllocBytesImpl<B> + ScratchFromBytesImpl<B>,
|
B: SvpPPolAllocBytesImpl<B> + ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_svp_ppol_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Scratch<B>) {
|
fn take_svp_ppol_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, B::svp_ppol_alloc_bytes_impl(n, cols));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, B::svp_ppol_bytes_of_impl(n, cols));
|
||||||
(
|
(
|
||||||
SvpPPol::from_data(take_slice, n, cols),
|
SvpPPol::from_data(take_slice, n, cols),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -95,7 +95,7 @@ where
|
|||||||
B: ScratchFromBytesImpl<B>,
|
B: ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_vec_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Scratch<B>) {
|
fn take_vec_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, VecZnx::alloc_bytes(n, cols, size));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, VecZnx::bytes_of(n, cols, size));
|
||||||
(
|
(
|
||||||
VecZnx::from_data(take_slice, n, cols, size),
|
VecZnx::from_data(take_slice, n, cols, size),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -115,7 +115,7 @@ where
|
|||||||
) -> (VecZnxBig<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VecZnxBig<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vec_znx_big_alloc_bytes_impl(n, cols, size),
|
B::vec_znx_big_bytes_of_impl(n, cols, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
VecZnxBig::from_data(take_slice, n, cols, size),
|
VecZnxBig::from_data(take_slice, n, cols, size),
|
||||||
@@ -136,7 +136,7 @@ where
|
|||||||
) -> (VecZnxDft<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VecZnxDft<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vec_znx_dft_alloc_bytes_impl(n, cols, size),
|
B::vec_znx_dft_bytes_of_impl(n, cols, size),
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
@@ -204,7 +204,7 @@ where
|
|||||||
) -> (VmpPMat<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VmpPMat<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vmp_pmat_alloc_bytes_impl(n, rows, cols_in, cols_out, size),
|
B::vmp_pmat_bytes_of_impl(n, rows, cols_in, cols_out, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
VmpPMat::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
VmpPMat::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
||||||
@@ -227,7 +227,7 @@ where
|
|||||||
) -> (MatZnx<&mut [u8]>, &mut Scratch<B>) {
|
) -> (MatZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
MatZnx::alloc_bytes(n, rows, cols_in, cols_out, size),
|
MatZnx::bytes_of(n, rows, cols_in, cols_out, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
MatZnx::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
MatZnx::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ unsafe impl SvpPPolAllocImpl<Self> for FFT64Avx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl SvpPPolAllocBytesImpl<Self> for FFT64Avx {
|
unsafe impl SvpPPolAllocBytesImpl<Self> for FFT64Avx {
|
||||||
fn svp_ppol_alloc_bytes_impl(n: usize, cols: usize) -> usize {
|
fn svp_ppol_bytes_of_impl(n: usize, cols: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * cols * size_of::<f64>()
|
Self::layout_prep_word_count() * n * cols * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsafe impl VecZnxBigAllocBytesImpl<Self> for FFT64Avx {
|
unsafe impl VecZnxBigAllocBytesImpl<Self> for FFT64Avx {
|
||||||
fn vec_znx_big_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_big_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
Self::layout_big_word_count() * n * cols * size * size_of::<f64>()
|
Self::layout_big_word_count() * n * cols * size * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ unsafe impl VecZnxDftFromBytesImpl<Self> for FFT64Avx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64Avx {
|
unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64Avx {
|
||||||
fn vec_znx_dft_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_dft_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Avx as Backend>::ScalarPrep>()
|
Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Avx as Backend>::ScalarPrep>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use poulpy_hal::{
|
|||||||
use crate::cpu_fft64_avx::{FFT64Avx, module::FFT64ModuleHandle};
|
use crate::cpu_fft64_avx::{FFT64Avx, module::FFT64ModuleHandle};
|
||||||
|
|
||||||
unsafe impl VmpPMatAllocBytesImpl<Self> for FFT64Avx {
|
unsafe impl VmpPMatAllocBytesImpl<Self> for FFT64Avx {
|
||||||
fn vmp_pmat_alloc_bytes_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
|
fn vmp_pmat_bytes_of_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
|
Self::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ where
|
|||||||
B: ScratchFromBytesImpl<B>,
|
B: ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_scalar_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Scratch<B>) {
|
fn take_scalar_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, ScalarZnx::alloc_bytes(n, cols));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, ScalarZnx::bytes_of(n, cols));
|
||||||
(
|
(
|
||||||
ScalarZnx::from_data(take_slice, n, cols),
|
ScalarZnx::from_data(take_slice, n, cols),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -82,7 +82,7 @@ where
|
|||||||
B: SvpPPolAllocBytesImpl<B> + ScratchFromBytesImpl<B>,
|
B: SvpPPolAllocBytesImpl<B> + ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_svp_ppol_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Scratch<B>) {
|
fn take_svp_ppol_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, B::svp_ppol_alloc_bytes_impl(n, cols));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, B::svp_ppol_bytes_of_impl(n, cols));
|
||||||
(
|
(
|
||||||
SvpPPol::from_data(take_slice, n, cols),
|
SvpPPol::from_data(take_slice, n, cols),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -95,7 +95,7 @@ where
|
|||||||
B: ScratchFromBytesImpl<B>,
|
B: ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_vec_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Scratch<B>) {
|
fn take_vec_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, VecZnx::alloc_bytes(n, cols, size));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, VecZnx::bytes_of(n, cols, size));
|
||||||
(
|
(
|
||||||
VecZnx::from_data(take_slice, n, cols, size),
|
VecZnx::from_data(take_slice, n, cols, size),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -115,7 +115,7 @@ where
|
|||||||
) -> (VecZnxBig<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VecZnxBig<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vec_znx_big_alloc_bytes_impl(n, cols, size),
|
B::vec_znx_big_bytes_of_impl(n, cols, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
VecZnxBig::from_data(take_slice, n, cols, size),
|
VecZnxBig::from_data(take_slice, n, cols, size),
|
||||||
@@ -136,7 +136,7 @@ where
|
|||||||
) -> (VecZnxDft<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VecZnxDft<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vec_znx_dft_alloc_bytes_impl(n, cols, size),
|
B::vec_znx_dft_bytes_of_impl(n, cols, size),
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
@@ -204,7 +204,7 @@ where
|
|||||||
) -> (VmpPMat<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VmpPMat<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vmp_pmat_alloc_bytes_impl(n, rows, cols_in, cols_out, size),
|
B::vmp_pmat_bytes_of_impl(n, rows, cols_in, cols_out, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
VmpPMat::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
VmpPMat::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
||||||
@@ -227,7 +227,7 @@ where
|
|||||||
) -> (MatZnx<&mut [u8]>, &mut Scratch<B>) {
|
) -> (MatZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
MatZnx::alloc_bytes(n, rows, cols_in, cols_out, size),
|
MatZnx::bytes_of(n, rows, cols_in, cols_out, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
MatZnx::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
MatZnx::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ unsafe impl SvpPPolAllocImpl<Self> for FFT64Ref {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl SvpPPolAllocBytesImpl<Self> for FFT64Ref {
|
unsafe impl SvpPPolAllocBytesImpl<Self> for FFT64Ref {
|
||||||
fn svp_ppol_alloc_bytes_impl(n: usize, cols: usize) -> usize {
|
fn svp_ppol_bytes_of_impl(n: usize, cols: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * cols * size_of::<f64>()
|
Self::layout_prep_word_count() * n * cols * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsafe impl VecZnxBigAllocBytesImpl<Self> for FFT64Ref {
|
unsafe impl VecZnxBigAllocBytesImpl<Self> for FFT64Ref {
|
||||||
fn vec_znx_big_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_big_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
Self::layout_big_word_count() * n * cols * size * size_of::<f64>()
|
Self::layout_big_word_count() * n * cols * size * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ unsafe impl VecZnxDftFromBytesImpl<Self> for FFT64Ref {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64Ref {
|
unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64Ref {
|
||||||
fn vec_znx_dft_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_dft_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Ref as Backend>::ScalarPrep>()
|
Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Ref as Backend>::ScalarPrep>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use poulpy_hal::{
|
|||||||
use crate::cpu_fft64_ref::{FFT64Ref, module::FFT64ModuleHandle};
|
use crate::cpu_fft64_ref::{FFT64Ref, module::FFT64ModuleHandle};
|
||||||
|
|
||||||
unsafe impl VmpPMatAllocBytesImpl<Self> for FFT64Ref {
|
unsafe impl VmpPMatAllocBytesImpl<Self> for FFT64Ref {
|
||||||
fn vmp_pmat_alloc_bytes_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
|
fn vmp_pmat_bytes_of_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
|
Self::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ where
|
|||||||
B: ScratchFromBytesImpl<B>,
|
B: ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_scalar_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Scratch<B>) {
|
fn take_scalar_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (ScalarZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, ScalarZnx::alloc_bytes(n, cols));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, ScalarZnx::bytes_of(n, cols));
|
||||||
(
|
(
|
||||||
ScalarZnx::from_data(take_slice, n, cols),
|
ScalarZnx::from_data(take_slice, n, cols),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -82,7 +82,7 @@ where
|
|||||||
B: SvpPPolAllocBytesImpl<B> + ScratchFromBytesImpl<B>,
|
B: SvpPPolAllocBytesImpl<B> + ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_svp_ppol_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Scratch<B>) {
|
fn take_svp_ppol_impl(scratch: &mut Scratch<B>, n: usize, cols: usize) -> (SvpPPol<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, B::svp_ppol_alloc_bytes_impl(n, cols));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, B::svp_ppol_bytes_of_impl(n, cols));
|
||||||
(
|
(
|
||||||
SvpPPol::from_data(take_slice, n, cols),
|
SvpPPol::from_data(take_slice, n, cols),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -95,7 +95,7 @@ where
|
|||||||
B: ScratchFromBytesImpl<B>,
|
B: ScratchFromBytesImpl<B>,
|
||||||
{
|
{
|
||||||
fn take_vec_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Scratch<B>) {
|
fn take_vec_znx_impl(scratch: &mut Scratch<B>, n: usize, cols: usize, size: usize) -> (VecZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, VecZnx::alloc_bytes(n, cols, size));
|
let (take_slice, rem_slice) = take_slice_aligned(&mut scratch.data, VecZnx::bytes_of(n, cols, size));
|
||||||
(
|
(
|
||||||
VecZnx::from_data(take_slice, n, cols, size),
|
VecZnx::from_data(take_slice, n, cols, size),
|
||||||
Scratch::from_bytes(rem_slice),
|
Scratch::from_bytes(rem_slice),
|
||||||
@@ -115,7 +115,7 @@ where
|
|||||||
) -> (VecZnxBig<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VecZnxBig<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vec_znx_big_alloc_bytes_impl(n, cols, size),
|
B::vec_znx_big_bytes_of_impl(n, cols, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
VecZnxBig::from_data(take_slice, n, cols, size),
|
VecZnxBig::from_data(take_slice, n, cols, size),
|
||||||
@@ -136,7 +136,7 @@ where
|
|||||||
) -> (VecZnxDft<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VecZnxDft<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vec_znx_dft_alloc_bytes_impl(n, cols, size),
|
B::vec_znx_dft_bytes_of_impl(n, cols, size),
|
||||||
);
|
);
|
||||||
|
|
||||||
(
|
(
|
||||||
@@ -204,7 +204,7 @@ where
|
|||||||
) -> (VmpPMat<&mut [u8], B>, &mut Scratch<B>) {
|
) -> (VmpPMat<&mut [u8], B>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
B::vmp_pmat_alloc_bytes_impl(n, rows, cols_in, cols_out, size),
|
B::vmp_pmat_bytes_of_impl(n, rows, cols_in, cols_out, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
VmpPMat::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
VmpPMat::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
||||||
@@ -227,7 +227,7 @@ where
|
|||||||
) -> (MatZnx<&mut [u8]>, &mut Scratch<B>) {
|
) -> (MatZnx<&mut [u8]>, &mut Scratch<B>) {
|
||||||
let (take_slice, rem_slice) = take_slice_aligned(
|
let (take_slice, rem_slice) = take_slice_aligned(
|
||||||
&mut scratch.data,
|
&mut scratch.data,
|
||||||
MatZnx::alloc_bytes(n, rows, cols_in, cols_out, size),
|
MatZnx::bytes_of(n, rows, cols_in, cols_out, size),
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
MatZnx::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
MatZnx::from_data(take_slice, n, rows, cols_in, cols_out, size),
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ unsafe impl SvpPPolAllocImpl<Self> for FFT64Spqlios {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl SvpPPolAllocBytesImpl<Self> for FFT64Spqlios {
|
unsafe impl SvpPPolAllocBytesImpl<Self> for FFT64Spqlios {
|
||||||
fn svp_ppol_alloc_bytes_impl(n: usize, cols: usize) -> usize {
|
fn svp_ppol_bytes_of_impl(n: usize, cols: usize) -> usize {
|
||||||
FFT64Spqlios::layout_prep_word_count() * n * cols * size_of::<f64>()
|
FFT64Spqlios::layout_prep_word_count() * n * cols * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsafe impl VecZnxBigAllocBytesImpl<Self> for FFT64Spqlios {
|
unsafe impl VecZnxBigAllocBytesImpl<Self> for FFT64Spqlios {
|
||||||
fn vec_znx_big_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_big_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
Self::layout_big_word_count() * n * cols * size * size_of::<f64>()
|
Self::layout_big_word_count() * n * cols * size * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ unsafe impl VecZnxDftFromBytesImpl<Self> for FFT64Spqlios {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64Spqlios {
|
unsafe impl VecZnxDftAllocBytesImpl<Self> for FFT64Spqlios {
|
||||||
fn vec_znx_dft_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_dft_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Spqlios as Backend>::ScalarPrep>()
|
Self::layout_prep_word_count() * n * cols * size * size_of::<<FFT64Spqlios as Backend>::ScalarPrep>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use crate::cpu_spqlios::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsafe impl VmpPMatAllocBytesImpl<Self> for FFT64Spqlios {
|
unsafe impl VmpPMatAllocBytesImpl<Self> for FFT64Spqlios {
|
||||||
fn vmp_pmat_alloc_bytes_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
|
fn vmp_pmat_bytes_of_impl(n: usize, rows: usize, cols_in: usize, cols_out: usize, size: usize) -> usize {
|
||||||
Self::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
|
Self::layout_prep_word_count() * n * rows * cols_in * cols_out * size * size_of::<f64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ unsafe impl SvpPPolAllocImpl<Self> for NTT120 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl SvpPPolAllocBytesImpl<Self> for NTT120 {
|
unsafe impl SvpPPolAllocBytesImpl<Self> for NTT120 {
|
||||||
fn svp_ppol_alloc_bytes_impl(n: usize, cols: usize) -> usize {
|
fn svp_ppol_bytes_of_impl(n: usize, cols: usize) -> usize {
|
||||||
NTT120::layout_prep_word_count() * n * cols * size_of::<i64>()
|
NTT120::layout_prep_word_count() * n * cols * size_of::<i64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use poulpy_hal::{layouts::Backend, oep::VecZnxBigAllocBytesImpl};
|
|||||||
use crate::cpu_spqlios::NTT120;
|
use crate::cpu_spqlios::NTT120;
|
||||||
|
|
||||||
unsafe impl VecZnxBigAllocBytesImpl<NTT120> for NTT120 {
|
unsafe impl VecZnxBigAllocBytesImpl<NTT120> for NTT120 {
|
||||||
fn vec_znx_big_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_big_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
NTT120::layout_big_word_count() * n * cols * size * size_of::<i128>()
|
NTT120::layout_big_word_count() * n * cols * size * size_of::<i128>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use poulpy_hal::{
|
|||||||
use crate::cpu_spqlios::NTT120;
|
use crate::cpu_spqlios::NTT120;
|
||||||
|
|
||||||
unsafe impl VecZnxDftAllocBytesImpl<NTT120> for NTT120 {
|
unsafe impl VecZnxDftAllocBytesImpl<NTT120> for NTT120 {
|
||||||
fn vec_znx_dft_alloc_bytes_impl(n: usize, cols: usize, size: usize) -> usize {
|
fn vec_znx_dft_bytes_of_impl(n: usize, cols: usize, size: usize) -> usize {
|
||||||
NTT120::layout_prep_word_count() * n * cols * size * size_of::<i64>()
|
NTT120::layout_prep_word_count() * n * cols * size * size_of::<i64>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use poulpy_core::layouts::{
|
use poulpy_core::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGSW, GGSWCiphertextLayout, GLWECiphertext, GLWECiphertextLayout, GLWESecret, Rank,
|
Base2K, Degree, Dnum, Dsize, GGSW, GGSWCiphertextLayout, GLWE, GLWELayout, GLWESecret, Rank, TorusPrecision,
|
||||||
TorusPrecision,
|
|
||||||
prepared::{GGSWPrepared, GLWESecretPrepared, PrepareAlloc},
|
prepared::{GGSWPrepared, GLWESecretPrepared, PrepareAlloc},
|
||||||
};
|
};
|
||||||
use std::hint::black_box;
|
use std::hint::black_box;
|
||||||
@@ -48,36 +47,36 @@ fn bench_external_product_glwe_fft64(c: &mut Criterion) {
|
|||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_out_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_out_layout: GLWELayout = GLWELayout {
|
||||||
n,
|
n,
|
||||||
base2k,
|
base2k,
|
||||||
k: k_ct_out,
|
k: k_ct_out,
|
||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_in_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_in_layout: GLWELayout = GLWELayout {
|
||||||
n,
|
n,
|
||||||
base2k,
|
base2k,
|
||||||
k: k_ct_in,
|
k: k_ct_in,
|
||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ct_ggsw: GGSW<Vec<u8>> = GGSW::alloc(&ggsw_layout);
|
let mut ct_ggsw: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_layout);
|
||||||
let mut ct_glwe_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_in_layout);
|
let mut ct_glwe_in: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_in_layout);
|
||||||
let mut ct_glwe_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_out_layout);
|
let mut ct_glwe_out: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_out_layout);
|
||||||
let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n.into(), 1);
|
let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n.into(), 1);
|
||||||
|
|
||||||
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
||||||
GGSW::encrypt_sk_scratch_space(&module, &ggsw_layout)
|
GGSW::encrypt_sk_scratch_space(&module, &ggsw_layout)
|
||||||
| GLWECiphertext::encrypt_sk_scratch_space(&module, &glwe_in_layout)
|
| GLWE::encrypt_sk_scratch_space(&module, &glwe_in_layout)
|
||||||
| GLWECiphertext::external_product_scratch_space(&module, &glwe_out_layout, &glwe_in_layout, &ggsw_layout),
|
| GLWE::external_product_scratch_space(&module, &glwe_out_layout, &glwe_in_layout, &ggsw_layout),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut source_xs = Source::new([0u8; 32]);
|
let mut source_xs = Source::new([0u8; 32]);
|
||||||
let mut source_xe = Source::new([0u8; 32]);
|
let mut source_xe = Source::new([0u8; 32]);
|
||||||
let mut source_xa = Source::new([0u8; 32]);
|
let mut source_xa = Source::new([0u8; 32]);
|
||||||
|
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_in_layout);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_in_layout);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
let sk_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk.prepare_alloc(&module, scratch.borrow());
|
let sk_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk.prepare_alloc(&module, scratch.borrow());
|
||||||
|
|
||||||
@@ -156,28 +155,28 @@ fn bench_external_product_glwe_inplace_fft64(c: &mut Criterion) {
|
|||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_layout: GLWELayout = GLWELayout {
|
||||||
n,
|
n,
|
||||||
base2k,
|
base2k,
|
||||||
k: k_glwe,
|
k: k_glwe,
|
||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ct_ggsw: GGSW<Vec<u8>> = GGSW::alloc(&ggsw_layout);
|
let mut ct_ggsw: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_layout);
|
||||||
let mut ct_glwe: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_layout);
|
let mut ct_glwe: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_layout);
|
||||||
let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n.into(), 1);
|
let pt_rgsw: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n.into(), 1);
|
||||||
|
|
||||||
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
||||||
GGSW::encrypt_sk_scratch_space(&module, &ggsw_layout)
|
GGSW::encrypt_sk_scratch_space(&module, &ggsw_layout)
|
||||||
| GLWECiphertext::encrypt_sk_scratch_space(&module, &glwe_layout)
|
| GLWE::encrypt_sk_scratch_space(&module, &glwe_layout)
|
||||||
| GLWECiphertext::external_product_inplace_scratch_space(&module, &glwe_layout, &ggsw_layout),
|
| GLWE::external_product_inplace_scratch_space(&module, &glwe_layout, &ggsw_layout),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
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 sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_layout);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_layout);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
let sk_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk.prepare_alloc(&module, scratch.borrow());
|
let sk_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk.prepare_alloc(&module, scratch.borrow());
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use poulpy_core::layouts::{
|
use poulpy_core::layouts::{
|
||||||
AutomorphismKey, AutomorphismKeyLayout, Base2K, Degree, Dnum, Dsize, GLWECiphertext, GLWECiphertextLayout, GLWESecret,
|
AutomorphismKey, AutomorphismKeyLayout, Base2K, Degree, Dnum, Dsize, GLWE, GLWELayout, GLWESecret, GLWESwitchingKey,
|
||||||
GLWESwitchingKey, GLWESwitchingKeyLayout, Rank, TorusPrecision,
|
GLWESwitchingKeyLayout, Rank, TorusPrecision,
|
||||||
prepared::{AutomorphismKeyPrepared, GLWESecretPrepared, GLWESwitchingKeyPrepared, PrepareAlloc},
|
prepared::{AutomorphismKeyPrepared, GLWESecretPrepared, GLWESwitchingKeyPrepared, PrepareAlloc},
|
||||||
};
|
};
|
||||||
use std::{hint::black_box, time::Duration};
|
use std::{hint::black_box, time::Duration};
|
||||||
@@ -48,28 +48,28 @@ fn bench_keyswitch_glwe_fft64(c: &mut Criterion) {
|
|||||||
dsize,
|
dsize,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_in_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_in_layout: GLWELayout = GLWELayout {
|
||||||
n,
|
n,
|
||||||
base2k,
|
base2k,
|
||||||
k: k_glwe_in,
|
k: k_glwe_in,
|
||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_out_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_out_layout: GLWELayout = GLWELayout {
|
||||||
n,
|
n,
|
||||||
base2k,
|
base2k,
|
||||||
k: k_glwe_out,
|
k: k_glwe_out,
|
||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ksk: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&gglwe_atk_layout);
|
let mut ksk: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&gglwe_atk_layout);
|
||||||
let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_in_layout);
|
let mut ct_in: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_in_layout);
|
||||||
let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_out_layout);
|
let mut ct_out: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_out_layout);
|
||||||
|
|
||||||
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
||||||
GLWESwitchingKey::encrypt_sk_scratch_space(&module, &gglwe_atk_layout)
|
GLWESwitchingKey::encrypt_sk_scratch_space(&module, &gglwe_atk_layout)
|
||||||
| GLWECiphertext::encrypt_sk_scratch_space(&module, &glwe_in_layout)
|
| GLWE::encrypt_sk_scratch_space(&module, &glwe_in_layout)
|
||||||
| GLWECiphertext::keyswitch_scratch_space(
|
| GLWE::keyswitch_scratch_space(
|
||||||
&module,
|
&module,
|
||||||
&glwe_out_layout,
|
&glwe_out_layout,
|
||||||
&glwe_in_layout,
|
&glwe_in_layout,
|
||||||
@@ -81,7 +81,7 @@ fn bench_keyswitch_glwe_fft64(c: &mut Criterion) {
|
|||||||
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 sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_in_layout);
|
let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_in_layout);
|
||||||
sk_in.fill_ternary_prob(0.5, &mut source_xs);
|
sk_in.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
let sk_in_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk_in.prepare_alloc(&module, scratch.borrow());
|
let sk_in_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk_in.prepare_alloc(&module, scratch.borrow());
|
||||||
|
|
||||||
@@ -167,31 +167,31 @@ fn bench_keyswitch_glwe_inplace_fft64(c: &mut Criterion) {
|
|||||||
rank_out: rank,
|
rank_out: rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_layout: GLWELayout = GLWELayout {
|
||||||
n,
|
n,
|
||||||
base2k,
|
base2k,
|
||||||
k: k_ct,
|
k: k_ct,
|
||||||
rank,
|
rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ksk: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc(&gglwe_layout);
|
let mut ksk: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc_from_infos(&gglwe_layout);
|
||||||
let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_layout);
|
let mut ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_layout);
|
||||||
|
|
||||||
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
||||||
GLWESwitchingKey::encrypt_sk_scratch_space(&module, &gglwe_layout)
|
GLWESwitchingKey::encrypt_sk_scratch_space(&module, &gglwe_layout)
|
||||||
| GLWECiphertext::encrypt_sk_scratch_space(&module, &glwe_layout)
|
| GLWE::encrypt_sk_scratch_space(&module, &glwe_layout)
|
||||||
| GLWECiphertext::keyswitch_inplace_scratch_space(&module, &glwe_layout, &gglwe_layout),
|
| GLWE::keyswitch_inplace_scratch_space(&module, &glwe_layout, &gglwe_layout),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
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 sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_layout);
|
let mut sk_in: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_layout);
|
||||||
sk_in.fill_ternary_prob(0.5, &mut source_xs);
|
sk_in.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
let sk_in_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk_in.prepare_alloc(&module, scratch.borrow());
|
let sk_in_dft: GLWESecretPrepared<Vec<u8>, FFT64Spqlios> = sk_in.prepare_alloc(&module, scratch.borrow());
|
||||||
|
|
||||||
let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_layout);
|
let mut sk_out: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_layout);
|
||||||
sk_out.fill_ternary_prob(0.5, &mut source_xs);
|
sk_out.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
|
|
||||||
ksk.encrypt_sk(
|
ksk.encrypt_sk(
|
||||||
|
|||||||
@@ -2,8 +2,7 @@ use poulpy_backend::cpu_spqlios::FFT64Spqlios;
|
|||||||
use poulpy_core::{
|
use poulpy_core::{
|
||||||
GLWEOperations, SIGMA,
|
GLWEOperations, SIGMA,
|
||||||
layouts::{
|
layouts::{
|
||||||
Base2K, Degree, GLWECiphertext, GLWECiphertextLayout, GLWEPlaintext, GLWEPlaintextLayout, GLWESecret, LWEInfos, Rank,
|
Base2K, Degree, GLWE, GLWELayout, GLWEPlaintext, GLWEPlaintextLayout, GLWESecret, LWEInfos, Rank, TorusPrecision,
|
||||||
TorusPrecision,
|
|
||||||
prepared::{GLWESecretPrepared, PrepareAlloc},
|
prepared::{GLWESecretPrepared, PrepareAlloc},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -34,7 +33,7 @@ fn main() {
|
|||||||
// Instantiate Module (DFT Tables)
|
// Instantiate Module (DFT Tables)
|
||||||
let module: Module<FFT64Spqlios> = Module::<FFT64Spqlios>::new(n.0 as u64);
|
let module: Module<FFT64Spqlios> = Module::<FFT64Spqlios>::new(n.0 as u64);
|
||||||
|
|
||||||
let glwe_ct_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_ct_infos: GLWELayout = GLWELayout {
|
||||||
n,
|
n,
|
||||||
base2k,
|
base2k,
|
||||||
k: k_ct,
|
k: k_ct,
|
||||||
@@ -44,9 +43,9 @@ fn main() {
|
|||||||
let glwe_pt_infos: GLWEPlaintextLayout = GLWEPlaintextLayout { n, base2k, k: k_pt };
|
let glwe_pt_infos: GLWEPlaintextLayout = GLWEPlaintextLayout { n, base2k, k: k_pt };
|
||||||
|
|
||||||
// Allocates ciphertext & plaintexts
|
// Allocates ciphertext & plaintexts
|
||||||
let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_ct_infos);
|
let mut ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_ct_infos);
|
||||||
let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&glwe_pt_infos);
|
let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_pt_infos);
|
||||||
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&glwe_pt_infos);
|
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_pt_infos);
|
||||||
|
|
||||||
// CPRNG
|
// CPRNG
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
@@ -55,12 +54,11 @@ fn main() {
|
|||||||
|
|
||||||
// Scratch space
|
// Scratch space
|
||||||
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<FFT64Spqlios> = ScratchOwned::alloc(
|
||||||
GLWECiphertext::encrypt_sk_scratch_space(&module, &glwe_ct_infos)
|
GLWE::encrypt_sk_scratch_space(&module, &glwe_ct_infos) | GLWE::decrypt_scratch_space(&module, &glwe_ct_infos),
|
||||||
| GLWECiphertext::decrypt_scratch_space(&module, &glwe_ct_infos),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Generate secret-key
|
// Generate secret-key
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_ct_infos);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_ct_infos);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
|
|
||||||
// Backend-prepared secret
|
// Backend-prepared secret
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero},
|
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{AutomorphismKey, GGLWEInfos, GLWECiphertext, prepared::AutomorphismKeyPrepared};
|
use crate::layouts::{AutomorphismKey, GGLWEInfos, GLWE, prepared::AutomorphismKeyPrepared};
|
||||||
|
|
||||||
impl AutomorphismKey<Vec<u8>> {
|
impl AutomorphismKey<Vec<u8>> {
|
||||||
pub fn automorphism_scratch_space<B: Backend, OUT, IN, KEY>(
|
pub fn automorphism_scratch_space<B: Backend, OUT, IN, KEY>(
|
||||||
@@ -22,7 +22,7 @@ impl AutomorphismKey<Vec<u8>> {
|
|||||||
KEY: GGLWEInfos,
|
KEY: GGLWEInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::keyswitch_scratch_space(
|
GLWE::keyswitch_scratch_space(
|
||||||
module,
|
module,
|
||||||
&out_infos.glwe_layout(),
|
&out_infos.glwe_layout(),
|
||||||
&in_infos.glwe_layout(),
|
&in_infos.glwe_layout(),
|
||||||
@@ -103,8 +103,8 @@ impl<DataSelf: DataMut> AutomorphismKey<DataSelf> {
|
|||||||
|
|
||||||
(0..self.rank_in().into()).for_each(|col_i| {
|
(0..self.rank_in().into()).for_each(|col_i| {
|
||||||
(0..self.dnum().into()).for_each(|row_j| {
|
(0..self.dnum().into()).for_each(|row_j| {
|
||||||
let mut res_ct: GLWECiphertext<&mut [u8]> = self.at_mut(row_j, col_i);
|
let mut res_ct: GLWE<&mut [u8]> = self.at_mut(row_j, col_i);
|
||||||
let lhs_ct: GLWECiphertext<&[u8]> = lhs.at(row_j, col_i);
|
let lhs_ct: GLWE<&[u8]> = lhs.at(row_j, col_i);
|
||||||
|
|
||||||
// Reverts the automorphism X^{-k}: (-pi^{-1}_{k}(s)a + s, a) to (-sa + pi_{k}(s), a)
|
// Reverts the automorphism X^{-k}: (-pi^{-1}_{k}(s)a + s, a) to (-sa + pi_{k}(s), a)
|
||||||
(0..cols_out).for_each(|i| {
|
(0..cols_out).for_each(|i| {
|
||||||
@@ -176,7 +176,7 @@ impl<DataSelf: DataMut> AutomorphismKey<DataSelf> {
|
|||||||
|
|
||||||
(0..self.rank_in().into()).for_each(|col_i| {
|
(0..self.rank_in().into()).for_each(|col_i| {
|
||||||
(0..self.dnum().into()).for_each(|row_j| {
|
(0..self.dnum().into()).for_each(|row_j| {
|
||||||
let mut res_ct: GLWECiphertext<&mut [u8]> = self.at_mut(row_j, col_i);
|
let mut res_ct: GLWE<&mut [u8]> = self.at_mut(row_j, col_i);
|
||||||
|
|
||||||
// Reverts the automorphism X^{-k}: (-pi^{-1}_{k}(s)a + s, a) to (-sa + pi_{k}(s), a)
|
// Reverts the automorphism X^{-k}: (-pi^{-1}_{k}(s)a + s, a) to (-sa + pi_{k}(s), a)
|
||||||
(0..cols_out).for_each(|i| {
|
(0..cols_out).for_each(|i| {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
GGLWEInfos, GGSW, GGSWInfos, GLWECiphertext,
|
GGLWEInfos, GGSW, GGSWInfos, GLWE,
|
||||||
prepared::{AutomorphismKeyPrepared, TensorKeyPrepared},
|
prepared::{AutomorphismKeyPrepared, TensorKeyPrepared},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,8 +33,8 @@ impl GGSW<Vec<u8>> {
|
|||||||
+ VecZnxBigNormalizeTmpBytes,
|
+ VecZnxBigNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
let out_size: usize = out_infos.size();
|
let out_size: usize = out_infos.size();
|
||||||
let ci_dft: usize = module.vec_znx_dft_alloc_bytes((key_infos.rank_out() + 1).into(), out_size);
|
let ci_dft: usize = module.vec_znx_dft_bytes_of((key_infos.rank_out() + 1).into(), out_size);
|
||||||
let ks_internal: usize = GLWECiphertext::keyswitch_scratch_space(
|
let ks_internal: usize = GLWE::keyswitch_scratch_space(
|
||||||
module,
|
module,
|
||||||
&out_infos.glwe_layout(),
|
&out_infos.glwe_layout(),
|
||||||
&in_infos.glwe_layout(),
|
&in_infos.glwe_layout(),
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, DataRef, Module, Scratch, VecZnxBig},
|
layouts::{Backend, DataMut, DataRef, Module, Scratch, VecZnxBig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GGLWEInfos, GLWECiphertext, GLWEInfos, LWEInfos, prepared::AutomorphismKeyPrepared};
|
use crate::layouts::{GGLWEInfos, GLWE, GLWEInfos, LWEInfos, prepared::AutomorphismKeyPrepared};
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
pub fn automorphism_scratch_space<B: Backend, OUT, IN, KEY>(
|
pub fn automorphism_scratch_space<B: Backend, OUT, IN, KEY>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
out_infos: &OUT,
|
out_infos: &OUT,
|
||||||
@@ -36,11 +36,11 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
impl<DataSelf: DataMut> GLWE<DataSelf> {
|
||||||
pub fn automorphism<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
pub fn automorphism<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lhs: &GLWECiphertext<DataLhs>,
|
lhs: &GLWE<DataLhs>,
|
||||||
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -93,7 +93,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
|||||||
pub fn automorphism_add<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
pub fn automorphism_add<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lhs: &GLWECiphertext<DataLhs>,
|
lhs: &GLWE<DataLhs>,
|
||||||
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -176,7 +176,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
|||||||
pub fn automorphism_sub_ab<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
pub fn automorphism_sub_ab<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lhs: &GLWECiphertext<DataLhs>,
|
lhs: &GLWE<DataLhs>,
|
||||||
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -261,7 +261,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
|||||||
pub fn automorphism_sub_negate<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
pub fn automorphism_sub_negate<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lhs: &GLWECiphertext<DataLhs>,
|
lhs: &GLWE<DataLhs>,
|
||||||
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
rhs: &AutomorphismKeyPrepared<DataRhs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
|
|||||||
@@ -9,13 +9,10 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
TakeGLWECt,
|
TakeGLWECt,
|
||||||
layouts::{
|
layouts::{GGLWEInfos, GLWE, GLWEInfos, GLWELayout, LWE, LWEInfos, Rank, prepared::GLWEToLWESwitchingKeyPrepared},
|
||||||
GGLWEInfos, GLWECiphertext, GLWECiphertextLayout, GLWEInfos, LWECiphertext, LWEInfos, Rank,
|
|
||||||
prepared::GLWEToLWESwitchingKeyPrepared,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl LWECiphertext<Vec<u8>> {
|
impl LWE<Vec<u8>> {
|
||||||
pub fn from_glwe_scratch_space<B: Backend, OUT, IN, KEY>(
|
pub fn from_glwe_scratch_space<B: Backend, OUT, IN, KEY>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lwe_infos: &OUT,
|
lwe_infos: &OUT,
|
||||||
@@ -28,24 +25,24 @@ impl LWECiphertext<Vec<u8>> {
|
|||||||
KEY: GGLWEInfos,
|
KEY: GGLWEInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
let glwe_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_layout: GLWELayout = GLWELayout {
|
||||||
n: module.n().into(),
|
n: module.n().into(),
|
||||||
base2k: lwe_infos.base2k(),
|
base2k: lwe_infos.base2k(),
|
||||||
k: lwe_infos.k(),
|
k: lwe_infos.k(),
|
||||||
rank: Rank(1),
|
rank: Rank(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
GLWECiphertext::alloc_bytes_with(
|
GLWE::bytes_of(
|
||||||
module.n().into(),
|
module.n().into(),
|
||||||
lwe_infos.base2k(),
|
lwe_infos.base2k(),
|
||||||
lwe_infos.k(),
|
lwe_infos.k(),
|
||||||
1u32.into(),
|
1u32.into(),
|
||||||
) + GLWECiphertext::keyswitch_scratch_space(module, &glwe_layout, glwe_infos, key_infos)
|
) + GLWE::keyswitch_scratch_space(module, &glwe_layout, glwe_infos, key_infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DLwe: DataMut> LWECiphertext<DLwe> {
|
impl<DLwe: DataMut> LWE<DLwe> {
|
||||||
pub fn sample_extract<DGlwe: DataRef>(&mut self, a: &GLWECiphertext<DGlwe>) {
|
pub fn sample_extract<DGlwe: DataRef>(&mut self, a: &GLWE<DGlwe>) {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
assert!(self.n() <= a.n());
|
assert!(self.n() <= a.n());
|
||||||
@@ -66,7 +63,7 @@ impl<DLwe: DataMut> LWECiphertext<DLwe> {
|
|||||||
pub fn from_glwe<DGlwe, DKs, B: Backend>(
|
pub fn from_glwe<DGlwe, DKs, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
a: &GLWECiphertext<DGlwe>,
|
a: &GLWE<DGlwe>,
|
||||||
ks: &GLWEToLWESwitchingKeyPrepared<DKs, B>,
|
ks: &GLWEToLWESwitchingKeyPrepared<DKs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -92,7 +89,7 @@ impl<DLwe: DataMut> LWECiphertext<DLwe> {
|
|||||||
assert!(self.n() <= module.n() as u32);
|
assert!(self.n() <= module.n() as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
let glwe_layout: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_layout: GLWELayout = GLWELayout {
|
||||||
n: module.n().into(),
|
n: module.n().into(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
|
|||||||
@@ -9,13 +9,10 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
TakeGLWECt,
|
TakeGLWECt,
|
||||||
layouts::{
|
layouts::{GGLWEInfos, GLWE, GLWEInfos, GLWELayout, LWE, LWEInfos, prepared::LWEToGLWESwitchingKeyPrepared},
|
||||||
GGLWEInfos, GLWECiphertext, GLWECiphertextLayout, GLWEInfos, LWECiphertext, LWEInfos,
|
|
||||||
prepared::LWEToGLWESwitchingKeyPrepared,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
pub fn from_lwe_scratch_space<B: Backend, OUT, IN, KEY>(
|
pub fn from_lwe_scratch_space<B: Backend, OUT, IN, KEY>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
glwe_infos: &OUT,
|
glwe_infos: &OUT,
|
||||||
@@ -28,27 +25,27 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
KEY: GGLWEInfos,
|
KEY: GGLWEInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
let ct: usize = GLWECiphertext::alloc_bytes_with(
|
let ct: usize = GLWE::bytes_of(
|
||||||
module.n().into(),
|
module.n().into(),
|
||||||
key_infos.base2k(),
|
key_infos.base2k(),
|
||||||
lwe_infos.k().max(glwe_infos.k()),
|
lwe_infos.k().max(glwe_infos.k()),
|
||||||
1u32.into(),
|
1u32.into(),
|
||||||
);
|
);
|
||||||
let ks: usize = GLWECiphertext::keyswitch_inplace_scratch_space(module, glwe_infos, key_infos);
|
let ks: usize = GLWE::keyswitch_inplace_scratch_space(module, glwe_infos, key_infos);
|
||||||
if lwe_infos.base2k() == key_infos.base2k() {
|
if lwe_infos.base2k() == key_infos.base2k() {
|
||||||
ct + ks
|
ct + ks
|
||||||
} else {
|
} else {
|
||||||
let a_conv = VecZnx::alloc_bytes(module.n(), 1, lwe_infos.size()) + module.vec_znx_normalize_tmp_bytes();
|
let a_conv = VecZnx::bytes_of(module.n(), 1, lwe_infos.size()) + module.vec_znx_normalize_tmp_bytes();
|
||||||
ct + a_conv + ks
|
ct + a_conv + ks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertext<D> {
|
impl<D: DataMut> GLWE<D> {
|
||||||
pub fn from_lwe<DLwe, DKsk, B: Backend>(
|
pub fn from_lwe<DLwe, DKsk, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lwe: &LWECiphertext<DLwe>,
|
lwe: &LWE<DLwe>,
|
||||||
ksk: &LWEToGLWESwitchingKeyPrepared<DKsk, B>,
|
ksk: &LWEToGLWESwitchingKeyPrepared<DKsk, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -74,7 +71,7 @@ impl<D: DataMut> GLWECiphertext<D> {
|
|||||||
assert!(lwe.n() <= module.n() as u32);
|
assert!(lwe.n() <= module.n() as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut glwe, scratch_1) = scratch.take_glwe_ct(&GLWECiphertextLayout {
|
let (mut glwe, scratch_1) = scratch.take_glwe_ct(&GLWELayout {
|
||||||
n: ksk.n(),
|
n: ksk.n(),
|
||||||
base2k: ksk.base2k(),
|
base2k: ksk.base2k(),
|
||||||
k: lwe.k(),
|
k: lwe.k(),
|
||||||
|
|||||||
@@ -6,20 +6,20 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, DataRef, DataViewMut, Module, Scratch},
|
layouts::{Backend, DataMut, DataRef, DataViewMut, Module, Scratch},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GLWECiphertext, GLWEInfos, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
use crate::layouts::{GLWE, GLWEInfos, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
pub fn decrypt_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
pub fn decrypt_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
|
Module<B>: VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
|
||||||
{
|
{
|
||||||
let size: usize = infos.size();
|
let size: usize = infos.size();
|
||||||
(module.vec_znx_normalize_tmp_bytes() | module.vec_znx_dft_alloc_bytes(1, size)) + module.vec_znx_dft_alloc_bytes(1, size)
|
(module.vec_znx_normalize_tmp_bytes() | module.vec_znx_dft_bytes_of(1, size)) + module.vec_znx_dft_bytes_of(1, size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DataSelf: DataRef> GLWECiphertext<DataSelf> {
|
impl<DataSelf: DataRef> GLWE<DataSelf> {
|
||||||
pub fn decrypt<DataPt: DataMut, DataSk: DataRef, B: Backend>(
|
pub fn decrypt<DataPt: DataMut, DataSk: DataRef, B: Backend>(
|
||||||
&self,
|
&self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ use poulpy_hal::{
|
|||||||
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl},
|
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{LWECiphertext, LWEInfos, LWEPlaintext, LWESecret};
|
use crate::layouts::{LWE, LWEInfos, LWEPlaintext, LWESecret};
|
||||||
|
|
||||||
impl<DataSelf> LWECiphertext<DataSelf>
|
impl<DataSelf> LWE<DataSelf>
|
||||||
where
|
where
|
||||||
DataSelf: DataRef,
|
DataSelf: DataRef,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,8 +20,7 @@ impl AutomorphismKeyCompressed<Vec<u8>> {
|
|||||||
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
|
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
|
||||||
{
|
{
|
||||||
assert_eq!(module.n() as u32, infos.n());
|
assert_eq!(module.n() as u32, infos.n());
|
||||||
GLWESwitchingKeyCompressed::encrypt_sk_scratch_space(module, infos)
|
GLWESwitchingKeyCompressed::encrypt_sk_scratch_space(module, infos) + GLWESecret::bytes_of(infos.n(), infos.rank_out())
|
||||||
+ GLWESecret::alloc_bytes_with(infos.n(), infos.rank_out())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ use crate::{
|
|||||||
encryption::{SIGMA, glwe_ct::GLWEEncryptSkInternal},
|
encryption::{SIGMA, glwe_ct::GLWEEncryptSkInternal},
|
||||||
layouts::{
|
layouts::{
|
||||||
GGLWE, GGLWEInfos, LWEInfos,
|
GGLWE, GGLWEInfos, LWEInfos,
|
||||||
compressed::{GGLWECiphertextCompressed, GGLWECiphertextCompressedToMut},
|
compressed::{GGLWECompressed, GGLWECompressedToMut},
|
||||||
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<D: DataMut> GGLWECiphertextCompressed<D> {
|
impl<D: DataMut> GGLWECompressed<D> {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
|
pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -34,7 +34,7 @@ impl<D: DataMut> GGLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GGLWECiphertextCompressed<Vec<u8>> {
|
impl GGLWECompressed<Vec<u8>> {
|
||||||
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
@@ -54,7 +54,7 @@ pub trait GGLWECompressedEncryptSk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GGLWECiphertextCompressedToMut,
|
R: GGLWECompressedToMut,
|
||||||
P: ScalarZnxToRef,
|
P: ScalarZnxToRef,
|
||||||
S: GLWESecretPreparedToRef<B>;
|
S: GLWESecretPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
@@ -78,11 +78,11 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GGLWECiphertextCompressedToMut,
|
R: GGLWECompressedToMut,
|
||||||
P: ScalarZnxToRef,
|
P: ScalarZnxToRef,
|
||||||
S: GLWESecretPreparedToRef<B>,
|
S: GLWESecretPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
let res: &mut GGLWECiphertextCompressed<&mut [u8]> = &mut res.to_mut();
|
let res: &mut GGLWECompressed<&mut [u8]> = &mut res.to_mut();
|
||||||
let pt: &ScalarZnx<&[u8]> = &pt.to_ref();
|
let pt: &ScalarZnx<&[u8]> = &pt.to_ref();
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -107,10 +107,10 @@ where
|
|||||||
assert_eq!(res.n(), sk.n());
|
assert_eq!(res.n(), sk.n());
|
||||||
assert_eq!(pt.n() as u32, sk.n());
|
assert_eq!(pt.n() as u32, sk.n());
|
||||||
assert!(
|
assert!(
|
||||||
scratch.available() >= GGLWECiphertextCompressed::encrypt_sk_scratch_space(self, res),
|
scratch.available() >= GGLWECompressed::encrypt_sk_scratch_space(self, res),
|
||||||
"scratch.available: {} < GGLWECiphertext::encrypt_sk_scratch_space: {}",
|
"scratch.available: {} < GGLWECiphertext::encrypt_sk_scratch_space: {}",
|
||||||
scratch.available(),
|
scratch.available(),
|
||||||
GGLWECiphertextCompressed::encrypt_sk_scratch_space(self, res)
|
GGLWECompressed::encrypt_sk_scratch_space(self, res)
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
res.dnum().0 * res.dsize().0 * res.base2k().0 <= res.k().0,
|
res.dnum().0 * res.dsize().0 * res.base2k().0 <= res.k().0,
|
||||||
|
|||||||
@@ -23,9 +23,9 @@ impl GLWESwitchingKeyCompressed<Vec<u8>> {
|
|||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
|
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + SvpPPolAllocBytes,
|
||||||
{
|
{
|
||||||
(GGLWE::encrypt_sk_scratch_space(module, infos) | ScalarZnx::alloc_bytes(module.n(), 1))
|
(GGLWE::encrypt_sk_scratch_space(module, infos) | ScalarZnx::bytes_of(module.n(), 1))
|
||||||
+ ScalarZnx::alloc_bytes(module.n(), infos.rank_in().into())
|
+ ScalarZnx::bytes_of(module.n(), infos.rank_in().into())
|
||||||
+ GLWESecretPrepared::alloc_bytes(module, infos.rank_out())
|
+ GLWESecretPrepared::bytes_of(module, infos.rank_out())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,12 @@ use crate::{
|
|||||||
encryption::{SIGMA, glwe_ct::GLWEEncryptSkInternal},
|
encryption::{SIGMA, glwe_ct::GLWEEncryptSkInternal},
|
||||||
layouts::{
|
layouts::{
|
||||||
GGSW, GGSWInfos, GLWEInfos, LWEInfos,
|
GGSW, GGSWInfos, GLWEInfos, LWEInfos,
|
||||||
compressed::{GGSWCiphertextCompressed, GGSWCiphertextCompressedToMut},
|
compressed::{GGSWCompressed, GGSWCompressedToMut},
|
||||||
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GGSWCiphertextCompressed<Vec<u8>> {
|
impl GGSWCompressed<Vec<u8>> {
|
||||||
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGSWInfos,
|
A: GGSWInfos,
|
||||||
@@ -34,7 +34,7 @@ pub trait GGSWCompressedEncryptSk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GGSWCiphertextCompressedToMut,
|
R: GGSWCompressedToMut,
|
||||||
P: ScalarZnxToRef,
|
P: ScalarZnxToRef,
|
||||||
S: GLWESecretPreparedToRef<B>;
|
S: GLWESecretPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
@@ -53,11 +53,11 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GGSWCiphertextCompressedToMut,
|
R: GGSWCompressedToMut,
|
||||||
P: ScalarZnxToRef,
|
P: ScalarZnxToRef,
|
||||||
S: GLWESecretPreparedToRef<B>,
|
S: GLWESecretPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
let res: &mut GGSWCiphertextCompressed<&mut [u8]> = &mut res.to_mut();
|
let res: &mut GGSWCompressed<&mut [u8]> = &mut res.to_mut();
|
||||||
let sk: &GLWESecretPrepared<&[u8], B> = &sk.to_ref();
|
let sk: &GLWESecretPrepared<&[u8], B> = &sk.to_ref();
|
||||||
let pt: &ScalarZnx<&[u8]> = &pt.to_ref();
|
let pt: &ScalarZnx<&[u8]> = &pt.to_ref();
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DataSelf: DataMut> GGSWCiphertextCompressed<DataSelf> {
|
impl<DataSelf: DataMut> GGSWCompressed<DataSelf> {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
|
pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@@ -7,19 +7,19 @@ use poulpy_hal::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
encryption::{SIGMA, glwe_ct::GLWEEncryptSkInternal},
|
encryption::{SIGMA, glwe_ct::GLWEEncryptSkInternal},
|
||||||
layouts::{
|
layouts::{
|
||||||
GLWECiphertext, GLWEInfos, GLWEPlaintext, GLWEPlaintextToRef, LWEInfos,
|
GLWE, GLWEInfos, GLWEPlaintext, GLWEPlaintextToRef, LWEInfos,
|
||||||
compressed::{GLWECiphertextCompressed, GLWECiphertextCompressedToMut},
|
compressed::{GLWECompressed, GLWECompressedToMut},
|
||||||
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GLWECiphertextCompressed<Vec<u8>> {
|
impl GLWECompressed<Vec<u8>> {
|
||||||
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
|
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::encrypt_sk_scratch_space(module, infos)
|
GLWE::encrypt_sk_scratch_space(module, infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ pub trait GLWECompressedEncryptSk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextCompressedToMut,
|
R: GLWECompressedToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
S: GLWESecretPreparedToRef<B>;
|
S: GLWESecretPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
@@ -51,11 +51,11 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextCompressedToMut,
|
R: GLWECompressedToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
S: GLWESecretPreparedToRef<B>,
|
S: GLWESecretPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
let res: &mut GLWECiphertextCompressed<&mut [u8]> = &mut res.to_mut();
|
let res: &mut GLWECompressed<&mut [u8]> = &mut res.to_mut();
|
||||||
let mut source_xa: Source = Source::new(seed_xa);
|
let mut source_xa: Source = Source::new(seed_xa);
|
||||||
let cols: usize = (res.rank() + 1).into();
|
let cols: usize = (res.rank() + 1).into();
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertextCompressed<D> {
|
impl<D: DataMut> GLWECompressed<D> {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
|
pub fn encrypt_sk<DataPt: DataRef, DataSk: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ impl AutomorphismKey<Vec<u8>> {
|
|||||||
infos.rank_out(),
|
infos.rank_out(),
|
||||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
|
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
|
||||||
);
|
);
|
||||||
GLWESwitchingKey::encrypt_sk_scratch_space(module, infos) + GLWESecret::alloc_bytes(&infos.glwe_layout())
|
GLWESwitchingKey::encrypt_sk_scratch_space(module, infos) + GLWESecret::bytes_of(&infos.glwe_layout())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt_pk_scratch_space<BE: Backend, A>(module: &Module<BE>, _infos: &A) -> usize
|
pub fn encrypt_pk_scratch_space<BE: Backend, A>(module: &Module<BE>, _infos: &A) -> usize
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::{
|
|||||||
TakeGLWEPt,
|
TakeGLWEPt,
|
||||||
encryption::glwe_ct::GLWEEncryptSk,
|
encryption::glwe_ct::GLWEEncryptSk,
|
||||||
layouts::{
|
layouts::{
|
||||||
GGLWE, GGLWECiphertextToMut, GGLWEInfos, GLWECiphertext, GLWEPlaintext, LWEInfos,
|
GGLWE, GGLWEInfos, GGLWEToMut, GLWE, GLWEPlaintext, LWEInfos,
|
||||||
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -22,8 +22,8 @@ impl GGLWE<Vec<u8>> {
|
|||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::encrypt_sk_scratch_space(module, &infos.glwe_layout())
|
GLWE::encrypt_sk_scratch_space(module, &infos.glwe_layout())
|
||||||
+ (GLWEPlaintext::alloc_bytes(&infos.glwe_layout()) | module.vec_znx_normalize_tmp_bytes())
|
+ (GLWEPlaintext::bytes_of(&infos.glwe_layout()) | module.vec_znx_normalize_tmp_bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt_pk_scratch_space<B: Backend, A>(_module: &Module<B>, _infos: &A) -> usize
|
pub fn encrypt_pk_scratch_space<B: Backend, A>(_module: &Module<B>, _infos: &A) -> usize
|
||||||
@@ -44,7 +44,7 @@ pub trait GGLWEEncryptSk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GGLWECiphertextToMut,
|
R: GGLWEToMut,
|
||||||
P: ScalarZnxToRef,
|
P: ScalarZnxToRef,
|
||||||
S: GLWESecretPreparedToRef<B>;
|
S: GLWESecretPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GGLWECiphertextToMut,
|
R: GGLWEToMut,
|
||||||
P: ScalarZnxToRef,
|
P: ScalarZnxToRef,
|
||||||
S: GLWESecretPreparedToRef<B>,
|
S: GLWESecretPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ impl GLWESwitchingKey<Vec<u8>> {
|
|||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
(GGLWE::encrypt_sk_scratch_space(module, infos) | ScalarZnx::alloc_bytes(module.n(), 1))
|
(GGLWE::encrypt_sk_scratch_space(module, infos) | ScalarZnx::bytes_of(module.n(), 1))
|
||||||
+ ScalarZnx::alloc_bytes(module.n(), infos.rank_in().into())
|
+ ScalarZnx::bytes_of(module.n(), infos.rank_in().into())
|
||||||
+ GLWESecretPrepared::alloc_bytes_from_infos(module, &infos.glwe_layout())
|
+ GLWESecretPrepared::bytes_of_from_infos(module, &infos.glwe_layout())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, _infos: &A) -> usize
|
pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, _infos: &A) -> usize
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ impl TensorKey<Vec<u8>> {
|
|||||||
Module<B>:
|
Module<B>:
|
||||||
SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + VecZnxBigAllocBytes,
|
SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes + VecZnxBigAllocBytes,
|
||||||
{
|
{
|
||||||
GLWESecretPrepared::alloc_bytes(module, infos.rank_out())
|
GLWESecretPrepared::bytes_of(module, infos.rank_out())
|
||||||
+ module.vec_znx_dft_alloc_bytes(infos.rank_out().into(), 1)
|
+ module.vec_znx_dft_bytes_of(infos.rank_out().into(), 1)
|
||||||
+ module.vec_znx_big_alloc_bytes(1, 1)
|
+ module.vec_znx_big_bytes_of(1, 1)
|
||||||
+ module.vec_znx_dft_alloc_bytes(1, 1)
|
+ module.vec_znx_dft_bytes_of(1, 1)
|
||||||
+ GLWESecret::alloc_bytes_with(Degree(module.n() as u32), Rank(1))
|
+ GLWESecret::bytes_of(Degree(module.n() as u32), Rank(1))
|
||||||
+ GLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
|
+ GLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
SIGMA, TakeGLWEPt,
|
SIGMA, TakeGLWEPt,
|
||||||
encryption::glwe_ct::GLWEEncryptSkInternal,
|
encryption::glwe_ct::GLWEEncryptSkInternal,
|
||||||
layouts::{
|
layouts::{
|
||||||
GGSW, GGSWInfos, GGSWToMut, GLWECiphertext, GLWEInfos, LWEInfos,
|
GGSW, GGSWInfos, GGSWToMut, GLWE, GLWEInfos, LWEInfos,
|
||||||
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -20,10 +20,10 @@ impl GGSW<Vec<u8>> {
|
|||||||
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
|
Module<B>: VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes,
|
||||||
{
|
{
|
||||||
let size = infos.size();
|
let size = infos.size();
|
||||||
GLWECiphertext::encrypt_sk_scratch_space(module, &infos.glwe_layout())
|
GLWE::encrypt_sk_scratch_space(module, &infos.glwe_layout())
|
||||||
+ VecZnx::alloc_bytes(module.n(), (infos.rank() + 1).into(), size)
|
+ VecZnx::bytes_of(module.n(), (infos.rank() + 1).into(), size)
|
||||||
+ VecZnx::alloc_bytes(module.n(), 1, size)
|
+ VecZnx::bytes_of(module.n(), 1, size)
|
||||||
+ module.vec_znx_dft_alloc_bytes((infos.rank() + 1).into(), size)
|
+ module.vec_znx_dft_bytes_of((infos.rank() + 1).into(), size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ use crate::{
|
|||||||
dist::Distribution,
|
dist::Distribution,
|
||||||
encryption::{SIGMA, SIGMA_BOUND},
|
encryption::{SIGMA, SIGMA_BOUND},
|
||||||
layouts::{
|
layouts::{
|
||||||
GLWECiphertext, GLWECiphertextToMut, GLWEInfos, GLWEPlaintext, GLWEPlaintextToRef, LWEInfos,
|
GLWE, GLWEInfos, GLWEPlaintext, GLWEPlaintextToRef, GLWEToMut, LWEInfos,
|
||||||
prepared::{GLWEPublicKeyPrepared, GLWEPublicKeyPreparedToRef, GLWESecretPrepared, GLWESecretPreparedToRef},
|
prepared::{GLWEPublicKeyPrepared, GLWEPublicKeyPreparedToRef, GLWESecretPrepared, GLWESecretPreparedToRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
pub fn encrypt_sk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
@@ -26,9 +26,7 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
{
|
{
|
||||||
let size: usize = infos.size();
|
let size: usize = infos.size();
|
||||||
assert_eq!(module.n() as u32, infos.n());
|
assert_eq!(module.n() as u32, infos.n());
|
||||||
module.vec_znx_normalize_tmp_bytes()
|
module.vec_znx_normalize_tmp_bytes() + 2 * VecZnx::bytes_of(module.n(), 1, size) + module.vec_znx_dft_bytes_of(1, size)
|
||||||
+ 2 * VecZnx::alloc_bytes(module.n(), 1, size)
|
|
||||||
+ module.vec_znx_dft_alloc_bytes(1, size)
|
|
||||||
}
|
}
|
||||||
pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
pub fn encrypt_pk_scratch_space<B: Backend, A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
@@ -37,14 +35,13 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
{
|
{
|
||||||
let size: usize = infos.size();
|
let size: usize = infos.size();
|
||||||
assert_eq!(module.n() as u32, infos.n());
|
assert_eq!(module.n() as u32, infos.n());
|
||||||
((module.vec_znx_dft_alloc_bytes(1, size) + module.vec_znx_big_alloc_bytes(1, size))
|
((module.vec_znx_dft_bytes_of(1, size) + module.vec_znx_big_bytes_of(1, size)) | ScalarZnx::bytes_of(module.n(), 1))
|
||||||
| ScalarZnx::alloc_bytes(module.n(), 1))
|
+ module.svp_ppol_bytes_of(1)
|
||||||
+ module.svp_ppol_alloc_bytes(1)
|
|
||||||
+ module.vec_znx_normalize_tmp_bytes()
|
+ module.vec_znx_normalize_tmp_bytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertext<D> {
|
impl<D: DataMut> GLWE<D> {
|
||||||
pub fn encrypt_sk<R, P, S, B: Backend>(
|
pub fn encrypt_sk<R, P, S, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
@@ -116,7 +113,7 @@ pub trait GLWEEncryptSk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
S: GLWESecretPreparedToRef<B>;
|
S: GLWESecretPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
@@ -135,11 +132,11 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
S: GLWESecretPreparedToRef<B>,
|
S: GLWESecretPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
let mut res: GLWECiphertext<&mut [u8]> = res.to_mut();
|
let mut res: GLWE<&mut [u8]> = res.to_mut();
|
||||||
let pt: GLWEPlaintext<&[u8]> = pt.to_ref();
|
let pt: GLWEPlaintext<&[u8]> = pt.to_ref();
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -150,10 +147,10 @@ where
|
|||||||
assert_eq!(sk.n(), self.n() as u32);
|
assert_eq!(sk.n(), self.n() as u32);
|
||||||
assert_eq!(pt.n(), self.n() as u32);
|
assert_eq!(pt.n(), self.n() as u32);
|
||||||
assert!(
|
assert!(
|
||||||
scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(self, &res),
|
scratch.available() >= GLWE::encrypt_sk_scratch_space(self, &res),
|
||||||
"scratch.available(): {} < GLWECiphertext::encrypt_sk_scratch_space: {}",
|
"scratch.available(): {} < GLWECiphertext::encrypt_sk_scratch_space: {}",
|
||||||
scratch.available(),
|
scratch.available(),
|
||||||
GLWECiphertext::encrypt_sk_scratch_space(self, &res)
|
GLWE::encrypt_sk_scratch_space(self, &res)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +180,7 @@ pub trait GLWEEncryptZeroSk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
S: GLWESecretPreparedToRef<B>;
|
S: GLWESecretPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,10 +197,10 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
S: GLWESecretPreparedToRef<B>,
|
S: GLWESecretPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
let mut res: GLWECiphertext<&mut [u8]> = res.to_mut();
|
let mut res: GLWE<&mut [u8]> = res.to_mut();
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
@@ -212,10 +209,10 @@ where
|
|||||||
assert_eq!(res.n(), self.n() as u32);
|
assert_eq!(res.n(), self.n() as u32);
|
||||||
assert_eq!(sk.n(), self.n() as u32);
|
assert_eq!(sk.n(), self.n() as u32);
|
||||||
assert!(
|
assert!(
|
||||||
scratch.available() >= GLWECiphertext::encrypt_sk_scratch_space(self, &res),
|
scratch.available() >= GLWE::encrypt_sk_scratch_space(self, &res),
|
||||||
"scratch.available(): {} < GLWECiphertext::encrypt_sk_scratch_space: {}",
|
"scratch.available(): {} < GLWECiphertext::encrypt_sk_scratch_space: {}",
|
||||||
scratch.available(),
|
scratch.available(),
|
||||||
GLWECiphertext::encrypt_sk_scratch_space(self, &res)
|
GLWE::encrypt_sk_scratch_space(self, &res)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,7 +243,7 @@ pub trait GLWEEncryptPk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
K: GLWEPublicKeyPreparedToRef<B>;
|
K: GLWEPublicKeyPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
@@ -264,7 +261,7 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
K: GLWEPublicKeyPreparedToRef<B>,
|
K: GLWEPublicKeyPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
@@ -281,7 +278,7 @@ pub trait GLWEEncryptZeroPk<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
K: GLWEPublicKeyPreparedToRef<B>;
|
K: GLWEPublicKeyPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -297,7 +294,7 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
K: GLWEPublicKeyPreparedToRef<B>,
|
K: GLWEPublicKeyPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
self.glwe_encrypt_pk_internal(
|
self.glwe_encrypt_pk_internal(
|
||||||
@@ -321,7 +318,7 @@ pub(crate) trait GLWEEncryptPkInternal<B: Backend> {
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
K: GLWEPublicKeyPreparedToRef<B>;
|
K: GLWEPublicKeyPreparedToRef<B>;
|
||||||
}
|
}
|
||||||
@@ -345,11 +342,11 @@ where
|
|||||||
source_xe: &mut Source,
|
source_xe: &mut Source,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
P: GLWEPlaintextToRef,
|
P: GLWEPlaintextToRef,
|
||||||
K: GLWEPublicKeyPreparedToRef<B>,
|
K: GLWEPublicKeyPreparedToRef<B>,
|
||||||
{
|
{
|
||||||
let res: &mut GLWECiphertext<&mut [u8]> = &mut res.to_mut();
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
||||||
let pk: &GLWEPublicKeyPrepared<&[u8], B> = &pk.to_ref();
|
let pk: &GLWEPublicKeyPrepared<&[u8], B> = &pk.to_ref();
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use poulpy_hal::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
encryption::glwe_ct::GLWEEncryptZeroSk,
|
encryption::glwe_ct::GLWEEncryptZeroSk,
|
||||||
layouts::{
|
layouts::{
|
||||||
GLWECiphertext, GLWEPublicKey, GLWEPublicKeyToMut,
|
GLWE, GLWEPublicKey, GLWEPublicKeyToMut,
|
||||||
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
prepared::{GLWESecretPrepared, GLWESecretPreparedToRef},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -45,9 +45,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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<B> = ScratchOwned::alloc(GLWECiphertext::encrypt_sk_scratch_space(self, res));
|
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWE::encrypt_sk_scratch_space(self, res));
|
||||||
|
|
||||||
let mut tmp: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(res);
|
let mut tmp: GLWE<Vec<u8>> = GLWE::alloc_from_infos(res);
|
||||||
|
|
||||||
tmp.encrypt_zero_sk(self, sk, source_xa, source_xe, scratch.borrow());
|
tmp.encrypt_zero_sk(self, sk, source_xa, source_xe, scratch.borrow());
|
||||||
res.dist = sk.dist;
|
res.dist = sk.dist;
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ impl GLWEToLWESwitchingKey<Vec<u8>> {
|
|||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: SvpPPolAllocBytes + VecZnxNormalizeTmpBytes + VecZnxDftAllocBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWESecretPrepared::alloc_bytes(module, infos.rank_in())
|
GLWESecretPrepared::bytes_of(module, infos.rank_in())
|
||||||
+ (GLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
|
+ (GLWESwitchingKey::encrypt_sk_scratch_space(module, infos) | GLWESecret::bytes_of(infos.n(), infos.rank_in()))
|
||||||
| GLWESecret::alloc_bytes_with(infos.n(), infos.rank_in()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
encryption::{SIGMA, SIGMA_BOUND},
|
encryption::{SIGMA, SIGMA_BOUND},
|
||||||
layouts::{LWECiphertext, LWEInfos, LWEPlaintext, LWESecret},
|
layouts::{LWE, LWEInfos, LWEPlaintext, LWESecret},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl<DataSelf: DataMut> LWECiphertext<DataSelf> {
|
impl<DataSelf: DataMut> LWE<DataSelf> {
|
||||||
pub fn encrypt_sk<DataPt, DataSk, B>(
|
pub fn encrypt_sk<DataPt, DataSk, B>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ impl LWESwitchingKey<Vec<u8>> {
|
|||||||
1,
|
1,
|
||||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||||
);
|
);
|
||||||
GLWESecret::alloc_bytes_with(Degree(module.n() as u32), Rank(1))
|
GLWESecret::bytes_of(Degree(module.n() as u32), Rank(1))
|
||||||
+ GLWESecretPrepared::alloc_bytes(module, Rank(1))
|
+ GLWESecretPrepared::bytes_of(module, Rank(1))
|
||||||
+ GLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
|
+ GLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ impl LWEToGLWESwitchingKey<Vec<u8>> {
|
|||||||
"rank_in != 1 is not supported for LWEToGLWESwitchingKey"
|
"rank_in != 1 is not supported for LWEToGLWESwitchingKey"
|
||||||
);
|
);
|
||||||
GLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
|
GLWESwitchingKey::encrypt_sk_scratch_space(module, infos)
|
||||||
+ GLWESecret::alloc_bytes_with(Degree(module.n() as u32), infos.rank_in())
|
+ GLWESecret::bytes_of(Degree(module.n() as u32), infos.rank_in())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero},
|
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GGLWEInfos, GGSWInfos, GLWECiphertext, GLWESwitchingKey, prepared::GGSWPrepared};
|
use crate::layouts::{GGLWEInfos, GGSWInfos, GLWE, GLWESwitchingKey, prepared::GGSWPrepared};
|
||||||
|
|
||||||
impl GLWESwitchingKey<Vec<u8>> {
|
impl GLWESwitchingKey<Vec<u8>> {
|
||||||
pub fn external_product_scratch_space<B: Backend, OUT, IN, GGSW>(
|
pub fn external_product_scratch_space<B: Backend, OUT, IN, GGSW>(
|
||||||
@@ -22,7 +22,7 @@ impl GLWESwitchingKey<Vec<u8>> {
|
|||||||
GGSW: GGSWInfos,
|
GGSW: GGSWInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::external_product_scratch_space(
|
GLWE::external_product_scratch_space(
|
||||||
module,
|
module,
|
||||||
&out_infos.glwe_layout(),
|
&out_infos.glwe_layout(),
|
||||||
&in_infos.glwe_layout(),
|
&in_infos.glwe_layout(),
|
||||||
@@ -40,7 +40,7 @@ impl GLWESwitchingKey<Vec<u8>> {
|
|||||||
GGSW: GGSWInfos,
|
GGSW: GGSWInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::external_product_inplace_scratch_space(module, &out_infos.glwe_layout(), ggsw_infos)
|
GLWE::external_product_inplace_scratch_space(module, &out_infos.glwe_layout(), ggsw_infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero},
|
layouts::{Backend, DataMut, DataRef, Module, Scratch, ZnxZero},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GGSW, GGSWInfos, GLWECiphertext, GLWEInfos, prepared::GGSWPrepared};
|
use crate::layouts::{GGSW, GGSWInfos, GLWE, GLWEInfos, prepared::GGSWPrepared};
|
||||||
|
|
||||||
impl GGSW<Vec<u8>> {
|
impl GGSW<Vec<u8>> {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
@@ -23,7 +23,7 @@ impl GGSW<Vec<u8>> {
|
|||||||
GGSW: GGSWInfos,
|
GGSW: GGSWInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::external_product_scratch_space(
|
GLWE::external_product_scratch_space(
|
||||||
module,
|
module,
|
||||||
&out_infos.glwe_layout(),
|
&out_infos.glwe_layout(),
|
||||||
&in_infos.glwe_layout(),
|
&in_infos.glwe_layout(),
|
||||||
@@ -41,7 +41,7 @@ impl GGSW<Vec<u8>> {
|
|||||||
GGSW: GGSWInfos,
|
GGSW: GGSWInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::external_product_inplace_scratch_space(module, &out_infos.glwe_layout(), apply_infos)
|
GLWE::external_product_inplace_scratch_space(module, &out_infos.glwe_layout(), apply_infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,12 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, DataRef, DataViewMut, Module, Scratch, VecZnx, VecZnxBig},
|
layouts::{Backend, DataMut, DataRef, DataViewMut, Module, Scratch, VecZnx, VecZnxBig},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::layouts::{
|
||||||
GLWEExternalProduct, GLWEExternalProductInplace,
|
GGSWInfos, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, LWEInfos,
|
||||||
layouts::{
|
|
||||||
GGSWInfos, GLWECiphertext, GLWECiphertextToMut, GLWECiphertextToRef, GLWEInfos, LWEInfos,
|
|
||||||
prepared::{GGSWCiphertextPreparedToRef, GGSWPrepared},
|
prepared::{GGSWCiphertextPreparedToRef, GGSWPrepared},
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn external_product_scratch_space<B: Backend, OUT, IN, GGSW>(
|
pub fn external_product_scratch_space<B: Backend, OUT, IN, GGSW>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
@@ -35,8 +32,8 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
.div_ceil(apply_infos.dsize().into()) as usize;
|
.div_ceil(apply_infos.dsize().into()) as usize;
|
||||||
let out_size: usize = out_infos.size();
|
let out_size: usize = out_infos.size();
|
||||||
let ggsw_size: usize = apply_infos.size();
|
let ggsw_size: usize = apply_infos.size();
|
||||||
let res_dft: usize = module.vec_znx_dft_alloc_bytes((apply_infos.rank() + 1).into(), ggsw_size);
|
let res_dft: usize = module.vec_znx_dft_bytes_of((apply_infos.rank() + 1).into(), ggsw_size);
|
||||||
let a_dft: usize = module.vec_znx_dft_alloc_bytes((apply_infos.rank() + 1).into(), in_size);
|
let a_dft: usize = module.vec_znx_dft_bytes_of((apply_infos.rank() + 1).into(), in_size);
|
||||||
let vmp: usize = module.vmp_apply_dft_to_dft_tmp_bytes(
|
let vmp: usize = module.vmp_apply_dft_to_dft_tmp_bytes(
|
||||||
out_size,
|
out_size,
|
||||||
in_size,
|
in_size,
|
||||||
@@ -50,7 +47,7 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
if in_infos.base2k() == apply_infos.base2k() {
|
if in_infos.base2k() == apply_infos.base2k() {
|
||||||
res_dft + a_dft + (vmp | normalize_big)
|
res_dft + a_dft + (vmp | normalize_big)
|
||||||
} else {
|
} else {
|
||||||
let normalize_conv: usize = VecZnx::alloc_bytes(module.n(), (apply_infos.rank() + 1).into(), in_size);
|
let normalize_conv: usize = VecZnx::bytes_of(module.n(), (apply_infos.rank() + 1).into(), in_size);
|
||||||
res_dft + ((a_dft + normalize_conv + (module.vec_znx_normalize_tmp_bytes() | vmp)) | normalize_big)
|
res_dft + ((a_dft + normalize_conv + (module.vec_znx_normalize_tmp_bytes() | vmp)) | normalize_big)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,11 +66,11 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
impl<DataSelf: DataMut> GLWE<DataSelf> {
|
||||||
pub fn external_product<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
pub fn external_product<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lhs: &GLWECiphertext<DataLhs>,
|
lhs: &GLWE<DataLhs>,
|
||||||
rhs: &GGSWPrepared<DataRhs, B>,
|
rhs: &GGSWPrepared<DataRhs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -88,15 +85,15 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
|||||||
rhs: &GGSWPrepared<DataRhs, B>,
|
rhs: &GGSWPrepared<DataRhs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
Module<B>: GLWEExternalProductInplace<B>,
|
Module<B>: GLWEExternalProduct<B>,
|
||||||
{
|
{
|
||||||
module.external_product_inplace(self, rhs, scratch);
|
module.external_product_inplace(self, rhs, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<BE: Backend> GLWEExternalProductInplace<BE> for Module<BE>
|
pub trait GLWEExternalProduct<BE: Backend>
|
||||||
where
|
where
|
||||||
Module<BE>: VecZnxDftAllocBytes
|
Self: VecZnxDftAllocBytes
|
||||||
+ VmpApplyDftToDftTmpBytes
|
+ VmpApplyDftToDftTmpBytes
|
||||||
+ VecZnxNormalizeTmpBytes
|
+ VecZnxNormalizeTmpBytes
|
||||||
+ VecZnxDftApply<BE>
|
+ VecZnxDftApply<BE>
|
||||||
@@ -107,12 +104,12 @@ where
|
|||||||
+ VecZnxNormalize<BE>,
|
+ VecZnxNormalize<BE>,
|
||||||
Scratch<BE>: TakeVecZnxDft<BE> + ScratchAvailable + TakeVecZnx,
|
Scratch<BE>: TakeVecZnxDft<BE> + ScratchAvailable + TakeVecZnx,
|
||||||
{
|
{
|
||||||
fn external_product_inplace<R, D>(&self, res: &mut R, ggsw: &D, scratch: &mut Scratch<BE>)
|
fn glwe_external_product_inplace<R, D>(&self, res: &mut R, ggsw: &D, scratch: &mut Scratch<BE>)
|
||||||
where
|
where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
D: GGSWCiphertextPreparedToRef<BE>,
|
D: GGSWCiphertextPreparedToRef<BE>,
|
||||||
{
|
{
|
||||||
let res: &mut GLWECiphertext<&mut [u8]> = &mut res.to_mut();
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
||||||
let rhs: &GGSWPrepared<&[u8], BE> = &ggsw.to_ref();
|
let rhs: &GGSWPrepared<&[u8], BE> = &ggsw.to_ref();
|
||||||
|
|
||||||
let basek_in: usize = res.base2k().into();
|
let basek_in: usize = res.base2k().into();
|
||||||
@@ -124,7 +121,7 @@ where
|
|||||||
|
|
||||||
assert_eq!(rhs.rank(), res.rank());
|
assert_eq!(rhs.rank(), res.rank());
|
||||||
assert_eq!(rhs.n(), res.n());
|
assert_eq!(rhs.n(), res.n());
|
||||||
assert!(scratch.available() >= GLWECiphertext::external_product_inplace_scratch_space(self, res, rhs));
|
assert!(scratch.available() >= GLWE::external_product_inplace_scratch_space(self, res, rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
let cols: usize = (rhs.rank() + 1).into();
|
let cols: usize = (rhs.rank() + 1).into();
|
||||||
@@ -213,29 +210,15 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<BE: Backend> GLWEExternalProduct<BE> for Module<BE>
|
fn glwe_external_product<R, A, D>(&self, res: &mut R, lhs: &A, rhs: &D, scratch: &mut Scratch<BE>)
|
||||||
where
|
|
||||||
Module<BE>: VecZnxDftAllocBytes
|
|
||||||
+ VmpApplyDftToDftTmpBytes
|
|
||||||
+ VecZnxNormalizeTmpBytes
|
|
||||||
+ VecZnxDftApply<BE>
|
|
||||||
+ VmpApplyDftToDft<BE>
|
|
||||||
+ VmpApplyDftToDftAdd<BE>
|
|
||||||
+ VecZnxIdftApplyConsume<BE>
|
|
||||||
+ VecZnxBigNormalize<BE>
|
|
||||||
+ VecZnxNormalize<BE>,
|
|
||||||
Scratch<BE>: TakeVecZnxDft<BE> + ScratchAvailable + TakeVecZnx,
|
|
||||||
{
|
|
||||||
fn external_product<R, A, D>(&self, res: &mut R, lhs: &A, rhs: &D, scratch: &mut Scratch<BE>)
|
|
||||||
where
|
where
|
||||||
R: GLWECiphertextToMut,
|
R: GLWEToMut,
|
||||||
A: GLWECiphertextToRef,
|
A: GLWEToRef,
|
||||||
D: GGSWCiphertextPreparedToRef<BE>,
|
D: GGSWCiphertextPreparedToRef<BE>,
|
||||||
{
|
{
|
||||||
let res: &mut GLWECiphertext<&mut [u8]> = &mut res.to_mut();
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
||||||
let lhs: &GLWECiphertext<&[u8]> = &lhs.to_ref();
|
let lhs: &GLWE<&[u8]> = &lhs.to_ref();
|
||||||
|
|
||||||
let rhs: &GGSWPrepared<&[u8], BE> = &rhs.to_ref();
|
let rhs: &GGSWPrepared<&[u8], BE> = &rhs.to_ref();
|
||||||
|
|
||||||
@@ -251,7 +234,7 @@ where
|
|||||||
assert_eq!(rhs.rank(), res.rank());
|
assert_eq!(rhs.rank(), res.rank());
|
||||||
assert_eq!(rhs.n(), res.n());
|
assert_eq!(rhs.n(), res.n());
|
||||||
assert_eq!(lhs.n(), res.n());
|
assert_eq!(lhs.n(), res.n());
|
||||||
assert!(scratch.available() >= GLWECiphertext::external_product_scratch_space(self, res, lhs, rhs));
|
assert!(scratch.available() >= GLWE::external_product_scratch_space(self, res, lhs, rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
let cols: usize = (rhs.rank() + 1).into();
|
let cols: usize = (rhs.rank() + 1).into();
|
||||||
@@ -342,3 +325,18 @@ where
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<BE: Backend> GLWEExternalProduct<BE> for Module<BE>
|
||||||
|
where
|
||||||
|
Self: VecZnxDftAllocBytes
|
||||||
|
+ VmpApplyDftToDftTmpBytes
|
||||||
|
+ VecZnxNormalizeTmpBytes
|
||||||
|
+ VecZnxDftApply<BE>
|
||||||
|
+ VmpApplyDftToDft<BE>
|
||||||
|
+ VmpApplyDftToDftAdd<BE>
|
||||||
|
+ VecZnxIdftApplyConsume<BE>
|
||||||
|
+ VecZnxBigNormalize<BE>
|
||||||
|
+ VecZnxNormalize<BE>,
|
||||||
|
Scratch<BE>: TakeVecZnxDft<BE> + ScratchAvailable + TakeVecZnx,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,23 +1,8 @@
|
|||||||
use poulpy_hal::layouts::{Backend, Scratch};
|
use poulpy_hal::layouts::{Backend, Scratch};
|
||||||
|
|
||||||
use crate::layouts::{GLWECiphertextToMut, GLWECiphertextToRef, prepared::GGSWCiphertextPreparedToRef};
|
use crate::layouts::{GLWEToMut, GLWEToRef, prepared::GGSWCiphertextPreparedToRef};
|
||||||
|
|
||||||
mod gglwe_atk;
|
mod gglwe_atk;
|
||||||
mod gglwe_ksk;
|
mod gglwe_ksk;
|
||||||
mod ggsw_ct;
|
mod ggsw_ct;
|
||||||
mod glwe_ct;
|
mod glwe_ct;
|
||||||
|
|
||||||
pub trait GLWEExternalProduct<BE: Backend> {
|
|
||||||
fn external_product<R, A, D>(&self, res: &mut R, a: &A, ggsw: &D, scratch: &mut Scratch<BE>)
|
|
||||||
where
|
|
||||||
R: GLWECiphertextToMut,
|
|
||||||
A: GLWECiphertextToRef,
|
|
||||||
D: GGSWCiphertextPreparedToRef<BE>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait GLWEExternalProductInplace<BE: Backend> {
|
|
||||||
fn external_product_inplace<R, D>(&self, res: &mut R, ggsw: &D, scratch: &mut Scratch<BE>)
|
|
||||||
where
|
|
||||||
R: GLWECiphertextToMut,
|
|
||||||
D: GGSWCiphertextPreparedToRef<BE>;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
GLWEOperations, TakeGLWECt,
|
GLWEOperations, TakeGLWECt,
|
||||||
layouts::{GGLWEInfos, GLWECiphertext, GLWEInfos, LWEInfos, prepared::AutomorphismKeyPrepared},
|
layouts::{GGLWEInfos, GLWE, GLWEInfos, LWEInfos, prepared::AutomorphismKeyPrepared},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// [GLWEPacker] enables only the fly GLWE packing
|
/// [GLWEPacker] enables only the fly GLWE packing
|
||||||
@@ -29,7 +29,7 @@ pub struct GLWEPacker {
|
|||||||
/// [Accumulator] stores intermediate packing result.
|
/// [Accumulator] stores intermediate packing result.
|
||||||
/// There are Log(N) such accumulators in a [GLWEPacker].
|
/// There are Log(N) such accumulators in a [GLWEPacker].
|
||||||
struct Accumulator {
|
struct Accumulator {
|
||||||
data: GLWECiphertext<Vec<u8>>,
|
data: GLWE<Vec<u8>>,
|
||||||
value: bool, // Implicit flag for zero ciphertext
|
value: bool, // Implicit flag for zero ciphertext
|
||||||
control: bool, // Can be combined with incoming value
|
control: bool, // Can be combined with incoming value
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ impl Accumulator {
|
|||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
data: GLWECiphertext::alloc(infos),
|
data: GLWE::alloc_from_infos(infos),
|
||||||
value: false,
|
value: false,
|
||||||
control: false,
|
control: false,
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ impl GLWEPacker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn galois_elements<B: Backend>(module: &Module<B>) -> Vec<i64> {
|
pub fn galois_elements<B: Backend>(module: &Module<B>) -> Vec<i64> {
|
||||||
GLWECiphertext::trace_galois_elements(module)
|
GLWE::trace_galois_elements(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a GLWE ciphertext to the [GLWEPacker].
|
/// Adds a GLWE ciphertext to the [GLWEPacker].
|
||||||
@@ -115,7 +115,7 @@ impl GLWEPacker {
|
|||||||
pub fn add<DataA: DataRef, DataAK: DataRef, B: Backend>(
|
pub fn add<DataA: DataRef, DataAK: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
a: Option<&GLWECiphertext<DataA>>,
|
a: Option<&GLWE<DataA>>,
|
||||||
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -162,7 +162,7 @@ impl GLWEPacker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Flush result to`res`.
|
/// Flush result to`res`.
|
||||||
pub fn flush<Data: DataMut, B: Backend>(&mut self, module: &Module<B>, res: &mut GLWECiphertext<Data>)
|
pub fn flush<Data: DataMut, B: Backend>(&mut self, module: &Module<B>, res: &mut GLWE<Data>)
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxCopy,
|
Module<B>: VecZnxCopy,
|
||||||
{
|
{
|
||||||
@@ -188,7 +188,7 @@ where
|
|||||||
|
|
||||||
fn pack_core<D: DataRef, DataAK: DataRef, B: Backend>(
|
fn pack_core<D: DataRef, DataAK: DataRef, B: Backend>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
a: Option<&GLWECiphertext<D>>,
|
a: Option<&GLWE<D>>,
|
||||||
accumulators: &mut [Accumulator],
|
accumulators: &mut [Accumulator],
|
||||||
i: usize,
|
i: usize,
|
||||||
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
||||||
@@ -258,7 +258,7 @@ fn pack_core<D: DataRef, DataAK: DataRef, B: Backend>(
|
|||||||
} else {
|
} else {
|
||||||
pack_core(
|
pack_core(
|
||||||
module,
|
module,
|
||||||
None::<&GLWECiphertext<Vec<u8>>>,
|
None::<&GLWE<Vec<u8>>>,
|
||||||
acc_next,
|
acc_next,
|
||||||
i + 1,
|
i + 1,
|
||||||
auto_keys,
|
auto_keys,
|
||||||
@@ -274,16 +274,15 @@ where
|
|||||||
KEY: GGLWEInfos,
|
KEY: GGLWEInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::alloc_bytes(out_infos)
|
GLWE::bytes_of(out_infos)
|
||||||
+ (GLWECiphertext::rsh_scratch_space(module.n())
|
+ (GLWE::rsh_scratch_space(module.n()) | GLWE::automorphism_inplace_scratch_space(module, out_infos, key_infos))
|
||||||
| GLWECiphertext::automorphism_inplace_scratch_space(module, out_infos, key_infos))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [combine] merges two ciphertexts together.
|
/// [combine] merges two ciphertexts together.
|
||||||
fn combine<D: DataRef, DataAK: DataRef, B: Backend>(
|
fn combine<D: DataRef, DataAK: DataRef, B: Backend>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
acc: &mut Accumulator,
|
acc: &mut Accumulator,
|
||||||
b: Option<&GLWECiphertext<D>>,
|
b: Option<&GLWE<D>>,
|
||||||
i: usize,
|
i: usize,
|
||||||
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
@@ -314,7 +313,7 @@ fn combine<D: DataRef, DataAK: DataRef, B: Backend>(
|
|||||||
Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx + TakeGLWECt,
|
Scratch<B>: TakeVecZnxDft<B> + ScratchAvailable + TakeVecZnx + TakeGLWECt,
|
||||||
{
|
{
|
||||||
let log_n: usize = acc.data.n().log2();
|
let log_n: usize = acc.data.n().log2();
|
||||||
let a: &mut GLWECiphertext<Vec<u8>> = &mut acc.data;
|
let a: &mut GLWE<Vec<u8>> = &mut acc.data;
|
||||||
|
|
||||||
let gal_el: i64 = if i == 0 {
|
let gal_el: i64 = if i == 0 {
|
||||||
-1
|
-1
|
||||||
@@ -395,7 +394,7 @@ fn combine<D: DataRef, DataAK: DataRef, B: Backend>(
|
|||||||
/// to [0: GLWE(m_0 * X^x_0 + m_1 * X^x_1 + ... + m_i * X^x_i)]
|
/// to [0: GLWE(m_0 * X^x_0 + m_1 * X^x_1 + ... + m_i * X^x_i)]
|
||||||
pub fn glwe_packing<D: DataMut, ATK, B: Backend>(
|
pub fn glwe_packing<D: DataMut, ATK, B: Backend>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
cts: &mut HashMap<usize, &mut GLWECiphertext<D>>,
|
cts: &mut HashMap<usize, &mut GLWE<D>>,
|
||||||
log_gap_out: usize,
|
log_gap_out: usize,
|
||||||
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<ATK, B>>,
|
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<ATK, B>>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
@@ -446,8 +445,8 @@ pub fn glwe_packing<D: DataMut, ATK, B: Backend>(
|
|||||||
};
|
};
|
||||||
|
|
||||||
(0..t).for_each(|j| {
|
(0..t).for_each(|j| {
|
||||||
let mut a: Option<&mut GLWECiphertext<D>> = cts.remove(&j);
|
let mut a: Option<&mut GLWE<D>> = cts.remove(&j);
|
||||||
let mut b: Option<&mut GLWECiphertext<D>> = cts.remove(&(j + t));
|
let mut b: Option<&mut GLWE<D>> = cts.remove(&(j + t));
|
||||||
|
|
||||||
pack_internal(module, &mut a, &mut b, i, auto_key, scratch);
|
pack_internal(module, &mut a, &mut b, i, auto_key, scratch);
|
||||||
|
|
||||||
@@ -463,8 +462,8 @@ pub fn glwe_packing<D: DataMut, ATK, B: Backend>(
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn pack_internal<A: DataMut, D: DataMut, DataAK: DataRef, B: Backend>(
|
fn pack_internal<A: DataMut, D: DataMut, DataAK: DataRef, B: Backend>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
a: &mut Option<&mut GLWECiphertext<A>>,
|
a: &mut Option<&mut GLWE<A>>,
|
||||||
b: &mut Option<&mut GLWECiphertext<D>>,
|
b: &mut Option<&mut GLWE<D>>,
|
||||||
i: usize,
|
i: usize,
|
||||||
auto_key: &AutomorphismKeyPrepared<DataAK, B>,
|
auto_key: &AutomorphismKeyPrepared<DataAK, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
TakeGLWECt,
|
TakeGLWECt,
|
||||||
layouts::{Base2K, GGLWEInfos, GLWECiphertext, GLWECiphertextLayout, GLWEInfos, LWEInfos, prepared::AutomorphismKeyPrepared},
|
layouts::{Base2K, GGLWEInfos, GLWE, GLWEInfos, GLWELayout, LWEInfos, prepared::AutomorphismKeyPrepared},
|
||||||
operations::GLWEOperations,
|
operations::GLWEOperations,
|
||||||
};
|
};
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
pub fn trace_galois_elements<B: Backend>(module: &Module<B>) -> Vec<i64> {
|
pub fn trace_galois_elements<B: Backend>(module: &Module<B>) -> Vec<i64> {
|
||||||
let mut gal_els: Vec<i64> = Vec::new();
|
let mut gal_els: Vec<i64> = Vec::new();
|
||||||
(0..module.log_n()).for_each(|i| {
|
(0..module.log_n()).for_each(|i| {
|
||||||
@@ -42,7 +42,7 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
{
|
{
|
||||||
let trace: usize = Self::automorphism_inplace_scratch_space(module, out_infos, key_infos);
|
let trace: usize = Self::automorphism_inplace_scratch_space(module, out_infos, key_infos);
|
||||||
if in_infos.base2k() != key_infos.base2k() {
|
if in_infos.base2k() != key_infos.base2k() {
|
||||||
let glwe_conv: usize = VecZnx::alloc_bytes(
|
let glwe_conv: usize = VecZnx::bytes_of(
|
||||||
module.n(),
|
module.n(),
|
||||||
(key_infos.rank_out() + 1).into(),
|
(key_infos.rank_out() + 1).into(),
|
||||||
out_infos.k().min(in_infos.k()).div_ceil(key_infos.base2k()) as usize,
|
out_infos.k().min(in_infos.k()).div_ceil(key_infos.base2k()) as usize,
|
||||||
@@ -63,13 +63,13 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
impl<DataSelf: DataMut> GLWE<DataSelf> {
|
||||||
pub fn trace<DataLhs: DataRef, DataAK: DataRef, B: Backend>(
|
pub fn trace<DataLhs: DataRef, DataAK: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
start: usize,
|
start: usize,
|
||||||
end: usize,
|
end: usize,
|
||||||
lhs: &GLWECiphertext<DataLhs>,
|
lhs: &GLWE<DataLhs>,
|
||||||
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
auto_keys: &HashMap<i64, AutomorphismKeyPrepared<DataAK, B>>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -135,7 +135,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.base2k() != basek_ksk {
|
if self.base2k() != basek_ksk {
|
||||||
let (mut self_conv, scratch_1) = scratch.take_glwe_ct(&GLWECiphertextLayout {
|
let (mut self_conv, scratch_1) = scratch.take_glwe_ct(&GLWELayout {
|
||||||
n: module.n().into(),
|
n: module.n().into(),
|
||||||
base2k: basek_ksk,
|
base2k: basek_ksk,
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
AutomorphismKey, GGLWEInfos, GLWECiphertext, GLWEInfos, GLWESwitchingKey,
|
AutomorphismKey, GGLWEInfos, GLWE, GLWEInfos, GLWESwitchingKey,
|
||||||
prepared::{AutomorphismKeyPrepared, GLWESwitchingKeyPrepared},
|
prepared::{AutomorphismKeyPrepared, GLWESwitchingKeyPrepared},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ impl GLWESwitchingKey<Vec<u8>> {
|
|||||||
KEY: GGLWEInfos,
|
KEY: GGLWEInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::keyswitch_scratch_space(module, out_infos, in_infos, key_apply)
|
GLWE::keyswitch_scratch_space(module, out_infos, in_infos, key_apply)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keyswitch_inplace_scratch_space<B: Backend, OUT, KEY>(module: &Module<B>, out_infos: &OUT, key_apply: &KEY) -> usize
|
pub fn keyswitch_inplace_scratch_space<B: Backend, OUT, KEY>(module: &Module<B>, out_infos: &OUT, key_apply: &KEY) -> usize
|
||||||
@@ -107,7 +107,7 @@ impl GLWESwitchingKey<Vec<u8>> {
|
|||||||
KEY: GGLWEInfos + GLWEInfos,
|
KEY: GGLWEInfos + GLWEInfos,
|
||||||
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
Module<B>: VecZnxDftAllocBytes + VmpApplyDftToDftTmpBytes + VecZnxBigNormalizeTmpBytes + VecZnxNormalizeTmpBytes,
|
||||||
{
|
{
|
||||||
GLWECiphertext::keyswitch_inplace_scratch_space(module, out_infos, key_apply)
|
GLWE::keyswitch_inplace_scratch_space(module, out_infos, key_apply)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
layouts::{
|
layouts::{
|
||||||
GGLWE, GGLWEInfos, GGSW, GGSWInfos, GLWECiphertext, GLWEInfos, LWEInfos,
|
GGLWE, GGLWEInfos, GGSW, GGSWInfos, GLWE, GLWEInfos, LWEInfos,
|
||||||
prepared::{GLWESwitchingKeyPrepared, TensorKeyPrepared},
|
prepared::{GLWESwitchingKeyPrepared, TensorKeyPrepared},
|
||||||
},
|
},
|
||||||
operations::GLWEOperations,
|
operations::GLWEOperations,
|
||||||
@@ -29,8 +29,8 @@ impl GGSW<Vec<u8>> {
|
|||||||
.div_ceil(tsk_infos.base2k())
|
.div_ceil(tsk_infos.base2k())
|
||||||
.div_ceil(tsk_infos.dsize().into()) as usize;
|
.div_ceil(tsk_infos.dsize().into()) as usize;
|
||||||
|
|
||||||
let tmp_dft_i: usize = module.vec_znx_dft_alloc_bytes((tsk_infos.rank_out() + 1).into(), tsk_size);
|
let tmp_dft_i: usize = module.vec_znx_dft_bytes_of((tsk_infos.rank_out() + 1).into(), tsk_size);
|
||||||
let tmp_a: usize = module.vec_znx_dft_alloc_bytes(1, size_in);
|
let tmp_a: usize = module.vec_znx_dft_bytes_of(1, size_in);
|
||||||
let vmp: usize = module.vmp_apply_dft_to_dft_tmp_bytes(
|
let vmp: usize = module.vmp_apply_dft_to_dft_tmp_bytes(
|
||||||
tsk_size,
|
tsk_size,
|
||||||
size_in,
|
size_in,
|
||||||
@@ -39,7 +39,7 @@ impl GGSW<Vec<u8>> {
|
|||||||
(tsk_infos.rank_out()).into(), // Verify if rank+1
|
(tsk_infos.rank_out()).into(), // Verify if rank+1
|
||||||
tsk_size,
|
tsk_size,
|
||||||
);
|
);
|
||||||
let tmp_idft: usize = module.vec_znx_big_alloc_bytes(1, tsk_size);
|
let tmp_idft: usize = module.vec_znx_big_bytes_of(1, tsk_size);
|
||||||
let norm: usize = module.vec_znx_normalize_tmp_bytes();
|
let norm: usize = module.vec_znx_normalize_tmp_bytes();
|
||||||
|
|
||||||
tmp_dft_i + ((tmp_a + vmp) | (tmp_idft + norm))
|
tmp_dft_i + ((tmp_a + vmp) | (tmp_idft + norm))
|
||||||
@@ -74,16 +74,16 @@ impl GGSW<Vec<u8>> {
|
|||||||
let rank: usize = apply_infos.rank_out().into();
|
let rank: usize = apply_infos.rank_out().into();
|
||||||
|
|
||||||
let size_out: usize = out_infos.k().div_ceil(out_infos.base2k()) as usize;
|
let size_out: usize = out_infos.k().div_ceil(out_infos.base2k()) as usize;
|
||||||
let res_znx: usize = VecZnx::alloc_bytes(module.n(), rank + 1, size_out);
|
let res_znx: usize = VecZnx::bytes_of(module.n(), rank + 1, size_out);
|
||||||
let ci_dft: usize = module.vec_znx_dft_alloc_bytes(rank + 1, size_out);
|
let ci_dft: usize = module.vec_znx_dft_bytes_of(rank + 1, size_out);
|
||||||
let ks: usize = GLWECiphertext::keyswitch_scratch_space(module, out_infos, in_infos, apply_infos);
|
let ks: usize = GLWE::keyswitch_scratch_space(module, out_infos, in_infos, apply_infos);
|
||||||
let expand_rows: usize = GGSW::expand_row_scratch_space(module, out_infos, tsk_infos);
|
let expand_rows: usize = GGSW::expand_row_scratch_space(module, out_infos, tsk_infos);
|
||||||
let res_dft: usize = module.vec_znx_dft_alloc_bytes(rank + 1, size_out);
|
let res_dft: usize = module.vec_znx_dft_bytes_of(rank + 1, size_out);
|
||||||
|
|
||||||
if in_infos.base2k() == tsk_infos.base2k() {
|
if in_infos.base2k() == tsk_infos.base2k() {
|
||||||
res_znx + ci_dft + (ks | expand_rows | res_dft)
|
res_znx + ci_dft + (ks | expand_rows | res_dft)
|
||||||
} else {
|
} else {
|
||||||
let a_conv: usize = VecZnx::alloc_bytes(
|
let a_conv: usize = VecZnx::bytes_of(
|
||||||
module.n(),
|
module.n(),
|
||||||
1,
|
1,
|
||||||
out_infos.k().div_ceil(tsk_infos.base2k()) as usize,
|
out_infos.k().div_ceil(tsk_infos.base2k()) as usize,
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, DataRef, DataViewMut, Module, Scratch, VecZnx, VecZnxBig, VecZnxDft, VmpPMat, ZnxInfos},
|
layouts::{Backend, DataMut, DataRef, DataViewMut, Module, Scratch, VecZnx, VecZnxBig, VecZnxDft, VmpPMat, ZnxInfos},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GGLWEInfos, GLWECiphertext, GLWEInfos, LWEInfos, prepared::GLWESwitchingKeyPrepared};
|
use crate::layouts::{GGLWEInfos, GLWE, GLWEInfos, LWEInfos, prepared::GLWESwitchingKeyPrepared};
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
pub fn keyswitch_scratch_space<B: Backend, OUT, IN, KEY>(
|
pub fn keyswitch_scratch_space<B: Backend, OUT, IN, KEY>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
out_infos: &OUT,
|
out_infos: &OUT,
|
||||||
@@ -28,8 +28,8 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
.div_ceil(key_apply.dsize().into()) as usize;
|
.div_ceil(key_apply.dsize().into()) as usize;
|
||||||
let out_size: usize = out_infos.size();
|
let out_size: usize = out_infos.size();
|
||||||
let ksk_size: usize = key_apply.size();
|
let ksk_size: usize = key_apply.size();
|
||||||
let res_dft: usize = module.vec_znx_dft_alloc_bytes((key_apply.rank_out() + 1).into(), ksk_size); // TODO OPTIMIZE
|
let res_dft: usize = module.vec_znx_dft_bytes_of((key_apply.rank_out() + 1).into(), ksk_size); // TODO OPTIMIZE
|
||||||
let ai_dft: usize = module.vec_znx_dft_alloc_bytes((key_apply.rank_in()).into(), in_size);
|
let ai_dft: usize = module.vec_znx_dft_bytes_of((key_apply.rank_in()).into(), in_size);
|
||||||
let vmp: usize = module.vmp_apply_dft_to_dft_tmp_bytes(
|
let vmp: usize = module.vmp_apply_dft_to_dft_tmp_bytes(
|
||||||
out_size,
|
out_size,
|
||||||
in_size,
|
in_size,
|
||||||
@@ -37,17 +37,17 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
(key_apply.rank_in()).into(),
|
(key_apply.rank_in()).into(),
|
||||||
(key_apply.rank_out() + 1).into(),
|
(key_apply.rank_out() + 1).into(),
|
||||||
ksk_size,
|
ksk_size,
|
||||||
) + module.vec_znx_dft_alloc_bytes((key_apply.rank_in()).into(), in_size);
|
) + module.vec_znx_dft_bytes_of((key_apply.rank_in()).into(), in_size);
|
||||||
let normalize_big: usize = module.vec_znx_big_normalize_tmp_bytes();
|
let normalize_big: usize = module.vec_znx_big_normalize_tmp_bytes();
|
||||||
if in_infos.base2k() == key_apply.base2k() {
|
if in_infos.base2k() == key_apply.base2k() {
|
||||||
res_dft + ((ai_dft + vmp) | normalize_big)
|
res_dft + ((ai_dft + vmp) | normalize_big)
|
||||||
} else if key_apply.dsize() == 1 {
|
} else if key_apply.dsize() == 1 {
|
||||||
// In this case, we only need one column, temporary, that we can drop once a_dft is computed.
|
// In this case, we only need one column, temporary, that we can drop once a_dft is computed.
|
||||||
let normalize_conv: usize = VecZnx::alloc_bytes(module.n(), 1, in_size) + module.vec_znx_normalize_tmp_bytes();
|
let normalize_conv: usize = VecZnx::bytes_of(module.n(), 1, in_size) + module.vec_znx_normalize_tmp_bytes();
|
||||||
res_dft + (((ai_dft + normalize_conv) | vmp) | normalize_big)
|
res_dft + (((ai_dft + normalize_conv) | vmp) | normalize_big)
|
||||||
} else {
|
} else {
|
||||||
// Since we stride over a to get a_dft when dsize > 1, we need to store the full columns of a with in the base conversion.
|
// Since we stride over a to get a_dft when dsize > 1, we need to store the full columns of a with in the base conversion.
|
||||||
let normalize_conv: usize = VecZnx::alloc_bytes(module.n(), (key_apply.rank_in()).into(), in_size);
|
let normalize_conv: usize = VecZnx::bytes_of(module.n(), (key_apply.rank_in()).into(), in_size);
|
||||||
res_dft + ((ai_dft + normalize_conv + (module.vec_znx_normalize_tmp_bytes() | vmp)) | normalize_big)
|
res_dft + ((ai_dft + normalize_conv + (module.vec_znx_normalize_tmp_bytes() | vmp)) | normalize_big)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,12 +62,12 @@ impl GLWECiphertext<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DataSelf: DataRef> GLWECiphertext<DataSelf> {
|
impl<DataSelf: DataRef> GLWE<DataSelf> {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub(crate) fn assert_keyswitch<B: Backend, DataLhs, DataRhs>(
|
pub(crate) fn assert_keyswitch<B: Backend, DataLhs, DataRhs>(
|
||||||
&self,
|
&self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
lhs: &GLWECiphertext<DataLhs>,
|
lhs: &GLWE<DataLhs>,
|
||||||
rhs: &GLWESwitchingKeyPrepared<DataRhs, B>,
|
rhs: &GLWESwitchingKeyPrepared<DataRhs, B>,
|
||||||
scratch: &Scratch<B>,
|
scratch: &Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -93,7 +93,7 @@ impl<DataSelf: DataRef> GLWECiphertext<DataSelf> {
|
|||||||
assert_eq!(rhs.n(), self.n());
|
assert_eq!(rhs.n(), self.n());
|
||||||
assert_eq!(lhs.n(), self.n());
|
assert_eq!(lhs.n(), self.n());
|
||||||
|
|
||||||
let scrach_needed: usize = GLWECiphertext::keyswitch_scratch_space(module, self, lhs, rhs);
|
let scrach_needed: usize = GLWE::keyswitch_scratch_space(module, self, lhs, rhs);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
scratch.available() >= scrach_needed,
|
scratch.available() >= scrach_needed,
|
||||||
@@ -134,7 +134,7 @@ impl<DataSelf: DataRef> GLWECiphertext<DataSelf> {
|
|||||||
|
|
||||||
assert_eq!(rhs.n(), self.n());
|
assert_eq!(rhs.n(), self.n());
|
||||||
|
|
||||||
let scrach_needed: usize = GLWECiphertext::keyswitch_inplace_scratch_space(module, self, rhs);
|
let scrach_needed: usize = GLWE::keyswitch_inplace_scratch_space(module, self, rhs);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
scratch.available() >= scrach_needed,
|
scratch.available() >= scrach_needed,
|
||||||
@@ -144,11 +144,11 @@ impl<DataSelf: DataRef> GLWECiphertext<DataSelf> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
impl<DataSelf: DataMut> GLWE<DataSelf> {
|
||||||
pub fn keyswitch<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
pub fn keyswitch<DataLhs: DataRef, DataRhs: DataRef, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
glwe_in: &GLWECiphertext<DataLhs>,
|
glwe_in: &GLWE<DataLhs>,
|
||||||
rhs: &GLWESwitchingKeyPrepared<DataRhs, B>,
|
rhs: &GLWESwitchingKeyPrepared<DataRhs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -232,7 +232,7 @@ impl<DataSelf: DataMut> GLWECiphertext<DataSelf> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GLWECiphertext<D> {
|
impl<D: DataRef> GLWE<D> {
|
||||||
pub(crate) fn keyswitch_internal<B: Backend, DataRes, DataKey>(
|
pub(crate) fn keyswitch_internal<B: Backend, DataRes, DataKey>(
|
||||||
&self,
|
&self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
|
|||||||
@@ -9,13 +9,10 @@ use poulpy_hal::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
TakeGLWECt,
|
TakeGLWECt,
|
||||||
layouts::{
|
layouts::{GGLWEInfos, GLWE, GLWELayout, LWE, LWEInfos, Rank, TorusPrecision, prepared::LWESwitchingKeyPrepared},
|
||||||
GGLWEInfos, GLWECiphertext, GLWECiphertextLayout, LWECiphertext, LWEInfos, Rank, TorusPrecision,
|
|
||||||
prepared::LWESwitchingKeyPrepared,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl LWECiphertext<Vec<u8>> {
|
impl LWE<Vec<u8>> {
|
||||||
pub fn keyswitch_scratch_space<B: Backend, OUT, IN, KEY>(
|
pub fn keyswitch_scratch_space<B: Backend, OUT, IN, KEY>(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
out_infos: &OUT,
|
out_infos: &OUT,
|
||||||
@@ -40,33 +37,33 @@ impl LWECiphertext<Vec<u8>> {
|
|||||||
{
|
{
|
||||||
let max_k: TorusPrecision = in_infos.k().max(out_infos.k());
|
let max_k: TorusPrecision = in_infos.k().max(out_infos.k());
|
||||||
|
|
||||||
let glwe_in_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_in_infos: GLWELayout = GLWELayout {
|
||||||
n: module.n().into(),
|
n: module.n().into(),
|
||||||
base2k: in_infos.base2k(),
|
base2k: in_infos.base2k(),
|
||||||
k: max_k,
|
k: max_k,
|
||||||
rank: Rank(1),
|
rank: Rank(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_out_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_out_infos: GLWELayout = GLWELayout {
|
||||||
n: module.n().into(),
|
n: module.n().into(),
|
||||||
base2k: out_infos.base2k(),
|
base2k: out_infos.base2k(),
|
||||||
k: max_k,
|
k: max_k,
|
||||||
rank: Rank(1),
|
rank: Rank(1),
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_in: usize = GLWECiphertext::alloc_bytes(&glwe_in_infos);
|
let glwe_in: usize = GLWE::bytes_of(&glwe_in_infos);
|
||||||
let glwe_out: usize = GLWECiphertext::alloc_bytes(&glwe_out_infos);
|
let glwe_out: usize = GLWE::bytes_of(&glwe_out_infos);
|
||||||
let ks: usize = GLWECiphertext::keyswitch_scratch_space(module, &glwe_out_infos, &glwe_in_infos, key_infos);
|
let ks: usize = GLWE::keyswitch_scratch_space(module, &glwe_out_infos, &glwe_in_infos, key_infos);
|
||||||
|
|
||||||
glwe_in + glwe_out + ks
|
glwe_in + glwe_out + ks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<DLwe: DataMut> LWECiphertext<DLwe> {
|
impl<DLwe: DataMut> LWE<DLwe> {
|
||||||
pub fn keyswitch<A, DKs, B: Backend>(
|
pub fn keyswitch<A, DKs, B: Backend>(
|
||||||
&mut self,
|
&mut self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
a: &LWECiphertext<A>,
|
a: &LWE<A>,
|
||||||
ksk: &LWESwitchingKeyPrepared<DKs, B>,
|
ksk: &LWESwitchingKeyPrepared<DKs, B>,
|
||||||
scratch: &mut Scratch<B>,
|
scratch: &mut Scratch<B>,
|
||||||
) where
|
) where
|
||||||
@@ -90,14 +87,14 @@ impl<DLwe: DataMut> LWECiphertext<DLwe> {
|
|||||||
{
|
{
|
||||||
assert!(self.n() <= module.n() as u32);
|
assert!(self.n() <= module.n() as u32);
|
||||||
assert!(a.n() <= module.n() as u32);
|
assert!(a.n() <= module.n() as u32);
|
||||||
assert!(scratch.available() >= LWECiphertext::keyswitch_scratch_space(module, self, a, ksk));
|
assert!(scratch.available() >= LWE::keyswitch_scratch_space(module, self, a, ksk));
|
||||||
}
|
}
|
||||||
|
|
||||||
let max_k: TorusPrecision = self.k().max(a.k());
|
let max_k: TorusPrecision = self.k().max(a.k());
|
||||||
|
|
||||||
let a_size: usize = a.k().div_ceil(ksk.base2k()) as usize;
|
let a_size: usize = a.k().div_ceil(ksk.base2k()) as usize;
|
||||||
|
|
||||||
let (mut glwe_in, scratch_1) = scratch.take_glwe_ct(&GLWECiphertextLayout {
|
let (mut glwe_in, scratch_1) = scratch.take_glwe_ct(&GLWELayout {
|
||||||
n: ksk.n(),
|
n: ksk.n(),
|
||||||
base2k: a.base2k(),
|
base2k: a.base2k(),
|
||||||
k: max_k,
|
k: max_k,
|
||||||
@@ -105,7 +102,7 @@ impl<DLwe: DataMut> LWECiphertext<DLwe> {
|
|||||||
});
|
});
|
||||||
glwe_in.data.zero();
|
glwe_in.data.zero();
|
||||||
|
|
||||||
let (mut glwe_out, scratch_1) = scratch_1.take_glwe_ct(&GLWECiphertextLayout {
|
let (mut glwe_out, scratch_1) = scratch_1.take_glwe_ct(&GLWELayout {
|
||||||
n: ksk.n(),
|
n: ksk.n(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
k: max_k,
|
k: max_k,
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
api::{VecZnxCopy, VecZnxFillUniform},
|
|
||||||
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
AutomorphismKey, Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
AutomorphismKey, AutomorphismKeyToMut, Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||||
compressed::{Decompress, GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedToMut, GLWESwitchingKeyCompressedToRef},
|
compressed::{
|
||||||
|
GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedAlloc, GLWESwitchingKeyCompressedToMut,
|
||||||
|
GLWESwitchingKeyCompressedToRef, GLWESwitchingKeyDecompress,
|
||||||
|
},
|
||||||
|
prepared::{GetAutomorphismGaloisElement, SetAutomorphismGaloisElement},
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -76,35 +79,100 @@ impl<D: DataRef> fmt::Display for AutomorphismKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait AutomorphismKeyCompressedAlloc
|
||||||
|
where
|
||||||
|
Self: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_automorphism_key_compressed(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> AutomorphismKeyCompressed<Vec<u8>> {
|
||||||
|
AutomorphismKeyCompressed {
|
||||||
|
key: self.alloc_glwe_switching_key_compressed(base2k, k, rank, rank, dnum, dsize),
|
||||||
|
p: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_automorphism_key_compressed_from_infos<A>(&self, infos: &A) -> AutomorphismKeyCompressed<Vec<u8>>
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(infos.rank_in(), infos.rank_out());
|
||||||
|
self.alloc_automorphism_key_compressed(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_automorphism_key_compressed(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize {
|
||||||
|
self.bytes_of_glwe_switching_key_compressed(base2k, k, rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_automorphism_key_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(infos.rank_in(), infos.rank_out());
|
||||||
|
self.bytes_of_automorphism_key_compressed(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AutomorphismKeyCompressed<Vec<u8>> {
|
impl AutomorphismKeyCompressed<Vec<u8>> {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: AutomorphismKeyCompressedAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(infos.rank_in(), infos.rank_out());
|
module.alloc_automorphism_key_compressed_from_infos(infos)
|
||||||
Self {
|
|
||||||
key: GLWESwitchingKeyCompressed::alloc(infos),
|
|
||||||
p: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
|
||||||
Self {
|
where
|
||||||
key: GLWESwitchingKeyCompressed::alloc_with(n, base2k, k, rank, rank, dnum, dsize),
|
Module<B>: AutomorphismKeyCompressedAlloc,
|
||||||
p: 0,
|
{
|
||||||
}
|
module.alloc_automorphism_key_compressed(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: AutomorphismKeyCompressedAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(infos.rank_in(), infos.rank_out());
|
module.bytes_of_automorphism_key_compressed_from_infos(infos)
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
pub fn bytes_of<B: Backend>(
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rank, dnum, dsize)
|
module: Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: AutomorphismKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_automorphism_key_compressed(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,13 +190,32 @@ impl<D: DataRef> WriterTo for AutomorphismKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, AutomorphismKeyCompressed<DR>> for AutomorphismKey<D>
|
pub trait AutomorphismKeyDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GLWESwitchingKeyDecompress,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &AutomorphismKeyCompressed<DR>) {
|
fn decompress_automorphism_key<R, O>(&self, res: &mut R, other: &O)
|
||||||
self.key.decompress(module, &other.key);
|
where
|
||||||
self.p = other.p;
|
R: AutomorphismKeyToMut + SetAutomorphismGaloisElement,
|
||||||
|
O: AutomorphismKeyCompressedToRef + GetAutomorphismGaloisElement,
|
||||||
|
{
|
||||||
|
self.decompress_glwe_switching_key(&mut res.to_mut().key, &other.to_ref().key);
|
||||||
|
res.set_p(other.p());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> AutomorphismKeyDecompress for Module<B> where Self: AutomorphismKeyDecompress {}
|
||||||
|
|
||||||
|
impl<D: DataMut> AutomorphismKey<D>
|
||||||
|
where
|
||||||
|
Self: SetAutomorphismGaloisElement,
|
||||||
|
{
|
||||||
|
pub fn decompressed<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: AutomorphismKeyCompressedToRef + GetAutomorphismGaloisElement,
|
||||||
|
Module<B>: AutomorphismKeyDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_automorphism_key(self, other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GGLWEToMut, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision,
|
||||||
compressed::{Decompress, GLWECiphertextCompressed},
|
compressed::{GLWECompressed, GLWEDecompress},
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct GGLWECiphertextCompressed<D: Data> {
|
pub struct GGLWECompressed<D: Data> {
|
||||||
pub(crate) data: MatZnx<D>,
|
pub(crate) data: MatZnx<D>,
|
||||||
pub(crate) base2k: Base2K,
|
pub(crate) base2k: Base2K,
|
||||||
pub(crate) k: TorusPrecision,
|
pub(crate) k: TorusPrecision,
|
||||||
@@ -23,7 +23,7 @@ pub struct GGLWECiphertextCompressed<D: Data> {
|
|||||||
pub(crate) seed: Vec<[u8; 32]>,
|
pub(crate) seed: Vec<[u8; 32]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> LWEInfos for GGLWECiphertextCompressed<D> {
|
impl<D: Data> LWEInfos for GGLWECompressed<D> {
|
||||||
fn n(&self) -> Degree {
|
fn n(&self) -> Degree {
|
||||||
Degree(self.data.n() as u32)
|
Degree(self.data.n() as u32)
|
||||||
}
|
}
|
||||||
@@ -40,13 +40,13 @@ impl<D: Data> LWEInfos for GGLWECiphertextCompressed<D> {
|
|||||||
self.data.size()
|
self.data.size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<D: Data> GLWEInfos for GGLWECiphertextCompressed<D> {
|
impl<D: Data> GLWEInfos for GGLWECompressed<D> {
|
||||||
fn rank(&self) -> Rank {
|
fn rank(&self) -> Rank {
|
||||||
self.rank_out()
|
self.rank_out()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> GGLWEInfos for GGLWECiphertextCompressed<D> {
|
impl<D: Data> GGLWEInfos for GGLWECompressed<D> {
|
||||||
fn rank_in(&self) -> Rank {
|
fn rank_in(&self) -> Rank {
|
||||||
Rank(self.data.cols_in() as u32)
|
Rank(self.data.cols_in() as u32)
|
||||||
}
|
}
|
||||||
@@ -64,53 +64,41 @@ impl<D: Data> GGLWEInfos for GGLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Debug for GGLWECiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Debug for GGLWECompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{self}")
|
write!(f, "{self}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> FillUniform for GGLWECiphertextCompressed<D> {
|
impl<D: DataMut> FillUniform for GGLWECompressed<D> {
|
||||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||||
self.data.fill_uniform(log_bound, source);
|
self.data.fill_uniform(log_bound, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Display for GGLWECiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Display for GGLWECompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"(GGLWECiphertextCompressed: base2k={} k={} dsize={}) {}",
|
"(GGLWECompressed: base2k={} k={} dsize={}) {}",
|
||||||
self.base2k.0, self.k.0, self.dsize.0, self.data
|
self.base2k.0, self.k.0, self.dsize.0, self.data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GGLWECiphertextCompressed<Vec<u8>> {
|
pub trait GGLWECompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GGLWEInfos,
|
{
|
||||||
{
|
fn alloc_gglwe_compressed(
|
||||||
Self::alloc_with(
|
&self,
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
|
||||||
infos.k(),
|
|
||||||
infos.rank_in(),
|
|
||||||
infos.rank_out(),
|
|
||||||
infos.dnum(),
|
|
||||||
infos.dsize(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(
|
|
||||||
n: Degree,
|
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
rank_in: Rank,
|
rank_in: Rank,
|
||||||
rank_out: Rank,
|
rank_out: Rank,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> Self {
|
) -> GGLWECompressed<Vec<u8>> {
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
@@ -125,9 +113,9 @@ impl GGLWECiphertextCompressed<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
GGLWECompressed {
|
||||||
data: MatZnx::alloc(
|
data: MatZnx::alloc(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
rank_in.into(),
|
rank_in.into(),
|
||||||
1,
|
1,
|
||||||
@@ -141,21 +129,22 @@ impl GGLWECiphertextCompressed<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_gglwe_compressed_from_infos<A>(&self, infos: &A) -> GGLWECompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(
|
assert_eq!(infos.n(), self.n());
|
||||||
infos.n(),
|
self.alloc_gglwe_compressed(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank_in(),
|
infos.rank_in(),
|
||||||
|
infos.rank_out(),
|
||||||
infos.dnum(),
|
infos.dnum(),
|
||||||
infos.dsize(),
|
infos.dsize(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
fn bytes_of_gglwe_compressed(&self, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
@@ -170,20 +159,83 @@ impl GGLWECiphertextCompressed<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
MatZnx::alloc_bytes(
|
MatZnx::bytes_of(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
rank_in.into(),
|
rank_in.into(),
|
||||||
1,
|
1,
|
||||||
k.0.div_ceil(base2k.0) as usize,
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bytes_of_gglwe_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(infos.n(), self.n());
|
||||||
|
self.bytes_of_gglwe_compressed(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank_in(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GGLWECiphertextCompressed<D> {
|
impl<B: Backend> GGLWECompressedAlloc for Module<B> where Self: GetDegree {}
|
||||||
pub(crate) fn at(&self, row: usize, col: usize) -> GLWECiphertextCompressed<&[u8]> {
|
|
||||||
|
impl GGLWECompressed<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GGLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_gglwe_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(
|
||||||
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GGLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_gglwe_compressed(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GGLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_gglwe_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn byte_of<B: Backend>(
|
||||||
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GGLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_gglwe_compressed(base2k, k, rank_in, dnum, dsize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> GGLWECompressed<D> {
|
||||||
|
pub(crate) fn at(&self, row: usize, col: usize) -> GLWECompressed<&[u8]> {
|
||||||
let rank_in: usize = self.rank_in().into();
|
let rank_in: usize = self.rank_in().into();
|
||||||
GLWECiphertextCompressed {
|
GLWECompressed {
|
||||||
data: self.data.at(row, col),
|
data: self.data.at(row, col),
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
@@ -193,10 +245,10 @@ impl<D: DataRef> GGLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GGLWECiphertextCompressed<D> {
|
impl<D: DataMut> GGLWECompressed<D> {
|
||||||
pub(crate) fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertextCompressed<&mut [u8]> {
|
pub(crate) fn at_mut(&mut self, row: usize, col: usize) -> GLWECompressed<&mut [u8]> {
|
||||||
let rank_in: usize = self.rank_in().into();
|
let rank_in: usize = self.rank_in().into();
|
||||||
GLWECiphertextCompressed {
|
GLWECompressed {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
rank: self.rank_out,
|
rank: self.rank_out,
|
||||||
@@ -206,7 +258,7 @@ impl<D: DataMut> GGLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> ReaderFrom for GGLWECiphertextCompressed<D> {
|
impl<D: DataMut> ReaderFrom for GGLWECompressed<D> {
|
||||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||||
@@ -221,7 +273,7 @@ impl<D: DataMut> ReaderFrom for GGLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> WriterTo for GGLWECiphertextCompressed<D> {
|
impl<D: DataRef> WriterTo for GGLWECompressed<D> {
|
||||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||||
writer.write_u32::<LittleEndian>(self.k.into())?;
|
writer.write_u32::<LittleEndian>(self.k.into())?;
|
||||||
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
||||||
@@ -235,70 +287,50 @@ impl<D: DataRef> WriterTo for GGLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GGLWECiphertextCompressed<DR>> for GGLWE<D>
|
pub trait GGLWEDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GLWEDecompress,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &GGLWECiphertextCompressed<DR>) {
|
fn decompress_gglwe<R, O>(&self, res: &mut R, other: &O)
|
||||||
#[cfg(debug_assertions)]
|
where
|
||||||
|
R: GGLWEToMut,
|
||||||
|
O: GGLWECompressedToRef,
|
||||||
{
|
{
|
||||||
assert_eq!(
|
let res: &mut GGLWE<&mut [u8]> = &mut res.to_mut();
|
||||||
self.n(),
|
let other: &GGLWECompressed<&[u8]> = &other.to_ref();
|
||||||
other.n(),
|
|
||||||
"invalid receiver: self.n()={} != other.n()={}",
|
|
||||||
self.n(),
|
|
||||||
other.n()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
self.size(),
|
|
||||||
other.size(),
|
|
||||||
"invalid receiver: self.size()={} != other.size()={}",
|
|
||||||
self.size(),
|
|
||||||
other.size()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
self.rank_in(),
|
|
||||||
other.rank_in(),
|
|
||||||
"invalid receiver: self.rank_in()={} != other.rank_in()={}",
|
|
||||||
self.rank_in(),
|
|
||||||
other.rank_in()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
self.rank_out(),
|
|
||||||
other.rank_out(),
|
|
||||||
"invalid receiver: self.rank_out()={} != other.rank_out()={}",
|
|
||||||
self.rank_out(),
|
|
||||||
other.rank_out()
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(res.gglwe_layout(), other.gglwe_layout());
|
||||||
self.dnum(),
|
|
||||||
other.dnum(),
|
let rank_in: usize = res.rank_in().into();
|
||||||
"invalid receiver: self.dnum()={} != other.dnum()={}",
|
let dnum: usize = res.dnum().into();
|
||||||
self.dnum(),
|
|
||||||
other.dnum()
|
for row_i in 0..dnum {
|
||||||
);
|
for col_i in 0..rank_in {
|
||||||
|
self.decompress_glwe(&mut res.at_mut(row_i, col_i), &other.at(row_i, col_i));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let rank_in: usize = self.rank_in().into();
|
|
||||||
let dnum: usize = self.dnum().into();
|
|
||||||
|
|
||||||
(0..rank_in).for_each(|col_i| {
|
|
||||||
(0..dnum).for_each(|row_i| {
|
|
||||||
self.at_mut(row_i, col_i)
|
|
||||||
.decompress(module, &other.at(row_i, col_i));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GGLWECiphertextCompressedToMut {
|
impl<B: Backend> GGLWEDecompress for Module<B> where Self: VecZnxFillUniform + VecZnxCopy {}
|
||||||
fn to_mut(&mut self) -> GGLWECiphertextCompressed<&mut [u8]>;
|
|
||||||
|
impl<D: DataMut> GGLWE<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: GGLWECompressedToRef,
|
||||||
|
Module<B>: GGLWEDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_gglwe(self, other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GGLWECiphertextCompressedToMut for GGLWECiphertextCompressed<D> {
|
pub trait GGLWECompressedToMut {
|
||||||
fn to_mut(&mut self) -> GGLWECiphertextCompressed<&mut [u8]> {
|
fn to_mut(&mut self) -> GGLWECompressed<&mut [u8]>;
|
||||||
GGLWECiphertextCompressed {
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> GGLWECompressedToMut for GGLWECompressed<D> {
|
||||||
|
fn to_mut(&mut self) -> GGLWECompressed<&mut [u8]> {
|
||||||
|
GGLWECompressed {
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
dsize: self.dsize(),
|
dsize: self.dsize(),
|
||||||
@@ -309,13 +341,13 @@ impl<D: DataMut> GGLWECiphertextCompressedToMut for GGLWECiphertextCompressed<D>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GGLWECiphertextCompressedToRef {
|
pub trait GGLWECompressedToRef {
|
||||||
fn to_ref(&self) -> GGLWECiphertextCompressed<&[u8]>;
|
fn to_ref(&self) -> GGLWECompressed<&[u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GGLWECiphertextCompressedToRef for GGLWECiphertextCompressed<D> {
|
impl<D: DataRef> GGLWECompressedToRef for GGLWECompressed<D> {
|
||||||
fn to_ref(&self) -> GGLWECiphertextCompressed<&[u8]> {
|
fn to_ref(&self) -> GGLWECompressed<&[u8]> {
|
||||||
GGLWECiphertextCompressed {
|
GGLWECompressed {
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
dsize: self.dsize(),
|
dsize: self.dsize(),
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
api::{VecZnxCopy, VecZnxFillUniform},
|
|
||||||
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, LWEInfos, Rank, TorusPrecision,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeySetMetaData, GLWESwitchingKeyToMut,
|
||||||
compressed::{Decompress, GGLWECiphertextCompressed, GGLWECiphertextCompressedToMut, GGLWECiphertextCompressedToRef},
|
LWEInfos, Rank, TorusPrecision,
|
||||||
|
compressed::{GGLWECompressed, GGLWECompressedAlloc, GGLWECompressedToMut, GGLWECompressedToRef, GGLWEDecompress},
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct GLWESwitchingKeyCompressed<D: Data> {
|
pub struct GLWESwitchingKeyCompressed<D: Data> {
|
||||||
pub(crate) key: GGLWECiphertextCompressed<D>,
|
pub(crate) key: GGLWECompressed<D>,
|
||||||
pub(crate) sk_in_n: usize, // Degree of sk_in
|
pub(crate) sk_in_n: usize, // Degree of sk_in
|
||||||
pub(crate) sk_out_n: usize, // Degree of sk_out
|
pub(crate) sk_out_n: usize, // Degree of sk_out
|
||||||
}
|
}
|
||||||
@@ -81,43 +81,103 @@ impl<D: DataRef> fmt::Display for GLWESwitchingKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWESwitchingKeyCompressed<Vec<u8>> {
|
pub trait GLWESwitchingKeyCompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GGLWECompressedAlloc,
|
||||||
A: GGLWEInfos,
|
{
|
||||||
{
|
fn alloc_glwe_switching_key_compressed(
|
||||||
GLWESwitchingKeyCompressed {
|
&self,
|
||||||
key: GGLWECiphertextCompressed::alloc(infos),
|
|
||||||
sk_in_n: 0,
|
|
||||||
sk_out_n: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(
|
|
||||||
n: Degree,
|
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
rank_in: Rank,
|
rank_in: Rank,
|
||||||
rank_out: Rank,
|
rank_out: Rank,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> Self {
|
) -> GLWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
GLWESwitchingKeyCompressed {
|
GLWESwitchingKeyCompressed {
|
||||||
key: GGLWECiphertextCompressed::alloc_with(n, base2k, k, rank_in, rank_out, dnum, dsize),
|
key: self.alloc_gglwe_compressed(base2k, k, rank_in, rank_out, dnum, dsize),
|
||||||
sk_in_n: 0,
|
sk_in_n: 0,
|
||||||
sk_out_n: 0,
|
sk_out_n: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> GLWESwitchingKeyCompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
GGLWECiphertextCompressed::alloc_bytes(infos)
|
self.alloc_glwe_switching_key_compressed(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank_in(),
|
||||||
|
infos.rank_out(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
fn bytes_of_glwe_switching_key_compressed(
|
||||||
GGLWECiphertextCompressed::alloc_bytes_with(n, base2k, k, rank_in, dnum, dsize)
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize {
|
||||||
|
self.bytes_of_gglwe_compressed(base2k, k, rank_in, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_gglwe_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GLWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(
|
||||||
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_switching_key_compressed(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(
|
||||||
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_switching_key_compressed(base2k, k, rank_in, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,14 +197,31 @@ impl<D: DataRef> WriterTo for GLWESwitchingKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, GLWESwitchingKeyCompressed<DR>> for GLWESwitchingKey<D>
|
pub trait GLWESwitchingKeyDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GGLWEDecompress,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &GLWESwitchingKeyCompressed<DR>) {
|
fn decompress_glwe_switching_key<R, O>(&self, res: &mut R, other: &O)
|
||||||
self.key.decompress(module, &other.key);
|
where
|
||||||
self.sk_in_n = other.sk_in_n;
|
R: GLWESwitchingKeyToMut + GLWESwitchingKeySetMetaData,
|
||||||
self.sk_out_n = other.sk_out_n;
|
O: GLWESwitchingKeyCompressedToRef,
|
||||||
|
{
|
||||||
|
let other: &GLWESwitchingKeyCompressed<&[u8]> = &other.to_ref();
|
||||||
|
self.decompress_gglwe(&mut res.to_mut().key, &other.key);
|
||||||
|
res.set_sk_in_n(other.sk_in_n);
|
||||||
|
res.set_sk_out_n(other.sk_out_n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> GLWESwitchingKeyDecompress for Module<B> where Self: GGLWEDecompress {}
|
||||||
|
|
||||||
|
impl<D: DataMut> GLWESwitchingKey<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: GLWESwitchingKeyCompressedToRef,
|
||||||
|
Module<B>: GGLWEDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_glwe_switching_key(self, other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +231,7 @@ pub trait GLWESwitchingKeyCompressedToMut {
|
|||||||
|
|
||||||
impl<D: DataMut> GLWESwitchingKeyCompressedToMut for GLWESwitchingKeyCompressed<D>
|
impl<D: DataMut> GLWESwitchingKeyCompressedToMut for GLWESwitchingKeyCompressed<D>
|
||||||
where
|
where
|
||||||
GGLWECiphertextCompressed<D>: GGLWECiphertextCompressedToMut,
|
GGLWECompressed<D>: GGLWECompressedToMut,
|
||||||
{
|
{
|
||||||
fn to_mut(&mut self) -> GLWESwitchingKeyCompressed<&mut [u8]> {
|
fn to_mut(&mut self) -> GLWESwitchingKeyCompressed<&mut [u8]> {
|
||||||
GLWESwitchingKeyCompressed {
|
GLWESwitchingKeyCompressed {
|
||||||
@@ -171,7 +248,7 @@ pub trait GLWESwitchingKeyCompressedToRef {
|
|||||||
|
|
||||||
impl<D: DataRef> GLWESwitchingKeyCompressedToRef for GLWESwitchingKeyCompressed<D>
|
impl<D: DataRef> GLWESwitchingKeyCompressedToRef for GLWESwitchingKeyCompressed<D>
|
||||||
where
|
where
|
||||||
GGLWECiphertextCompressed<D>: GGLWECiphertextCompressedToRef,
|
GGLWECompressed<D>: GGLWECompressedToRef,
|
||||||
{
|
{
|
||||||
fn to_ref(&self) -> GLWESwitchingKeyCompressed<&[u8]> {
|
fn to_ref(&self) -> GLWESwitchingKeyCompressed<&[u8]> {
|
||||||
GLWESwitchingKeyCompressed {
|
GLWESwitchingKeyCompressed {
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
api::{VecZnxCopy, VecZnxFillUniform},
|
|
||||||
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TensorKey, TorusPrecision,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TensorKey, TensorKeyToMut, TorusPrecision,
|
||||||
compressed::{Decompress, GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedToMut, GLWESwitchingKeyCompressedToRef},
|
compressed::{
|
||||||
|
GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedAlloc, GLWESwitchingKeyCompressedToMut,
|
||||||
|
GLWESwitchingKeyCompressedToRef, GLWESwitchingKeyDecompress,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -80,8 +82,27 @@ impl<D: DataRef> fmt::Display for TensorKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TensorKeyCompressed<Vec<u8>> {
|
pub trait TensorKeyCompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
|
Self: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
fn tensor_key_compressed_alloc(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> TensorKeyCompressed<Vec<u8>> {
|
||||||
|
let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1);
|
||||||
|
TensorKeyCompressed {
|
||||||
|
keys: (0..pairs)
|
||||||
|
.map(|_| self.alloc_glwe_switching_key_compressed(base2k, k, Rank(1), rank, dnum, dsize))
|
||||||
|
.collect(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tensor_key_compressed_alloc_from_infos<A>(&self, infos: &A) -> TensorKeyCompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -90,58 +111,70 @@ impl TensorKeyCompressed<Vec<u8>> {
|
|||||||
infos.rank_out(),
|
infos.rank_out(),
|
||||||
"rank_in != rank_out is not supported for GGLWETensorKeyCompressed"
|
"rank_in != rank_out is not supported for GGLWETensorKeyCompressed"
|
||||||
);
|
);
|
||||||
Self::alloc_with(
|
self.tensor_key_compressed_alloc(
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank_out(),
|
infos.rank(),
|
||||||
infos.dnum(),
|
infos.dnum(),
|
||||||
infos.dsize(),
|
infos.dsize(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
fn tensor_key_compressed_bytes_of(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
let mut keys: Vec<GLWESwitchingKeyCompressed<Vec<u8>>> = Vec::new();
|
|
||||||
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
|
|
||||||
(0..pairs).for_each(|_| {
|
|
||||||
keys.push(GLWESwitchingKeyCompressed::alloc_with(
|
|
||||||
n,
|
|
||||||
base2k,
|
|
||||||
k,
|
|
||||||
Rank(1),
|
|
||||||
rank,
|
|
||||||
dnum,
|
|
||||||
dsize,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
Self { keys }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
|
||||||
where
|
|
||||||
A: GGLWEInfos,
|
|
||||||
{
|
|
||||||
assert_eq!(
|
|
||||||
infos.rank_in(),
|
|
||||||
infos.rank_out(),
|
|
||||||
"rank_in != rank_out is not supported for GGLWETensorKeyCompressed"
|
|
||||||
);
|
|
||||||
let rank_out: usize = infos.rank_out().into();
|
|
||||||
let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1);
|
|
||||||
pairs
|
|
||||||
* GLWESwitchingKeyCompressed::alloc_bytes_with(
|
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
|
||||||
infos.k(),
|
|
||||||
Rank(1),
|
|
||||||
infos.dnum(),
|
|
||||||
infos.dsize(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
|
||||||
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
|
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
|
||||||
pairs * GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, dsize)
|
pairs * self.bytes_of_glwe_switching_key_compressed(base2k, k, Rank(1), dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tensor_key_compressed_bytes_of_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
self.tensor_key_compressed_bytes_of(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TensorKeyCompressed<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: TensorKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.tensor_key_compressed_alloc_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: TensorKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.tensor_key_compressed_alloc(base2k, k, rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: TensorKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.tensor_key_compressed_bytes_of_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(
|
||||||
|
module: Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: TensorKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.tensor_key_compressed_bytes_of(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,28 +214,41 @@ impl<D: DataMut> TensorKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, TensorKeyCompressed<DR>> for TensorKey<D>
|
pub trait TensorKeyDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GLWESwitchingKeyDecompress,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &TensorKeyCompressed<DR>) {
|
fn decompress_tensor_key<R, O>(&self, res: &mut R, other: &O)
|
||||||
#[cfg(debug_assertions)]
|
where
|
||||||
|
R: TensorKeyToMut,
|
||||||
|
O: TensorKeyCompressedToRef,
|
||||||
{
|
{
|
||||||
|
let res: &mut TensorKey<&mut [u8]> = &mut res.to_mut();
|
||||||
|
let other: &TensorKeyCompressed<&[u8]> = &other.to_ref();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
self.keys.len(),
|
res.keys.len(),
|
||||||
other.keys.len(),
|
other.keys.len(),
|
||||||
"invalid receiver: self.keys.len()={} != other.keys.len()={}",
|
"invalid receiver: res.keys.len()={} != other.keys.len()={}",
|
||||||
self.keys.len(),
|
res.keys.len(),
|
||||||
other.keys.len()
|
other.keys.len()
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
self.keys
|
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
|
||||||
.iter_mut()
|
self.decompress_glwe_switching_key(a, b);
|
||||||
.zip(other.keys.iter())
|
}
|
||||||
.for_each(|(a, b)| {
|
}
|
||||||
a.decompress(module, b);
|
}
|
||||||
});
|
|
||||||
|
impl<B: Backend> TensorKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
|
||||||
|
|
||||||
|
impl<D: DataMut> TensorKey<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: TensorKeyCompressedToRef,
|
||||||
|
Module<B>: GLWESwitchingKeyDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_tensor_key(self, other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
api::{VecZnxCopy, VecZnxFillUniform},
|
|
||||||
layouts::{
|
layouts::{
|
||||||
Backend, Data, DataMut, DataRef, FillUniform, MatZnx, MatZnxToMut, MatZnxToRef, Module, ReaderFrom, WriterTo, ZnxInfos,
|
Backend, Data, DataMut, DataRef, FillUniform, MatZnx, MatZnxToMut, MatZnxToRef, Module, ReaderFrom, WriterTo, ZnxInfos,
|
||||||
},
|
},
|
||||||
@@ -7,14 +6,14 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGSW, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
Base2K, Degree, Dnum, Dsize, GGSW, GGSWInfos, GGSWToMut, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision,
|
||||||
compressed::{Decompress, GLWECiphertextCompressed},
|
compressed::{GLWECompressed, GLWEDecompress},
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct GGSWCiphertextCompressed<D: Data> {
|
pub struct GGSWCompressed<D: Data> {
|
||||||
pub(crate) data: MatZnx<D>,
|
pub(crate) data: MatZnx<D>,
|
||||||
pub(crate) k: TorusPrecision,
|
pub(crate) k: TorusPrecision,
|
||||||
pub(crate) base2k: Base2K,
|
pub(crate) base2k: Base2K,
|
||||||
@@ -23,7 +22,7 @@ pub struct GGSWCiphertextCompressed<D: Data> {
|
|||||||
pub(crate) seed: Vec<[u8; 32]>,
|
pub(crate) seed: Vec<[u8; 32]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> LWEInfos for GGSWCiphertextCompressed<D> {
|
impl<D: Data> LWEInfos for GGSWCompressed<D> {
|
||||||
fn n(&self) -> Degree {
|
fn n(&self) -> Degree {
|
||||||
Degree(self.data.n() as u32)
|
Degree(self.data.n() as u32)
|
||||||
}
|
}
|
||||||
@@ -39,13 +38,13 @@ impl<D: Data> LWEInfos for GGSWCiphertextCompressed<D> {
|
|||||||
self.data.size()
|
self.data.size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<D: Data> GLWEInfos for GGSWCiphertextCompressed<D> {
|
impl<D: Data> GLWEInfos for GGSWCompressed<D> {
|
||||||
fn rank(&self) -> Rank {
|
fn rank(&self) -> Rank {
|
||||||
self.rank
|
self.rank
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> GGSWInfos for GGSWCiphertextCompressed<D> {
|
impl<D: Data> GGSWInfos for GGSWCompressed<D> {
|
||||||
fn dsize(&self) -> Dsize {
|
fn dsize(&self) -> Dsize {
|
||||||
self.dsize
|
self.dsize
|
||||||
}
|
}
|
||||||
@@ -55,46 +54,42 @@ impl<D: Data> GGSWInfos for GGSWCiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Debug for GGSWCiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Debug for GGSWCompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", self.data)
|
write!(f, "{}", self.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Display for GGSWCiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Display for GGSWCompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"(GGSWCiphertextCompressed: base2k={} k={} dsize={}) {}",
|
"(GGSWCompressed: base2k={} k={} dsize={}) {}",
|
||||||
self.base2k, self.k, self.dsize, self.data
|
self.base2k, self.k, self.dsize, self.data
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> FillUniform for GGSWCiphertextCompressed<D> {
|
impl<D: DataMut> FillUniform for GGSWCompressed<D> {
|
||||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||||
self.data.fill_uniform(log_bound, source);
|
self.data.fill_uniform(log_bound, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GGSWCiphertextCompressed<Vec<u8>> {
|
pub trait GGSWCompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GGSWInfos,
|
{
|
||||||
{
|
fn alloc_ggsw_compressed(
|
||||||
Self::alloc_with(
|
&self,
|
||||||
infos.n(),
|
base2k: Base2K,
|
||||||
infos.base2k(),
|
k: TorusPrecision,
|
||||||
infos.k(),
|
rank: Rank,
|
||||||
infos.rank(),
|
dnum: Dnum,
|
||||||
infos.dnum(),
|
dsize: Dsize,
|
||||||
infos.dsize(),
|
) -> GGSWCompressed<Vec<u8>> {
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
"invalid ggsw: ceil(k/base2k): {size} <= dsize: {}",
|
"invalid ggsw: ceil(k/base2k): {size} <= dsize: {}",
|
||||||
dsize.0
|
dsize.0
|
||||||
@@ -107,9 +102,9 @@ impl GGSWCiphertextCompressed<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
GGSWCompressed {
|
||||||
data: MatZnx::alloc(
|
data: MatZnx::alloc(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
(rank + 1).into(),
|
(rank + 1).into(),
|
||||||
1,
|
1,
|
||||||
@@ -123,12 +118,11 @@ impl GGSWCiphertextCompressed<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_ggsw_compressed_from_infos<A>(&self, infos: &A) -> GGSWCompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGSWInfos,
|
A: GGSWInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(
|
self.alloc_ggsw_compressed(
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank(),
|
infos.rank(),
|
||||||
@@ -137,9 +131,9 @@ impl GGSWCiphertextCompressed<Vec<u8>> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
fn bytes_of_ggsw_compressed(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
"invalid ggsw: ceil(k/base2k): {size} <= dsize: {}",
|
"invalid ggsw: ceil(k/base2k): {size} <= dsize: {}",
|
||||||
dsize.0
|
dsize.0
|
||||||
@@ -152,20 +146,72 @@ impl GGSWCiphertextCompressed<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
MatZnx::alloc_bytes(
|
MatZnx::bytes_of(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
(rank + 1).into(),
|
(rank + 1).into(),
|
||||||
1,
|
1,
|
||||||
k.0.div_ceil(base2k.0) as usize,
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bytes_of_ggsw_compressed_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGSWInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_ggsw_compressed(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GGSWCiphertextCompressed<D> {
|
impl GGSWCompressed<Vec<u8>> {
|
||||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertextCompressed<&[u8]> {
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGSWInfos,
|
||||||
|
Module<B>: GGSWCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_ggsw_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GGSWCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_ggsw_compressed(base2k, k, rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGSWInfos,
|
||||||
|
Module<B>: GGSWCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_ggsw_compressed_key_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(
|
||||||
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GGSWCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_ggsw_compressed(base2k, k, rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> GGSWCompressed<D> {
|
||||||
|
pub fn at(&self, row: usize, col: usize) -> GLWECompressed<&[u8]> {
|
||||||
let rank: usize = self.rank().into();
|
let rank: usize = self.rank().into();
|
||||||
GLWECiphertextCompressed {
|
GLWECompressed {
|
||||||
data: self.data.at(row, col),
|
data: self.data.at(row, col),
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
@@ -175,10 +221,10 @@ impl<D: DataRef> GGSWCiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GGSWCiphertextCompressed<D> {
|
impl<D: DataMut> GGSWCompressed<D> {
|
||||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertextCompressed<&mut [u8]> {
|
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECompressed<&mut [u8]> {
|
||||||
let rank: usize = self.rank().into();
|
let rank: usize = self.rank().into();
|
||||||
GLWECiphertextCompressed {
|
GLWECompressed {
|
||||||
data: self.data.at_mut(row, col),
|
data: self.data.at_mut(row, col),
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
@@ -188,7 +234,7 @@ impl<D: DataMut> GGSWCiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> ReaderFrom for GGSWCiphertextCompressed<D> {
|
impl<D: DataMut> ReaderFrom for GGSWCompressed<D> {
|
||||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||||
@@ -203,7 +249,7 @@ impl<D: DataMut> ReaderFrom for GGSWCiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> WriterTo for GGSWCiphertextCompressed<D> {
|
impl<D: DataRef> WriterTo for GGSWCompressed<D> {
|
||||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||||
writer.write_u32::<LittleEndian>(self.k.into())?;
|
writer.write_u32::<LittleEndian>(self.k.into())?;
|
||||||
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
||||||
@@ -217,34 +263,49 @@ impl<D: DataRef> WriterTo for GGSWCiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GGSWCiphertextCompressed<DR>> for GGSW<D>
|
pub trait GGSWDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GLWEDecompress,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &GGSWCiphertextCompressed<DR>) {
|
fn decompress_ggsw<R, O>(&self, res: &mut R, other: &O)
|
||||||
#[cfg(debug_assertions)]
|
where
|
||||||
|
R: GGSWToMut,
|
||||||
|
O: GGSWCompressedToRef,
|
||||||
{
|
{
|
||||||
assert_eq!(self.rank(), other.rank())
|
let res: &mut GGSW<&mut [u8]> = &mut res.to_mut();
|
||||||
}
|
let other: &GGSWCompressed<&[u8]> = &other.to_ref();
|
||||||
|
|
||||||
let dnum: usize = self.dnum().into();
|
assert_eq!(res.rank(), other.rank());
|
||||||
let rank: usize = self.rank().into();
|
let dnum: usize = res.dnum().into();
|
||||||
(0..dnum).for_each(|row_i| {
|
let rank: usize = res.rank().into();
|
||||||
(0..rank + 1).for_each(|col_j| {
|
|
||||||
self.at_mut(row_i, col_j)
|
for row_i in 0..dnum {
|
||||||
.decompress(module, &other.at(row_i, col_j));
|
for col_j in 0..rank + 1 {
|
||||||
});
|
self.decompress_glwe(&mut res.at_mut(row_i, col_j), &other.at(row_i, col_j));
|
||||||
});
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GGSWCiphertextCompressedToMut {
|
impl<B: Backend> GGSWDecompress for Module<B> where Self: GGSWDecompress {}
|
||||||
fn to_mut(&mut self) -> GGSWCiphertextCompressed<&mut [u8]>;
|
|
||||||
|
impl<D: DataMut> GGSW<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: GGSWCompressedToRef,
|
||||||
|
Module<B>: GGSWDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_ggsw(self, other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GGSWCiphertextCompressedToMut for GGSWCiphertextCompressed<D> {
|
pub trait GGSWCompressedToMut {
|
||||||
fn to_mut(&mut self) -> GGSWCiphertextCompressed<&mut [u8]> {
|
fn to_mut(&mut self) -> GGSWCompressed<&mut [u8]>;
|
||||||
GGSWCiphertextCompressed {
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> GGSWCompressedToMut for GGSWCompressed<D> {
|
||||||
|
fn to_mut(&mut self) -> GGSWCompressed<&mut [u8]> {
|
||||||
|
GGSWCompressed {
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
dsize: self.dsize(),
|
dsize: self.dsize(),
|
||||||
@@ -255,13 +316,13 @@ impl<D: DataMut> GGSWCiphertextCompressedToMut for GGSWCiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GGSWCiphertextCompressedToRef {
|
pub trait GGSWCompressedToRef {
|
||||||
fn to_ref(&self) -> GGSWCiphertextCompressed<&[u8]>;
|
fn to_ref(&self) -> GGSWCompressed<&[u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GGSWCiphertextCompressedToRef for GGSWCiphertextCompressed<D> {
|
impl<D: DataRef> GGSWCompressedToRef for GGSWCompressed<D> {
|
||||||
fn to_ref(&self) -> GGSWCiphertextCompressed<&[u8]> {
|
fn to_ref(&self) -> GGSWCompressed<&[u8]> {
|
||||||
GGSWCiphertextCompressed {
|
GGSWCompressed {
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
dsize: self.dsize(),
|
dsize: self.dsize(),
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ use poulpy_hal::{
|
|||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{Base2K, Degree, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::Decompress};
|
use crate::layouts::{Base2K, Degree, GLWE, GLWEInfos, GLWEToMut, GetDegree, LWEInfos, Rank, SetGLWEInfos, TorusPrecision};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct GLWECiphertextCompressed<D: Data> {
|
pub struct GLWECompressed<D: Data> {
|
||||||
pub(crate) data: VecZnx<D>,
|
pub(crate) data: VecZnx<D>,
|
||||||
pub(crate) base2k: Base2K,
|
pub(crate) base2k: Base2K,
|
||||||
pub(crate) k: TorusPrecision,
|
pub(crate) k: TorusPrecision,
|
||||||
@@ -19,7 +19,7 @@ pub struct GLWECiphertextCompressed<D: Data> {
|
|||||||
pub(crate) seed: [u8; 32],
|
pub(crate) seed: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> LWEInfos for GLWECiphertextCompressed<D> {
|
impl<D: Data> LWEInfos for GLWECompressed<D> {
|
||||||
fn base2k(&self) -> Base2K {
|
fn base2k(&self) -> Base2K {
|
||||||
self.base2k
|
self.base2k
|
||||||
}
|
}
|
||||||
@@ -36,23 +36,23 @@ impl<D: Data> LWEInfos for GLWECiphertextCompressed<D> {
|
|||||||
Degree(self.data.n() as u32)
|
Degree(self.data.n() as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<D: Data> GLWEInfos for GLWECiphertextCompressed<D> {
|
impl<D: Data> GLWEInfos for GLWECompressed<D> {
|
||||||
fn rank(&self) -> Rank {
|
fn rank(&self) -> Rank {
|
||||||
self.rank
|
self.rank
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Debug for GLWECiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Debug for GLWECompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{self}")
|
write!(f, "{self}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Display for GLWECiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Display for GLWECompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"GLWECiphertextCompressed: base2k={} k={} rank={} seed={:?}: {}",
|
"GLWECompressed: base2k={} k={} rank={} seed={:?}: {}",
|
||||||
self.base2k(),
|
self.base2k(),
|
||||||
self.k(),
|
self.k(),
|
||||||
self.rank(),
|
self.rank(),
|
||||||
@@ -62,23 +62,19 @@ impl<D: DataRef> fmt::Display for GLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> FillUniform for GLWECiphertextCompressed<D> {
|
impl<D: DataMut> FillUniform for GLWECompressed<D> {
|
||||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||||
self.data.fill_uniform(log_bound, source);
|
self.data.fill_uniform(log_bound, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWECiphertextCompressed<Vec<u8>> {
|
pub trait GLWECompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GLWEInfos,
|
{
|
||||||
{
|
fn alloc_glwe_compressed(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> GLWECompressed<Vec<u8>> {
|
||||||
Self::alloc_with(infos.n(), infos.base2k(), infos.k(), infos.rank())
|
GLWECompressed {
|
||||||
}
|
data: VecZnx::alloc(self.n().into(), 1, k.0.div_ceil(base2k.0) as usize),
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
|
|
||||||
Self {
|
|
||||||
data: VecZnx::alloc(n.into(), 1, k.0.div_ceil(base2k.0) as usize),
|
|
||||||
base2k,
|
base2k,
|
||||||
k,
|
k,
|
||||||
rank,
|
rank,
|
||||||
@@ -86,19 +82,62 @@ impl GLWECiphertextCompressed<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_compressed_from_infos<A>(&self, infos: &A) -> GLWECompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(infos.n(), infos.base2k(), infos.k())
|
assert_eq!(self.n(), infos.n());
|
||||||
|
self.alloc_glwe_compressed(infos.base2k(), infos.k(), infos.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision) -> usize {
|
fn bytes_of_glwe_compressed(&self, base2k: Base2K, k: TorusPrecision) -> usize {
|
||||||
VecZnx::alloc_bytes(n.into(), 1, k.0.div_ceil(base2k.0) as usize)
|
VecZnx::bytes_of(self.n().into(), 1, k.0.div_ceil(base2k.0) as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(self.n(), infos.n());
|
||||||
|
self.bytes_of_glwe_compressed(infos.base2k(), infos.k())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> ReaderFrom for GLWECiphertextCompressed<D> {
|
impl<B: Backend> GLWECompressedAlloc for Module<B> where Self: GetDegree {}
|
||||||
|
|
||||||
|
impl GLWECompressed<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_compressed(base2k, k, rank)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_compressed(base2k, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> ReaderFrom for GLWECompressed<D> {
|
||||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||||
@@ -108,7 +147,7 @@ impl<D: DataMut> ReaderFrom for GLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> WriterTo for GLWECiphertextCompressed<D> {
|
impl<D: DataRef> WriterTo for GLWECompressed<D> {
|
||||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||||
writer.write_u32::<LittleEndian>(self.k.into())?;
|
writer.write_u32::<LittleEndian>(self.k.into())?;
|
||||||
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
||||||
@@ -118,74 +157,61 @@ impl<D: DataRef> WriterTo for GLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GLWECiphertextCompressed<DR>> for GLWECiphertext<D>
|
pub trait GLWEDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GetDegree + VecZnxFillUniform + VecZnxCopy,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &GLWECiphertextCompressed<DR>) {
|
fn decompress_glwe<R, O>(&self, res: &mut R, other: &O)
|
||||||
#[cfg(debug_assertions)]
|
where
|
||||||
|
R: GLWEToMut + SetGLWEInfos,
|
||||||
|
O: GLWECompressedToRef + GLWEInfos,
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
||||||
|
let other: &GLWECompressed<&[u8]> = &other.to_ref();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
res.n(),
|
||||||
self.n(),
|
self.n(),
|
||||||
other.n(),
|
"invalid receiver: res.n()={} != other.n()={}",
|
||||||
"invalid receiver: self.n()={} != other.n()={}",
|
res.n(),
|
||||||
self.n(),
|
self.n()
|
||||||
other.n()
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
|
||||||
self.size(),
|
assert_eq!(res.lwe_layout(), other.lwe_layout());
|
||||||
other.size(),
|
assert_eq!(res.glwe_layout(), other.glwe_layout());
|
||||||
"invalid receiver: self.size()={} != other.size()={}",
|
|
||||||
self.size(),
|
|
||||||
other.size()
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
self.rank(),
|
|
||||||
other.rank(),
|
|
||||||
"invalid receiver: self.rank()={} != other.rank()={}",
|
|
||||||
self.rank(),
|
|
||||||
other.rank()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut source: Source = Source::new(other.seed);
|
let mut source: Source = Source::new(other.seed);
|
||||||
self.decompress_internal(module, other, &mut source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertext<D> {
|
self.vec_znx_copy(&mut res.data, 0, &other.data, 0);
|
||||||
pub(crate) fn decompress_internal<DataOther, B: Backend>(
|
|
||||||
&mut self,
|
|
||||||
module: &Module<B>,
|
|
||||||
other: &GLWECiphertextCompressed<DataOther>,
|
|
||||||
source: &mut Source,
|
|
||||||
) where
|
|
||||||
DataOther: DataRef,
|
|
||||||
Module<B>: VecZnxCopy + VecZnxFillUniform,
|
|
||||||
{
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
{
|
|
||||||
assert_eq!(self.rank(), other.rank());
|
|
||||||
debug_assert_eq!(self.size(), other.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
module.vec_znx_copy(&mut self.data, 0, &other.data, 0);
|
|
||||||
(1..(other.rank() + 1).into()).for_each(|i| {
|
(1..(other.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_fill_uniform(other.base2k.into(), &mut self.data, i, source);
|
self.vec_znx_fill_uniform(other.base2k.into(), &mut res.data, i, &mut source);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
self.base2k = other.base2k;
|
res.set_base2k(other.base2k());
|
||||||
self.k = other.k;
|
res.set_k(other.k());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GLWECiphertextCompressedToRef {
|
impl<B: Backend> GLWEDecompress for Module<B> where Self: GetDegree + VecZnxFillUniform + VecZnxCopy {}
|
||||||
fn to_ref(&self) -> GLWECiphertextCompressed<&[u8]>;
|
|
||||||
|
impl<D: DataMut> GLWE<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: GLWECompressedToRef + GLWEInfos,
|
||||||
|
Module<B>: GLWEDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_glwe(self, other);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GLWECiphertextCompressedToRef for GLWECiphertextCompressed<D> {
|
pub trait GLWECompressedToRef {
|
||||||
fn to_ref(&self) -> GLWECiphertextCompressed<&[u8]> {
|
fn to_ref(&self) -> GLWECompressed<&[u8]>;
|
||||||
GLWECiphertextCompressed {
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> GLWECompressedToRef for GLWECompressed<D> {
|
||||||
|
fn to_ref(&self) -> GLWECompressed<&[u8]> {
|
||||||
|
GLWECompressed {
|
||||||
seed: self.seed.clone(),
|
seed: self.seed.clone(),
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
k: self.k,
|
k: self.k,
|
||||||
@@ -195,13 +221,13 @@ impl<D: DataRef> GLWECiphertextCompressedToRef for GLWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GLWECiphertextCompressedToMut {
|
pub trait GLWECompressedToMut {
|
||||||
fn to_mut(&mut self) -> GLWECiphertextCompressed<&mut [u8]>;
|
fn to_mut(&mut self) -> GLWECompressed<&mut [u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertextCompressedToMut for GLWECiphertextCompressed<D> {
|
impl<D: DataMut> GLWECompressedToMut for GLWECompressed<D> {
|
||||||
fn to_mut(&mut self) -> GLWECiphertextCompressed<&mut [u8]> {
|
fn to_mut(&mut self) -> GLWECompressed<&mut [u8]> {
|
||||||
GLWECiphertextCompressed {
|
GLWECompressed {
|
||||||
seed: self.seed.clone(),
|
seed: self.seed.clone(),
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
k: self.k,
|
k: self.k,
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::GLWESwitchingKeyCompressed,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWESwitchingKey, GLWEToLWESwitchingKeyToMut, LWEInfos, Rank,
|
||||||
|
TorusPrecision,
|
||||||
|
compressed::{
|
||||||
|
GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedAlloc, GLWESwitchingKeyCompressedToMut,
|
||||||
|
GLWESwitchingKeyCompressedToRef, GLWESwitchingKeyDecompress,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
@@ -83,54 +88,146 @@ impl<D: DataRef> WriterTo for GLWEToLWESwitchingKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
|
pub trait GLWEToLWESwitchingKeyCompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
|
Self: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_glwe_to_lwe_switching_key_compressed(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
) -> GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
|
GLWEToLWESwitchingKeyCompressed(self.alloc_glwe_switching_key_compressed(base2k, k, rank_in, Rank(1), dnum, Dsize(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_glwe_to_lwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> GLWEToLWESwitchingKeyCompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_out().0,
|
infos.rank_out().0,
|
||||||
1,
|
1,
|
||||||
"rank_out > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
"rank_out > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.dsize().0,
|
infos.dsize().0,
|
||||||
1,
|
1,
|
||||||
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
Self(GLWESwitchingKeyCompressed::alloc(infos))
|
self.alloc_glwe_to_lwe_switching_key_compressed(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self {
|
fn bytes_of_glwe_to_lwe_switching_key_compressed(
|
||||||
Self(GLWESwitchingKeyCompressed::alloc_with(
|
&self,
|
||||||
n,
|
base2k: Base2K,
|
||||||
base2k,
|
k: TorusPrecision,
|
||||||
k,
|
rank_in: Rank,
|
||||||
rank_in,
|
dnum: Dnum,
|
||||||
Rank(1),
|
) -> usize {
|
||||||
dnum,
|
self.bytes_of_glwe_switching_key_compressed(base2k, k, rank_in, dnum, Dsize(1))
|
||||||
Dsize(1),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn bytes_of_glwe_to_lwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_out().0,
|
infos.rank_out().0,
|
||||||
1,
|
1,
|
||||||
"rank_out > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
"rank_out > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.dsize().0,
|
infos.dsize().0,
|
||||||
1,
|
1,
|
||||||
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
self.bytes_of_glwe_switching_key_compressed_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_in: Rank) -> usize {
|
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rank_in, dnum, Dsize(1))
|
impl<B: Backend> GLWEToLWESwitchingKeyCompressedAlloc for Module<B> where Self: GLWESwitchingKeyCompressedAlloc {}
|
||||||
|
|
||||||
|
impl GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_to_lwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_to_lwe_switching_key_compressed(base2k, k, rank_in, dnum)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_to_lwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_in: Rank) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_to_lwe_switching_key_compressed(base2k, k, rank_in, dnum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GLWEToLWESwitchingKeyDecompress
|
||||||
|
where
|
||||||
|
Self: GLWESwitchingKeyDecompress,
|
||||||
|
{
|
||||||
|
fn decompress_glwe_to_lwe_switching_key<R, O>(&self, res: &mut R, other: &O)
|
||||||
|
where
|
||||||
|
R: GLWEToLWESwitchingKeyToMut,
|
||||||
|
O: GLWEToLWESwitchingKeyCompressedToRef,
|
||||||
|
{
|
||||||
|
self.decompress_glwe_switching_key(&mut res.to_mut().0, &other.to_ref().0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> GLWEToLWESwitchingKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
|
||||||
|
|
||||||
|
impl<D: DataMut> GLWEToLWESwitchingKey<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: GLWEToLWESwitchingKeyCompressedToRef,
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_glwe_to_lwe_switching_key(self, other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GLWEToLWESwitchingKeyCompressedToRef {
|
||||||
|
fn to_ref(&self) -> GLWEToLWESwitchingKeyCompressed<&[u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> GLWEToLWESwitchingKeyCompressedToRef for GLWEToLWESwitchingKeyCompressed<D>
|
||||||
|
where
|
||||||
|
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToRef,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> GLWEToLWESwitchingKeyCompressed<&[u8]> {
|
||||||
|
GLWEToLWESwitchingKeyCompressed(self.0.to_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GLWEToLWESwitchingKeyCompressedToMut {
|
||||||
|
fn to_mut(&mut self) -> GLWEToLWESwitchingKeyCompressed<&mut [u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> GLWEToLWESwitchingKeyCompressedToMut for GLWEToLWESwitchingKeyCompressed<D>
|
||||||
|
where
|
||||||
|
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToMut,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> GLWEToLWESwitchingKeyCompressed<&mut [u8]> {
|
||||||
|
GLWEToLWESwitchingKeyCompressed(self.0.to_mut())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,24 @@ use std::fmt;
|
|||||||
|
|
||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
api::ZnFillUniform,
|
api::ZnFillUniform,
|
||||||
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo, Zn, ZnxInfos, ZnxView, ZnxViewMut},
|
layouts::{
|
||||||
|
Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo, Zn, ZnToMut, ZnToRef, ZnxInfos, ZnxView,
|
||||||
|
ZnxViewMut,
|
||||||
|
},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{Base2K, Degree, LWECiphertext, LWEInfos, TorusPrecision, compressed::Decompress};
|
use crate::layouts::{Base2K, Degree, LWE, LWEInfos, LWEToMut, TorusPrecision};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct LWECiphertextCompressed<D: Data> {
|
pub struct LWECompressed<D: Data> {
|
||||||
pub(crate) data: Zn<D>,
|
pub(crate) data: Zn<D>,
|
||||||
pub(crate) k: TorusPrecision,
|
pub(crate) k: TorusPrecision,
|
||||||
pub(crate) base2k: Base2K,
|
pub(crate) base2k: Base2K,
|
||||||
pub(crate) seed: [u8; 32],
|
pub(crate) seed: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> LWEInfos for LWECiphertextCompressed<D> {
|
impl<D: Data> LWEInfos for LWECompressed<D> {
|
||||||
fn base2k(&self) -> Base2K {
|
fn base2k(&self) -> Base2K {
|
||||||
self.base2k
|
self.base2k
|
||||||
}
|
}
|
||||||
@@ -34,17 +37,17 @@ impl<D: Data> LWEInfos for LWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Debug for LWECiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Debug for LWECompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{self}")
|
write!(f, "{self}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Display for LWECiphertextCompressed<D> {
|
impl<D: DataRef> fmt::Display for LWECompressed<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"LWECiphertextCompressed: base2k={} k={} seed={:?}: {}",
|
"LWECompressed: base2k={} k={} seed={:?}: {}",
|
||||||
self.base2k(),
|
self.base2k(),
|
||||||
self.k(),
|
self.k(),
|
||||||
self.seed,
|
self.seed,
|
||||||
@@ -53,22 +56,15 @@ impl<D: DataRef> fmt::Display for LWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> FillUniform for LWECiphertextCompressed<D> {
|
impl<D: DataMut> FillUniform for LWECompressed<D> {
|
||||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||||
self.data.fill_uniform(log_bound, source);
|
self.data.fill_uniform(log_bound, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LWECiphertextCompressed<Vec<u8>> {
|
pub trait LWECompressedAlloc {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
fn alloc_lwe_compressed(&self, base2k: Base2K, k: TorusPrecision) -> LWECompressed<Vec<u8>> {
|
||||||
where
|
LWECompressed {
|
||||||
A: LWEInfos,
|
|
||||||
{
|
|
||||||
Self::alloc_with(infos.base2k(), infos.k())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(base2k: Base2K, k: TorusPrecision) -> Self {
|
|
||||||
Self {
|
|
||||||
data: Zn::alloc(1, 1, k.0.div_ceil(base2k.0) as usize),
|
data: Zn::alloc(1, 1, k.0.div_ceil(base2k.0) as usize),
|
||||||
k,
|
k,
|
||||||
base2k,
|
base2k,
|
||||||
@@ -76,21 +72,60 @@ impl LWECiphertextCompressed<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_lwe_compressed_from_infos<A>(&self, infos: &A) -> LWECompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: LWEInfos,
|
A: LWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(infos.base2k(), infos.k())
|
self.alloc_lwe_compressed(infos.base2k(), infos.k())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(base2k: Base2K, k: TorusPrecision) -> usize {
|
fn bytes_of_lwe_compressed(&self, base2k: Base2K, k: TorusPrecision) -> usize {
|
||||||
Zn::alloc_bytes(1, 1, k.0.div_ceil(base2k.0) as usize)
|
Zn::bytes_of(1, 1, k.0.div_ceil(base2k.0) as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_lwe_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_lwe_compressed(infos.base2k(), infos.k())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LWECompressed<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
Module<B>: LWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: LWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_compressed(base2k, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
Module<B>: LWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: LWECompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_compressed(base2k, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
impl<D: DataMut> ReaderFrom for LWECiphertextCompressed<D> {
|
impl<D: DataMut> ReaderFrom for LWECompressed<D> {
|
||||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||||
@@ -99,7 +134,7 @@ impl<D: DataMut> ReaderFrom for LWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> WriterTo for LWECiphertextCompressed<D> {
|
impl<D: DataRef> WriterTo for LWECompressed<D> {
|
||||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||||
writer.write_u32::<LittleEndian>(self.k.into())?;
|
writer.write_u32::<LittleEndian>(self.k.into())?;
|
||||||
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
||||||
@@ -108,22 +143,72 @@ impl<D: DataRef> WriterTo for LWECiphertextCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, LWECiphertextCompressed<DR>> for LWECiphertext<D>
|
pub trait LWEDecompress
|
||||||
where
|
where
|
||||||
Module<B>: ZnFillUniform,
|
Self: ZnFillUniform,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &LWECiphertextCompressed<DR>) {
|
fn decompress_lwe<R, O>(&self, res: &mut R, other: &O)
|
||||||
debug_assert_eq!(self.size(), other.size());
|
where
|
||||||
|
R: LWEToMut,
|
||||||
|
O: LWECompressedToRef,
|
||||||
|
{
|
||||||
|
let res: &mut LWE<&mut [u8]> = &mut res.to_mut();
|
||||||
|
let other: &LWECompressed<&[u8]> = &other.to_ref();
|
||||||
|
|
||||||
|
assert_eq!(res.lwe_layout(), other.lwe_layout());
|
||||||
|
|
||||||
let mut source: Source = Source::new(other.seed);
|
let mut source: Source = Source::new(other.seed);
|
||||||
module.zn_fill_uniform(
|
self.zn_fill_uniform(
|
||||||
self.n().into(),
|
res.n().into(),
|
||||||
other.base2k().into(),
|
other.base2k().into(),
|
||||||
&mut self.data,
|
&mut res.data,
|
||||||
0,
|
0,
|
||||||
&mut source,
|
&mut source,
|
||||||
);
|
);
|
||||||
(0..self.size()).for_each(|i| {
|
for i in 0..res.size() {
|
||||||
self.data.at_mut(0, i)[0] = other.data.at(0, i)[0];
|
res.data.at_mut(0, i)[0] = other.data.at(0, i)[0];
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> LWEDecompress for Module<B> where Self: ZnFillUniform {}
|
||||||
|
|
||||||
|
impl<D: DataMut> LWE<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: LWECompressedToRef,
|
||||||
|
Module<B>: LWEDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_lwe(self, other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWECompressedToRef {
|
||||||
|
fn to_ref(&self) -> LWECompressed<&[u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> LWECompressedToRef for LWECompressed<D> {
|
||||||
|
fn to_ref(&self) -> LWECompressed<&[u8]> {
|
||||||
|
LWECompressed {
|
||||||
|
k: self.k,
|
||||||
|
base2k: self.base2k,
|
||||||
|
seed: self.seed,
|
||||||
|
data: self.data.to_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWECompressedToMut {
|
||||||
|
fn to_mut(&mut self) -> LWECompressed<&mut [u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> LWECompressedToMut for LWECompressed<D> {
|
||||||
|
fn to_mut(&mut self) -> LWECompressed<&mut [u8]> {
|
||||||
|
LWECompressed {
|
||||||
|
k: self.k,
|
||||||
|
base2k: self.base2k,
|
||||||
|
seed: self.seed,
|
||||||
|
data: self.data.to_mut(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
api::{VecZnxCopy, VecZnxFillUniform},
|
|
||||||
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, TorusPrecision,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, LWESwitchingKeyToMut, Rank, TorusPrecision,
|
||||||
compressed::{Decompress, GLWESwitchingKeyCompressed},
|
compressed::{
|
||||||
|
GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedAlloc, GLWESwitchingKeyCompressedToMut,
|
||||||
|
GLWESwitchingKeyCompressedToRef, GLWESwitchingKeyDecompress,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -83,73 +85,147 @@ impl<D: DataRef> WriterTo for LWESwitchingKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LWESwitchingKeyCompressed<Vec<u8>> {
|
pub trait LWESwitchingKeyCompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
|
Self: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_lwe_switching_key_compressed(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
dnum: Dnum,
|
||||||
|
) -> LWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
|
LWESwitchingKeyCompressed(self.alloc_glwe_switching_key_compressed(base2k, k, Rank(1), Rank(1), dnum, Dsize(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_lwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> LWESwitchingKeyCompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.dsize().0,
|
infos.dsize().0,
|
||||||
1,
|
1,
|
||||||
"dsize > 1 is not supported for LWESwitchingKeyCompressed"
|
"dsize > 1 is not supported for LWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_in().0,
|
infos.rank_in().0,
|
||||||
1,
|
1,
|
||||||
"rank_in > 1 is not supported for LWESwitchingKeyCompressed"
|
"rank_in > 1 is not supported for LWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_out().0,
|
infos.rank_out().0,
|
||||||
1,
|
1,
|
||||||
"rank_out > 1 is not supported for LWESwitchingKeyCompressed"
|
"rank_out > 1 is not supported for LWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
Self(GLWESwitchingKeyCompressed::alloc(infos))
|
self.alloc_lwe_switching_key_compressed(infos.base2k(), infos.k(), infos.dnum())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
|
fn bytes_of_lwe_switching_key_compressed(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||||
Self(GLWESwitchingKeyCompressed::alloc_with(
|
self.bytes_of_glwe_switching_key_compressed(base2k, k, Rank(1), dnum, Dsize(1))
|
||||||
n,
|
|
||||||
base2k,
|
|
||||||
k,
|
|
||||||
Rank(1),
|
|
||||||
Rank(1),
|
|
||||||
dnum,
|
|
||||||
Dsize(1),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn bytes_of_lwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.dsize().0,
|
infos.dsize().0,
|
||||||
1,
|
1,
|
||||||
"dsize > 1 is not supported for LWESwitchingKey"
|
"dsize > 1 is not supported for LWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_in().0,
|
infos.rank_in().0,
|
||||||
1,
|
1,
|
||||||
"rank_in > 1 is not supported for LWESwitchingKey"
|
"rank_in > 1 is not supported for LWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_out().0,
|
infos.rank_out().0,
|
||||||
1,
|
1,
|
||||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
"rank_out > 1 is not supported for LWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
self.bytes_of_glwe_switching_key_compressed_from_infos(infos)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, LWESwitchingKeyCompressed<DR>> for LWESwitchingKey<D>
|
impl LWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: LWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_switching_key_compressed(base2k, k, dnum)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: LWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_switching_key_compressed(base2k, k, dnum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWESwitchingKeyDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GLWESwitchingKeyDecompress,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &LWESwitchingKeyCompressed<DR>) {
|
fn decompress_lwe_switching_key<R, O>(&self, res: &mut R, other: &O)
|
||||||
self.0.decompress(module, &other.0);
|
where
|
||||||
|
R: LWESwitchingKeyToMut,
|
||||||
|
O: LWESwitchingKeyCompressedToRef,
|
||||||
|
{
|
||||||
|
self.decompress_glwe_switching_key(&mut res.to_mut().0, &other.to_ref().0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> LWESwitchingKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
|
||||||
|
|
||||||
|
impl<D: DataMut> LWESwitchingKey<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: LWESwitchingKeyCompressedToRef,
|
||||||
|
Module<B>: LWESwitchingKeyDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_lwe_switching_key(self, other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWESwitchingKeyCompressedToRef {
|
||||||
|
fn to_ref(&self) -> LWESwitchingKeyCompressed<&[u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> LWESwitchingKeyCompressedToRef for LWESwitchingKeyCompressed<D>
|
||||||
|
where
|
||||||
|
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToRef,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> LWESwitchingKeyCompressed<&[u8]> {
|
||||||
|
LWESwitchingKeyCompressed(self.0.to_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWESwitchingKeyCompressedToMut {
|
||||||
|
fn to_mut(&mut self) -> LWESwitchingKeyCompressed<&mut [u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> LWESwitchingKeyCompressedToMut for LWESwitchingKeyCompressed<D>
|
||||||
|
where
|
||||||
|
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToMut,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> LWESwitchingKeyCompressed<&mut [u8]> {
|
||||||
|
LWESwitchingKeyCompressed(self.0.to_mut())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
api::{VecZnxCopy, VecZnxFillUniform},
|
|
||||||
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, Rank, TorusPrecision,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, LWEToGLWESwitchingKeyToMut, Rank,
|
||||||
compressed::{Decompress, GLWESwitchingKeyCompressed},
|
TorusPrecision,
|
||||||
|
compressed::{
|
||||||
|
GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedAlloc, GLWESwitchingKeyCompressedToMut,
|
||||||
|
GLWESwitchingKeyCompressedToRef, GLWESwitchingKeyDecompress,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -83,63 +86,138 @@ impl<D: DataRef> WriterTo for LWEToGLWESwitchingKeyCompressed<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
|
pub trait LWEToGLWESwitchingKeyCompressedAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
|
Self: GLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_lwe_to_glwe_switching_key_compressed(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
) -> LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
|
LWEToGLWESwitchingKeyCompressed(self.alloc_glwe_switching_key_compressed(base2k, k, Rank(1), rank_out, dnum, Dsize(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_lwe_to_glwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> LWEToGLWESwitchingKeyCompressed<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.dsize().0,
|
infos.dsize().0,
|
||||||
1,
|
1,
|
||||||
"dsize > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
|
"dsize > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_in().0,
|
infos.rank_in().0,
|
||||||
1,
|
1,
|
||||||
"rank_in > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
|
"rank_in > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
Self(GLWESwitchingKeyCompressed::alloc(infos))
|
self.alloc_lwe_to_glwe_switching_key_compressed(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
|
fn bytes_of_lwe_to_glwe_switching_key_compressed(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||||
Self(GLWESwitchingKeyCompressed::alloc_with(
|
self.bytes_of_glwe_switching_key_compressed(base2k, k, Rank(1), dnum, Dsize(1))
|
||||||
n,
|
|
||||||
base2k,
|
|
||||||
k,
|
|
||||||
Rank(1),
|
|
||||||
rank_out,
|
|
||||||
dnum,
|
|
||||||
Dsize(1),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn bytes_of_lwe_to_glwe_switching_key_compressed_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
assert_eq!(
|
||||||
infos.rank_in().0,
|
|
||||||
1,
|
|
||||||
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.dsize().0,
|
infos.dsize().0,
|
||||||
1,
|
1,
|
||||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
"dsize > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
|
||||||
);
|
);
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
assert_eq!(
|
||||||
}
|
infos.rank_in().0,
|
||||||
|
1,
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
"rank_in > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
|
||||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
|
);
|
||||||
|
self.bytes_of_lwe_to_glwe_switching_key_compressed(infos.base2k(), infos.k(), infos.dnum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, LWEToGLWESwitchingKeyCompressed<DR>> for LWEToGLWESwitchingKey<D>
|
impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
|
||||||
|
pub fn alloc<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_to_glwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc_with<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_to_glwe_switching_key_compressed(base2k, k, rank_out, dnum)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_to_glwe_switching_key_compressed_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyCompressedAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_to_glwe_switching_key_compressed(base2k, k, dnum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWEToGLWESwitchingKeyDecompress
|
||||||
where
|
where
|
||||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
Self: GLWESwitchingKeyDecompress,
|
||||||
{
|
{
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &LWEToGLWESwitchingKeyCompressed<DR>) {
|
fn decompress_lwe_to_glwe_switching_key<R, O>(&self, res: &mut R, other: &O)
|
||||||
self.0.decompress(module, &other.0);
|
where
|
||||||
|
R: LWEToGLWESwitchingKeyToMut,
|
||||||
|
O: LWEToGLWESwitchingKeyCompressedToRef,
|
||||||
|
{
|
||||||
|
self.decompress_glwe_switching_key(&mut res.to_mut().0, &other.to_ref().0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> LWEToGLWESwitchingKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
|
||||||
|
|
||||||
|
impl<D: DataMut> LWEToGLWESwitchingKey<D> {
|
||||||
|
pub fn decompress<O, B: Backend>(&mut self, module: &Module<B>, other: &O)
|
||||||
|
where
|
||||||
|
O: LWEToGLWESwitchingKeyCompressedToRef,
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyDecompress,
|
||||||
|
{
|
||||||
|
module.decompress_lwe_to_glwe_switching_key(self, other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWEToGLWESwitchingKeyCompressedToRef {
|
||||||
|
fn to_ref(&self) -> LWEToGLWESwitchingKeyCompressed<&[u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> LWEToGLWESwitchingKeyCompressedToRef for LWEToGLWESwitchingKeyCompressed<D>
|
||||||
|
where
|
||||||
|
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToRef,
|
||||||
|
{
|
||||||
|
fn to_ref(&self) -> LWEToGLWESwitchingKeyCompressed<&[u8]> {
|
||||||
|
LWEToGLWESwitchingKeyCompressed(self.0.to_ref())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LWEToGLWESwitchingKeyCompressedToMut {
|
||||||
|
fn to_mut(&mut self) -> LWEToGLWESwitchingKeyCompressed<&mut [u8]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> LWEToGLWESwitchingKeyCompressedToMut for LWEToGLWESwitchingKeyCompressed<D>
|
||||||
|
where
|
||||||
|
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToMut,
|
||||||
|
{
|
||||||
|
fn to_mut(&mut self) -> LWEToGLWESwitchingKeyCompressed<&mut [u8]> {
|
||||||
|
LWEToGLWESwitchingKeyCompressed(self.0.to_mut())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,3 @@ pub use glwe_to_lwe_ksk::*;
|
|||||||
pub use lwe_ct::*;
|
pub use lwe_ct::*;
|
||||||
pub use lwe_ksk::*;
|
pub use lwe_ksk::*;
|
||||||
pub use lwe_to_glwe_ksk::*;
|
pub use lwe_to_glwe_ksk::*;
|
||||||
|
|
||||||
use poulpy_hal::layouts::{Backend, Module};
|
|
||||||
|
|
||||||
pub trait Decompress<B: Backend, C> {
|
|
||||||
fn decompress(&mut self, module: &Module<B>, other: &C);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWECiphertext, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWE, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyAlloc, GLWESwitchingKeyToMut,
|
||||||
GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
@@ -131,43 +131,105 @@ impl<D: DataRef> fmt::Display for AutomorphismKey<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> AutomorphismKeyAlloc for Module<B> where Self: GLWESwitchingKeyAlloc {}
|
||||||
|
|
||||||
|
pub trait AutomorphismKeyAlloc
|
||||||
|
where
|
||||||
|
Self: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_automorphism_key(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> AutomorphismKey<Vec<u8>> {
|
||||||
|
AutomorphismKey {
|
||||||
|
key: self.alloc_glwe_switching_key(base2k, k, rank, rank, dnum, dsize),
|
||||||
|
p: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_automorphism_key_from_infos<A>(&self, infos: &A) -> AutomorphismKey<Vec<u8>>
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
self.alloc_automorphism_key(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_automorphism_key(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
|
self.bytes_of_glwe_switching_key(base2k, k, rank, rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_automorphism_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_in(),
|
||||||
|
infos.rank_out(),
|
||||||
|
"rank_in != rank_out is not supported for AutomorphismKey"
|
||||||
|
);
|
||||||
|
self.bytes_of_automorphism_key(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AutomorphismKey<Vec<u8>> {
|
impl AutomorphismKey<Vec<u8>> {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: AutomorphismKeyAlloc,
|
||||||
{
|
{
|
||||||
assert_eq!(
|
module.alloc_automorphism_key_from_infos(infos)
|
||||||
infos.rank_in(),
|
|
||||||
infos.rank_out(),
|
|
||||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
|
|
||||||
);
|
|
||||||
AutomorphismKey {
|
|
||||||
key: GLWESwitchingKey::alloc(infos),
|
|
||||||
p: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
pub fn alloc_with<B: Backend>(
|
||||||
AutomorphismKey {
|
module: &Module<B>,
|
||||||
key: GLWESwitchingKey::alloc_with(n, base2k, k, rank, rank, dnum, dsize),
|
base2k: Base2K,
|
||||||
p: 0,
|
k: TorusPrecision,
|
||||||
}
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: AutomorphismKeyAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_automorphism_key(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: AutomorphismKeyAlloc,
|
||||||
{
|
{
|
||||||
assert_eq!(
|
module.bytes_of_automorphism_key_from_infos(infos)
|
||||||
infos.rank_in(),
|
|
||||||
infos.rank_out(),
|
|
||||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
|
|
||||||
);
|
|
||||||
GLWESwitchingKey::alloc_bytes(infos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
pub fn bytes_of<B: Backend>(
|
||||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, rank, rank, dnum, dsize)
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: AutomorphismKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_automorphism_key(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,13 +266,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> AutomorphismKey<D> {
|
impl<D: DataRef> AutomorphismKey<D> {
|
||||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
pub fn at(&self, row: usize, col: usize) -> GLWE<&[u8]> {
|
||||||
self.key.at(row, col)
|
self.key.at(row, col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> AutomorphismKey<D> {
|
impl<D: DataMut> AutomorphismKey<D> {
|
||||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWE<&mut [u8]> {
|
||||||
self.key.at_mut(row, col)
|
self.key.at_mut(row, col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, MatZnx, MatZnxToMut, MatZnxToRef, ReaderFrom, WriterTo, ZnxInfos},
|
layouts::{
|
||||||
|
Backend, Data, DataMut, DataRef, FillUniform, MatZnx, MatZnxToMut, MatZnxToRef, Module, ReaderFrom, WriterTo, ZnxInfos,
|
||||||
|
},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision};
|
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GLWE, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -16,7 +18,7 @@ where
|
|||||||
fn dsize(&self) -> Dsize;
|
fn dsize(&self) -> Dsize;
|
||||||
fn rank_in(&self) -> Rank;
|
fn rank_in(&self) -> Rank;
|
||||||
fn rank_out(&self) -> Rank;
|
fn rank_out(&self) -> Rank;
|
||||||
fn layout(&self) -> GGLWECiphertextLayout {
|
fn gglwe_layout(&self) -> GGLWECiphertextLayout {
|
||||||
GGLWECiphertextLayout {
|
GGLWECiphertextLayout {
|
||||||
n: self.n(),
|
n: self.n(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
@@ -170,8 +172,8 @@ impl<D: DataRef> fmt::Display for GGLWE<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GGLWE<D> {
|
impl<D: DataRef> GGLWE<D> {
|
||||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
pub fn at(&self, row: usize, col: usize) -> GLWE<&[u8]> {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.at(row, col),
|
data: self.data.at(row, col),
|
||||||
@@ -180,8 +182,8 @@ impl<D: DataRef> GGLWE<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GGLWE<D> {
|
impl<D: DataMut> GGLWE<D> {
|
||||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWE<&mut [u8]> {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.at_mut(row, col),
|
data: self.data.at_mut(row, col),
|
||||||
@@ -189,31 +191,19 @@ impl<D: DataMut> GGLWE<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GGLWE<Vec<u8>> {
|
pub trait GGLWEAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GGLWEInfos,
|
{
|
||||||
{
|
fn alloc_gglwe(
|
||||||
Self::alloc_with(
|
&self,
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
|
||||||
infos.k(),
|
|
||||||
infos.rank_in(),
|
|
||||||
infos.rank_out(),
|
|
||||||
infos.dnum(),
|
|
||||||
infos.dsize(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(
|
|
||||||
n: Degree,
|
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
rank_in: Rank,
|
rank_in: Rank,
|
||||||
rank_out: Rank,
|
rank_out: Rank,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> Self {
|
) -> GGLWE<Vec<u8>> {
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
@@ -228,9 +218,9 @@ impl GGLWE<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
GGLWE {
|
||||||
data: MatZnx::alloc(
|
data: MatZnx::alloc(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
rank_in.into(),
|
rank_in.into(),
|
||||||
(rank_out + 1).into(),
|
(rank_out + 1).into(),
|
||||||
@@ -242,12 +232,11 @@ impl GGLWE<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_from_infos<A>(&self, infos: &A) -> GGLWE<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(
|
self.alloc_gglwe(
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank_in(),
|
infos.rank_in(),
|
||||||
@@ -257,8 +246,8 @@ impl GGLWE<Vec<u8>> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(
|
fn bytes_of_gglwe(
|
||||||
n: Degree,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
rank_in: Rank,
|
rank_in: Rank,
|
||||||
@@ -280,21 +269,85 @@ impl GGLWE<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
MatZnx::alloc_bytes(
|
MatZnx::bytes_of(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
rank_in.into(),
|
rank_in.into(),
|
||||||
(rank_out + 1).into(),
|
(rank_out + 1).into(),
|
||||||
k.0.div_ceil(base2k.0) as usize,
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bytes_of_gglwe_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_gglwe(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank_in(),
|
||||||
|
infos.rank_out(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GGLWECiphertextToMut {
|
impl<B: Backend> GGLWEAlloc for Module<B> where Self: GetDegree {}
|
||||||
|
|
||||||
|
impl GGLWE<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GGLWEAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(
|
||||||
|
module: Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GGLWEAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_gglwe(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GGLWEAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_gglwe_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(
|
||||||
|
module: Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GGLWEAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_gglwe(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait GGLWEToMut {
|
||||||
fn to_mut(&mut self) -> GGLWE<&mut [u8]>;
|
fn to_mut(&mut self) -> GGLWE<&mut [u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GGLWECiphertextToMut for GGLWE<D> {
|
impl<D: DataMut> GGLWEToMut for GGLWE<D> {
|
||||||
fn to_mut(&mut self) -> GGLWE<&mut [u8]> {
|
fn to_mut(&mut self) -> GGLWE<&mut [u8]> {
|
||||||
GGLWE {
|
GGLWE {
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWECiphertextToMut, GGLWEInfos, GGLWEToRef, GLWECiphertext, GLWEInfos, LWEInfos, Rank,
|
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWEAlloc, GGLWEInfos, GGLWEToMut, GGLWEToRef, GLWE, GLWEInfos, LWEInfos, Rank,
|
||||||
TorusPrecision,
|
TorusPrecision,
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
@@ -163,43 +163,42 @@ impl<D: DataMut> FillUniform for GLWESwitchingKey<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWESwitchingKey<Vec<u8>> {
|
pub trait GLWESwitchingKeyAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GGLWEAlloc,
|
||||||
A: GGLWEInfos,
|
{
|
||||||
{
|
fn alloc_glwe_switching_key(
|
||||||
GLWESwitchingKey {
|
&self,
|
||||||
key: GGLWE::alloc(infos),
|
|
||||||
sk_in_n: 0,
|
|
||||||
sk_out_n: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(
|
|
||||||
n: Degree,
|
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
rank_in: Rank,
|
rank_in: Rank,
|
||||||
rank_out: Rank,
|
rank_out: Rank,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> Self {
|
) -> GLWESwitchingKey<Vec<u8>> {
|
||||||
GLWESwitchingKey {
|
GLWESwitchingKey {
|
||||||
key: GGLWE::alloc_with(n, base2k, k, rank_in, rank_out, dnum, dsize),
|
key: self.alloc_gglwe(base2k, k, rank_in, rank_out, dnum, dsize),
|
||||||
sk_in_n: 0,
|
sk_in_n: 0,
|
||||||
sk_out_n: 0,
|
sk_out_n: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_switching_key_from_infos<A>(&self, infos: &A) -> GLWESwitchingKey<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
GGLWE::alloc_bytes(infos)
|
self.alloc_glwe_switching_key(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank_in(),
|
||||||
|
infos.rank_out(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(
|
fn bytes_of_glwe_switching_key(
|
||||||
n: Degree,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
rank_in: Rank,
|
rank_in: Rank,
|
||||||
@@ -207,7 +206,69 @@ impl GLWESwitchingKey<Vec<u8>> {
|
|||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
GGLWE::alloc_bytes_with(n, base2k, k, rank_in, rank_out, dnum, dsize)
|
self.bytes_of_gglwe(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_switching_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_glwe_switching_key(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank_in(),
|
||||||
|
infos.rank_out(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GLWESwitchingKey<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_switching_key_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(
|
||||||
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_switching_key(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_switching_key_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(
|
||||||
|
module: &Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_switching_key(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +278,7 @@ pub trait GLWESwitchingKeyToMut {
|
|||||||
|
|
||||||
impl<D: DataMut> GLWESwitchingKeyToMut for GLWESwitchingKey<D>
|
impl<D: DataMut> GLWESwitchingKeyToMut for GLWESwitchingKey<D>
|
||||||
where
|
where
|
||||||
GGLWE<D>: GGLWECiphertextToMut,
|
GGLWE<D>: GGLWEToMut,
|
||||||
{
|
{
|
||||||
fn to_mut(&mut self) -> GLWESwitchingKey<&mut [u8]> {
|
fn to_mut(&mut self) -> GLWESwitchingKey<&mut [u8]> {
|
||||||
GLWESwitchingKey {
|
GLWESwitchingKey {
|
||||||
@@ -246,13 +307,13 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GLWESwitchingKey<D> {
|
impl<D: DataRef> GLWESwitchingKey<D> {
|
||||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
pub fn at(&self, row: usize, col: usize) -> GLWE<&[u8]> {
|
||||||
self.key.at(row, col)
|
self.key.at(row, col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWESwitchingKey<D> {
|
impl<D: DataMut> GLWESwitchingKey<D> {
|
||||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWE<&mut [u8]> {
|
||||||
self.key.at_mut(row, col)
|
self.key.at_mut(row, col)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyAlloc, GLWESwitchingKeyToMut,
|
||||||
Rank, TorusPrecision,
|
GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
@@ -130,44 +130,20 @@ impl<D: DataRef> fmt::Display for TensorKey<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TensorKey<Vec<u8>> {
|
pub trait TensorKeyAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GLWESwitchingKeyAlloc,
|
||||||
A: GGLWEInfos,
|
{
|
||||||
{
|
fn alloc_tensor_key(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> TensorKey<Vec<u8>> {
|
||||||
assert_eq!(
|
|
||||||
infos.rank_in(),
|
|
||||||
infos.rank_out(),
|
|
||||||
"rank_in != rank_out is not supported for GGLWETensorKey"
|
|
||||||
);
|
|
||||||
Self::alloc_with(
|
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
|
||||||
infos.k(),
|
|
||||||
infos.rank_out(),
|
|
||||||
infos.dnum(),
|
|
||||||
infos.dsize(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
|
||||||
let mut keys: Vec<GLWESwitchingKey<Vec<u8>>> = Vec::new();
|
|
||||||
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
|
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
|
||||||
(0..pairs).for_each(|_| {
|
TensorKey {
|
||||||
keys.push(GLWESwitchingKey::alloc_with(
|
keys: (0..pairs)
|
||||||
n,
|
.map(|_| self.alloc_glwe_switching_key(base2k, k, Rank(1), rank, dnum, dsize))
|
||||||
base2k,
|
.collect(),
|
||||||
k,
|
}
|
||||||
Rank(1),
|
|
||||||
rank,
|
|
||||||
dnum,
|
|
||||||
dsize,
|
|
||||||
));
|
|
||||||
});
|
|
||||||
Self { keys }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_tensor_key_from_infos<A>(&self, infos: &A) -> TensorKey<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -176,23 +152,77 @@ impl TensorKey<Vec<u8>> {
|
|||||||
infos.rank_out(),
|
infos.rank_out(),
|
||||||
"rank_in != rank_out is not supported for GGLWETensorKey"
|
"rank_in != rank_out is not supported for GGLWETensorKey"
|
||||||
);
|
);
|
||||||
let rank_out: usize = infos.rank_out().into();
|
self.alloc_tensor_key(
|
||||||
let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1);
|
|
||||||
pairs
|
|
||||||
* GLWESwitchingKey::alloc_bytes_with(
|
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
Rank(1),
|
infos.rank(),
|
||||||
infos.rank_out(),
|
|
||||||
infos.dnum(),
|
infos.dnum(),
|
||||||
infos.dsize(),
|
infos.dsize(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
fn bytes_of_tensor_key(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
|
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
|
||||||
pairs * GLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), rank, dnum, dsize)
|
pairs * self.bytes_of_glwe_switching_key(base2k, k, Rank(1), rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_tensor_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_in(),
|
||||||
|
infos.rank_out(),
|
||||||
|
"rank_in != rank_out is not supported for GGLWETensorKey"
|
||||||
|
);
|
||||||
|
self.bytes_of_tensor_key(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> TensorKeyAlloc for Module<B> where Self: GLWESwitchingKeyAlloc {}
|
||||||
|
|
||||||
|
impl TensorKey<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: TensorKeyAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_tensor_key_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: TensorKeyAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_tensor_key(base2k, k, rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
Module<B>: TensorKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_tensor_key_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(
|
||||||
|
module: Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: TensorKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_tensor_key(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,14 +290,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait TensorKeyToMut {
|
pub trait TensorKeyToMut {
|
||||||
fn to_ref(&mut self) -> TensorKey<&mut [u8]>;
|
fn to_mut(&mut self) -> TensorKey<&mut [u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> TensorKeyToMut for TensorKey<D>
|
impl<D: DataMut> TensorKeyToMut for TensorKey<D>
|
||||||
where
|
where
|
||||||
GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
|
GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
|
||||||
{
|
{
|
||||||
fn to_ref(&mut self) -> TensorKey<&mut [u8]> {
|
fn to_mut(&mut self) -> TensorKey<&mut [u8]> {
|
||||||
TensorKey {
|
TensorKey {
|
||||||
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
|
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, MatZnx, MatZnxToMut, MatZnxToRef, ReaderFrom, WriterTo, ZnxInfos},
|
layouts::{
|
||||||
|
Backend, Data, DataMut, DataRef, FillUniform, MatZnx, MatZnxToMut, MatZnxToRef, Module, ReaderFrom, WriterTo, ZnxInfos,
|
||||||
|
},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision};
|
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GLWE, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision};
|
||||||
|
|
||||||
pub trait GGSWInfos
|
pub trait GGSWInfos
|
||||||
where
|
where
|
||||||
@@ -131,8 +133,8 @@ impl<D: DataMut> FillUniform for GGSW<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GGSW<D> {
|
impl<D: DataRef> GGSW<D> {
|
||||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
pub fn at(&self, row: usize, col: usize) -> GLWE<&[u8]> {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.at(row, col),
|
data: self.data.at(row, col),
|
||||||
@@ -141,8 +143,8 @@ impl<D: DataRef> GGSW<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GGSW<D> {
|
impl<D: DataMut> GGSW<D> {
|
||||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWE<&mut [u8]> {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.at_mut(row, col),
|
data: self.data.at_mut(row, col),
|
||||||
@@ -150,22 +152,13 @@ impl<D: DataMut> GGSW<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GGSW<Vec<u8>> {
|
impl<B: Backend> GGSWAlloc for Module<B> where Self: GetDegree {}
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
|
||||||
where
|
|
||||||
A: GGSWInfos,
|
|
||||||
{
|
|
||||||
Self::alloc_with(
|
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
|
||||||
infos.k(),
|
|
||||||
infos.rank(),
|
|
||||||
infos.dnum(),
|
|
||||||
infos.dsize(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
pub trait GGSWAlloc
|
||||||
|
where
|
||||||
|
Self: GetDegree,
|
||||||
|
{
|
||||||
|
fn alloc_ggsw(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> GGSW<Vec<u8>> {
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
@@ -180,9 +173,9 @@ impl GGSW<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
GGSW {
|
||||||
data: MatZnx::alloc(
|
data: MatZnx::alloc(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
(rank + 1).into(),
|
(rank + 1).into(),
|
||||||
(rank + 1).into(),
|
(rank + 1).into(),
|
||||||
@@ -194,12 +187,11 @@ impl GGSW<Vec<u8>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_ggsw_from_infos<A>(&self, infos: &A) -> GGSW<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GGSWInfos,
|
A: GGSWInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(
|
self.alloc_ggsw(
|
||||||
infos.n(),
|
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank(),
|
infos.rank(),
|
||||||
@@ -208,7 +200,7 @@ impl GGSW<Vec<u8>> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
fn bytes_of_ggsw(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
@@ -223,14 +215,66 @@ impl GGSW<Vec<u8>> {
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
MatZnx::alloc_bytes(
|
MatZnx::bytes_of(
|
||||||
n.into(),
|
self.n().into(),
|
||||||
dnum.into(),
|
dnum.into(),
|
||||||
(rank + 1).into(),
|
(rank + 1).into(),
|
||||||
(rank + 1).into(),
|
(rank + 1).into(),
|
||||||
k.0.div_ceil(base2k.0) as usize,
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bytes_of_ggsw_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGSWInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_ggsw(
|
||||||
|
infos.base2k(),
|
||||||
|
infos.k(),
|
||||||
|
infos.rank(),
|
||||||
|
infos.dnum(),
|
||||||
|
infos.dsize(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GGSW<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GGSWInfos,
|
||||||
|
Module<B>: GGSWAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_ggsw_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GGSWAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_ggsw(base2k, k, rank, dnum, dsize)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGSWInfos,
|
||||||
|
Module<B>: GGSWAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_ggsw_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(
|
||||||
|
module: Module<B>,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
dsize: Dsize,
|
||||||
|
) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GGSWAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_ggsw(base2k, k, rank, dnum, dsize)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{
|
layouts::{
|
||||||
Data, DataMut, DataRef, FillUniform, ReaderFrom, ToOwnedDeep, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo, ZnxInfos,
|
Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, ToOwnedDeep, VecZnx, VecZnxToMut, VecZnxToRef,
|
||||||
|
WriterTo, ZnxInfos,
|
||||||
},
|
},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{Base2K, Degree, LWEInfos, Rank, TorusPrecision};
|
use crate::layouts::{Base2K, Degree, GetDegree, LWEInfos, Rank, TorusPrecision};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
@@ -14,8 +15,8 @@ where
|
|||||||
Self: LWEInfos,
|
Self: LWEInfos,
|
||||||
{
|
{
|
||||||
fn rank(&self) -> Rank;
|
fn rank(&self) -> Rank;
|
||||||
fn glwe_layout(&self) -> GLWECiphertextLayout {
|
fn glwe_layout(&self) -> GLWELayout {
|
||||||
GLWECiphertextLayout {
|
GLWELayout {
|
||||||
n: self.n(),
|
n: self.n(),
|
||||||
base2k: self.base2k(),
|
base2k: self.base2k(),
|
||||||
k: self.k(),
|
k: self.k(),
|
||||||
@@ -24,20 +25,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GLWELayoutSet {
|
pub trait SetGLWEInfos {
|
||||||
fn set_k(&mut self, k: TorusPrecision);
|
fn set_k(&mut self, k: TorusPrecision);
|
||||||
fn set_basek(&mut self, base2k: Base2K);
|
fn set_base2k(&mut self, base2k: Base2K);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
pub struct GLWECiphertextLayout {
|
pub struct GLWELayout {
|
||||||
pub n: Degree,
|
pub n: Degree,
|
||||||
pub base2k: Base2K,
|
pub base2k: Base2K,
|
||||||
pub k: TorusPrecision,
|
pub k: TorusPrecision,
|
||||||
pub rank: Rank,
|
pub rank: Rank,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LWEInfos for GLWECiphertextLayout {
|
impl LWEInfos for GLWELayout {
|
||||||
fn n(&self) -> Degree {
|
fn n(&self) -> Degree {
|
||||||
self.n
|
self.n
|
||||||
}
|
}
|
||||||
@@ -51,21 +52,21 @@ impl LWEInfos for GLWECiphertextLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWEInfos for GLWECiphertextLayout {
|
impl GLWEInfos for GLWELayout {
|
||||||
fn rank(&self) -> Rank {
|
fn rank(&self) -> Rank {
|
||||||
self.rank
|
self.rank
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct GLWECiphertext<D: Data> {
|
pub struct GLWE<D: Data> {
|
||||||
pub(crate) data: VecZnx<D>,
|
pub(crate) data: VecZnx<D>,
|
||||||
pub(crate) base2k: Base2K,
|
pub(crate) base2k: Base2K,
|
||||||
pub(crate) k: TorusPrecision,
|
pub(crate) k: TorusPrecision,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWELayoutSet for GLWECiphertext<D> {
|
impl<D: DataMut> SetGLWEInfos for GLWE<D> {
|
||||||
fn set_basek(&mut self, base2k: Base2K) {
|
fn set_base2k(&mut self, base2k: Base2K) {
|
||||||
self.base2k = base2k
|
self.base2k = base2k
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,19 +75,19 @@ impl<D: DataMut> GLWELayoutSet for GLWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GLWECiphertext<D> {
|
impl<D: DataRef> GLWE<D> {
|
||||||
pub fn data(&self) -> &VecZnx<D> {
|
pub fn data(&self) -> &VecZnx<D> {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertext<D> {
|
impl<D: DataMut> GLWE<D> {
|
||||||
pub fn data_mut(&mut self) -> &mut VecZnx<D> {
|
pub fn data_mut(&mut self) -> &mut VecZnx<D> {
|
||||||
&mut self.data
|
&mut self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> LWEInfos for GLWECiphertext<D> {
|
impl<D: Data> LWEInfos for GLWE<D> {
|
||||||
fn base2k(&self) -> Base2K {
|
fn base2k(&self) -> Base2K {
|
||||||
self.base2k
|
self.base2k
|
||||||
}
|
}
|
||||||
@@ -104,16 +105,16 @@ impl<D: Data> LWEInfos for GLWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> GLWEInfos for GLWECiphertext<D> {
|
impl<D: Data> GLWEInfos for GLWE<D> {
|
||||||
fn rank(&self) -> Rank {
|
fn rank(&self) -> Rank {
|
||||||
Rank(self.data.cols() as u32 - 1)
|
Rank(self.data.cols() as u32 - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> ToOwnedDeep for GLWECiphertext<D> {
|
impl<D: DataRef> ToOwnedDeep for GLWE<D> {
|
||||||
type Owned = GLWECiphertext<Vec<u8>>;
|
type Owned = GLWE<Vec<u8>>;
|
||||||
fn to_owned_deep(&self) -> Self::Owned {
|
fn to_owned_deep(&self) -> Self::Owned {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
data: self.data.to_owned_deep(),
|
data: self.data.to_owned_deep(),
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
@@ -121,17 +122,17 @@ impl<D: DataRef> ToOwnedDeep for GLWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Debug for GLWECiphertext<D> {
|
impl<D: DataRef> fmt::Debug for GLWE<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{self}")
|
write!(f, "{self}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Display for GLWECiphertext<D> {
|
impl<D: DataRef> fmt::Display for GLWE<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"GLWECiphertext: base2k={} k={}: {}",
|
"GLWE: base2k={} k={}: {}",
|
||||||
self.base2k().0,
|
self.base2k().0,
|
||||||
self.k().0,
|
self.k().0,
|
||||||
self.data
|
self.data
|
||||||
@@ -139,41 +140,86 @@ impl<D: DataRef> fmt::Display for GLWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> FillUniform for GLWECiphertext<D> {
|
impl<D: DataMut> FillUniform for GLWE<D> {
|
||||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||||
self.data.fill_uniform(log_bound, source);
|
self.data.fill_uniform(log_bound, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
pub trait GLWEAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GLWEInfos,
|
{
|
||||||
{
|
fn alloc_glwe(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> GLWE<Vec<u8>> {
|
||||||
Self::alloc_with(infos.n(), infos.base2k(), infos.k(), infos.rank())
|
GLWE {
|
||||||
}
|
data: VecZnx::alloc(
|
||||||
|
self.n().into(),
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
|
(rank + 1).into(),
|
||||||
Self {
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
data: VecZnx::alloc(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize),
|
),
|
||||||
base2k,
|
base2k,
|
||||||
k,
|
k,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_from_infos<A>(&self, infos: &A) -> GLWE<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(infos.n(), infos.base2k(), infos.k(), infos.rank())
|
self.alloc_glwe(infos.base2k(), infos.k(), infos.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
fn bytes_of_glwe(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
||||||
VecZnx::alloc_bytes(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize)
|
VecZnx::bytes_of(
|
||||||
|
self.n().into(),
|
||||||
|
(rank + 1).into(),
|
||||||
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_glwe(infos.base2k(), infos.k(), infos.rank())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> ReaderFrom for GLWECiphertext<D> {
|
impl<B: Backend> GLWEAlloc for Module<B> where Self: GetDegree {}
|
||||||
|
|
||||||
|
impl GLWE<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWEAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWEAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe(base2k, k, rank)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWEAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWEAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe(base2k, k, rank)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataMut> ReaderFrom for GLWE<D> {
|
||||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||||
@@ -181,7 +227,7 @@ impl<D: DataMut> ReaderFrom for GLWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> WriterTo for GLWECiphertext<D> {
|
impl<D: DataRef> WriterTo for GLWE<D> {
|
||||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||||
writer.write_u32::<LittleEndian>(self.k.0)?;
|
writer.write_u32::<LittleEndian>(self.k.0)?;
|
||||||
writer.write_u32::<LittleEndian>(self.base2k.0)?;
|
writer.write_u32::<LittleEndian>(self.base2k.0)?;
|
||||||
@@ -189,13 +235,13 @@ impl<D: DataRef> WriterTo for GLWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GLWECiphertextToRef {
|
pub trait GLWEToRef {
|
||||||
fn to_ref(&self) -> GLWECiphertext<&[u8]>;
|
fn to_ref(&self) -> GLWE<&[u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GLWECiphertextToRef for GLWECiphertext<D> {
|
impl<D: DataRef> GLWEToRef for GLWE<D> {
|
||||||
fn to_ref(&self) -> GLWECiphertext<&[u8]> {
|
fn to_ref(&self) -> GLWE<&[u8]> {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.to_ref(),
|
data: self.data.to_ref(),
|
||||||
@@ -203,13 +249,13 @@ impl<D: DataRef> GLWECiphertextToRef for GLWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GLWECiphertextToMut {
|
pub trait GLWEToMut {
|
||||||
fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]>;
|
fn to_mut(&mut self) -> GLWE<&mut [u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertextToMut for GLWECiphertext<D> {
|
impl<D: DataMut> GLWEToMut for GLWE<D> {
|
||||||
fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]> {
|
fn to_mut(&mut self) -> GLWE<&mut [u8]> {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.to_mut(),
|
data: self.data.to_mut(),
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
use poulpy_hal::layouts::{Data, DataMut, DataRef, ReaderFrom, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo, ZnxInfos};
|
use poulpy_hal::layouts::{
|
||||||
|
Backend, Data, DataMut, DataRef, Module, ReaderFrom, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo, ZnxInfos,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dist::Distribution,
|
dist::Distribution,
|
||||||
layouts::{Base2K, Degree, GLWEInfos, LWEInfos, Rank, TorusPrecision},
|
layouts::{Base2K, Degree, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision},
|
||||||
};
|
};
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
@@ -80,32 +82,75 @@ impl GLWEInfos for GLWEPublicKeyLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWEPublicKey<Vec<u8>> {
|
pub trait GLWEPublicKeyAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GLWEInfos,
|
{
|
||||||
{
|
fn alloc_glwe_public_key(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> GLWEPublicKey<Vec<u8>> {
|
||||||
Self::alloc_with(infos.n(), infos.base2k(), infos.k(), infos.rank())
|
GLWEPublicKey {
|
||||||
}
|
data: VecZnx::alloc(
|
||||||
|
self.n().into(),
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
|
(rank + 1).into(),
|
||||||
Self {
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
data: VecZnx::alloc(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize),
|
),
|
||||||
base2k,
|
base2k,
|
||||||
k,
|
k,
|
||||||
dist: Distribution::NONE,
|
dist: Distribution::NONE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_public_key_from_infos<A>(&self, infos: &A) -> GLWEPublicKey<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(infos.n(), infos.base2k(), infos.k(), infos.rank())
|
self.alloc_glwe_public_key(infos.base2k(), infos.k(), infos.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
fn bytes_of_glwe_public_key(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
||||||
VecZnx::alloc_bytes(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize)
|
VecZnx::bytes_of(
|
||||||
|
self.n().into(),
|
||||||
|
(rank + 1).into(),
|
||||||
|
k.0.div_ceil(base2k.0) as usize,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_public_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_glwe_public_key(infos.base2k(), infos.k(), infos.rank())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GLWEPublicKey<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWEPublicKeyAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_public_key_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWEPublicKeyAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_public_key(base2k, k, rank)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWEPublicKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_public_key_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWEPublicKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_public_key(base2k, k, rank)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use poulpy_hal::layouts::{Data, DataMut, DataRef, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos};
|
use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, VecZnx, VecZnxToMut, VecZnxToRef, ZnxInfos};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, GLWECiphertext, GLWECiphertextToMut, GLWECiphertextToRef, GLWEInfos, GLWELayoutSet, LWEInfos, Rank,
|
Base2K, Degree, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, GetDegree, LWEInfos, Rank, SetGLWEInfos, TorusPrecision,
|
||||||
TorusPrecision,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
@@ -40,8 +39,8 @@ pub struct GLWEPlaintext<D: Data> {
|
|||||||
pub k: TorusPrecision,
|
pub k: TorusPrecision,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWELayoutSet for GLWEPlaintext<D> {
|
impl<D: DataMut> SetGLWEInfos for GLWEPlaintext<D> {
|
||||||
fn set_basek(&mut self, base2k: Base2K) {
|
fn set_base2k(&mut self, base2k: Base2K) {
|
||||||
self.base2k = base2k
|
self.base2k = base2k
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,39 +85,72 @@ impl<D: DataRef> fmt::Display for GLWEPlaintext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWEPlaintext<Vec<u8>> {
|
pub trait GLWEPlaintextAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GLWEInfos,
|
{
|
||||||
{
|
fn alloc_glwe_plaintext(&self, base2k: Base2K, k: TorusPrecision) -> GLWEPlaintext<Vec<u8>> {
|
||||||
Self::alloc_with(infos.n(), infos.base2k(), infos.k(), Rank(0))
|
GLWEPlaintext {
|
||||||
}
|
data: VecZnx::alloc(self.n().into(), 1, k.0.div_ceil(base2k.0) as usize),
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
|
|
||||||
debug_assert!(rank.0 == 0);
|
|
||||||
Self {
|
|
||||||
data: VecZnx::alloc(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize),
|
|
||||||
base2k,
|
base2k,
|
||||||
k,
|
k,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_plaintext_from_infos<A>(&self, infos: &A) -> GLWEPlaintext<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(infos.n(), infos.base2k(), infos.k(), Rank(0))
|
self.alloc_glwe_plaintext(infos.base2k(), infos.k())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
fn bytes_of_glwe_plaintext(&self, base2k: Base2K, k: TorusPrecision) -> usize {
|
||||||
debug_assert!(rank.0 == 0);
|
VecZnx::bytes_of(self.n().into(), 1, k.0.div_ceil(base2k.0) as usize)
|
||||||
VecZnx::alloc_bytes(n.into(), (rank + 1).into(), k.0.div_ceil(base2k.0) as usize)
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_plaintext_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_glwe_plaintext(infos.base2k(), infos.k())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> GLWECiphertextToRef for GLWEPlaintext<D> {
|
impl GLWEPlaintext<Vec<u8>> {
|
||||||
fn to_ref(&self) -> GLWECiphertext<&[u8]> {
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
GLWECiphertext {
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWEPlaintextAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_plaintext_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWEPlaintextAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_plaintext(base2k, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWEPlaintextAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_plaintext_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWEPlaintextAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_plaintext(base2k, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D: DataRef> GLWEToRef for GLWEPlaintext<D> {
|
||||||
|
fn to_ref(&self) -> GLWE<&[u8]> {
|
||||||
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.to_ref(),
|
data: self.data.to_ref(),
|
||||||
@@ -126,9 +158,9 @@ impl<D: DataRef> GLWECiphertextToRef for GLWEPlaintext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWECiphertextToMut for GLWEPlaintext<D> {
|
impl<D: DataMut> GLWEToMut for GLWEPlaintext<D> {
|
||||||
fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]> {
|
fn to_mut(&mut self) -> GLWE<&mut [u8]> {
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.to_mut(),
|
data: self.data.to_mut(),
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, ReaderFrom, ScalarZnx, ScalarZnxToMut, ScalarZnxToRef, WriterTo, ZnxInfos, ZnxZero},
|
layouts::{
|
||||||
|
Backend, Data, DataMut, DataRef, Module, ReaderFrom, ScalarZnx, ScalarZnxToMut, ScalarZnxToRef, WriterTo, ZnxInfos,
|
||||||
|
ZnxZero,
|
||||||
|
},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dist::Distribution,
|
dist::Distribution,
|
||||||
layouts::{Base2K, Degree, GLWEInfos, LWEInfos, Rank, TorusPrecision},
|
layouts::{Base2K, Degree, GLWEInfos, GetDegree, LWEInfos, Rank, TorusPrecision},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
@@ -67,30 +70,65 @@ impl<D: Data> GLWEInfos for GLWESecret<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWESecret<Vec<u8>> {
|
pub trait GLWESecretAlloc
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
where
|
||||||
where
|
Self: GetDegree,
|
||||||
A: GLWEInfos,
|
{
|
||||||
{
|
fn alloc_glwe_secret(&self, rank: Rank) -> GLWESecret<Vec<u8>> {
|
||||||
Self::alloc_with(infos.n(), infos.rank())
|
GLWESecret {
|
||||||
}
|
data: ScalarZnx::alloc(self.n().into(), rank.into()),
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, rank: Rank) -> Self {
|
|
||||||
Self {
|
|
||||||
data: ScalarZnx::alloc(n.into(), rank.into()),
|
|
||||||
dist: Distribution::NONE,
|
dist: Distribution::NONE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_glwe_secret_from_infos<A>(&self, infos: &A) -> GLWESecret<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(infos.n(), infos.rank())
|
self.alloc_glwe_secret(infos.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, rank: Rank) -> usize {
|
fn bytes_of_glwe_secret(&self, rank: Rank) -> usize {
|
||||||
ScalarZnx::alloc_bytes(n.into(), rank.into())
|
ScalarZnx::bytes_of(self.n().into(), rank.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_secret_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_glwe_secret(infos.rank())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GLWESecret<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWESecretAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_secret_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, rank: Rank) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: GLWESecretAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_glwe_secret(rank)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GLWEInfos,
|
||||||
|
Module<B>: GLWESecretAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_secret_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: Module<B>, rank: Rank) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: GLWESecretAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_secret(rank)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyAlloc, GLWESwitchingKeyToMut,
|
||||||
Rank, TorusPrecision,
|
GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -132,55 +132,88 @@ impl<D: DataRef> WriterTo for GLWEToLWESwitchingKey<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait GLWEToLWESwitchingKeyAlloc
|
||||||
|
where
|
||||||
|
Self: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_glwe_to_lwe_switching_key(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_in: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
) -> GLWEToLWESwitchingKey<Vec<u8>> {
|
||||||
|
GLWEToLWESwitchingKey(self.alloc_glwe_switching_key(base2k, k, rank_in, Rank(1), dnum, Dsize(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_glwe_to_lwe_switching_key_from_infos<A>(&self, infos: &A) -> GLWEToLWESwitchingKey<Vec<u8>>
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_out().0,
|
||||||
|
1,
|
||||||
|
"rank_out > 1 is not supported for GLWEToLWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.dsize().0,
|
||||||
|
1,
|
||||||
|
"dsize > 1 is not supported for GLWEToLWESwitchingKey"
|
||||||
|
);
|
||||||
|
self.alloc_glwe_to_lwe_switching_key(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_to_lwe_switching_key(&self, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
|
||||||
|
self.bytes_of_glwe_switching_key(base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_glwe_to_lwe_switching_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_out().0,
|
||||||
|
1,
|
||||||
|
"rank_out > 1 is not supported for GLWEToLWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.dsize().0,
|
||||||
|
1,
|
||||||
|
"dsize > 1 is not supported for GLWEToLWESwitchingKey"
|
||||||
|
);
|
||||||
|
self.bytes_of_glwe_to_lwe_switching_key(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GLWEToLWESwitchingKey<Vec<u8>> {
|
impl GLWEToLWESwitchingKey<Vec<u8>> {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
module.alloc_glwe_to_lwe_switching_key_from_infos(infos)
|
||||||
infos.rank_out().0,
|
|
||||||
1,
|
|
||||||
"rank_out > 1 is not supported for GLWEToLWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.dsize().0,
|
|
||||||
1,
|
|
||||||
"dsize > 1 is not supported for GLWEToLWESwitchingKey"
|
|
||||||
);
|
|
||||||
Self(GLWESwitchingKey::alloc(infos))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self {
|
pub fn alloc<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self
|
||||||
Self(GLWESwitchingKey::alloc_with(
|
where
|
||||||
n,
|
Module<B>: GLWEToLWESwitchingKeyAlloc,
|
||||||
base2k,
|
{
|
||||||
k,
|
module.alloc_glwe_to_lwe_switching_key(base2k, k, rank_in, dnum)
|
||||||
rank_in,
|
|
||||||
Rank(1),
|
|
||||||
dnum,
|
|
||||||
Dsize(1),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
module.bytes_of_glwe_to_lwe_switching_key_from_infos(infos)
|
||||||
infos.rank_out().0,
|
|
||||||
1,
|
|
||||||
"rank_out > 1 is not supported for GLWEToLWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.dsize().0,
|
|
||||||
1,
|
|
||||||
"dsize > 1 is not supported for GLWEToLWESwitchingKey"
|
|
||||||
);
|
|
||||||
GLWESwitchingKey::alloc_bytes(infos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
|
pub fn bytes_of<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize
|
||||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
where
|
||||||
|
Module<B>: GLWEToLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_glwe_to_lwe_switching_key(base2k, k, rank_in, dnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo, Zn, ZnToMut, ZnToRef, ZnxInfos},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo, Zn, ZnToMut, ZnToRef, ZnxInfos},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,13 +53,13 @@ impl LWEInfos for LWECiphertextLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
pub struct LWECiphertext<D: Data> {
|
pub struct LWE<D: Data> {
|
||||||
pub(crate) data: Zn<D>,
|
pub(crate) data: Zn<D>,
|
||||||
pub(crate) k: TorusPrecision,
|
pub(crate) k: TorusPrecision,
|
||||||
pub(crate) base2k: Base2K,
|
pub(crate) base2k: Base2K,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> LWEInfos for LWECiphertext<D> {
|
impl<D: Data> LWEInfos for LWE<D> {
|
||||||
fn base2k(&self) -> Base2K {
|
fn base2k(&self) -> Base2K {
|
||||||
self.base2k
|
self.base2k
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ impl<D: Data> LWEInfos for LWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Data> SetLWEInfos for LWECiphertext<D> {
|
impl<D: Data> SetLWEInfos for LWE<D> {
|
||||||
fn set_base2k(&mut self, base2k: Base2K) {
|
fn set_base2k(&mut self, base2k: Base2K) {
|
||||||
self.base2k = base2k
|
self.base2k = base2k
|
||||||
}
|
}
|
||||||
@@ -86,25 +86,25 @@ impl<D: Data> SetLWEInfos for LWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> LWECiphertext<D> {
|
impl<D: DataRef> LWE<D> {
|
||||||
pub fn data(&self) -> &Zn<D> {
|
pub fn data(&self) -> &Zn<D> {
|
||||||
&self.data
|
&self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> LWECiphertext<D> {
|
impl<D: DataMut> LWE<D> {
|
||||||
pub fn data_mut(&mut self) -> &Zn<D> {
|
pub fn data_mut(&mut self) -> &Zn<D> {
|
||||||
&mut self.data
|
&mut self.data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Debug for LWECiphertext<D> {
|
impl<D: DataRef> fmt::Debug for LWE<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{self}")
|
write!(f, "{self}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Display for LWECiphertext<D> {
|
impl<D: DataRef> fmt::Display for LWE<D> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
@@ -116,7 +116,7 @@ impl<D: DataRef> fmt::Display for LWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> FillUniform for LWECiphertext<D>
|
impl<D: DataMut> FillUniform for LWE<D>
|
||||||
where
|
where
|
||||||
Zn<D>: FillUniform,
|
Zn<D>: FillUniform,
|
||||||
{
|
{
|
||||||
@@ -125,41 +125,73 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LWECiphertext<Vec<u8>> {
|
pub trait LWEAlloc {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
fn alloc_lwe(&self, n: Degree, base2k: Base2K, k: TorusPrecision) -> LWE<Vec<u8>> {
|
||||||
where
|
LWE {
|
||||||
A: LWEInfos,
|
|
||||||
{
|
|
||||||
Self::alloc_with(infos.n(), infos.base2k(), infos.k())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision) -> Self {
|
|
||||||
Self {
|
|
||||||
data: Zn::alloc((n + 1).into(), 1, k.0.div_ceil(base2k.0) as usize),
|
data: Zn::alloc((n + 1).into(), 1, k.0.div_ceil(base2k.0) as usize),
|
||||||
k,
|
k,
|
||||||
base2k,
|
base2k,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
fn alloc_lwe_from_infos<A>(&self, infos: &A) -> LWE<Vec<u8>>
|
||||||
where
|
where
|
||||||
A: LWEInfos,
|
A: LWEInfos,
|
||||||
{
|
{
|
||||||
Self::alloc_bytes_with(infos.n(), infos.base2k(), infos.k())
|
self.alloc_lwe(infos.n(), infos.base2k(), infos.k())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision) -> usize {
|
fn bytes_of_lwe(&self, n: Degree, base2k: Base2K, k: TorusPrecision) -> usize {
|
||||||
Zn::alloc_bytes((n + 1).into(), 1, k.0.div_ceil(base2k.0) as usize)
|
Zn::bytes_of((n + 1).into(), 1, k.0.div_ceil(base2k.0) as usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_lwe_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
{
|
||||||
|
self.bytes_of_lwe(infos.n(), infos.base2k(), infos.k())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LWE<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
Module<B>: LWEAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: &Module<B>, n: Degree, base2k: Base2K, k: TorusPrecision) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: LWEAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe(n, base2k, k)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
Module<B>: LWEAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes_of<B: Backend>(module: &Module<B>, n: Degree, base2k: Base2K, k: TorusPrecision) -> usize
|
||||||
|
where
|
||||||
|
Module<B>: LWEAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe(n, base2k, k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LWECiphertextToRef {
|
pub trait LWECiphertextToRef {
|
||||||
fn to_ref(&self) -> LWECiphertext<&[u8]>;
|
fn to_ref(&self) -> LWE<&[u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> LWECiphertextToRef for LWECiphertext<D> {
|
impl<D: DataRef> LWECiphertextToRef for LWE<D> {
|
||||||
fn to_ref(&self) -> LWECiphertext<&[u8]> {
|
fn to_ref(&self) -> LWE<&[u8]> {
|
||||||
LWECiphertext {
|
LWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.to_ref(),
|
data: self.data.to_ref(),
|
||||||
@@ -167,14 +199,14 @@ impl<D: DataRef> LWECiphertextToRef for LWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait LWECiphertextToMut {
|
pub trait LWEToMut {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn to_mut(&mut self) -> LWECiphertext<&mut [u8]>;
|
fn to_mut(&mut self) -> LWE<&mut [u8]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> LWECiphertextToMut for LWECiphertext<D> {
|
impl<D: DataMut> LWEToMut for LWE<D> {
|
||||||
fn to_mut(&mut self) -> LWECiphertext<&mut [u8]> {
|
fn to_mut(&mut self) -> LWE<&mut [u8]> {
|
||||||
LWECiphertext {
|
LWE {
|
||||||
k: self.k,
|
k: self.k,
|
||||||
base2k: self.base2k,
|
base2k: self.base2k,
|
||||||
data: self.data.to_mut(),
|
data: self.data.to_mut(),
|
||||||
@@ -182,7 +214,7 @@ impl<D: DataMut> LWECiphertextToMut for LWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> ReaderFrom for LWECiphertext<D> {
|
impl<D: DataMut> ReaderFrom for LWE<D> {
|
||||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||||
@@ -190,7 +222,7 @@ impl<D: DataMut> ReaderFrom for LWECiphertext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> WriterTo for LWECiphertext<D> {
|
impl<D: DataRef> WriterTo for LWE<D> {
|
||||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||||
writer.write_u32::<LittleEndian>(self.k.into())?;
|
writer.write_u32::<LittleEndian>(self.k.into())?;
|
||||||
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
writer.write_u32::<LittleEndian>(self.base2k.into())?;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyAlloc, GLWESwitchingKeyToMut,
|
||||||
Rank, TorusPrecision,
|
GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
@@ -101,65 +101,94 @@ impl<D: Data> GGLWEInfos for LWESwitchingKey<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait LWESwitchingKeyAlloc
|
||||||
|
where
|
||||||
|
Self: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_lwe_switching_key(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> LWESwitchingKey<Vec<u8>> {
|
||||||
|
LWESwitchingKey(self.alloc_glwe_switching_key(base2k, k, Rank(1), Rank(1), dnum, Dsize(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_lwe_switching_key_from_infos<A>(&self, infos: &A) -> LWESwitchingKey<Vec<u8>>
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.dsize().0,
|
||||||
|
1,
|
||||||
|
"dsize > 1 is not supported for LWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_in().0,
|
||||||
|
1,
|
||||||
|
"rank_in > 1 is not supported for LWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_out().0,
|
||||||
|
1,
|
||||||
|
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||||
|
);
|
||||||
|
self.alloc_lwe_switching_key(infos.base2k(), infos.k(), infos.dnum())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_lwe_switching_key(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||||
|
self.bytes_of_glwe_switching_key(base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_lwe_switching_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.dsize().0,
|
||||||
|
1,
|
||||||
|
"dsize > 1 is not supported for LWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_in().0,
|
||||||
|
1,
|
||||||
|
"rank_in > 1 is not supported for LWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_out().0,
|
||||||
|
1,
|
||||||
|
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||||
|
);
|
||||||
|
self.bytes_of_lwe_switching_key(infos.base2k(), infos.k(), infos.dnum())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> LWESwitchingKeyAlloc for Module<B> where Self: GLWESwitchingKeyAlloc {}
|
||||||
|
|
||||||
impl LWESwitchingKey<Vec<u8>> {
|
impl LWESwitchingKey<Vec<u8>> {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWESwitchingKeyAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
module.alloc_lwe_switching_key_from_infos(infos)
|
||||||
infos.dsize().0,
|
|
||||||
1,
|
|
||||||
"dsize > 1 is not supported for LWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.rank_in().0,
|
|
||||||
1,
|
|
||||||
"rank_in > 1 is not supported for LWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.rank_out().0,
|
|
||||||
1,
|
|
||||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
|
||||||
);
|
|
||||||
Self(GLWESwitchingKey::alloc(infos))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
|
pub fn alloc<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self
|
||||||
Self(GLWESwitchingKey::alloc_with(
|
where
|
||||||
n,
|
Module<B>: LWESwitchingKeyAlloc,
|
||||||
base2k,
|
{
|
||||||
k,
|
module.alloc_lwe_switching_key(base2k, k, dnum)
|
||||||
Rank(1),
|
|
||||||
Rank(1),
|
|
||||||
dnum,
|
|
||||||
Dsize(1),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWESwitchingKeyAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
module.bytes_of_glwe_switching_key_from_infos(infos)
|
||||||
infos.dsize().0,
|
|
||||||
1,
|
|
||||||
"dsize > 1 is not supported for LWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.rank_in().0,
|
|
||||||
1,
|
|
||||||
"rank_in > 1 is not supported for LWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.rank_out().0,
|
|
||||||
1,
|
|
||||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
|
||||||
);
|
|
||||||
GLWESwitchingKey::alloc_bytes(infos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
pub fn bytes_of<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize
|
||||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
where
|
||||||
|
Module<B>: LWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_switching_key(base2k, k, dnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use poulpy_hal::layouts::{Data, DataMut, DataRef, Zn, ZnToMut, ZnToRef, ZnxInfos};
|
use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Zn, ZnToMut, ZnToRef, ZnxInfos};
|
||||||
|
|
||||||
use crate::layouts::{Base2K, Degree, LWEInfos, TorusPrecision};
|
use crate::layouts::{Base2K, Degree, LWEInfos, TorusPrecision};
|
||||||
|
|
||||||
@@ -52,21 +52,36 @@ impl<D: Data> LWEInfos for LWEPlaintext<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LWEPlaintext<Vec<u8>> {
|
pub trait LWEPlaintextAlloc {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
fn alloc_lwe_plaintext(&self, base2k: Base2K, k: TorusPrecision) -> LWEPlaintext<Vec<u8>> {
|
||||||
where
|
LWEPlaintext {
|
||||||
A: LWEInfos,
|
|
||||||
{
|
|
||||||
Self::alloc_with(infos.base2k(), infos.k())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn alloc_with(base2k: Base2K, k: TorusPrecision) -> Self {
|
|
||||||
Self {
|
|
||||||
data: Zn::alloc(1, 1, k.0.div_ceil(base2k.0) as usize),
|
data: Zn::alloc(1, 1, k.0.div_ceil(base2k.0) as usize),
|
||||||
k,
|
k,
|
||||||
base2k,
|
base2k,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn alloc_lwe_plaintext_from_infos<A>(&self, infos: &A) -> LWEPlaintext<Vec<u8>>
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
{
|
||||||
|
self.alloc_lwe_plaintext(infos.base2k(), infos.k())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> LWEPlaintextAlloc for Module<B> {}
|
||||||
|
|
||||||
|
impl LWEPlaintext<Vec<u8>> {
|
||||||
|
pub fn alloc_from_infos<A, B: Backend>(module: Module<B>, infos: &A) -> Self
|
||||||
|
where
|
||||||
|
A: LWEInfos,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_plaintext_from_infos(infos)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alloc<B: Backend>(module: Module<B>, base2k: Base2K, k: TorusPrecision) -> Self {
|
||||||
|
module.alloc_lwe_plaintext(base2k, k)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataRef> fmt::Display for LWEPlaintext<D> {
|
impl<D: DataRef> fmt::Display for LWEPlaintext<D> {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, ScalarZnx, ScalarZnxToMut, ScalarZnxToRef, ZnxInfos, ZnxView, ZnxZero},
|
layouts::{Backend, Data, DataMut, DataRef, Module, ScalarZnx, ScalarZnxToMut, ScalarZnxToRef, ZnxInfos, ZnxView, ZnxZero},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -13,15 +13,26 @@ pub struct LWESecret<D: Data> {
|
|||||||
pub(crate) dist: Distribution,
|
pub(crate) dist: Distribution,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LWESecret<Vec<u8>> {
|
pub trait LWESecretAlloc {
|
||||||
pub fn alloc(n: Degree) -> Self {
|
fn alloc_lwe_secret(&self, n: Degree) -> LWESecret<Vec<u8>> {
|
||||||
Self {
|
LWESecret {
|
||||||
data: ScalarZnx::alloc(n.into(), 1),
|
data: ScalarZnx::alloc(n.into(), 1),
|
||||||
dist: Distribution::NONE,
|
dist: Distribution::NONE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> LWESecretAlloc for Module<B> {}
|
||||||
|
|
||||||
|
impl LWESecret<Vec<u8>> {
|
||||||
|
pub fn alloc<B: Backend>(module: &Module<B>, n: Degree) -> Self
|
||||||
|
where
|
||||||
|
Module<B>: LWESecretAlloc,
|
||||||
|
{
|
||||||
|
module.alloc_lwe_secret(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<D: DataRef> LWESecret<D> {
|
impl<D: DataRef> LWESecret<D> {
|
||||||
pub fn raw(&self) -> &[i64] {
|
pub fn raw(&self) -> &[i64] {
|
||||||
self.data.at(0, 0)
|
self.data.at(0, 0)
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use poulpy_hal::{
|
use poulpy_hal::{
|
||||||
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
|
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, WriterTo},
|
||||||
source::Source,
|
source::Source,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyAlloc, GLWESwitchingKeyToMut,
|
||||||
Rank, TorusPrecision,
|
GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||||
@@ -131,55 +131,91 @@ impl<D: DataRef> WriterTo for LWEToGLWESwitchingKey<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait LWEToGLWESwitchingKeyAlloc
|
||||||
|
where
|
||||||
|
Self: GLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
fn alloc_lwe_to_glwe_switching_key(
|
||||||
|
&self,
|
||||||
|
base2k: Base2K,
|
||||||
|
k: TorusPrecision,
|
||||||
|
rank_out: Rank,
|
||||||
|
dnum: Dnum,
|
||||||
|
) -> LWEToGLWESwitchingKey<Vec<u8>> {
|
||||||
|
LWEToGLWESwitchingKey(self.alloc_glwe_switching_key(base2k, k, Rank(1), rank_out, dnum, Dsize(1)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_lwe_to_glwe_switching_key_from_infos<A>(&self, infos: &A) -> LWEToGLWESwitchingKey<Vec<u8>>
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_in().0,
|
||||||
|
1,
|
||||||
|
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.dsize().0,
|
||||||
|
1,
|
||||||
|
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||||
|
);
|
||||||
|
|
||||||
|
self.alloc_lwe_to_glwe_switching_key(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_lwe_to_glwe_switching_key(&self, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> usize {
|
||||||
|
self.bytes_of_glwe_switching_key(base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bytes_of_lwe_to_glwe_switching_key_from_infos<A>(&self, infos: &A) -> usize
|
||||||
|
where
|
||||||
|
A: GGLWEInfos,
|
||||||
|
{
|
||||||
|
assert_eq!(
|
||||||
|
infos.rank_in().0,
|
||||||
|
1,
|
||||||
|
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
infos.dsize().0,
|
||||||
|
1,
|
||||||
|
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||||
|
);
|
||||||
|
self.bytes_of_lwe_to_glwe_switching_key(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: Backend> LWEToGLWESwitchingKeyAlloc for Module<B> where Self: GLWESwitchingKeyAlloc {}
|
||||||
|
|
||||||
impl LWEToGLWESwitchingKey<Vec<u8>> {
|
impl LWEToGLWESwitchingKey<Vec<u8>> {
|
||||||
pub fn alloc<A>(infos: &A) -> Self
|
pub fn alloc_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> Self
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
module.alloc_lwe_to_glwe_switching_key_from_infos(infos)
|
||||||
infos.rank_in().0,
|
|
||||||
1,
|
|
||||||
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.dsize().0,
|
|
||||||
1,
|
|
||||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
|
||||||
);
|
|
||||||
Self(GLWESwitchingKey::alloc(infos))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
|
pub fn alloc<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self
|
||||||
Self(GLWESwitchingKey::alloc_with(
|
where
|
||||||
n,
|
Module<B>: LWEToGLWESwitchingKeyAlloc,
|
||||||
base2k,
|
{
|
||||||
k,
|
module.alloc_lwe_to_glwe_switching_key(base2k, k, rank_out, dnum)
|
||||||
Rank(1),
|
|
||||||
rank_out,
|
|
||||||
dnum,
|
|
||||||
Dsize(1),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(infos: &A) -> usize
|
pub fn bytes_of_from_infos<A, B: Backend>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyAlloc,
|
||||||
{
|
{
|
||||||
debug_assert_eq!(
|
module.bytes_of_lwe_to_glwe_switching_key_from_infos(infos)
|
||||||
infos.rank_in().0,
|
|
||||||
1,
|
|
||||||
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
|
|
||||||
);
|
|
||||||
debug_assert_eq!(
|
|
||||||
infos.dsize().0,
|
|
||||||
1,
|
|
||||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
|
||||||
);
|
|
||||||
GLWESwitchingKey::alloc_bytes(infos)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize {
|
pub fn bytes_of<B: Backend>(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize
|
||||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
where
|
||||||
|
Module<B>: LWEToGLWESwitchingKeyAlloc,
|
||||||
|
{
|
||||||
|
module.bytes_of_lwe_to_glwe_switching_key(base2k, k, rank_out, dnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ pub trait AutomorphismKeyPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GLWESwitchingKeyPreparedAlloc<B>,
|
Self: GLWESwitchingKeyPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
fn automorphism_key_prepared_alloc(
|
fn alloc_automorphism_key_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -89,12 +89,12 @@ where
|
|||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> AutomorphismKeyPrepared<Vec<u8>, B> {
|
) -> AutomorphismKeyPrepared<Vec<u8>, B> {
|
||||||
AutomorphismKeyPrepared::<Vec<u8>, B> {
|
AutomorphismKeyPrepared::<Vec<u8>, B> {
|
||||||
key: self.glwe_switching_key_prepared_alloc(base2k, k, rank, rank, dnum, dsize),
|
key: self.alloc_glwe_switching_key_prepared(base2k, k, rank, rank, dnum, dsize),
|
||||||
p: 0,
|
p: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn automorphism_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> AutomorphismKeyPrepared<Vec<u8>, B>
|
fn alloc_automorphism_key_prepared_from_infos<A>(&self, infos: &A) -> AutomorphismKeyPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -103,7 +103,7 @@ where
|
|||||||
infos.rank_out(),
|
infos.rank_out(),
|
||||||
"rank_in != rank_out is not supported for AutomorphismKeyPrepared"
|
"rank_in != rank_out is not supported for AutomorphismKeyPrepared"
|
||||||
);
|
);
|
||||||
self.automorphism_key_prepared_alloc(
|
self.alloc_automorphism_key_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank(),
|
infos.rank(),
|
||||||
@@ -112,7 +112,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn automorphism_key_prepared_alloc_bytes(
|
fn bytes_of_automorphism_key_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -120,10 +120,10 @@ where
|
|||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
self.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank, rank, dnum, dsize)
|
self.bytes_of_glwe_switching_key_prepared(base2k, k, rank, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn automorphism_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn bytes_of_automorphism_key_prepared_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -132,7 +132,7 @@ where
|
|||||||
infos.rank_out(),
|
infos.rank_out(),
|
||||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared"
|
"rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared"
|
||||||
);
|
);
|
||||||
self.automorphism_key_prepared_alloc_bytes(
|
self.bytes_of_automorphism_key_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank(),
|
infos.rank(),
|
||||||
@@ -150,29 +150,29 @@ impl<B: Backend> AutomorphismKeyPrepared<Vec<u8>, B> {
|
|||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
module.automorphism_key_prepared_alloc_from_infos(infos)
|
module.alloc_automorphism_key_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
|
pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
|
||||||
where
|
where
|
||||||
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
module.automorphism_key_prepared_alloc(base2k, k, rank, dnum, dsize)
|
module.alloc_automorphism_key_prepared(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
module.automorphism_key_prepared_alloc_bytes_from_infos(infos)
|
module.bytes_of_automorphism_key_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize
|
pub fn bytes_of(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize
|
||||||
where
|
where
|
||||||
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
Module<B>: AutomorphismKeyPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
module.automorphism_key_prepared_alloc_bytes(base2k, k, rank, dnum, dsize)
|
module.bytes_of_automorphism_key_prepared(base2k, k, rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,19 +180,19 @@ pub trait AutomorphismKeyPrepare<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GLWESwitchingKeyPrepare<B>,
|
Self: GLWESwitchingKeyPrepare<B>,
|
||||||
{
|
{
|
||||||
fn automorphism_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
fn prepare_automorphism_key_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_switching_key_prepare_tmp_bytes(infos)
|
self.prepare_glwe_switching_key_tmp_bytes(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn automorphism_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
fn prepare_automorphism_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||||
where
|
where
|
||||||
R: AutomorphismKeyPreparedToMut<B> + SetAutomorphismGaloisElement,
|
R: AutomorphismKeyPreparedToMut<B> + SetAutomorphismGaloisElement,
|
||||||
O: AutomorphismKeyToRef + GetAutomorphismGaloisElement,
|
O: AutomorphismKeyToRef + GetAutomorphismGaloisElement,
|
||||||
{
|
{
|
||||||
self.glwe_switching_prepare(&mut res.to_mut().key, &other.to_ref().key, scratch);
|
self.prepare_glwe_switching(&mut res.to_mut().key, &other.to_ref().key, scratch);
|
||||||
res.set_p(other.p());
|
res.set_p(other.p());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ impl<B: Backend> AutomorphismKeyPrepared<Vec<u8>, B> {
|
|||||||
where
|
where
|
||||||
Module<B>: GLWESwitchingKeyPrepare<B>,
|
Module<B>: GLWESwitchingKeyPrepare<B>,
|
||||||
{
|
{
|
||||||
module.automorphism_key_prepare_tmp_bytes(self)
|
module.prepare_automorphism_key_tmp_bytes(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +214,7 @@ impl<D: DataMut, B: Backend> AutomorphismKeyPrepared<D, B> {
|
|||||||
O: AutomorphismKeyToRef + GetAutomorphismGaloisElement,
|
O: AutomorphismKeyToRef + GetAutomorphismGaloisElement,
|
||||||
Module<B>: AutomorphismKeyPrepare<B>,
|
Module<B>: AutomorphismKeyPrepare<B>,
|
||||||
{
|
{
|
||||||
module.automorphism_key_prepare(self, other, scratch);
|
module.prepare_automorphism_key(self, other, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ pub trait GGLWEPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes,
|
Self: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes,
|
||||||
{
|
{
|
||||||
fn gglwe_prepared_alloc(
|
fn alloc_gglwe_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -92,12 +92,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gglwe_prepared_alloc_from_infos<A>(&self, infos: &A) -> GGLWEPrepared<Vec<u8>, B>
|
fn alloc_gglwe_prepared_from_infos<A>(&self, infos: &A) -> GGLWEPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
assert_eq!(self.n(), infos.n());
|
assert_eq!(self.n(), infos.n());
|
||||||
self.gglwe_prepared_alloc(
|
self.alloc_gglwe_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank_in(),
|
infos.rank_in(),
|
||||||
@@ -107,7 +107,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gglwe_prepared_alloc_bytes(
|
fn bytes_of_gglwe_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -130,15 +130,15 @@ where
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.vmp_pmat_alloc_bytes(dnum.into(), rank_in.into(), (rank_out + 1).into(), size)
|
self.vmp_pmat_bytes_of(dnum.into(), rank_in.into(), (rank_out + 1).into(), size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gglwe_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn bytes_of_gglwe_prepared_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
assert_eq!(self.n(), infos.n());
|
assert_eq!(self.n(), infos.n());
|
||||||
self.gglwe_prepared_alloc_bytes(
|
self.bytes_of_gglwe_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank_in(),
|
infos.rank_in(),
|
||||||
@@ -159,7 +159,7 @@ where
|
|||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.gglwe_prepared_alloc_from_infos(infos)
|
module.alloc_gglwe_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc(
|
pub fn alloc(
|
||||||
@@ -171,17 +171,17 @@ where
|
|||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
module.gglwe_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize)
|
module.alloc_gglwe_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.gglwe_prepared_alloc_bytes_from_infos(infos)
|
module.bytes_of_gglwe_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes(
|
pub fn bytes_of(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -190,7 +190,7 @@ where
|
|||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
module.gglwe_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize)
|
module.bytes_of_gglwe_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ pub trait GGLWEPrepare<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GetDegree + VmpPrepareTmpBytes + VmpPrepare<B>,
|
Self: GetDegree + VmpPrepareTmpBytes + VmpPrepare<B>,
|
||||||
{
|
{
|
||||||
fn gglwe_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
fn prepare_gglwe_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -210,7 +210,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gglwe_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
fn prepare_gglwe<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||||
where
|
where
|
||||||
R: GGLWEPreparedToMut<B>,
|
R: GGLWEPreparedToMut<B>,
|
||||||
O: GGLWEToRef,
|
O: GGLWEToRef,
|
||||||
@@ -238,7 +238,7 @@ where
|
|||||||
where
|
where
|
||||||
O: GGLWEToRef,
|
O: GGLWEToRef,
|
||||||
{
|
{
|
||||||
module.gglwe_prepare(self, other, scratch);
|
module.prepare_gglwe(self, other, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ impl<B: Backend> GGLWEPrepared<Vec<u8>, B> {
|
|||||||
where
|
where
|
||||||
Module<B>: GGLWEPrepare<B>,
|
Module<B>: GGLWEPrepare<B>,
|
||||||
{
|
{
|
||||||
module.gglwe_prepare_tmp_bytes(self)
|
module.prepare_gglwe_tmp_bytes(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ pub trait GLWESwitchingKeyPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GGLWEPreparedAlloc<B>,
|
Self: GGLWEPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
fn glwe_switching_key_prepared_alloc(
|
fn alloc_glwe_switching_key_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -89,7 +89,7 @@ where
|
|||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> GLWESwitchingKeyPrepared<Vec<u8>, B> {
|
) -> GLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||||
GLWESwitchingKeyPrepared::<Vec<u8>, B> {
|
GLWESwitchingKeyPrepared::<Vec<u8>, B> {
|
||||||
key: self.gglwe_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize),
|
key: self.alloc_gglwe_prepared(base2k, k, rank_in, rank_out, dnum, dsize),
|
||||||
sk_in_n: 0,
|
sk_in_n: 0,
|
||||||
sk_out_n: 0,
|
sk_out_n: 0,
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ where
|
|||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_switching_key_prepared_alloc(
|
self.alloc_glwe_switching_key_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank_in(),
|
infos.rank_in(),
|
||||||
@@ -109,7 +109,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_switching_key_prepared_alloc_bytes(
|
fn bytes_of_glwe_switching_key_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -118,14 +118,14 @@ where
|
|||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
self.gglwe_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize)
|
self.bytes_of_gglwe_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn glwe_switching_key_prepared_bytes_of_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_switching_key_prepared_alloc_bytes(
|
self.bytes_of_glwe_switching_key_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank_in(),
|
infos.rank_in(),
|
||||||
@@ -158,17 +158,17 @@ where
|
|||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
module.glwe_switching_key_prepared_alloc(base2k, k, rank_in, rank_out, dnum, dsize)
|
module.alloc_glwe_switching_key_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.glwe_switching_key_prepared_alloc_bytes_from_infos(infos)
|
module.glwe_switching_key_prepared_bytes_of_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes(
|
pub fn bytes_of(
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -177,7 +177,7 @@ where
|
|||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
dsize: Dsize,
|
dsize: Dsize,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
module.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank_in, rank_out, dnum, dsize)
|
module.bytes_of_glwe_switching_key_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,19 +185,19 @@ pub trait GLWESwitchingKeyPrepare<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GGLWEPrepare<B>,
|
Self: GGLWEPrepare<B>,
|
||||||
{
|
{
|
||||||
fn glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
fn prepare_glwe_switching_key_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.gglwe_prepare_tmp_bytes(infos)
|
self.prepare_gglwe_tmp_bytes(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_switching_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
fn prepare_glwe_switching<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||||
where
|
where
|
||||||
R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeySetMetaData,
|
R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeySetMetaData,
|
||||||
O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData,
|
O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData,
|
||||||
{
|
{
|
||||||
self.gglwe_prepare(&mut res.to_mut().key, &other.to_ref().key, scratch);
|
self.prepare_gglwe(&mut res.to_mut().key, &other.to_ref().key, scratch);
|
||||||
res.set_sk_in_n(other.sk_in_n());
|
res.set_sk_in_n(other.sk_in_n());
|
||||||
res.set_sk_out_n(other.sk_out_n());
|
res.set_sk_out_n(other.sk_out_n());
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ impl<D: DataMut, B: Backend> GLWESwitchingKeyPrepared<D, B> {
|
|||||||
O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData,
|
O: GLWESwitchingKeyToRef + GLWESwtichingKeyGetMetaData,
|
||||||
Module<B>: GLWESwitchingKeyPrepare<B>,
|
Module<B>: GLWESwitchingKeyPrepare<B>,
|
||||||
{
|
{
|
||||||
module.glwe_switching_prepare(self, other, scratch);
|
module.prepare_glwe_switching(self, other, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ where
|
|||||||
Module<B>: GLWESwitchingKeyPrepare<B>,
|
Module<B>: GLWESwitchingKeyPrepare<B>,
|
||||||
{
|
{
|
||||||
pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize {
|
pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize {
|
||||||
module.gglwe_prepare_tmp_bytes(self)
|
module.prepare_gglwe_tmp_bytes(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ pub trait TensorKeyPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GLWESwitchingKeyPreparedAlloc<B>,
|
Self: GLWESwitchingKeyPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
fn tensor_key_prepared_alloc(
|
fn alloc_tensor_key_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -70,12 +70,12 @@ where
|
|||||||
let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1);
|
let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1);
|
||||||
TensorKeyPrepared {
|
TensorKeyPrepared {
|
||||||
keys: (0..pairs)
|
keys: (0..pairs)
|
||||||
.map(|_| self.glwe_switching_key_prepared_alloc(base2k, k, Rank(1), rank, dnum, dsize))
|
.map(|_| self.alloc_glwe_switching_key_prepared(base2k, k, Rank(1), rank, dnum, dsize))
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tensor_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> TensorKeyPrepared<Vec<u8>, B>
|
fn alloc_tensor_key_prepared_from_infos<A>(&self, infos: &A) -> TensorKeyPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -84,7 +84,7 @@ where
|
|||||||
infos.rank_out(),
|
infos.rank_out(),
|
||||||
"rank_in != rank_out is not supported for GGLWETensorKeyPrepared"
|
"rank_in != rank_out is not supported for GGLWETensorKeyPrepared"
|
||||||
);
|
);
|
||||||
self.tensor_key_prepared_alloc(
|
self.alloc_tensor_key_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.dnum(),
|
infos.dnum(),
|
||||||
@@ -93,16 +93,16 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tensor_key_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
fn bytes_of_tensor_key_prepared(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
|
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
|
||||||
pairs * self.glwe_switching_key_prepared_alloc_bytes(base2k, k, Rank(1), rank, dnum, dsize)
|
pairs * self.bytes_of_glwe_switching_key_prepared(base2k, k, Rank(1), rank, dnum, dsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tensor_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn bytes_of_tensor_key_prepared_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.tensor_key_prepared_alloc_bytes(
|
self.bytes_of_tensor_key_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.rank(),
|
infos.rank(),
|
||||||
@@ -122,29 +122,22 @@ where
|
|||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.tensor_key_prepared_alloc_from_infos(infos)
|
module.alloc_tensor_key_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self {
|
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self {
|
||||||
module.tensor_key_prepared_alloc(base2k, k, dnum, dsize, rank)
|
module.alloc_tensor_key_prepared(base2k, k, dnum, dsize, rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.tensor_key_prepared_alloc_bytes_from_infos(infos)
|
module.bytes_of_tensor_key_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(
|
pub fn bytes_of(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||||
module: &Module<B>,
|
module.bytes_of_tensor_key_prepared(base2k, k, rank, dnum, dsize)
|
||||||
base2k: Base2K,
|
|
||||||
k: TorusPrecision,
|
|
||||||
rank: Rank,
|
|
||||||
dnum: Dnum,
|
|
||||||
dsize: Dsize,
|
|
||||||
) -> usize {
|
|
||||||
module.tensor_key_prepared_alloc_bytes(base2k, k, rank, dnum, dsize)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,14 +167,14 @@ pub trait TensorKeyPrepare<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GLWESwitchingKeyPrepare<B>,
|
Self: GLWESwitchingKeyPrepare<B>,
|
||||||
{
|
{
|
||||||
fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
fn prepare_tensor_key_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_switching_key_prepare_tmp_bytes(infos)
|
self.prepare_glwe_switching_key_tmp_bytes(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
fn prepare_tensor_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||||
where
|
where
|
||||||
R: TensorKeyPreparedToMut<B>,
|
R: TensorKeyPreparedToMut<B>,
|
||||||
O: TensorKeyToRef,
|
O: TensorKeyToRef,
|
||||||
@@ -192,7 +185,7 @@ where
|
|||||||
assert_eq!(res.keys.len(), other.keys.len());
|
assert_eq!(res.keys.len(), other.keys.len());
|
||||||
|
|
||||||
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
|
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
|
||||||
self.glwe_switching_prepare(a, b, scratch);
|
self.prepare_glwe_switching(a, b, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,7 +200,7 @@ where
|
|||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.tensor_key_prepare_tmp_bytes(infos)
|
module.prepare_tensor_key_tmp_bytes(infos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +212,7 @@ where
|
|||||||
where
|
where
|
||||||
O: TensorKeyToRef,
|
O: TensorKeyToRef,
|
||||||
{
|
{
|
||||||
module.tensor_key_prepare(self, other, scratch);
|
module.prepare_tensor_key(self, other, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ pub trait GGSWPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes,
|
Self: GetDegree + VmpPMatAlloc<B> + VmpPMatAllocBytes,
|
||||||
{
|
{
|
||||||
fn ggsw_prepared_alloc(
|
fn alloc_ggsw_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
@@ -88,12 +88,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ggsw_prepared_alloc_from_infos<A>(&self, infos: &A) -> GGSWPrepared<Vec<u8>, B>
|
fn alloc_ggsw_prepared_from_infos<A>(&self, infos: &A) -> GGSWPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
A: GGSWInfos,
|
A: GGSWInfos,
|
||||||
{
|
{
|
||||||
assert_eq!(self.n(), infos.n());
|
assert_eq!(self.n(), infos.n());
|
||||||
self.ggsw_prepared_alloc(
|
self.alloc_ggsw_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.dnum(),
|
infos.dnum(),
|
||||||
@@ -102,7 +102,7 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ggsw_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> usize {
|
fn bytes_of_ggsw_prepared(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> usize {
|
||||||
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
let size: usize = k.0.div_ceil(base2k.0) as usize;
|
||||||
debug_assert!(
|
debug_assert!(
|
||||||
size as u32 > dsize.0,
|
size as u32 > dsize.0,
|
||||||
@@ -117,15 +117,15 @@ where
|
|||||||
dsize.0,
|
dsize.0,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.vmp_pmat_alloc_bytes(dnum.into(), (rank + 1).into(), (rank + 1).into(), size)
|
self.vmp_pmat_bytes_of(dnum.into(), (rank + 1).into(), (rank + 1).into(), size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ggsw_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn bytes_of_ggsw_prepared_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGSWInfos,
|
A: GGSWInfos,
|
||||||
{
|
{
|
||||||
assert_eq!(self.n(), infos.n());
|
assert_eq!(self.n(), infos.n());
|
||||||
self.ggsw_prepared_alloc_bytes(
|
self.bytes_of_ggsw_prepared(
|
||||||
infos.base2k(),
|
infos.base2k(),
|
||||||
infos.k(),
|
infos.k(),
|
||||||
infos.dnum(),
|
infos.dnum(),
|
||||||
@@ -145,29 +145,22 @@ where
|
|||||||
where
|
where
|
||||||
A: GGSWInfos,
|
A: GGSWInfos,
|
||||||
{
|
{
|
||||||
module.ggsw_prepared_alloc_from_infos(infos)
|
module.alloc_ggsw_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self {
|
pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> Self {
|
||||||
module.ggsw_prepared_alloc(base2k, k, dnum, dsize, rank)
|
module.alloc_ggsw_prepared(base2k, k, dnum, dsize, rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGSWInfos,
|
A: GGSWInfos,
|
||||||
{
|
{
|
||||||
module.ggsw_prepared_alloc_bytes_from_infos(infos)
|
module.bytes_of_ggsw_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(
|
pub fn bytes_of(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, dsize: Dsize, rank: Rank) -> usize {
|
||||||
module: &Module<B>,
|
module.bytes_of_ggsw_prepared(base2k, k, dnum, dsize, rank)
|
||||||
base2k: Base2K,
|
|
||||||
k: TorusPrecision,
|
|
||||||
dnum: Dnum,
|
|
||||||
dsize: Dsize,
|
|
||||||
rank: Rank,
|
|
||||||
) -> usize {
|
|
||||||
module.ggsw_prepared_alloc_bytes(base2k, k, dnum, dsize, rank)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ pub trait GLWEPublicKeyPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GetDegree + VecZnxDftAlloc<B> + VecZnxDftAllocBytes,
|
Self: GetDegree + VecZnxDftAlloc<B> + VecZnxDftAllocBytes,
|
||||||
{
|
{
|
||||||
fn glwe_public_key_prepared_alloc(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> GLWEPublicKeyPrepared<Vec<u8>, B> {
|
fn alloc_glwe_public_key_prepared(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> GLWEPublicKeyPrepared<Vec<u8>, B> {
|
||||||
GLWEPublicKeyPrepared {
|
GLWEPublicKeyPrepared {
|
||||||
data: self.vec_znx_dft_alloc((rank + 1).into(), k.0.div_ceil(base2k.0) as usize),
|
data: self.vec_znx_dft_alloc((rank + 1).into(), k.0.div_ceil(base2k.0) as usize),
|
||||||
base2k,
|
base2k,
|
||||||
@@ -63,22 +63,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_public_key_alloc_from_infos<A>(&self, infos: &A) -> GLWEPublicKeyPrepared<Vec<u8>, B>
|
fn alloc_glwe_public_key_prepared_from_infos<A>(&self, infos: &A) -> GLWEPublicKeyPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_public_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank())
|
self.alloc_glwe_public_key_prepared(infos.base2k(), infos.k(), infos.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_public_key_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
fn bytes_of_glwe_public_key_prepared(&self, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
||||||
self.vec_znx_dft_alloc_bytes((rank + 1).into(), k.0.div_ceil(base2k.0) as usize)
|
self.vec_znx_dft_bytes_of((rank + 1).into(), k.0.div_ceil(base2k.0) as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_public_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn bytes_of_glwe_public_key_prepared_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_public_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.rank())
|
self.bytes_of_glwe_public_key_prepared(infos.base2k(), infos.k(), infos.rank())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,22 +92,22 @@ where
|
|||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
module.glwe_public_key_alloc_from_infos(infos)
|
module.alloc_glwe_public_key_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
|
pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> Self {
|
||||||
module.glwe_public_key_prepared_alloc(base2k, k, rank)
|
module.alloc_glwe_public_key_prepared(base2k, k, rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
module.glwe_public_key_prepared_alloc_bytes_from_infos(infos)
|
module.bytes_of_glwe_public_key_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
pub fn bytes_of(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank) -> usize {
|
||||||
module.glwe_public_key_prepared_alloc_bytes(base2k, k, rank)
|
module.bytes_of_glwe_public_key_prepared(base2k, k, rank)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ pub trait GLWEPublicKeyPrepare<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GetDegree + VecZnxDftApply<B>,
|
Self: GetDegree + VecZnxDftApply<B>,
|
||||||
{
|
{
|
||||||
fn glwe_public_key_prepare<R, O>(&self, res: &mut R, other: &O)
|
fn prepare_glwe_public_key<R, O>(&self, res: &mut R, other: &O)
|
||||||
where
|
where
|
||||||
R: GLWEPublicKeyPreparedToMut<B> + SetDist,
|
R: GLWEPublicKeyPreparedToMut<B> + SetDist,
|
||||||
O: GLWEPublicKeyToRef + GetDist,
|
O: GLWEPublicKeyToRef + GetDist,
|
||||||
@@ -149,7 +149,7 @@ where
|
|||||||
where
|
where
|
||||||
O: GLWEPublicKeyToRef + GetDist,
|
O: GLWEPublicKeyToRef + GetDist,
|
||||||
{
|
{
|
||||||
module.glwe_public_key_prepare(self, other);
|
module.prepare_glwe_public_key(self, other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,29 +49,29 @@ pub trait GLWESecretPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GetDegree + SvpPPolAllocBytes + SvpPPolAlloc<B>,
|
Self: GetDegree + SvpPPolAllocBytes + SvpPPolAlloc<B>,
|
||||||
{
|
{
|
||||||
fn glwe_secret_prepared_alloc(&self, rank: Rank) -> GLWESecretPrepared<Vec<u8>, B> {
|
fn alloc_glwe_secret_prepared(&self, rank: Rank) -> GLWESecretPrepared<Vec<u8>, B> {
|
||||||
GLWESecretPrepared {
|
GLWESecretPrepared {
|
||||||
data: self.svp_ppol_alloc(rank.into()),
|
data: self.svp_ppol_alloc(rank.into()),
|
||||||
dist: Distribution::NONE,
|
dist: Distribution::NONE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn glwe_secret_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWESecretPrepared<Vec<u8>, B>
|
fn alloc_glwe_secret_prepared_from_infos<A>(&self, infos: &A) -> GLWESecretPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
assert_eq!(self.n(), infos.n());
|
assert_eq!(self.n(), infos.n());
|
||||||
self.glwe_secret_prepared_alloc(infos.rank())
|
self.alloc_glwe_secret_prepared(infos.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_secret_alloc_bytes(&self, rank: Rank) -> usize {
|
fn bytes_of_glwe_secret(&self, rank: Rank) -> usize {
|
||||||
self.svp_ppol_alloc_bytes(rank.into())
|
self.svp_ppol_bytes_of(rank.into())
|
||||||
}
|
}
|
||||||
fn glwe_secret_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn bytes_of_glwe_secret_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
assert_eq!(self.n(), infos.n());
|
assert_eq!(self.n(), infos.n());
|
||||||
self.glwe_secret_alloc_bytes(infos.rank())
|
self.bytes_of_glwe_secret(infos.rank())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,22 +85,22 @@ where
|
|||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
module.glwe_secret_prepared_alloc_from_infos(infos)
|
module.alloc_glwe_secret_prepared_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc(module: &Module<B>, rank: Rank) -> Self {
|
pub fn alloc(module: &Module<B>, rank: Rank) -> Self {
|
||||||
module.glwe_secret_prepared_alloc(rank)
|
module.alloc_glwe_secret_prepared(rank)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
module.glwe_secret_alloc_bytes_from_infos(infos)
|
module.bytes_of_glwe_secret_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes(module: &Module<B>, rank: Rank) -> usize {
|
pub fn bytes_of(module: &Module<B>, rank: Rank) -> usize {
|
||||||
module.glwe_secret_alloc_bytes(rank)
|
module.bytes_of_glwe_secret(rank)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ pub trait GLWESecretPrepare<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: SvpPrepare<B>,
|
Self: SvpPrepare<B>,
|
||||||
{
|
{
|
||||||
fn glwe_secret_prepare<R, O>(&self, res: &mut R, other: &O)
|
fn prepare_glwe_secret<R, O>(&self, res: &mut R, other: &O)
|
||||||
where
|
where
|
||||||
R: GLWESecretPreparedToMut<B> + SetDist,
|
R: GLWESecretPreparedToMut<B> + SetDist,
|
||||||
O: GLWESecretToRef + GetDist,
|
O: GLWESecretToRef + GetDist,
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ where
|
|||||||
rank_in: Rank,
|
rank_in: Rank,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
|
) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||||
GLWEToLWESwitchingKeyPrepared(self.glwe_switching_key_prepared_alloc(base2k, k, rank_in, Rank(1), dnum, Dsize(1)))
|
GLWEToLWESwitchingKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, rank_in, Rank(1), dnum, Dsize(1)))
|
||||||
}
|
}
|
||||||
fn glwe_to_lwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>
|
fn glwe_to_lwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
@@ -83,17 +83,11 @@ where
|
|||||||
self.glwe_to_lwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
|
self.glwe_to_lwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_to_lwe_switching_key_prepared_alloc_bytes(
|
fn glwe_to_lwe_switching_key_prepared_bytes_of(&self, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
|
||||||
&self,
|
self.bytes_of_glwe_switching_key_prepared(base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
||||||
base2k: Base2K,
|
|
||||||
k: TorusPrecision,
|
|
||||||
rank_in: Rank,
|
|
||||||
dnum: Dnum,
|
|
||||||
) -> usize {
|
|
||||||
self.glwe_switching_key_prepared_alloc_bytes(base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_to_lwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn glwe_to_lwe_switching_key_prepared_bytes_of_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -107,7 +101,7 @@ where
|
|||||||
1,
|
1,
|
||||||
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
|
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
|
||||||
);
|
);
|
||||||
self.glwe_to_lwe_switching_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
|
self.glwe_to_lwe_switching_key_prepared_bytes_of(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,15 +122,15 @@ where
|
|||||||
module.glwe_to_lwe_switching_key_prepared_alloc(base2k, k, rank_in, dnum)
|
module.glwe_to_lwe_switching_key_prepared_alloc(base2k, k, rank_in, dnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.glwe_to_lwe_switching_key_prepared_alloc_bytes_from_infos(infos)
|
module.glwe_to_lwe_switching_key_prepared_bytes_of_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
|
pub fn bytes_of(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
|
||||||
module.glwe_to_lwe_switching_key_prepared_alloc_bytes(base2k, k, rank_in, dnum)
|
module.glwe_to_lwe_switching_key_prepared_bytes_of(base2k, k, rank_in, dnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +142,7 @@ where
|
|||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_switching_key_prepare_tmp_bytes(infos);
|
self.prepare_glwe_switching_key_tmp_bytes(infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn glwe_to_lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
fn glwe_to_lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||||
@@ -156,7 +150,7 @@ where
|
|||||||
R: GLWEToLWESwitchingKeyPreparedToMut<B>,
|
R: GLWEToLWESwitchingKeyPreparedToMut<B>,
|
||||||
O: GLWEToLWESwitchingKeyToRef,
|
O: GLWEToLWESwitchingKeyToRef,
|
||||||
{
|
{
|
||||||
self.glwe_switching_prepare(&mut res.to_mut().0, &other.to_ref().0, scratch);
|
self.prepare_glwe_switching(&mut res.to_mut().0, &other.to_ref().0, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,13 +56,13 @@ pub trait LWESwitchingKeyPreparedAlloc<B: Backend>
|
|||||||
where
|
where
|
||||||
Self: GLWESwitchingKeyPreparedAlloc<B>,
|
Self: GLWESwitchingKeyPreparedAlloc<B>,
|
||||||
{
|
{
|
||||||
fn lwe_switching_key_prepared_alloc(
|
fn alloc_lwe_switching_key_prepared(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
) -> LWESwitchingKeyPrepared<Vec<u8>, B> {
|
) -> LWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||||
LWESwitchingKeyPrepared(self.glwe_switching_key_prepared_alloc(base2k, k, Rank(1), Rank(1), dnum, Dsize(1)))
|
LWESwitchingKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, Rank(1), Rank(1), dnum, Dsize(1)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> LWESwitchingKeyPrepared<Vec<u8>, B>
|
fn lwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> LWESwitchingKeyPrepared<Vec<u8>, B>
|
||||||
@@ -84,14 +84,14 @@ where
|
|||||||
1,
|
1,
|
||||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||||
);
|
);
|
||||||
self.lwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.dnum())
|
self.alloc_lwe_switching_key_prepared(infos.base2k(), infos.k(), infos.dnum())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwe_switching_key_prepared_alloc_bytes(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
fn lwe_switching_key_prepared_bytes_of(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||||
self.glwe_switching_key_prepared_alloc_bytes(base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
self.bytes_of_glwe_switching_key_prepared(base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn lwe_switching_key_prepared_bytes_of_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -110,7 +110,7 @@ where
|
|||||||
1,
|
1,
|
||||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||||
);
|
);
|
||||||
self.lwe_switching_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.dnum())
|
self.lwe_switching_key_prepared_bytes_of(infos.base2k(), infos.k(), infos.dnum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,18 +128,18 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
|
pub fn alloc(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
|
||||||
module.lwe_switching_key_prepared_alloc(base2k, k, dnum)
|
module.alloc_lwe_switching_key_prepared(base2k, k, dnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.lwe_switching_key_prepared_alloc_bytes_from_infos(infos)
|
module.lwe_switching_key_prepared_bytes_of_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
pub fn bytes_of(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||||
module.lwe_switching_key_prepared_alloc_bytes(base2k, k, dnum)
|
module.lwe_switching_key_prepared_bytes_of(base2k, k, dnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,14 +151,14 @@ where
|
|||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_switching_key_prepare_tmp_bytes(infos);
|
self.prepare_glwe_switching_key_tmp_bytes(infos);
|
||||||
}
|
}
|
||||||
fn lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
fn lwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||||
where
|
where
|
||||||
R: LWESwitchingKeyPreparedToMut<B>,
|
R: LWESwitchingKeyPreparedToMut<B>,
|
||||||
O: LWESwitchingKeyToRef,
|
O: LWESwitchingKeyToRef,
|
||||||
{
|
{
|
||||||
self.glwe_switching_prepare(&mut res.to_mut().0, &other.to_ref().0, scratch);
|
self.prepare_glwe_switching(&mut res.to_mut().0, &other.to_ref().0, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ where
|
|||||||
rank_out: Rank,
|
rank_out: Rank,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||||
LWEToGLWESwitchingKeyPrepared(self.glwe_switching_key_prepared_alloc(base2k, k, Rank(1), rank_out, dnum, Dsize(1)))
|
LWEToGLWESwitchingKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, Rank(1), rank_out, dnum, Dsize(1)))
|
||||||
}
|
}
|
||||||
fn lwe_to_glwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B>
|
fn lwe_to_glwe_switching_key_prepared_alloc_from_infos<A>(&self, infos: &A) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B>
|
||||||
where
|
where
|
||||||
@@ -84,17 +84,17 @@ where
|
|||||||
self.lwe_to_glwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
|
self.lwe_to_glwe_switching_key_prepared_alloc(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwe_to_glwe_switching_key_prepared_alloc_bytes(
|
fn lwe_to_glwe_switching_key_prepared_bytes_of(
|
||||||
&self,
|
&self,
|
||||||
base2k: Base2K,
|
base2k: Base2K,
|
||||||
k: TorusPrecision,
|
k: TorusPrecision,
|
||||||
rank_out: Rank,
|
rank_out: Rank,
|
||||||
dnum: Dnum,
|
dnum: Dnum,
|
||||||
) -> usize {
|
) -> usize {
|
||||||
self.glwe_switching_key_prepared_alloc_bytes(base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
self.bytes_of_glwe_switching_key_prepared(base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwe_to_glwe_switching_key_prepared_alloc_bytes_from_infos<A>(&self, infos: &A) -> usize
|
fn lwe_to_glwe_switching_key_prepared_bytes_of_from_infos<A>(&self, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
@@ -108,7 +108,7 @@ where
|
|||||||
1,
|
1,
|
||||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||||
);
|
);
|
||||||
self.lwe_to_glwe_switching_key_prepared_alloc_bytes(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
|
self.lwe_to_glwe_switching_key_prepared_bytes_of(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,15 +129,15 @@ where
|
|||||||
module.lwe_to_glwe_switching_key_prepared_alloc(base2k, k, rank_out, dnum)
|
module.lwe_to_glwe_switching_key_prepared_alloc(base2k, k, rank_out, dnum)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
pub fn bytes_of_from_infos<A>(module: &Module<B>, infos: &A) -> usize
|
||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
module.lwe_to_glwe_switching_key_prepared_alloc_bytes_from_infos(infos)
|
module.lwe_to_glwe_switching_key_prepared_bytes_of_from_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> usize {
|
pub fn bytes_of(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> usize {
|
||||||
module.lwe_to_glwe_switching_key_prepared_alloc_bytes(base2k, k, rank_out, dnum)
|
module.lwe_to_glwe_switching_key_prepared_bytes_of(base2k, k, rank_out, dnum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ where
|
|||||||
where
|
where
|
||||||
A: GGLWEInfos,
|
A: GGLWEInfos,
|
||||||
{
|
{
|
||||||
self.glwe_switching_key_prepare_tmp_bytes(infos);
|
self.prepare_glwe_switching_key_tmp_bytes(infos);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwe_to_glwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
fn lwe_to_glwe_switching_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||||
@@ -157,7 +157,7 @@ where
|
|||||||
R: LWEToGLWESwitchingKeyPreparedToMut<B>,
|
R: LWEToGLWESwitchingKeyPreparedToMut<B>,
|
||||||
O: LWEToGLWESwitchingKeyToRef,
|
O: LWEToGLWESwitchingKeyToRef,
|
||||||
{
|
{
|
||||||
self.glwe_switching_prepare(&mut res.to_mut().0, &other.to_ref().0, scratch);
|
self.prepare_glwe_switching(&mut res.to_mut().0, &other.to_ref().0, scratch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use poulpy_hal::{
|
|||||||
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl},
|
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GGLWE, GGLWEInfos, GLWECiphertext, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
use crate::layouts::{GGLWE, GGLWEInfos, GLWE, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
||||||
|
|
||||||
impl<D: DataRef> GGLWE<D> {
|
impl<D: DataRef> GGLWE<D> {
|
||||||
pub fn assert_noise<B, DataSk, DataWant>(
|
pub fn assert_noise<B, DataSk, DataWant>(
|
||||||
@@ -35,8 +35,8 @@ impl<D: DataRef> GGLWE<D> {
|
|||||||
let dsize: usize = self.dsize().into();
|
let dsize: usize = self.dsize().into();
|
||||||
let base2k: usize = self.base2k().into();
|
let base2k: usize = self.base2k().into();
|
||||||
|
|
||||||
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWECiphertext::decrypt_scratch_space(module, self));
|
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWE::decrypt_scratch_space(module, self));
|
||||||
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(self);
|
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self);
|
||||||
|
|
||||||
(0..self.rank_in().into()).for_each(|col_i| {
|
(0..self.rank_in().into()).for_each(|col_i| {
|
||||||
(0..self.dnum().into()).for_each(|row_i| {
|
(0..self.dnum().into()).for_each(|row_i| {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use poulpy_hal::{
|
|||||||
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl},
|
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GGSW, GGSWInfos, GLWECiphertext, GLWEInfos, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
use crate::layouts::{GGSW, GGSWInfos, GLWE, GLWEInfos, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
||||||
|
|
||||||
impl<D: DataRef> GGSW<D> {
|
impl<D: DataRef> GGSW<D> {
|
||||||
pub fn assert_noise<B, DataSk, DataScalar, F>(
|
pub fn assert_noise<B, DataSk, DataScalar, F>(
|
||||||
@@ -42,13 +42,13 @@ impl<D: DataRef> GGSW<D> {
|
|||||||
let base2k: usize = self.base2k().into();
|
let base2k: usize = self.base2k().into();
|
||||||
let dsize: usize = self.dsize().into();
|
let dsize: usize = self.dsize().into();
|
||||||
|
|
||||||
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(self);
|
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self);
|
||||||
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(self);
|
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self);
|
||||||
let mut pt_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(1, self.size());
|
let mut pt_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(1, self.size());
|
||||||
let mut pt_big: VecZnxBig<Vec<u8>, B> = module.vec_znx_big_alloc(1, self.size());
|
let mut pt_big: VecZnxBig<Vec<u8>, B> = module.vec_znx_big_alloc(1, self.size());
|
||||||
|
|
||||||
let mut scratch: ScratchOwned<B> =
|
let mut scratch: ScratchOwned<B> =
|
||||||
ScratchOwned::alloc(GLWECiphertext::decrypt_scratch_space(module, self) | module.vec_znx_normalize_tmp_bytes());
|
ScratchOwned::alloc(GLWE::decrypt_scratch_space(module, self) | module.vec_znx_normalize_tmp_bytes());
|
||||||
|
|
||||||
(0..(self.rank() + 1).into()).for_each(|col_j| {
|
(0..(self.rank() + 1).into()).for_each(|col_j| {
|
||||||
(0..self.dnum().into()).for_each(|row_i| {
|
(0..self.dnum().into()).for_each(|row_i| {
|
||||||
@@ -114,13 +114,13 @@ impl<D: DataRef> GGSW<D> {
|
|||||||
let base2k: usize = self.base2k().into();
|
let base2k: usize = self.base2k().into();
|
||||||
let dsize: usize = self.dsize().into();
|
let dsize: usize = self.dsize().into();
|
||||||
|
|
||||||
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(self);
|
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self);
|
||||||
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(self);
|
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self);
|
||||||
let mut pt_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(1, self.size());
|
let mut pt_dft: VecZnxDft<Vec<u8>, B> = module.vec_znx_dft_alloc(1, self.size());
|
||||||
let mut pt_big: VecZnxBig<Vec<u8>, B> = module.vec_znx_big_alloc(1, self.size());
|
let mut pt_big: VecZnxBig<Vec<u8>, B> = module.vec_znx_big_alloc(1, self.size());
|
||||||
|
|
||||||
let mut scratch: ScratchOwned<B> =
|
let mut scratch: ScratchOwned<B> =
|
||||||
ScratchOwned::alloc(GLWECiphertext::decrypt_scratch_space(module, self) | module.vec_znx_normalize_tmp_bytes());
|
ScratchOwned::alloc(GLWE::decrypt_scratch_space(module, self) | module.vec_znx_normalize_tmp_bytes());
|
||||||
|
|
||||||
(0..(self.rank() + 1).into()).for_each(|col_j| {
|
(0..(self.rank() + 1).into()).for_each(|col_j| {
|
||||||
(0..self.dnum().into()).for_each(|row_i| {
|
(0..self.dnum().into()).for_each(|row_i| {
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use poulpy_hal::{
|
|||||||
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl},
|
oep::{ScratchOwnedAllocImpl, ScratchOwnedBorrowImpl, TakeVecZnxBigImpl, TakeVecZnxDftImpl},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{GLWECiphertext, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
use crate::layouts::{GLWE, GLWEPlaintext, LWEInfos, prepared::GLWESecretPrepared};
|
||||||
|
|
||||||
impl<D: DataRef> GLWECiphertext<D> {
|
impl<D: DataRef> GLWE<D> {
|
||||||
pub fn noise<B, DataSk, DataPt>(
|
pub fn noise<B, DataSk, DataPt>(
|
||||||
&self,
|
&self,
|
||||||
module: &Module<B>,
|
module: &Module<B>,
|
||||||
@@ -32,7 +32,7 @@ impl<D: DataRef> GLWECiphertext<D> {
|
|||||||
+ VecZnxBigNormalize<B>,
|
+ VecZnxBigNormalize<B>,
|
||||||
Scratch<B>: TakeVecZnxDft<B> + TakeVecZnxBig<B>,
|
Scratch<B>: TakeVecZnxDft<B> + TakeVecZnxBig<B>,
|
||||||
{
|
{
|
||||||
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(self);
|
let mut pt_have: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(self);
|
||||||
self.decrypt(module, &mut pt_have, sk_prepared, scratch);
|
self.decrypt(module, &mut pt_have, sk_prepared, scratch);
|
||||||
module.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt_want.data, 0);
|
module.vec_znx_sub_inplace(&mut pt_have.data, 0, &pt_want.data, 0);
|
||||||
module.vec_znx_normalize_inplace(self.base2k().into(), &mut pt_have.data, 0, scratch);
|
module.vec_znx_normalize_inplace(self.base2k().into(), &mut pt_have.data, 0, scratch);
|
||||||
@@ -61,7 +61,7 @@ impl<D: DataRef> GLWECiphertext<D> {
|
|||||||
+ VecZnxNormalizeInplace<B>,
|
+ VecZnxNormalizeInplace<B>,
|
||||||
B: Backend + TakeVecZnxDftImpl<B> + TakeVecZnxBigImpl<B> + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
|
B: Backend + TakeVecZnxDftImpl<B> + TakeVecZnxBigImpl<B> + ScratchOwnedAllocImpl<B> + ScratchOwnedBorrowImpl<B>,
|
||||||
{
|
{
|
||||||
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWECiphertext::decrypt_scratch_space(module, self));
|
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(GLWE::decrypt_scratch_space(module, self));
|
||||||
let noise_have: f64 = self.noise(module, sk_prepared, pt_want, scratch.borrow());
|
let noise_have: f64 = self.noise(module, sk_prepared, pt_want, scratch.borrow());
|
||||||
assert!(noise_have <= max_noise, "{noise_have} {max_noise}");
|
assert!(noise_have <= max_noise, "{noise_have} {max_noise}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,24 +7,22 @@ use poulpy_hal::{
|
|||||||
layouts::{Backend, DataMut, Module, Scratch, VecZnx, ZnxZero},
|
layouts::{Backend, DataMut, Module, Scratch, VecZnx, ZnxZero},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{GLWE, GLWEInfos, GLWEPlaintext, GLWEToMut, GLWEToRef, LWEInfos, SetGLWEInfos, TorusPrecision};
|
||||||
GLWECiphertext, GLWECiphertextToMut, GLWECiphertextToRef, GLWEInfos, GLWELayoutSet, GLWEPlaintext, LWEInfos, TorusPrecision,
|
|
||||||
};
|
|
||||||
|
|
||||||
impl<D> GLWEOperations for GLWEPlaintext<D>
|
impl<D> GLWEOperations for GLWEPlaintext<D>
|
||||||
where
|
where
|
||||||
D: DataMut,
|
D: DataMut,
|
||||||
GLWEPlaintext<D>: GLWECiphertextToMut + GLWEInfos,
|
GLWEPlaintext<D>: GLWEToMut + GLWEInfos,
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: DataMut> GLWEOperations for GLWECiphertext<D> where GLWECiphertext<D>: GLWECiphertextToMut + GLWEInfos {}
|
impl<D: DataMut> GLWEOperations for GLWE<D> where GLWE<D>: GLWEToMut + GLWEInfos {}
|
||||||
|
|
||||||
pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Sized {
|
pub trait GLWEOperations: GLWEToMut + GLWEInfos + SetGLWEInfos + Sized {
|
||||||
fn add<A, B, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A, b: &B)
|
fn add<A, B, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A, b: &B)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
B: GLWECiphertextToRef + GLWEInfos,
|
B: GLWEToRef + GLWEInfos,
|
||||||
Module<BACKEND>: VecZnxAdd + VecZnxCopy,
|
Module<BACKEND>: VecZnxAdd + VecZnxCopy,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -39,9 +37,9 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
let max_col: usize = (a.rank().max(b.rank() + 1)).into();
|
let max_col: usize = (a.rank().max(b.rank() + 1)).into();
|
||||||
let self_col: usize = (self.rank() + 1).into();
|
let self_col: usize = (self.rank() + 1).into();
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
let b_ref: &GLWECiphertext<&[u8]> = &b.to_ref();
|
let b_ref: &GLWE<&[u8]> = &b.to_ref();
|
||||||
|
|
||||||
(0..min_col).for_each(|i| {
|
(0..min_col).for_each(|i| {
|
||||||
module.vec_znx_add(&mut self_mut.data, i, &a_ref.data, i, &b_ref.data, i);
|
module.vec_znx_add(&mut self_mut.data, i, &a_ref.data, i, &b_ref.data, i);
|
||||||
@@ -64,13 +62,13 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
self.set_basek(a.base2k());
|
self.set_base2k(a.base2k());
|
||||||
self.set_k(set_k_binary(self, a, b));
|
self.set_k(set_k_binary(self, a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_inplace<A, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A)
|
fn add_inplace<A, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
Module<BACKEND>: VecZnxAddInplace,
|
Module<BACKEND>: VecZnxAddInplace,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -80,8 +78,8 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
assert!(self.rank() >= a.rank())
|
assert!(self.rank() >= a.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
|
|
||||||
(0..(a.rank() + 1).into()).for_each(|i| {
|
(0..(a.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_add_inplace(&mut self_mut.data, i, &a_ref.data, i);
|
module.vec_znx_add_inplace(&mut self_mut.data, i, &a_ref.data, i);
|
||||||
@@ -92,8 +90,8 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
|
|
||||||
fn sub<A, B, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A, b: &B)
|
fn sub<A, B, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A, b: &B)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
B: GLWECiphertextToRef + GLWEInfos,
|
B: GLWEToRef + GLWEInfos,
|
||||||
Module<BACKEND>: VecZnxSub + VecZnxCopy + VecZnxNegateInplace,
|
Module<BACKEND>: VecZnxSub + VecZnxCopy + VecZnxNegateInplace,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -108,9 +106,9 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
let max_col: usize = (a.rank().max(b.rank() + 1)).into();
|
let max_col: usize = (a.rank().max(b.rank() + 1)).into();
|
||||||
let self_col: usize = (self.rank() + 1).into();
|
let self_col: usize = (self.rank() + 1).into();
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
let b_ref: &GLWECiphertext<&[u8]> = &b.to_ref();
|
let b_ref: &GLWE<&[u8]> = &b.to_ref();
|
||||||
|
|
||||||
(0..min_col).for_each(|i| {
|
(0..min_col).for_each(|i| {
|
||||||
module.vec_znx_sub(&mut self_mut.data, i, &a_ref.data, i, &b_ref.data, i);
|
module.vec_znx_sub(&mut self_mut.data, i, &a_ref.data, i, &b_ref.data, i);
|
||||||
@@ -134,13 +132,13 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
self.set_basek(a.base2k());
|
self.set_base2k(a.base2k());
|
||||||
self.set_k(set_k_binary(self, a, b));
|
self.set_k(set_k_binary(self, a, b));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sub_inplace_ab<A, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A)
|
fn sub_inplace_ab<A, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
Module<BACKEND>: VecZnxSubInplace,
|
Module<BACKEND>: VecZnxSubInplace,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -150,8 +148,8 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
assert!(self.rank() >= a.rank())
|
assert!(self.rank() >= a.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
|
|
||||||
(0..(a.rank() + 1).into()).for_each(|i| {
|
(0..(a.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_sub_inplace(&mut self_mut.data, i, &a_ref.data, i);
|
module.vec_znx_sub_inplace(&mut self_mut.data, i, &a_ref.data, i);
|
||||||
@@ -162,7 +160,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
|
|
||||||
fn sub_inplace_ba<A, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A)
|
fn sub_inplace_ba<A, BACKEND: Backend>(&mut self, module: &Module<BACKEND>, a: &A)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
Module<BACKEND>: VecZnxSubNegateInplace,
|
Module<BACKEND>: VecZnxSubNegateInplace,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -172,8 +170,8 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
assert!(self.rank() >= a.rank())
|
assert!(self.rank() >= a.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
|
|
||||||
(0..(a.rank() + 1).into()).for_each(|i| {
|
(0..(a.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_sub_negate_inplace(&mut self_mut.data, i, &a_ref.data, i);
|
module.vec_znx_sub_negate_inplace(&mut self_mut.data, i, &a_ref.data, i);
|
||||||
@@ -184,7 +182,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
|
|
||||||
fn rotate<A, B: Backend>(&mut self, module: &Module<B>, k: i64, a: &A)
|
fn rotate<A, B: Backend>(&mut self, module: &Module<B>, k: i64, a: &A)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
Module<B>: VecZnxRotate,
|
Module<B>: VecZnxRotate,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -193,14 +191,14 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
assert_eq!(self.rank(), a.rank())
|
assert_eq!(self.rank(), a.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
|
|
||||||
(0..(a.rank() + 1).into()).for_each(|i| {
|
(0..(a.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_rotate(k, &mut self_mut.data, i, &a_ref.data, i);
|
module.vec_znx_rotate(k, &mut self_mut.data, i, &a_ref.data, i);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.set_basek(a.base2k());
|
self.set_base2k(a.base2k());
|
||||||
self.set_k(set_k_unary(self, a))
|
self.set_k(set_k_unary(self, a))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +206,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
where
|
where
|
||||||
Module<B>: VecZnxRotateInplace<B>,
|
Module<B>: VecZnxRotateInplace<B>,
|
||||||
{
|
{
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
|
|
||||||
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_rotate_inplace(k, &mut self_mut.data, i, scratch);
|
module.vec_znx_rotate_inplace(k, &mut self_mut.data, i, scratch);
|
||||||
@@ -217,7 +215,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
|
|
||||||
fn mul_xp_minus_one<A, B: Backend>(&mut self, module: &Module<B>, k: i64, a: &A)
|
fn mul_xp_minus_one<A, B: Backend>(&mut self, module: &Module<B>, k: i64, a: &A)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
Module<B>: VecZnxMulXpMinusOne,
|
Module<B>: VecZnxMulXpMinusOne,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -226,14 +224,14 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
assert_eq!(self.rank(), a.rank())
|
assert_eq!(self.rank(), a.rank())
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
|
|
||||||
(0..(a.rank() + 1).into()).for_each(|i| {
|
(0..(a.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_mul_xp_minus_one(k, &mut self_mut.data, i, &a_ref.data, i);
|
module.vec_znx_mul_xp_minus_one(k, &mut self_mut.data, i, &a_ref.data, i);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.set_basek(a.base2k());
|
self.set_base2k(a.base2k());
|
||||||
self.set_k(set_k_unary(self, a))
|
self.set_k(set_k_unary(self, a))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,7 +239,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
where
|
where
|
||||||
Module<B>: VecZnxMulXpMinusOneInplace<B>,
|
Module<B>: VecZnxMulXpMinusOneInplace<B>,
|
||||||
{
|
{
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
|
|
||||||
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_mul_xp_minus_one_inplace(k, &mut self_mut.data, i, scratch);
|
module.vec_znx_mul_xp_minus_one_inplace(k, &mut self_mut.data, i, scratch);
|
||||||
@@ -250,7 +248,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
|
|
||||||
fn copy<A, B: Backend>(&mut self, module: &Module<B>, a: &A)
|
fn copy<A, B: Backend>(&mut self, module: &Module<B>, a: &A)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
Module<B>: VecZnxCopy,
|
Module<B>: VecZnxCopy,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -259,15 +257,15 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
assert_eq!(self.rank(), a.rank());
|
assert_eq!(self.rank(), a.rank());
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
|
|
||||||
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_copy(&mut self_mut.data, i, &a_ref.data, i);
|
module.vec_znx_copy(&mut self_mut.data, i, &a_ref.data, i);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.set_k(a.k().min(self.max_k()));
|
self.set_k(a.k().min(self.max_k()));
|
||||||
self.set_basek(a.base2k());
|
self.set_base2k(a.base2k());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rsh<B: Backend>(&mut self, module: &Module<B>, k: usize, scratch: &mut Scratch<B>)
|
fn rsh<B: Backend>(&mut self, module: &Module<B>, k: usize, scratch: &mut Scratch<B>)
|
||||||
@@ -282,7 +280,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
|
|
||||||
fn normalize<A, B: Backend>(&mut self, module: &Module<B>, a: &A, scratch: &mut Scratch<B>)
|
fn normalize<A, B: Backend>(&mut self, module: &Module<B>, a: &A, scratch: &mut Scratch<B>)
|
||||||
where
|
where
|
||||||
A: GLWECiphertextToRef + GLWEInfos,
|
A: GLWEToRef + GLWEInfos,
|
||||||
Module<B>: VecZnxNormalize<B>,
|
Module<B>: VecZnxNormalize<B>,
|
||||||
{
|
{
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
@@ -291,8 +289,8 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
assert_eq!(self.rank(), a.rank());
|
assert_eq!(self.rank(), a.rank());
|
||||||
}
|
}
|
||||||
|
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
let a_ref: &GLWECiphertext<&[u8]> = &a.to_ref();
|
let a_ref: &GLWE<&[u8]> = &a.to_ref();
|
||||||
|
|
||||||
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_normalize(
|
module.vec_znx_normalize(
|
||||||
@@ -305,7 +303,7 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
scratch,
|
scratch,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
self.set_basek(a.base2k());
|
self.set_base2k(a.base2k());
|
||||||
self.set_k(a.k().min(self.k()));
|
self.set_k(a.k().min(self.k()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,14 +311,14 @@ pub trait GLWEOperations: GLWECiphertextToMut + GLWEInfos + GLWELayoutSet + Size
|
|||||||
where
|
where
|
||||||
Module<B>: VecZnxNormalizeInplace<B>,
|
Module<B>: VecZnxNormalizeInplace<B>,
|
||||||
{
|
{
|
||||||
let self_mut: &mut GLWECiphertext<&mut [u8]> = &mut self.to_mut();
|
let self_mut: &mut GLWE<&mut [u8]> = &mut self.to_mut();
|
||||||
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
(0..(self_mut.rank() + 1).into()).for_each(|i| {
|
||||||
module.vec_znx_normalize_inplace(self_mut.base2k().into(), &mut self_mut.data, i, scratch);
|
module.vec_znx_normalize_inplace(self_mut.base2k().into(), &mut self_mut.data, i, scratch);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GLWECiphertext<Vec<u8>> {
|
impl GLWE<Vec<u8>> {
|
||||||
pub fn rsh_scratch_space(n: usize) -> usize {
|
pub fn rsh_scratch_space(n: usize) -> usize {
|
||||||
VecZnx::rsh_scratch_space(n)
|
VecZnx::rsh_scratch_space(n)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use poulpy_hal::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
dist::Distribution,
|
dist::Distribution,
|
||||||
layouts::{
|
layouts::{
|
||||||
AutomorphismKey, Degree, GGLWE, GGLWEInfos, GGSW, GGSWInfos, GLWECiphertext, GLWEInfos, GLWEPlaintext, GLWEPublicKey,
|
AutomorphismKey, Degree, GGLWE, GGLWEInfos, GGSW, GGSWInfos, GLWE, GLWEInfos, GLWEPlaintext, GLWEPublicKey, GLWESecret,
|
||||||
GLWESecret, GLWESwitchingKey, Rank, TensorKey,
|
GLWESwitchingKey, Rank, TensorKey,
|
||||||
prepared::{
|
prepared::{
|
||||||
AutomorphismKeyPrepared, GGLWEPrepared, GGSWPrepared, GLWEPublicKeyPrepared, GLWESecretPrepared,
|
AutomorphismKeyPrepared, GGLWEPrepared, GGSWPrepared, GLWEPublicKeyPrepared, GLWESecretPrepared,
|
||||||
GLWESwitchingKeyPrepared, TensorKeyPrepared,
|
GLWESwitchingKeyPrepared, TensorKeyPrepared,
|
||||||
@@ -16,13 +16,13 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub trait TakeGLWECt {
|
pub trait TakeGLWECt {
|
||||||
fn take_glwe_ct<A>(&mut self, infos: &A) -> (GLWECiphertext<&mut [u8]>, &mut Self)
|
fn take_glwe_ct<A>(&mut self, infos: &A) -> (GLWE<&mut [u8]>, &mut Self)
|
||||||
where
|
where
|
||||||
A: GLWEInfos;
|
A: GLWEInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait TakeGLWECtSlice {
|
pub trait TakeGLWECtSlice {
|
||||||
fn take_glwe_ct_slice<A>(&mut self, size: usize, infos: &A) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self)
|
fn take_glwe_ct_slice<A>(&mut self, size: usize, infos: &A) -> (Vec<GLWE<&mut [u8]>>, &mut Self)
|
||||||
where
|
where
|
||||||
A: GLWEInfos;
|
A: GLWEInfos;
|
||||||
}
|
}
|
||||||
@@ -123,13 +123,13 @@ impl<B: Backend> TakeGLWECt for Scratch<B>
|
|||||||
where
|
where
|
||||||
Scratch<B>: TakeVecZnx,
|
Scratch<B>: TakeVecZnx,
|
||||||
{
|
{
|
||||||
fn take_glwe_ct<A>(&mut self, infos: &A) -> (GLWECiphertext<&mut [u8]>, &mut Self)
|
fn take_glwe_ct<A>(&mut self, infos: &A) -> (GLWE<&mut [u8]>, &mut Self)
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
let (data, scratch) = self.take_vec_znx(infos.n().into(), (infos.rank() + 1).into(), infos.size());
|
let (data, scratch) = self.take_vec_znx(infos.n().into(), (infos.rank() + 1).into(), infos.size());
|
||||||
(
|
(
|
||||||
GLWECiphertext {
|
GLWE {
|
||||||
k: infos.k(),
|
k: infos.k(),
|
||||||
base2k: infos.base2k(),
|
base2k: infos.base2k(),
|
||||||
data,
|
data,
|
||||||
@@ -143,12 +143,12 @@ impl<B: Backend> TakeGLWECtSlice for Scratch<B>
|
|||||||
where
|
where
|
||||||
Scratch<B>: TakeVecZnx,
|
Scratch<B>: TakeVecZnx,
|
||||||
{
|
{
|
||||||
fn take_glwe_ct_slice<A>(&mut self, size: usize, infos: &A) -> (Vec<GLWECiphertext<&mut [u8]>>, &mut Self)
|
fn take_glwe_ct_slice<A>(&mut self, size: usize, infos: &A) -> (Vec<GLWE<&mut [u8]>>, &mut Self)
|
||||||
where
|
where
|
||||||
A: GLWEInfos,
|
A: GLWEInfos,
|
||||||
{
|
{
|
||||||
let mut scratch: &mut Scratch<B> = self;
|
let mut scratch: &mut Scratch<B> = self;
|
||||||
let mut cts: Vec<GLWECiphertext<&mut [u8]>> = Vec::with_capacity(size);
|
let mut cts: Vec<GLWE<&mut [u8]>> = Vec::with_capacity(size);
|
||||||
for _ in 0..size {
|
for _ in 0..size {
|
||||||
let (ct, new_scratch) = scratch.take_glwe_ct(infos);
|
let (ct, new_scratch) = scratch.take_glwe_ct(infos);
|
||||||
scratch = new_scratch;
|
scratch = new_scratch;
|
||||||
@@ -463,7 +463,7 @@ where
|
|||||||
|
|
||||||
let mut scratch: &mut Scratch<B> = self;
|
let mut scratch: &mut Scratch<B> = self;
|
||||||
|
|
||||||
let mut ksk_infos: crate::layouts::GGLWECiphertextLayout = infos.layout();
|
let mut ksk_infos: crate::layouts::GGLWECiphertextLayout = infos.gglwe_layout();
|
||||||
ksk_infos.rank_in = Rank(1);
|
ksk_infos.rank_in = Rank(1);
|
||||||
|
|
||||||
if pairs != 0 {
|
if pairs != 0 {
|
||||||
@@ -499,7 +499,7 @@ where
|
|||||||
|
|
||||||
let mut scratch: &mut Scratch<B> = self;
|
let mut scratch: &mut Scratch<B> = self;
|
||||||
|
|
||||||
let mut ksk_infos: crate::layouts::GGLWECiphertextLayout = infos.layout();
|
let mut ksk_infos: crate::layouts::GGLWECiphertextLayout = infos.gglwe_layout();
|
||||||
ksk_infos.rank_in = Rank(1);
|
ksk_infos.rank_in = Rank(1);
|
||||||
|
|
||||||
if pairs != 0 {
|
if pairs != 0 {
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
use poulpy_hal::test_suite::serialization::test_reader_writer_interface;
|
use poulpy_hal::test_suite::serialization::test_reader_writer_interface;
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
AutomorphismKey, Base2K, Degree, Dnum, Dsize, GGLWE, GGSW, GLWECiphertext, GLWESwitchingKey, GLWEToLWESwitchingKey,
|
AutomorphismKey, Base2K, Degree, Dnum, Dsize, GGLWE, GGSW, GLWE, GLWESwitchingKey, GLWEToLWESwitchingKey, LWE,
|
||||||
LWECiphertext, LWESwitchingKey, LWEToGLWESwitchingKey, Rank, TensorKey, TorusPrecision,
|
LWESwitchingKey, LWEToGLWESwitchingKey, Rank, TensorKey, TorusPrecision,
|
||||||
compressed::{
|
compressed::{
|
||||||
AutomorphismKeyCompressed, GGLWECiphertextCompressed, GGSWCiphertextCompressed, GLWECiphertextCompressed,
|
AutomorphismKeyCompressed, GGLWECompressed, GGSWCompressed, GLWECompressed, GLWESwitchingKeyCompressed,
|
||||||
GLWESwitchingKeyCompressed, GLWEToLWESwitchingKeyCompressed, LWECiphertextCompressed, LWESwitchingKeyCompressed,
|
GLWEToLWESwitchingKeyCompressed, LWECompressed, LWESwitchingKeyCompressed, LWEToGLWESwitchingKeyCompressed,
|
||||||
LWEToGLWESwitchingKeyCompressed, TensorKeyCompressed,
|
TensorKeyCompressed,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -20,51 +20,50 @@ const DSIZE: Dsize = Dsize(1);
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glwe_serialization() {
|
fn glwe_serialization() {
|
||||||
let original: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc_with(N_GLWE, BASE2K, K, RANK);
|
let original: GLWE<Vec<u8>> = GLWE::alloc(N_GLWE, BASE2K, K, RANK);
|
||||||
poulpy_hal::test_suite::serialization::test_reader_writer_interface(original);
|
poulpy_hal::test_suite::serialization::test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glwe_compressed_serialization() {
|
fn glwe_compressed_serialization() {
|
||||||
let original: GLWECiphertextCompressed<Vec<u8>> = GLWECiphertextCompressed::alloc_with(N_GLWE, BASE2K, K, RANK);
|
let original: GLWECompressed<Vec<u8>> = GLWECompressed::alloc(N_GLWE, BASE2K, K, RANK);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lwe_serialization() {
|
fn lwe_serialization() {
|
||||||
let original: LWECiphertext<Vec<u8>> = LWECiphertext::alloc_with(N_LWE, BASE2K, K);
|
let original: LWE<Vec<u8>> = LWE::alloc(N_LWE, BASE2K, K);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lwe_compressed_serialization() {
|
fn lwe_compressed_serialization() {
|
||||||
let original: LWECiphertextCompressed<Vec<u8>> = LWECiphertextCompressed::alloc_with(BASE2K, K);
|
let original: LWECompressed<Vec<u8>> = LWECompressed::alloc(BASE2K, K);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gglwe_serialization() {
|
fn test_gglwe_serialization() {
|
||||||
let original: GGLWE<Vec<u8>> = GGLWE::alloc_with(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
let original: GGLWE<Vec<u8>> = GGLWE::alloc(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_gglwe_compressed_serialization() {
|
fn test_gglwe_compressed_serialization() {
|
||||||
let original: GGLWECiphertextCompressed<Vec<u8>> =
|
let original: GGLWECompressed<Vec<u8>> = GGLWECompressed::alloc(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
||||||
GGLWECiphertextCompressed::alloc_with(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_glwe_switching_key_serialization() {
|
fn test_glwe_switching_key_serialization() {
|
||||||
let original: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc_with(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
let original: GLWESwitchingKey<Vec<u8>> = GLWESwitchingKey::alloc(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_glwe_switching_key_compressed_serialization() {
|
fn test_glwe_switching_key_compressed_serialization() {
|
||||||
let original: GLWESwitchingKeyCompressed<Vec<u8>> =
|
let original: GLWESwitchingKeyCompressed<Vec<u8>> =
|
||||||
GLWESwitchingKeyCompressed::alloc_with(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
GLWESwitchingKeyCompressed::alloc(N_GLWE, BASE2K, K, RANK, RANK, DNUM, DSIZE);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,39 +75,38 @@ fn test_automorphism_key_serialization() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_automorphism_key_compressed_serialization() {
|
fn test_automorphism_key_compressed_serialization() {
|
||||||
let original: AutomorphismKeyCompressed<Vec<u8>> =
|
let original: AutomorphismKeyCompressed<Vec<u8>> = AutomorphismKeyCompressed::alloc(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
||||||
AutomorphismKeyCompressed::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tensor_key_serialization() {
|
fn test_tensor_key_serialization() {
|
||||||
let original: TensorKey<Vec<u8>> = TensorKey::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
let original: TensorKey<Vec<u8>> = TensorKey::alloc(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tensor_key_compressed_serialization() {
|
fn test_tensor_key_compressed_serialization() {
|
||||||
let original: TensorKeyCompressed<Vec<u8>> = TensorKeyCompressed::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
let original: TensorKeyCompressed<Vec<u8>> = TensorKeyCompressed::alloc(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glwe_to_lwe_switching_key_serialization() {
|
fn glwe_to_lwe_switching_key_serialization() {
|
||||||
let original: GLWEToLWESwitchingKey<Vec<u8>> = GLWEToLWESwitchingKey::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM);
|
let original: GLWEToLWESwitchingKey<Vec<u8>> = GLWEToLWESwitchingKey::alloc(N_GLWE, BASE2K, K, RANK, DNUM);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn glwe_to_lwe_switching_key_compressed_serialization() {
|
fn glwe_to_lwe_switching_key_compressed_serialization() {
|
||||||
let original: GLWEToLWESwitchingKeyCompressed<Vec<u8>> =
|
let original: GLWEToLWESwitchingKeyCompressed<Vec<u8>> =
|
||||||
GLWEToLWESwitchingKeyCompressed::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM);
|
GLWEToLWESwitchingKeyCompressed::alloc(N_GLWE, BASE2K, K, RANK, DNUM);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lwe_to_glwe_switching_key_serialization() {
|
fn lwe_to_glwe_switching_key_serialization() {
|
||||||
let original: LWEToGLWESwitchingKey<Vec<u8>> = LWEToGLWESwitchingKey::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM);
|
let original: LWEToGLWESwitchingKey<Vec<u8>> = LWEToGLWESwitchingKey::alloc(N_GLWE, BASE2K, K, RANK, DNUM);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,24 +119,24 @@ fn lwe_to_glwe_switching_key_compressed_serialization() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lwe_switching_key_serialization() {
|
fn lwe_switching_key_serialization() {
|
||||||
let original: LWESwitchingKey<Vec<u8>> = LWESwitchingKey::alloc_with(N_GLWE, BASE2K, K, DNUM);
|
let original: LWESwitchingKey<Vec<u8>> = LWESwitchingKey::alloc(N_GLWE, BASE2K, K, DNUM);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lwe_switching_key_compressed_serialization() {
|
fn lwe_switching_key_compressed_serialization() {
|
||||||
let original: LWESwitchingKeyCompressed<Vec<u8>> = LWESwitchingKeyCompressed::alloc_with(N_GLWE, BASE2K, K, DNUM);
|
let original: LWESwitchingKeyCompressed<Vec<u8>> = LWESwitchingKeyCompressed::alloc(N_GLWE, BASE2K, K, DNUM);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ggsw_serialization() {
|
fn ggsw_serialization() {
|
||||||
let original: GGSW<Vec<u8>> = GGSW::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
let original: GGSW<Vec<u8>> = GGSW::alloc(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn ggsw_compressed_serialization() {
|
fn ggsw_compressed_serialization() {
|
||||||
let original: GGSWCiphertextCompressed<Vec<u8>> = GGSWCiphertextCompressed::alloc_with(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
let original: GGSWCompressed<Vec<u8>> = GGSWCompressed::alloc(N_GLWE, BASE2K, K, RANK, DNUM, DSIZE);
|
||||||
test_reader_writer_interface(original);
|
test_reader_writer_interface(original);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,9 +111,9 @@ where
|
|||||||
rank: rank.into(),
|
rank: rank.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut auto_key_in: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&auto_key_in_infos);
|
let mut auto_key_in: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&auto_key_in_infos);
|
||||||
let mut auto_key_out: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&auto_key_out_infos);
|
let mut auto_key_out: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&auto_key_out_infos);
|
||||||
let mut auto_key_apply: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&auto_key_apply_infos);
|
let mut auto_key_apply: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&auto_key_apply_infos);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
let mut source_xe: Source = Source::new([0u8; 32]);
|
let mut source_xe: Source = Source::new([0u8; 32]);
|
||||||
@@ -130,7 +130,7 @@ where
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&auto_key_in);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&auto_key_in);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
|
|
||||||
// gglwe_{s1}(s0) = s0 -> s1
|
// gglwe_{s1}(s0) = s0 -> s1
|
||||||
@@ -166,9 +166,9 @@ where
|
|||||||
scratch.borrow(),
|
scratch.borrow(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&auto_key_out_infos);
|
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&auto_key_out_infos);
|
||||||
|
|
||||||
let mut sk_auto: GLWESecret<Vec<u8>> = GLWESecret::alloc(&auto_key_out_infos);
|
let mut sk_auto: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&auto_key_out_infos);
|
||||||
sk_auto.fill_zero(); // Necessary to avoid panic of unfilled sk
|
sk_auto.fill_zero(); // Necessary to avoid panic of unfilled sk
|
||||||
for i in 0..rank {
|
for i in 0..rank {
|
||||||
module.vec_znx_automorphism(
|
module.vec_znx_automorphism(
|
||||||
@@ -311,8 +311,8 @@ where
|
|||||||
rank: rank.into(),
|
rank: rank.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut auto_key: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&auto_key_layout);
|
let mut auto_key: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&auto_key_layout);
|
||||||
let mut auto_key_apply: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&auto_key_apply_layout);
|
let mut auto_key_apply: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&auto_key_apply_layout);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
let mut source_xe: Source = Source::new([0u8; 32]);
|
let mut source_xe: Source = Source::new([0u8; 32]);
|
||||||
@@ -324,7 +324,7 @@ where
|
|||||||
| AutomorphismKey::automorphism_inplace_scratch_space(module, &auto_key, &auto_key_apply),
|
| AutomorphismKey::automorphism_inplace_scratch_space(module, &auto_key, &auto_key_apply),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&auto_key);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&auto_key);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
|
|
||||||
// gglwe_{s1}(s0) = s0 -> s1
|
// gglwe_{s1}(s0) = s0 -> s1
|
||||||
@@ -355,9 +355,9 @@ where
|
|||||||
// gglwe_{s1}(s0) (x) gglwe_{s2}(s1) = gglwe_{s2}(s0)
|
// gglwe_{s1}(s0) (x) gglwe_{s2}(s1) = gglwe_{s2}(s0)
|
||||||
auto_key.automorphism_inplace(module, &auto_key_apply_prepared, scratch.borrow());
|
auto_key.automorphism_inplace(module, &auto_key_apply_prepared, scratch.borrow());
|
||||||
|
|
||||||
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&auto_key);
|
let mut pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&auto_key);
|
||||||
|
|
||||||
let mut sk_auto: GLWESecret<Vec<u8>> = GLWESecret::alloc(&auto_key);
|
let mut sk_auto: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&auto_key);
|
||||||
sk_auto.fill_zero(); // Necessary to avoid panic of unfilled sk
|
sk_auto.fill_zero(); // Necessary to avoid panic of unfilled sk
|
||||||
|
|
||||||
for i in 0..rank {
|
for i in 0..rank {
|
||||||
|
|||||||
@@ -128,10 +128,10 @@ where
|
|||||||
rank: rank.into(),
|
rank: rank.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ct_in: GGSW<Vec<u8>> = GGSW::alloc(&ggsw_in_layout);
|
let mut ct_in: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_in_layout);
|
||||||
let mut ct_out: GGSW<Vec<u8>> = GGSW::alloc(&ggsw_out_layout);
|
let mut ct_out: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_out_layout);
|
||||||
let mut tensor_key: TensorKey<Vec<u8>> = TensorKey::alloc(&tensor_key_layout);
|
let mut tensor_key: TensorKey<Vec<u8>> = TensorKey::alloc_from_infos(&tensor_key_layout);
|
||||||
let mut auto_key: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&auto_key_layout);
|
let mut auto_key: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&auto_key_layout);
|
||||||
let mut pt_scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
|
let mut pt_scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
@@ -147,7 +147,7 @@ where
|
|||||||
|
|
||||||
let var_xs: f64 = 0.5;
|
let var_xs: f64 = 0.5;
|
||||||
|
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&ct_out);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&ct_out);
|
||||||
sk.fill_ternary_prob(var_xs, &mut source_xs);
|
sk.fill_ternary_prob(var_xs, &mut source_xs);
|
||||||
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
||||||
|
|
||||||
@@ -309,9 +309,9 @@ where
|
|||||||
rank: rank.into(),
|
rank: rank.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ct: GGSW<Vec<u8>> = GGSW::alloc(&ggsw_out_layout);
|
let mut ct: GGSW<Vec<u8>> = GGSW::alloc_from_infos(&ggsw_out_layout);
|
||||||
let mut tensor_key: TensorKey<Vec<u8>> = TensorKey::alloc(&tensor_key_layout);
|
let mut tensor_key: TensorKey<Vec<u8>> = TensorKey::alloc_from_infos(&tensor_key_layout);
|
||||||
let mut auto_key: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&auto_key_layout);
|
let mut auto_key: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&auto_key_layout);
|
||||||
let mut pt_scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
|
let mut pt_scalar: ScalarZnx<Vec<u8>> = ScalarZnx::alloc(n, 1);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
@@ -327,7 +327,7 @@ where
|
|||||||
|
|
||||||
let var_xs: f64 = 0.5;
|
let var_xs: f64 = 0.5;
|
||||||
|
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&ct);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&ct);
|
||||||
sk.fill_ternary_prob(var_xs, &mut source_xs);
|
sk.fill_ternary_prob(var_xs, &mut source_xs);
|
||||||
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use poulpy_hal::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
encryption::SIGMA,
|
encryption::SIGMA,
|
||||||
layouts::{
|
layouts::{
|
||||||
AutomorphismKey, AutomorphismKeyLayout, GLWECiphertext, GLWECiphertextLayout, GLWEPlaintext, GLWESecret,
|
AutomorphismKey, AutomorphismKeyLayout, GLWE, GLWELayout, GLWEPlaintext, GLWESecret,
|
||||||
prepared::{AutomorphismKeyPrepared, GLWESecretPrepared, Prepare, PrepareAlloc},
|
prepared::{AutomorphismKeyPrepared, GLWESecretPrepared, Prepare, PrepareAlloc},
|
||||||
},
|
},
|
||||||
noise::log2_std_noise_gglwe_product,
|
noise::log2_std_noise_gglwe_product,
|
||||||
@@ -77,14 +77,14 @@ where
|
|||||||
let n: usize = module.n();
|
let n: usize = module.n();
|
||||||
let dnum: usize = k_in.div_ceil(base2k * dsize);
|
let dnum: usize = k_in.div_ceil(base2k * dsize);
|
||||||
|
|
||||||
let ct_in_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let ct_in_infos: GLWELayout = GLWELayout {
|
||||||
n: n.into(),
|
n: n.into(),
|
||||||
base2k: base2k.into(),
|
base2k: base2k.into(),
|
||||||
k: k_in.into(),
|
k: k_in.into(),
|
||||||
rank: rank.into(),
|
rank: rank.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let ct_out_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let ct_out_infos: GLWELayout = GLWELayout {
|
||||||
n: n.into(),
|
n: n.into(),
|
||||||
base2k: base2k.into(),
|
base2k: base2k.into(),
|
||||||
k: k_out.into(),
|
k: k_out.into(),
|
||||||
@@ -100,10 +100,10 @@ where
|
|||||||
dsize: di.into(),
|
dsize: di.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut autokey: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&autokey_infos);
|
let mut autokey: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&autokey_infos);
|
||||||
let mut ct_in: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&ct_in_infos);
|
let mut ct_in: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&ct_in_infos);
|
||||||
let mut ct_out: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&ct_out_infos);
|
let mut ct_out: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&ct_out_infos);
|
||||||
let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&ct_out_infos);
|
let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&ct_out_infos);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
let mut source_xe: Source = Source::new([0u8; 32]);
|
let mut source_xe: Source = Source::new([0u8; 32]);
|
||||||
@@ -113,12 +113,12 @@ where
|
|||||||
|
|
||||||
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
||||||
AutomorphismKey::encrypt_sk_scratch_space(module, &autokey)
|
AutomorphismKey::encrypt_sk_scratch_space(module, &autokey)
|
||||||
| GLWECiphertext::decrypt_scratch_space(module, &ct_out)
|
| GLWE::decrypt_scratch_space(module, &ct_out)
|
||||||
| GLWECiphertext::encrypt_sk_scratch_space(module, &ct_in)
|
| GLWE::encrypt_sk_scratch_space(module, &ct_in)
|
||||||
| GLWECiphertext::automorphism_scratch_space(module, &ct_out, &ct_in, &autokey),
|
| GLWE::automorphism_scratch_space(module, &ct_out, &ct_in, &autokey),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&ct_out);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&ct_out);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
||||||
|
|
||||||
@@ -219,7 +219,7 @@ where
|
|||||||
let n: usize = module.n();
|
let n: usize = module.n();
|
||||||
let dnum: usize = k_out.div_ceil(base2k * dsize);
|
let dnum: usize = k_out.div_ceil(base2k * dsize);
|
||||||
|
|
||||||
let ct_out_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let ct_out_infos: GLWELayout = GLWELayout {
|
||||||
n: n.into(),
|
n: n.into(),
|
||||||
base2k: base2k.into(),
|
base2k: base2k.into(),
|
||||||
k: k_out.into(),
|
k: k_out.into(),
|
||||||
@@ -235,9 +235,9 @@ where
|
|||||||
dsize: di.into(),
|
dsize: di.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut autokey: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc(&autokey_infos);
|
let mut autokey: AutomorphismKey<Vec<u8>> = AutomorphismKey::alloc_from_infos(&autokey_infos);
|
||||||
let mut ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&ct_out_infos);
|
let mut ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&ct_out_infos);
|
||||||
let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&ct_out_infos);
|
let mut pt_want: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&ct_out_infos);
|
||||||
|
|
||||||
let mut source_xs: Source = Source::new([0u8; 32]);
|
let mut source_xs: Source = Source::new([0u8; 32]);
|
||||||
let mut source_xe: Source = Source::new([0u8; 32]);
|
let mut source_xe: Source = Source::new([0u8; 32]);
|
||||||
@@ -247,12 +247,12 @@ where
|
|||||||
|
|
||||||
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
||||||
AutomorphismKey::encrypt_sk_scratch_space(module, &autokey)
|
AutomorphismKey::encrypt_sk_scratch_space(module, &autokey)
|
||||||
| GLWECiphertext::decrypt_scratch_space(module, &ct)
|
| GLWE::decrypt_scratch_space(module, &ct)
|
||||||
| GLWECiphertext::encrypt_sk_scratch_space(module, &ct)
|
| GLWE::encrypt_sk_scratch_space(module, &ct)
|
||||||
| GLWECiphertext::automorphism_inplace_scratch_space(module, &ct, &autokey),
|
| GLWE::automorphism_inplace_scratch_space(module, &ct, &autokey),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc(&ct);
|
let mut sk: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&ct);
|
||||||
sk.fill_ternary_prob(0.5, &mut source_xs);
|
sk.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
let sk_prepared: GLWESecretPrepared<Vec<u8>, B> = sk.prepare_alloc(module, scratch.borrow());
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,8 @@ use poulpy_hal::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::layouts::{
|
use crate::layouts::{
|
||||||
Base2K, Degree, Dnum, GLWECiphertext, GLWECiphertextLayout, GLWEPlaintext, GLWESecret, GLWEToLWEKeyLayout,
|
Base2K, Degree, Dnum, GLWE, GLWELayout, GLWEPlaintext, GLWESecret, GLWEToLWEKeyLayout, GLWEToLWESwitchingKey, LWE,
|
||||||
GLWEToLWESwitchingKey, LWECiphertext, LWECiphertextLayout, LWEPlaintext, LWESecret, LWEToGLWESwitchingKey,
|
LWECiphertextLayout, LWEPlaintext, LWESecret, LWEToGLWESwitchingKey, LWEToGLWESwitchingKeyLayout, Rank, TorusPrecision,
|
||||||
LWEToGLWESwitchingKeyLayout, Rank, TorusPrecision,
|
|
||||||
prepared::{GLWESecretPrepared, GLWEToLWESwitchingKeyPrepared, LWEToGLWESwitchingKeyPrepared, PrepareAlloc},
|
prepared::{GLWESecretPrepared, GLWEToLWESwitchingKeyPrepared, LWEToGLWESwitchingKeyPrepared, PrepareAlloc},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,7 +82,7 @@ where
|
|||||||
rank_out: rank,
|
rank_out: rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_infos: GLWELayout = GLWELayout {
|
||||||
n: n_glwe,
|
n: n_glwe,
|
||||||
base2k: Base2K(17),
|
base2k: Base2K(17),
|
||||||
k: TorusPrecision(34),
|
k: TorusPrecision(34),
|
||||||
@@ -98,11 +97,11 @@ where
|
|||||||
|
|
||||||
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
||||||
LWEToGLWESwitchingKey::encrypt_sk_scratch_space(module, &lwe_to_glwe_infos)
|
LWEToGLWESwitchingKey::encrypt_sk_scratch_space(module, &lwe_to_glwe_infos)
|
||||||
| GLWECiphertext::from_lwe_scratch_space(module, &glwe_infos, &lwe_infos, &lwe_to_glwe_infos)
|
| GLWE::from_lwe_scratch_space(module, &glwe_infos, &lwe_infos, &lwe_to_glwe_infos)
|
||||||
| GLWECiphertext::decrypt_scratch_space(module, &glwe_infos),
|
| GLWE::decrypt_scratch_space(module, &glwe_infos),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_infos);
|
let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
|
||||||
sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
|
sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
|
|
||||||
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
|
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
|
||||||
@@ -112,13 +111,13 @@ where
|
|||||||
|
|
||||||
let data: i64 = 17;
|
let data: i64 = 17;
|
||||||
|
|
||||||
let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(&lwe_infos);
|
let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc_from_infos(&lwe_infos);
|
||||||
lwe_pt.encode_i64(data, k_lwe_pt);
|
lwe_pt.encode_i64(data, k_lwe_pt);
|
||||||
|
|
||||||
let mut lwe_ct: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(&lwe_infos);
|
let mut lwe_ct: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_infos);
|
||||||
lwe_ct.encrypt_sk(module, &lwe_pt, &sk_lwe, &mut source_xa, &mut source_xe);
|
lwe_ct.encrypt_sk(module, &lwe_pt, &sk_lwe, &mut source_xa, &mut source_xe);
|
||||||
|
|
||||||
let mut ksk: LWEToGLWESwitchingKey<Vec<u8>> = LWEToGLWESwitchingKey::alloc(&lwe_to_glwe_infos);
|
let mut ksk: LWEToGLWESwitchingKey<Vec<u8>> = LWEToGLWESwitchingKey::alloc_from_infos(&lwe_to_glwe_infos);
|
||||||
|
|
||||||
ksk.encrypt_sk(
|
ksk.encrypt_sk(
|
||||||
module,
|
module,
|
||||||
@@ -129,13 +128,13 @@ where
|
|||||||
scratch.borrow(),
|
scratch.borrow(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut glwe_ct: GLWECiphertext<Vec<u8>> = GLWECiphertext::alloc(&glwe_infos);
|
let mut glwe_ct: GLWE<Vec<u8>> = GLWE::alloc_from_infos(&glwe_infos);
|
||||||
|
|
||||||
let ksk_prepared: LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow());
|
let ksk_prepared: LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow());
|
||||||
|
|
||||||
glwe_ct.from_lwe(module, &lwe_ct, &ksk_prepared, scratch.borrow());
|
glwe_ct.from_lwe(module, &lwe_ct, &ksk_prepared, scratch.borrow());
|
||||||
|
|
||||||
let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&glwe_infos);
|
let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
|
||||||
glwe_ct.decrypt(module, &mut glwe_pt, &sk_glwe_prepared, scratch.borrow());
|
glwe_ct.decrypt(module, &mut glwe_pt, &sk_glwe_prepared, scratch.borrow());
|
||||||
|
|
||||||
assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
|
assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
|
||||||
@@ -196,7 +195,7 @@ where
|
|||||||
rank_in: rank,
|
rank_in: rank,
|
||||||
};
|
};
|
||||||
|
|
||||||
let glwe_infos: GLWECiphertextLayout = GLWECiphertextLayout {
|
let glwe_infos: GLWELayout = GLWELayout {
|
||||||
n: n_glwe,
|
n: n_glwe,
|
||||||
base2k: Base2K(17),
|
base2k: Base2K(17),
|
||||||
k: TorusPrecision(34),
|
k: TorusPrecision(34),
|
||||||
@@ -215,11 +214,11 @@ where
|
|||||||
|
|
||||||
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
let mut scratch: ScratchOwned<B> = ScratchOwned::alloc(
|
||||||
GLWEToLWESwitchingKey::encrypt_sk_scratch_space(module, &glwe_to_lwe_infos)
|
GLWEToLWESwitchingKey::encrypt_sk_scratch_space(module, &glwe_to_lwe_infos)
|
||||||
| LWECiphertext::from_glwe_scratch_space(module, &lwe_infos, &glwe_infos, &glwe_to_lwe_infos)
|
| LWE::from_glwe_scratch_space(module, &lwe_infos, &glwe_infos, &glwe_to_lwe_infos)
|
||||||
| GLWECiphertext::decrypt_scratch_space(module, &glwe_infos),
|
| GLWE::decrypt_scratch_space(module, &glwe_infos),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc(&glwe_infos);
|
let mut sk_glwe: GLWESecret<Vec<u8>> = GLWESecret::alloc_from_infos(&glwe_infos);
|
||||||
sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
|
sk_glwe.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
|
|
||||||
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
|
let sk_glwe_prepared: GLWESecretPrepared<Vec<u8>, B> = sk_glwe.prepare_alloc(module, scratch.borrow());
|
||||||
@@ -228,10 +227,10 @@ where
|
|||||||
sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
|
sk_lwe.fill_ternary_prob(0.5, &mut source_xs);
|
||||||
|
|
||||||
let data: i64 = 17;
|
let data: i64 = 17;
|
||||||
let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc(&glwe_infos);
|
let mut glwe_pt: GLWEPlaintext<Vec<u8>> = GLWEPlaintext::alloc_from_infos(&glwe_infos);
|
||||||
glwe_pt.encode_coeff_i64(data, k_lwe_pt, 0);
|
glwe_pt.encode_coeff_i64(data, k_lwe_pt, 0);
|
||||||
|
|
||||||
let mut glwe_ct = GLWECiphertext::alloc(&glwe_infos);
|
let mut glwe_ct = GLWE::alloc_from_infos(&glwe_infos);
|
||||||
glwe_ct.encrypt_sk(
|
glwe_ct.encrypt_sk(
|
||||||
module,
|
module,
|
||||||
&glwe_pt,
|
&glwe_pt,
|
||||||
@@ -252,13 +251,13 @@ where
|
|||||||
scratch.borrow(),
|
scratch.borrow(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut lwe_ct: LWECiphertext<Vec<u8>> = LWECiphertext::alloc(&lwe_infos);
|
let mut lwe_ct: LWE<Vec<u8>> = LWE::alloc_from_infos(&lwe_infos);
|
||||||
|
|
||||||
let ksk_prepared: GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow());
|
let ksk_prepared: GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> = ksk.prepare_alloc(module, scratch.borrow());
|
||||||
|
|
||||||
lwe_ct.from_glwe(module, &glwe_ct, &ksk_prepared, scratch.borrow());
|
lwe_ct.from_glwe(module, &glwe_ct, &ksk_prepared, scratch.borrow());
|
||||||
|
|
||||||
let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc(&lwe_infos);
|
let mut lwe_pt: LWEPlaintext<Vec<u8>> = LWEPlaintext::alloc_from_infos(&lwe_infos);
|
||||||
lwe_ct.decrypt(module, &mut lwe_pt, &sk_lwe);
|
lwe_ct.decrypt(module, &mut lwe_pt, &sk_lwe);
|
||||||
|
|
||||||
assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
|
assert_eq!(glwe_pt.data.at(0, 0)[0], lwe_pt.data.at(0, 0)[0]);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user