mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 21:26:41 +01:00
372 lines
13 KiB
Rust
372 lines
13 KiB
Rust
use poulpy_hal::{
|
|
api::{
|
|
ScratchTakeBasic, VecZnxAutomorphismInplace, VecZnxBigAddSmallInplace, VecZnxBigAutomorphismInplace, VecZnxBigNormalize,
|
|
VecZnxBigSubSmallInplace, VecZnxBigSubSmallNegateInplace, VecZnxNormalize,
|
|
},
|
|
layouts::{Backend, DataMut, Module, Scratch, VecZnxBig},
|
|
};
|
|
|
|
use crate::{
|
|
GLWEKeySwitchInternal, GLWEKeyswitch, ScratchTakeCore,
|
|
layouts::{GGLWEInfos, GGLWEPreparedToRef, GLWE, GLWEInfos, GLWEToMut, GLWEToRef, GetGaloisElement, LWEInfos},
|
|
};
|
|
|
|
impl GLWE<Vec<u8>> {
|
|
pub fn automorphism_tmp_bytes<M, R, A, K, BE: Backend>(module: &M, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
|
|
where
|
|
R: GLWEInfos,
|
|
A: GLWEInfos,
|
|
K: GGLWEInfos,
|
|
M: GLWEAutomorphism<BE>,
|
|
{
|
|
module.glwe_automorphism_tmp_bytes(res_infos, a_infos, key_infos)
|
|
}
|
|
}
|
|
|
|
impl<DataSelf: DataMut> GLWE<DataSelf> {
|
|
pub fn automorphism<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism(self, a, key, scratch);
|
|
}
|
|
|
|
pub fn automorphism_add<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism_add(self, a, key, scratch);
|
|
}
|
|
|
|
pub fn automorphism_sub<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism_sub(self, a, key, scratch);
|
|
}
|
|
|
|
pub fn automorphism_sub_negate<M, A, K, BE: Backend>(&mut self, module: &M, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism_sub_negate(self, a, key, scratch);
|
|
}
|
|
|
|
pub fn automorphism_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism_inplace(self, key, scratch);
|
|
}
|
|
|
|
pub fn automorphism_add_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism_add_inplace(self, key, scratch);
|
|
}
|
|
|
|
pub fn automorphism_sub_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism_sub_inplace(self, key, scratch);
|
|
}
|
|
|
|
pub fn automorphism_sub_negate_inplace<M, K, BE: Backend>(&mut self, module: &M, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
M: GLWEAutomorphism<BE>,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
module.glwe_automorphism_sub_negate_inplace(self, key, scratch);
|
|
}
|
|
}
|
|
|
|
pub trait GLWEAutomorphism<BE: Backend> {
|
|
fn glwe_automorphism_tmp_bytes<R, A, K>(&self, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
|
|
where
|
|
R: GLWEInfos,
|
|
A: GLWEInfos,
|
|
K: GGLWEInfos;
|
|
|
|
fn glwe_automorphism<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
|
|
fn glwe_automorphism_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
|
|
fn glwe_automorphism_add<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
|
|
fn glwe_automorphism_add_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
|
|
fn glwe_automorphism_sub<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
|
|
fn glwe_automorphism_sub_negate<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
|
|
fn glwe_automorphism_sub_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
|
|
fn glwe_automorphism_sub_negate_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos;
|
|
}
|
|
|
|
impl<BE: Backend> GLWEAutomorphism<BE> for Module<BE>
|
|
where
|
|
Self: Sized
|
|
+ GLWEKeyswitch<BE>
|
|
+ GLWEKeySwitchInternal<BE>
|
|
+ VecZnxNormalize<BE>
|
|
+ VecZnxAutomorphismInplace<BE>
|
|
+ VecZnxBigAutomorphismInplace<BE>
|
|
+ VecZnxBigSubSmallInplace<BE>
|
|
+ VecZnxBigSubSmallNegateInplace<BE>
|
|
+ VecZnxBigAddSmallInplace<BE>
|
|
+ VecZnxBigNormalize<BE>,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
fn glwe_automorphism_tmp_bytes<R, A, K>(&self, res_infos: &R, a_infos: &A, key_infos: &K) -> usize
|
|
where
|
|
R: GLWEInfos,
|
|
A: GLWEInfos,
|
|
K: GGLWEInfos,
|
|
{
|
|
self.glwe_keyswitch_tmp_bytes(res_infos, a_infos, key_infos)
|
|
}
|
|
|
|
fn glwe_automorphism<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
self.glwe_keyswitch(res, a, key, scratch);
|
|
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_automorphism_inplace(key.p(), res.data_mut(), i, scratch);
|
|
}
|
|
}
|
|
|
|
fn glwe_automorphism_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
self.glwe_keyswitch_inplace(res, key, scratch);
|
|
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_automorphism_inplace(key.p(), res.data_mut(), i, scratch);
|
|
}
|
|
}
|
|
|
|
fn glwe_automorphism_add<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
let a: &GLWE<&[u8]> = &a.to_ref();
|
|
|
|
let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
|
|
let mut res_big: VecZnxBig<_, BE> = self.glwe_keyswitch_internal(res_dft, a, key, scratch_1);
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
|
|
self.vec_znx_big_add_small_inplace(&mut res_big, i, a.data(), i);
|
|
self.vec_znx_big_normalize(
|
|
res.base2k().into(),
|
|
res.data_mut(),
|
|
i,
|
|
key.base2k().into(),
|
|
&res_big,
|
|
i,
|
|
scratch_1,
|
|
);
|
|
}
|
|
}
|
|
|
|
fn glwe_automorphism_add_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
|
|
let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
|
|
let mut res_big: VecZnxBig<_, BE> = self.glwe_keyswitch_internal(res_dft, res, key, scratch_1);
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
|
|
self.vec_znx_big_add_small_inplace(&mut res_big, i, res.data(), i);
|
|
self.vec_znx_big_normalize(
|
|
res.base2k().into(),
|
|
res.data_mut(),
|
|
i,
|
|
key.base2k().into(),
|
|
&res_big,
|
|
i,
|
|
scratch_1,
|
|
);
|
|
}
|
|
}
|
|
|
|
fn glwe_automorphism_sub<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
let a: &GLWE<&[u8]> = &a.to_ref();
|
|
|
|
let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
|
|
let mut res_big: VecZnxBig<_, BE> = self.glwe_keyswitch_internal(res_dft, a, key, scratch_1);
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
|
|
self.vec_znx_big_sub_small_inplace(&mut res_big, i, a.data(), i);
|
|
self.vec_znx_big_normalize(
|
|
res.base2k().into(),
|
|
res.data_mut(),
|
|
i,
|
|
key.base2k().into(),
|
|
&res_big,
|
|
i,
|
|
scratch_1,
|
|
);
|
|
}
|
|
}
|
|
|
|
fn glwe_automorphism_sub_negate<R, A, K>(&self, res: &mut R, a: &A, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
A: GLWEToRef,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
let a: &GLWE<&[u8]> = &a.to_ref();
|
|
|
|
let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
|
|
let mut res_big: VecZnxBig<_, BE> = self.glwe_keyswitch_internal(res_dft, a, key, scratch_1);
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
|
|
self.vec_znx_big_sub_small_negate_inplace(&mut res_big, i, a.data(), i);
|
|
self.vec_znx_big_normalize(
|
|
res.base2k().into(),
|
|
res.data_mut(),
|
|
i,
|
|
key.base2k().into(),
|
|
&res_big,
|
|
i,
|
|
scratch_1,
|
|
);
|
|
}
|
|
}
|
|
|
|
fn glwe_automorphism_sub_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
|
|
let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
|
|
let mut res_big: VecZnxBig<_, BE> = self.glwe_keyswitch_internal(res_dft, res, key, scratch_1);
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
|
|
self.vec_znx_big_sub_small_inplace(&mut res_big, i, res.data(), i);
|
|
self.vec_znx_big_normalize(
|
|
res.base2k().into(),
|
|
res.data_mut(),
|
|
i,
|
|
key.base2k().into(),
|
|
&res_big,
|
|
i,
|
|
scratch_1,
|
|
);
|
|
}
|
|
}
|
|
|
|
fn glwe_automorphism_sub_negate_inplace<R, K>(&self, res: &mut R, key: &K, scratch: &mut Scratch<BE>)
|
|
where
|
|
R: GLWEToMut,
|
|
K: GetGaloisElement + GGLWEPreparedToRef<BE> + GGLWEInfos,
|
|
Scratch<BE>: ScratchTakeCore<BE>,
|
|
{
|
|
let res: &mut GLWE<&mut [u8]> = &mut res.to_mut();
|
|
|
|
let (res_dft, scratch_1) = scratch.take_vec_znx_dft(self, (res.rank() + 1).into(), key.size()); // TODO: optimise size
|
|
let mut res_big: VecZnxBig<_, BE> = self.glwe_keyswitch_internal(res_dft, res, key, scratch_1);
|
|
|
|
for i in 0..res.rank().as_usize() + 1 {
|
|
self.vec_znx_big_automorphism_inplace(key.p(), &mut res_big, i, scratch_1);
|
|
self.vec_znx_big_sub_small_negate_inplace(&mut res_big, i, res.data(), i);
|
|
self.vec_znx_big_normalize(
|
|
res.base2k().into(),
|
|
res.data_mut(),
|
|
i,
|
|
key.base2k().into(),
|
|
&res_big,
|
|
i,
|
|
scratch_1,
|
|
);
|
|
}
|
|
}
|
|
}
|