mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 13:16:44 +01:00
updated repo for publishing (#74)
This commit is contained in:
committed by
GitHub
parent
0be569eca0
commit
62eb87cc07
101
poulpy-core/src/layouts/prepared/gglwe_atk.rs
Normal file
101
poulpy-core/src/layouts/prepared/gglwe_atk.rs
Normal file
@@ -0,0 +1,101 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
GGLWEAutomorphismKey, Infos,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWEAutomorphismKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) key: GGLWESwitchingKeyPrepared<D, B>,
|
||||
pub(crate) p: i64,
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
GGLWEAutomorphismKeyPrepared::<Vec<u8>, B> {
|
||||
key: GGLWESwitchingKeyPrepared::alloc(module, n, basek, k, rows, digits, rank, rank),
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::bytes_of(module, n, basek, k, rows, digits, rank, rank)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> Infos for GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
self.key.inner()
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.key.basek()
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.key.k()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
pub fn p(&self) -> i64 {
|
||||
self.p
|
||||
}
|
||||
|
||||
pub fn digits(&self) -> usize {
|
||||
self.key.digits()
|
||||
}
|
||||
|
||||
pub fn rank(&self) -> usize {
|
||||
self.key.rank()
|
||||
}
|
||||
|
||||
pub fn rank_in(&self) -> usize {
|
||||
self.key.rank_in()
|
||||
}
|
||||
|
||||
pub fn rank_out(&self) -> usize {
|
||||
self.key.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWEAutomorphismKey<DR>> for GGLWEAutomorphismKeyPrepared<D, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GGLWEAutomorphismKey<DR>, scratch: &mut Scratch<B>) {
|
||||
self.key.prepare(module, &other.key, scratch);
|
||||
self.p = other.p;
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>> for GGLWEAutomorphismKey<D>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
|
||||
let mut atk_prepared: GGLWEAutomorphismKeyPrepared<Vec<u8>, B> = GGLWEAutomorphismKeyPrepared::alloc(
|
||||
module,
|
||||
self.n(),
|
||||
self.basek(),
|
||||
self.k(),
|
||||
self.rows(),
|
||||
self.digits(),
|
||||
self.rank(),
|
||||
);
|
||||
atk_prepared.prepare(module, self, scratch);
|
||||
atk_prepared
|
||||
}
|
||||
}
|
||||
156
poulpy-core/src/layouts/prepared/gglwe_ct.rs
Normal file
156
poulpy-core/src/layouts/prepared/gglwe_ct.rs
Normal file
@@ -0,0 +1,156 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
GGLWECiphertext, Infos,
|
||||
prepared::{Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWECiphertextPrepared<D: Data, B: Backend> {
|
||||
pub(crate) data: VmpPMat<D, B>,
|
||||
pub(crate) basek: usize,
|
||||
pub(crate) k: usize,
|
||||
pub(crate) digits: usize,
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWECiphertextPrepared<Vec<u8>, B> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn alloc(
|
||||
module: &Module<B>,
|
||||
n: usize,
|
||||
basek: usize,
|
||||
k: usize,
|
||||
rows: usize,
|
||||
digits: usize,
|
||||
rank_in: usize,
|
||||
rank_out: usize,
|
||||
) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
let size: usize = k.div_ceil(basek);
|
||||
debug_assert!(
|
||||
size > digits,
|
||||
"invalid gglwe: ceil(k/basek): {} <= digits: {}",
|
||||
size,
|
||||
digits
|
||||
);
|
||||
|
||||
assert!(
|
||||
rows * digits <= size,
|
||||
"invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
|
||||
rows,
|
||||
digits,
|
||||
size
|
||||
);
|
||||
|
||||
Self {
|
||||
data: module.vmp_pmat_alloc(n, rows, rank_in, rank_out + 1, size),
|
||||
basek,
|
||||
k,
|
||||
digits,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn bytes_of(
|
||||
module: &Module<B>,
|
||||
n: usize,
|
||||
basek: usize,
|
||||
k: usize,
|
||||
rows: usize,
|
||||
digits: usize,
|
||||
rank_in: usize,
|
||||
rank_out: usize,
|
||||
) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
let size: usize = k.div_ceil(basek);
|
||||
debug_assert!(
|
||||
size > digits,
|
||||
"invalid gglwe: ceil(k/basek): {} <= digits: {}",
|
||||
size,
|
||||
digits
|
||||
);
|
||||
|
||||
assert!(
|
||||
rows * digits <= size,
|
||||
"invalid gglwe: rows: {} * digits:{} > ceil(k/basek): {}",
|
||||
rows,
|
||||
digits,
|
||||
size
|
||||
);
|
||||
|
||||
module.vmp_pmat_alloc_bytes(n, rows, rank_in, rank_out + 1, rows)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> Infos for GGLWECiphertextPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.basek
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.k
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWECiphertextPrepared<D, B> {
|
||||
pub fn rank(&self) -> usize {
|
||||
self.data.cols_out() - 1
|
||||
}
|
||||
|
||||
pub fn digits(&self) -> usize {
|
||||
self.digits
|
||||
}
|
||||
|
||||
pub fn rank_in(&self) -> usize {
|
||||
self.data.cols_in()
|
||||
}
|
||||
|
||||
pub fn rank_out(&self) -> usize {
|
||||
self.data.cols_out() - 1
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWECiphertext<DR>> for GGLWECiphertextPrepared<D, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GGLWECiphertext<DR>, scratch: &mut Scratch<B>) {
|
||||
module.vmp_prepare(&mut self.data, &other.data, scratch);
|
||||
self.basek = other.basek;
|
||||
self.k = other.k;
|
||||
self.digits = other.digits;
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWECiphertextPrepared<Vec<u8>, B>> for GGLWECiphertext<D>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWECiphertextPrepared<Vec<u8>, B> {
|
||||
let mut atk_prepared: GGLWECiphertextPrepared<Vec<u8>, B> = GGLWECiphertextPrepared::alloc(
|
||||
module,
|
||||
self.n(),
|
||||
self.basek(),
|
||||
self.k(),
|
||||
self.rows(),
|
||||
self.digits(),
|
||||
self.rank_in(),
|
||||
self.rank_out(),
|
||||
);
|
||||
atk_prepared.prepare(module, self, scratch);
|
||||
atk_prepared
|
||||
}
|
||||
}
|
||||
129
poulpy-core/src/layouts/prepared/gglwe_ksk.rs
Normal file
129
poulpy-core/src/layouts/prepared/gglwe_ksk.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
GGLWESwitchingKey, Infos,
|
||||
prepared::{GGLWECiphertextPrepared, Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWESwitchingKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) key: GGLWECiphertextPrepared<D, B>,
|
||||
pub(crate) sk_in_n: usize, // Degree of sk_in
|
||||
pub(crate) sk_out_n: usize, // Degree of sk_out
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn alloc(
|
||||
module: &Module<B>,
|
||||
n: usize,
|
||||
basek: usize,
|
||||
k: usize,
|
||||
rows: usize,
|
||||
digits: usize,
|
||||
rank_in: usize,
|
||||
rank_out: usize,
|
||||
) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::<Vec<u8>, B> {
|
||||
key: GGLWECiphertextPrepared::alloc(module, n, basek, k, rows, digits, rank_in, rank_out),
|
||||
sk_in_n: 0,
|
||||
sk_out_n: 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn bytes_of(
|
||||
module: &Module<B>,
|
||||
n: usize,
|
||||
basek: usize,
|
||||
k: usize,
|
||||
rows: usize,
|
||||
digits: usize,
|
||||
rank_in: usize,
|
||||
rank_out: usize,
|
||||
) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWECiphertextPrepared::bytes_of(module, n, basek, k, rows, digits, rank_in, rank_out)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> Infos for GGLWESwitchingKeyPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
self.key.inner()
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.key.basek()
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.key.k()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWESwitchingKeyPrepared<D, B> {
|
||||
pub fn rank(&self) -> usize {
|
||||
self.key.data.cols_out() - 1
|
||||
}
|
||||
|
||||
pub fn rank_in(&self) -> usize {
|
||||
self.key.data.cols_in()
|
||||
}
|
||||
|
||||
pub fn rank_out(&self) -> usize {
|
||||
self.key.data.cols_out() - 1
|
||||
}
|
||||
|
||||
pub fn digits(&self) -> usize {
|
||||
self.key.digits()
|
||||
}
|
||||
|
||||
pub fn sk_degree_in(&self) -> usize {
|
||||
self.sk_in_n
|
||||
}
|
||||
|
||||
pub fn sk_degree_out(&self) -> usize {
|
||||
self.sk_out_n
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWESwitchingKey<DR>> for GGLWESwitchingKeyPrepared<D, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GGLWESwitchingKey<DR>, scratch: &mut Scratch<B>) {
|
||||
self.key.prepare(module, &other.key, scratch);
|
||||
self.sk_in_n = other.sk_in_n;
|
||||
self.sk_out_n = other.sk_out_n;
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWESwitchingKeyPrepared<Vec<u8>, B>> for GGLWESwitchingKey<D>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
let mut atk_prepared: GGLWESwitchingKeyPrepared<Vec<u8>, B> = GGLWESwitchingKeyPrepared::alloc(
|
||||
module,
|
||||
self.n(),
|
||||
self.basek(),
|
||||
self.k(),
|
||||
self.rows(),
|
||||
self.digits(),
|
||||
self.rank_in(),
|
||||
self.rank_out(),
|
||||
);
|
||||
atk_prepared.prepare(module, self, scratch);
|
||||
atk_prepared
|
||||
}
|
||||
}
|
||||
131
poulpy-core/src/layouts/prepared/gglwe_tsk.rs
Normal file
131
poulpy-core/src/layouts/prepared/gglwe_tsk.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
GGLWETensorKey, Infos,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWETensorKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) keys: Vec<GGLWESwitchingKeyPrepared<D, B>>,
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
let mut keys: Vec<GGLWESwitchingKeyPrepared<Vec<u8>, B>> = Vec::new();
|
||||
let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
|
||||
(0..pairs).for_each(|_| {
|
||||
keys.push(GGLWESwitchingKeyPrepared::alloc(
|
||||
module, n, basek, k, rows, digits, 1, rank,
|
||||
));
|
||||
});
|
||||
Self { keys }
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
let pairs: usize = (((rank + 1) * rank) >> 1).max(1);
|
||||
pairs * GGLWESwitchingKeyPrepared::bytes_of(module, n, basek, k, rows, digits, 1, rank)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> Infos for GGLWETensorKeyPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
self.keys[0].inner()
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.keys[0].basek()
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.keys[0].k()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWETensorKeyPrepared<D, B> {
|
||||
pub fn rank(&self) -> usize {
|
||||
self.keys[0].rank()
|
||||
}
|
||||
|
||||
pub fn rank_in(&self) -> usize {
|
||||
self.keys[0].rank_in()
|
||||
}
|
||||
|
||||
pub fn rank_out(&self) -> usize {
|
||||
self.keys[0].rank_out()
|
||||
}
|
||||
|
||||
pub fn digits(&self) -> usize {
|
||||
self.keys[0].digits()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GGLWETensorKeyPrepared<D, B> {
|
||||
// Returns a mutable reference to GLWESwitchingKey_{s}(s[i] * s[j])
|
||||
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWESwitchingKeyPrepared<D, B> {
|
||||
if i > j {
|
||||
std::mem::swap(&mut i, &mut j);
|
||||
};
|
||||
let rank: usize = self.rank();
|
||||
&mut self.keys[i * rank + j - (i * (i + 1) / 2)]
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> GGLWETensorKeyPrepared<D, B> {
|
||||
// Returns a reference to GLWESwitchingKey_{s}(s[i] * s[j])
|
||||
pub fn at(&self, mut i: usize, mut j: usize) -> &GGLWESwitchingKeyPrepared<D, B> {
|
||||
if i > j {
|
||||
std::mem::swap(&mut i, &mut j);
|
||||
};
|
||||
let rank: usize = self.rank();
|
||||
&self.keys[i * rank + j - (i * (i + 1) / 2)]
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWETensorKey<DR>> for GGLWETensorKeyPrepared<D, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GGLWETensorKey<DR>, scratch: &mut Scratch<B>) {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
assert_eq!(self.keys.len(), other.keys.len());
|
||||
}
|
||||
self.keys
|
||||
.iter_mut()
|
||||
.zip(other.keys.iter())
|
||||
.for_each(|(a, b)| {
|
||||
a.prepare(module, b, scratch);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWETensorKeyPrepared<Vec<u8>, B>> for GGLWETensorKey<D>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGLWETensorKeyPrepared<Vec<u8>, B> {
|
||||
let mut tsk_prepared: GGLWETensorKeyPrepared<Vec<u8>, B> = GGLWETensorKeyPrepared::alloc(
|
||||
module,
|
||||
self.n(),
|
||||
self.basek(),
|
||||
self.k(),
|
||||
self.rows(),
|
||||
self.digits(),
|
||||
self.rank(),
|
||||
);
|
||||
tsk_prepared.prepare(module, self, scratch);
|
||||
tsk_prepared
|
||||
}
|
||||
}
|
||||
135
poulpy-core/src/layouts/prepared/ggsw_ct.rs
Normal file
135
poulpy-core/src/layouts/prepared/ggsw_ct.rs
Normal file
@@ -0,0 +1,135 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
GGSWCiphertext, Infos,
|
||||
prepared::{Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGSWCiphertextPrepared<D: Data, B: Backend> {
|
||||
pub(crate) data: VmpPMat<D, B>,
|
||||
pub(crate) basek: usize,
|
||||
pub(crate) k: usize,
|
||||
pub(crate) digits: usize,
|
||||
}
|
||||
|
||||
impl<B: Backend> GGSWCiphertextPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
let size: usize = k.div_ceil(basek);
|
||||
debug_assert!(digits > 0, "invalid ggsw: `digits` == 0");
|
||||
|
||||
debug_assert!(
|
||||
size > digits,
|
||||
"invalid ggsw: ceil(k/basek): {} <= digits: {}",
|
||||
size,
|
||||
digits
|
||||
);
|
||||
|
||||
assert!(
|
||||
rows * digits <= size,
|
||||
"invalid ggsw: rows: {} * digits:{} > ceil(k/basek): {}",
|
||||
rows,
|
||||
digits,
|
||||
size
|
||||
);
|
||||
|
||||
Self {
|
||||
data: module.vmp_pmat_alloc(n, rows, rank + 1, rank + 1, k.div_ceil(basek)),
|
||||
basek,
|
||||
k,
|
||||
digits,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank: usize) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
let size: usize = k.div_ceil(basek);
|
||||
debug_assert!(
|
||||
size > digits,
|
||||
"invalid ggsw: ceil(k/basek): {} <= digits: {}",
|
||||
size,
|
||||
digits
|
||||
);
|
||||
|
||||
assert!(
|
||||
rows * digits <= size,
|
||||
"invalid ggsw: rows: {} * digits:{} > ceil(k/basek): {}",
|
||||
rows,
|
||||
digits,
|
||||
size
|
||||
);
|
||||
|
||||
module.vmp_pmat_alloc_bytes(n, rows, rank + 1, rank + 1, size)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> Infos for GGSWCiphertextPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.basek
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.k
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGSWCiphertextPrepared<D, B> {
|
||||
pub fn rank(&self) -> usize {
|
||||
self.data.cols_out() - 1
|
||||
}
|
||||
|
||||
pub fn digits(&self) -> usize {
|
||||
self.digits
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> GGSWCiphertextPrepared<D, B> {
|
||||
pub fn data(&self) -> &VmpPMat<D, B> {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGSWCiphertext<DR>> for GGSWCiphertextPrepared<D, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GGSWCiphertext<DR>, scratch: &mut Scratch<B>) {
|
||||
module.vmp_prepare(&mut self.data, &other.data, scratch);
|
||||
self.k = other.k;
|
||||
self.basek = other.basek;
|
||||
self.digits = other.digits;
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGSWCiphertextPrepared<Vec<u8>, B>> for GGSWCiphertext<D>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GGSWCiphertextPrepared<Vec<u8>, B> {
|
||||
let mut ggsw_prepared: GGSWCiphertextPrepared<Vec<u8>, B> = GGSWCiphertextPrepared::alloc(
|
||||
module,
|
||||
self.n(),
|
||||
self.basek(),
|
||||
self.k(),
|
||||
self.rows(),
|
||||
self.digits(),
|
||||
self.rank(),
|
||||
);
|
||||
ggsw_prepared.prepare(module, self, scratch);
|
||||
ggsw_prepared
|
||||
}
|
||||
}
|
||||
177
poulpy-core/src/layouts/prepared/glwe_ct.rs
Normal file
177
poulpy-core/src/layouts/prepared/glwe_ct.rs
Normal file
@@ -0,0 +1,177 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{FillUniform, Reset, VecZnxCopy, VecZnxFillUniform},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, ReaderFrom, VecZnx, WriterTo},
|
||||
};
|
||||
|
||||
|
||||
use crate::layouts::{GLWECiphertext, Infos, compressed::Decompress};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GLWECiphertextCompressed<D: Data> {
|
||||
pub(crate) data: VecZnx<D>,
|
||||
pub(crate) basek: usize,
|
||||
pub(crate) k: usize,
|
||||
pub(crate) rank: usize,
|
||||
pub(crate) seed: [u8; 32],
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GLWECiphertextCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GLWECiphertextCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"GLWECiphertextCompressed: basek={} k={} rank={} seed={:?}: {}",
|
||||
self.basek(),
|
||||
self.k(),
|
||||
self.rank,
|
||||
self.seed,
|
||||
self.data
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> Reset for GLWECiphertextCompressed<D> {
|
||||
fn reset(&mut self) {
|
||||
self.data.reset();
|
||||
self.basek = 0;
|
||||
self.k = 0;
|
||||
self.rank = 0;
|
||||
self.seed = [0u8; 32];
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GLWECiphertextCompressed<D> {
|
||||
fn fill_uniform(&mut self, source: &mut Source) {
|
||||
self.data.fill_uniform(source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> Infos for GLWECiphertextCompressed<D> {
|
||||
type Inner = VecZnx<D>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.basek
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.k
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWECiphertextCompressed<D> {
|
||||
pub fn rank(&self) -> usize {
|
||||
self.rank
|
||||
}
|
||||
}
|
||||
|
||||
impl GLWECiphertextCompressed<Vec<u8>> {
|
||||
pub fn alloc(n: usize, basek: usize, k: usize, rank: usize) -> Self {
|
||||
Self {
|
||||
data: VecZnx::alloc(n, 1, k.div_ceil(basek)),
|
||||
basek,
|
||||
k,
|
||||
rank,
|
||||
seed: [0u8; 32],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_of(n: usize, basek: usize, k: usize) -> usize {
|
||||
GLWECiphertext::bytes_of(n, basek, k, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GLWECiphertextCompressed<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.k = reader.read_u64::<LittleEndian>()? as usize;
|
||||
self.basek = reader.read_u64::<LittleEndian>()? as usize;
|
||||
self.rank = reader.read_u64::<LittleEndian>()? as usize;
|
||||
reader.read_exact(&mut self.seed)?;
|
||||
self.data.read_from(reader)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GLWECiphertextCompressed<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write_u64::<LittleEndian>(self.k as u64)?;
|
||||
writer.write_u64::<LittleEndian>(self.basek as u64)?;
|
||||
writer.write_u64::<LittleEndian>(self.rank as u64)?;
|
||||
writer.write_all(&self.seed)?;
|
||||
self.data.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GLWECiphertextCompressed<DR>> for GLWECiphertext<D> {
|
||||
fn decompress(&mut self, module: &Module<B>, other: &GLWECiphertextCompressed<DR>)
|
||||
where
|
||||
Module<B>: VecZnxCopy + VecZnxFillUniform,
|
||||
{
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
use poulpy_backend::hal::api::ZnxInfos;
|
||||
|
||||
assert_eq!(
|
||||
self.n(),
|
||||
other.data.n(),
|
||||
"invalid receiver: self.n()={} != other.n()={}",
|
||||
self.n(),
|
||||
other.data.n()
|
||||
);
|
||||
assert_eq!(
|
||||
self.size(),
|
||||
other.size(),
|
||||
"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);
|
||||
self.decompress_internal(module, other, &mut source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GLWECiphertext<D> {
|
||||
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())
|
||||
}
|
||||
|
||||
let k: usize = other.k;
|
||||
let basek: usize = other.basek;
|
||||
let cols: usize = other.rank() + 1;
|
||||
module.vec_znx_copy(&mut self.data, 0, &other.data, 0);
|
||||
(1..cols).for_each(|i| {
|
||||
module.vec_znx_fill_uniform(basek, &mut self.data, i, k, source);
|
||||
});
|
||||
|
||||
self.basek = basek;
|
||||
self.k = k;
|
||||
}
|
||||
}
|
||||
95
poulpy-core/src/layouts/prepared/glwe_pk.rs
Normal file
95
poulpy-core/src/layouts/prepared/glwe_pk.rs
Normal file
@@ -0,0 +1,95 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VecZnxDftAlloc, VecZnxDftAllocBytes, VecZnxDftFromVecZnx},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VecZnxDft},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
dist::Distribution,
|
||||
layouts::{
|
||||
GLWEPublicKey, Infos,
|
||||
prepared::{Prepare, PrepareAlloc},
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GLWEPublicKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) data: VecZnxDft<D, B>,
|
||||
pub(crate) basek: usize,
|
||||
pub(crate) k: usize,
|
||||
pub(crate) dist: Distribution,
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> Infos for GLWEPublicKeyPrepared<D, B> {
|
||||
type Inner = VecZnxDft<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.basek
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.k
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEPublicKeyPrepared<D, B> {
|
||||
pub fn rank(&self) -> usize {
|
||||
self.cols() - 1
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GLWEPublicKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rank: usize) -> Self
|
||||
where
|
||||
Module<B>: VecZnxDftAlloc<B>,
|
||||
{
|
||||
Self {
|
||||
data: module.vec_znx_dft_alloc(n, rank + 1, k.div_ceil(basek)),
|
||||
basek,
|
||||
k,
|
||||
dist: Distribution::NONE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rank: usize) -> usize
|
||||
where
|
||||
Module<B>: VecZnxDftAllocBytes,
|
||||
{
|
||||
module.vec_znx_dft_alloc_bytes(n, rank + 1, k.div_ceil(basek))
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWEPublicKeyPrepared<Vec<u8>, B>> for GLWEPublicKey<D>
|
||||
where
|
||||
Module<B>: VecZnxDftAlloc<B> + VecZnxDftFromVecZnx<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GLWEPublicKeyPrepared<Vec<u8>, B> {
|
||||
let mut pk_prepared: GLWEPublicKeyPrepared<Vec<u8>, B> =
|
||||
GLWEPublicKeyPrepared::alloc(module, self.n(), self.basek(), self.k(), self.rank());
|
||||
pk_prepared.prepare(module, self, scratch);
|
||||
pk_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWEPublicKey<DR>> for GLWEPublicKeyPrepared<DM, B>
|
||||
where
|
||||
Module<B>: VecZnxDftFromVecZnx<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GLWEPublicKey<DR>, _scratch: &mut Scratch<B>) {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
assert_eq!(self.n(), other.n());
|
||||
assert_eq!(self.size(), other.size());
|
||||
}
|
||||
|
||||
(0..self.cols()).for_each(|i| {
|
||||
module.vec_znx_dft_from_vec_znx(1, 0, &mut self.data, i, &other.data, i);
|
||||
});
|
||||
self.k = other.k;
|
||||
self.basek = other.basek;
|
||||
self.dist = other.dist;
|
||||
}
|
||||
}
|
||||
77
poulpy-core/src/layouts/prepared/glwe_sk.rs
Normal file
77
poulpy-core/src/layouts/prepared/glwe_sk.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{SvpPPolAlloc, SvpPPolAllocBytes, SvpPrepare, ZnxInfos},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, SvpPPol},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
dist::Distribution,
|
||||
layouts::{
|
||||
GLWESecret,
|
||||
prepared::{Prepare, PrepareAlloc},
|
||||
},
|
||||
};
|
||||
|
||||
pub struct GLWESecretPrepared<D: Data, B: Backend> {
|
||||
pub(crate) data: SvpPPol<D, B>,
|
||||
pub(crate) dist: Distribution,
|
||||
}
|
||||
|
||||
impl<B: Backend> GLWESecretPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, rank: usize) -> Self
|
||||
where
|
||||
Module<B>: SvpPPolAlloc<B>,
|
||||
{
|
||||
Self {
|
||||
data: module.svp_ppol_alloc(n, rank),
|
||||
dist: Distribution::NONE,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, rank: usize) -> usize
|
||||
where
|
||||
Module<B>: SvpPPolAllocBytes,
|
||||
{
|
||||
module.svp_ppol_alloc_bytes(n, rank)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWESecretPrepared<D, B> {
|
||||
pub fn n(&self) -> usize {
|
||||
self.data.n()
|
||||
}
|
||||
|
||||
pub fn log_n(&self) -> usize {
|
||||
self.data.log_n()
|
||||
}
|
||||
|
||||
pub fn rank(&self) -> usize {
|
||||
self.data.cols()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWESecretPrepared<Vec<u8>, B>> for GLWESecret<D>
|
||||
where
|
||||
Module<B>: SvpPrepare<B> + SvpPPolAlloc<B>,
|
||||
{
|
||||
fn prepare_alloc(
|
||||
&self,
|
||||
module: &Module<B>,
|
||||
scratch: &mut poulpy_backend::hal::layouts::Scratch<B>,
|
||||
) -> GLWESecretPrepared<Vec<u8>, B> {
|
||||
let mut sk_dft: GLWESecretPrepared<Vec<u8>, B> = GLWESecretPrepared::alloc(module, self.n(), self.rank());
|
||||
sk_dft.prepare(module, self, scratch);
|
||||
sk_dft
|
||||
}
|
||||
}
|
||||
|
||||
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWESecret<DR>> for GLWESecretPrepared<DM, B>
|
||||
where
|
||||
Module<B>: SvpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GLWESecret<DR>, _scratch: &mut poulpy_backend::hal::layouts::Scratch<B>) {
|
||||
(0..self.rank()).for_each(|i| {
|
||||
module.svp_prepare(&mut self.data, i, &other.data, i);
|
||||
});
|
||||
self.dist = other.dist
|
||||
}
|
||||
}
|
||||
91
poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rs
Normal file
91
poulpy-core/src/layouts/prepared/glwe_to_lwe_ksk.rs
Normal file
@@ -0,0 +1,91 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
GLWEToLWESwitchingKey, Infos,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GLWEToLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
|
||||
|
||||
impl<D: Data, B: Backend> Infos for GLWEToLWESwitchingKeyPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
self.0.inner()
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.0.basek()
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.0.k()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEToLWESwitchingKeyPrepared<D, B> {
|
||||
pub fn digits(&self) -> usize {
|
||||
self.0.digits()
|
||||
}
|
||||
|
||||
pub fn rank(&self) -> usize {
|
||||
self.0.rank()
|
||||
}
|
||||
|
||||
pub fn rank_in(&self) -> usize {
|
||||
self.0.rank_in()
|
||||
}
|
||||
|
||||
pub fn rank_out(&self) -> usize {
|
||||
self.0.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, rank_in: usize) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
Self(GGLWESwitchingKeyPrepared::alloc(
|
||||
module, n, basek, k, rows, 1, rank_in, 1,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_in: usize) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::<Vec<u8>, B>::bytes_of(module, n, basek, k, rows, digits, rank_in, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>> for GLWEToLWESwitchingKey<D>
|
||||
where
|
||||
Module<B>: VmpPrepare<B> + VmpPMatAlloc<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
let mut ksk_prepared: GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> = GLWEToLWESwitchingKeyPrepared::alloc(
|
||||
module,
|
||||
self.0.n(),
|
||||
self.0.basek(),
|
||||
self.0.k(),
|
||||
self.0.rows(),
|
||||
self.0.rank_in(),
|
||||
);
|
||||
ksk_prepared.prepare(module, self, scratch);
|
||||
ksk_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWEToLWESwitchingKey<DR>> for GLWEToLWESwitchingKeyPrepared<DM, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GLWEToLWESwitchingKey<DR>, scratch: &mut Scratch<B>) {
|
||||
self.0.prepare(module, &other.0, scratch);
|
||||
}
|
||||
}
|
||||
90
poulpy-core/src/layouts/prepared/lwe_ksk.rs
Normal file
90
poulpy-core/src/layouts/prepared/lwe_ksk.rs
Normal file
@@ -0,0 +1,90 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Infos, LWESwitchingKey,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct LWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
|
||||
|
||||
impl<D: Data, B: Backend> Infos for LWESwitchingKeyPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
self.0.inner()
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.0.basek()
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.0.k()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWESwitchingKeyPrepared<D, B> {
|
||||
pub fn digits(&self) -> usize {
|
||||
self.0.digits()
|
||||
}
|
||||
|
||||
pub fn rank(&self) -> usize {
|
||||
self.0.rank()
|
||||
}
|
||||
|
||||
pub fn rank_in(&self) -> usize {
|
||||
self.0.rank_in()
|
||||
}
|
||||
|
||||
pub fn rank_out(&self) -> usize {
|
||||
self.0.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
Self(GGLWESwitchingKeyPrepared::alloc(
|
||||
module, n, basek, k, rows, 1, 1, 1,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::<Vec<u8>, B>::bytes_of(module, n, basek, k, rows, digits, 1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, LWESwitchingKeyPrepared<Vec<u8>, B>> for LWESwitchingKey<D>
|
||||
where
|
||||
Module<B>: VmpPrepare<B> + VmpPMatAlloc<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> LWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
let mut ksk_prepared: LWESwitchingKeyPrepared<Vec<u8>, B> = LWESwitchingKeyPrepared::alloc(
|
||||
module,
|
||||
self.0.n(),
|
||||
self.0.basek(),
|
||||
self.0.k(),
|
||||
self.0.rows(),
|
||||
);
|
||||
ksk_prepared.prepare(module, self, scratch);
|
||||
ksk_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, LWESwitchingKey<DR>> for LWESwitchingKeyPrepared<DM, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &LWESwitchingKey<DR>, scratch: &mut Scratch<B>) {
|
||||
self.0.prepare(module, &other.0, scratch);
|
||||
}
|
||||
}
|
||||
92
poulpy-core/src/layouts/prepared/lwe_to_glwe_ksk.rs
Normal file
92
poulpy-core/src/layouts/prepared/lwe_to_glwe_ksk.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use poulpy_backend::hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Infos, LWEToGLWESwitchingKey,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc},
|
||||
};
|
||||
|
||||
/// A special [GLWESwitchingKey] required to for the conversion from [LWECiphertext] to [GLWECiphertext].
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct LWEToGLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
|
||||
|
||||
impl<D: Data, B: Backend> Infos for LWEToGLWESwitchingKeyPrepared<D, B> {
|
||||
type Inner = VmpPMat<D, B>;
|
||||
|
||||
fn inner(&self) -> &Self::Inner {
|
||||
self.0.inner()
|
||||
}
|
||||
|
||||
fn basek(&self) -> usize {
|
||||
self.0.basek()
|
||||
}
|
||||
|
||||
fn k(&self) -> usize {
|
||||
self.0.k()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWEToGLWESwitchingKeyPrepared<D, B> {
|
||||
pub fn digits(&self) -> usize {
|
||||
self.0.digits()
|
||||
}
|
||||
|
||||
pub fn rank(&self) -> usize {
|
||||
self.0.rank()
|
||||
}
|
||||
|
||||
pub fn rank_in(&self) -> usize {
|
||||
self.0.rank_in()
|
||||
}
|
||||
|
||||
pub fn rank_out(&self) -> usize {
|
||||
self.0.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, rank_out: usize) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
Self(GGLWESwitchingKeyPrepared::alloc(
|
||||
module, n, basek, k, rows, 1, 1, rank_out,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn bytes_of(module: &Module<B>, n: usize, basek: usize, k: usize, rows: usize, digits: usize, rank_out: usize) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::<Vec<u8>, B>::bytes_of(module, n, basek, k, rows, digits, 1, rank_out)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, LWEToGLWESwitchingKeyPrepared<Vec<u8>, B>> for LWEToGLWESwitchingKey<D>
|
||||
where
|
||||
Module<B>: VmpPrepare<B> + VmpPMatAlloc<B>,
|
||||
{
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
let mut ksk_prepared: LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> = LWEToGLWESwitchingKeyPrepared::alloc(
|
||||
module,
|
||||
self.0.n(),
|
||||
self.0.basek(),
|
||||
self.0.k(),
|
||||
self.0.rows(),
|
||||
self.0.rank_out(),
|
||||
);
|
||||
ksk_prepared.prepare(module, self, scratch);
|
||||
ksk_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, LWEToGLWESwitchingKey<DR>> for LWEToGLWESwitchingKeyPrepared<DM, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn prepare(&mut self, module: &Module<B>, other: &LWEToGLWESwitchingKey<DR>, scratch: &mut Scratch<B>) {
|
||||
self.0.prepare(module, &other.0, scratch);
|
||||
}
|
||||
}
|
||||
30
poulpy-core/src/layouts/prepared/mod.rs
Normal file
30
poulpy-core/src/layouts/prepared/mod.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
mod gglwe_atk;
|
||||
mod gglwe_ct;
|
||||
mod gglwe_ksk;
|
||||
mod gglwe_tsk;
|
||||
mod ggsw_ct;
|
||||
mod glwe_pk;
|
||||
mod glwe_sk;
|
||||
mod glwe_to_lwe_ksk;
|
||||
mod lwe_ksk;
|
||||
mod lwe_to_glwe_ksk;
|
||||
|
||||
pub use gglwe_atk::*;
|
||||
pub use gglwe_ct::*;
|
||||
pub use gglwe_ksk::*;
|
||||
pub use gglwe_tsk::*;
|
||||
pub use ggsw_ct::*;
|
||||
pub use glwe_pk::*;
|
||||
pub use glwe_sk::*;
|
||||
pub use glwe_to_lwe_ksk::*;
|
||||
pub use lwe_ksk::*;
|
||||
pub use lwe_to_glwe_ksk::*;
|
||||
use poulpy_backend::hal::layouts::{Backend, Module, Scratch};
|
||||
|
||||
pub trait PrepareAlloc<B: Backend, T> {
|
||||
fn prepare_alloc(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> T;
|
||||
}
|
||||
|
||||
pub trait Prepare<B: Backend, T> {
|
||||
fn prepare(&mut self, module: &Module<B>, other: &T, scratch: &mut Scratch<B>);
|
||||
}
|
||||
Reference in New Issue
Block a user