mirror of
https://github.com/arnaucube/poulpy.git
synced 2026-02-10 21:26:41 +01:00
wip
This commit is contained in:
@@ -5,19 +5,19 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEAutomorphismKey, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GGLWEKeyCompressed, GGLWEKeyCompressedToMut, GGLWEKeyCompressedToRef},
|
||||
AutomorphismKey, Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedToMut, GLWESwitchingKeyCompressedToRef},
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGLWEAutomorphismKeyCompressed<D: Data> {
|
||||
pub(crate) key: GGLWEKeyCompressed<D>,
|
||||
pub struct AutomorphismKeyCompressed<D: Data> {
|
||||
pub(crate) key: GLWESwitchingKeyCompressed<D>,
|
||||
pub(crate) p: i64,
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: Data> LWEInfos for AutomorphismKeyCompressed<D> {
|
||||
fn n(&self) -> Degree {
|
||||
self.key.n()
|
||||
}
|
||||
@@ -34,13 +34,13 @@ impl<D: Data> LWEInfos for GGLWEAutomorphismKeyCompressed<D> {
|
||||
self.key.size()
|
||||
}
|
||||
}
|
||||
impl<D: Data> GLWEInfos for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: Data> GLWEInfos for AutomorphismKeyCompressed<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEInfos for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: Data> GGLWEInfos for AutomorphismKeyCompressed<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.key.rank_in()
|
||||
}
|
||||
@@ -58,39 +58,39 @@ impl<D: Data> GGLWEInfos for GGLWEAutomorphismKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: DataRef> fmt::Debug for AutomorphismKeyCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: DataMut> FillUniform for AutomorphismKeyCompressed<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.key.fill_uniform(log_bound, source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: DataRef> fmt::Display for AutomorphismKeyCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "(AutomorphismKeyCompressed: p={}) {}", self.p, self.key)
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWEAutomorphismKeyCompressed<Vec<u8>> {
|
||||
impl AutomorphismKeyCompressed<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
debug_assert_eq!(infos.rank_in(), infos.rank_out());
|
||||
Self {
|
||||
key: GGLWEKeyCompressed::alloc(infos),
|
||||
key: GLWESwitchingKeyCompressed::alloc(infos),
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
||||
Self {
|
||||
key: GGLWEKeyCompressed::alloc_with(n, base2k, k, rank, rank, dnum, dsize),
|
||||
key: GLWESwitchingKeyCompressed::alloc_with(n, base2k, k, rank, rank, dnum, dsize),
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
@@ -100,64 +100,64 @@ impl GGLWEAutomorphismKeyCompressed<Vec<u8>> {
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
debug_assert_eq!(infos.rank_in(), infos.rank_out());
|
||||
GGLWEKeyCompressed::alloc_bytes(infos)
|
||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||
GGLWEKeyCompressed::alloc_bytes_with(n, base2k, k, rank, dnum, dsize)
|
||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rank, dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: DataMut> ReaderFrom for AutomorphismKeyCompressed<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.p = reader.read_u64::<LittleEndian>()? as i64;
|
||||
self.key.read_from(reader)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGLWEAutomorphismKeyCompressed<D> {
|
||||
impl<D: DataRef> WriterTo for AutomorphismKeyCompressed<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write_u64::<LittleEndian>(self.p as u64)?;
|
||||
self.key.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, GGLWEAutomorphismKeyCompressed<DR>> for GGLWEAutomorphismKey<D>
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, AutomorphismKeyCompressed<DR>> for AutomorphismKey<D>
|
||||
where
|
||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
||||
{
|
||||
fn decompress(&mut self, module: &Module<B>, other: &GGLWEAutomorphismKeyCompressed<DR>) {
|
||||
fn decompress(&mut self, module: &Module<B>, other: &AutomorphismKeyCompressed<DR>) {
|
||||
self.key.decompress(module, &other.key);
|
||||
self.p = other.p;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEAutomorphismKeyCompressedToRef {
|
||||
fn to_ref(&self) -> GGLWEAutomorphismKeyCompressed<&[u8]>;
|
||||
pub trait AutomorphismKeyCompressedToRef {
|
||||
fn to_ref(&self) -> AutomorphismKeyCompressed<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWEAutomorphismKeyCompressedToRef for GGLWEAutomorphismKeyCompressed<D>
|
||||
impl<D: DataRef> AutomorphismKeyCompressedToRef for AutomorphismKeyCompressed<D>
|
||||
where
|
||||
GGLWEKeyCompressed<D>: GGLWEKeyCompressedToRef,
|
||||
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToRef,
|
||||
{
|
||||
fn to_ref(&self) -> GGLWEAutomorphismKeyCompressed<&[u8]> {
|
||||
GGLWEAutomorphismKeyCompressed {
|
||||
fn to_ref(&self) -> AutomorphismKeyCompressed<&[u8]> {
|
||||
AutomorphismKeyCompressed {
|
||||
key: self.key.to_ref(),
|
||||
p: self.p,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEAutomorphismKeyCompressedToMut {
|
||||
fn to_mut(&mut self) -> GGLWEAutomorphismKeyCompressed<&mut [u8]>;
|
||||
pub trait AutomorphismKeyCompressedToMut {
|
||||
fn to_mut(&mut self) -> AutomorphismKeyCompressed<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWEAutomorphismKeyCompressedToMut for GGLWEAutomorphismKeyCompressed<D>
|
||||
impl<D: DataMut> AutomorphismKeyCompressedToMut for AutomorphismKeyCompressed<D>
|
||||
where
|
||||
GGLWEKeyCompressed<D>: GGLWEKeyCompressedToMut,
|
||||
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> GGLWEAutomorphismKeyCompressed<&mut [u8]> {
|
||||
GGLWEAutomorphismKeyCompressed {
|
||||
fn to_mut(&mut self) -> AutomorphismKeyCompressed<&mut [u8]> {
|
||||
AutomorphismKeyCompressed {
|
||||
p: self.p,
|
||||
key: self.key.to_mut(),
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWECiphertext, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GLWECiphertextCompressed},
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
@@ -235,7 +235,7 @@ impl<D: DataRef> WriterTo for GGLWECiphertextCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GGLWECiphertextCompressed<DR>> for GGLWECiphertext<D>
|
||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GGLWECiphertextCompressed<DR>> for GGLWE<D>
|
||||
where
|
||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
||||
{
|
||||
@@ -313,7 +313,7 @@ pub trait GGLWECiphertextCompressedToRef {
|
||||
fn to_ref(&self) -> GGLWECiphertextCompressed<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWECiphertextCompressedToRef for GGLWECiphertextCompressed<D> {
|
||||
impl<D: DataRef> GGLWECiphertextCompressedToRef for GGLWECiphertextCompressed<D> {
|
||||
fn to_ref(&self) -> GGLWECiphertextCompressed<&[u8]> {
|
||||
GGLWECiphertextCompressed {
|
||||
k: self.k(),
|
||||
|
||||
@@ -5,20 +5,20 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, LWEInfos, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GGLWECiphertextCompressed, GGLWECiphertextCompressedToMut, GGLWECiphertextCompressedToRef},
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGLWEKeyCompressed<D: Data> {
|
||||
pub struct GLWESwitchingKeyCompressed<D: Data> {
|
||||
pub(crate) key: GGLWECiphertextCompressed<D>,
|
||||
pub(crate) sk_in_n: usize, // Degree of sk_in
|
||||
pub(crate) sk_out_n: usize, // Degree of sk_out
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGLWEKeyCompressed<D> {
|
||||
impl<D: Data> LWEInfos for GLWESwitchingKeyCompressed<D> {
|
||||
fn n(&self) -> Degree {
|
||||
self.key.n()
|
||||
}
|
||||
@@ -35,13 +35,13 @@ impl<D: Data> LWEInfos for GGLWEKeyCompressed<D> {
|
||||
self.key.size()
|
||||
}
|
||||
}
|
||||
impl<D: Data> GLWEInfos for GGLWEKeyCompressed<D> {
|
||||
impl<D: Data> GLWEInfos for GLWESwitchingKeyCompressed<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEInfos for GGLWEKeyCompressed<D> {
|
||||
impl<D: Data> GGLWEInfos for GLWESwitchingKeyCompressed<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.key.rank_in()
|
||||
}
|
||||
@@ -59,19 +59,19 @@ impl<D: Data> GGLWEInfos for GGLWEKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGLWEKeyCompressed<D> {
|
||||
impl<D: DataRef> fmt::Debug for GLWESwitchingKeyCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGLWEKeyCompressed<D> {
|
||||
impl<D: DataMut> FillUniform for GLWESwitchingKeyCompressed<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.key.fill_uniform(log_bound, source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGLWEKeyCompressed<D> {
|
||||
impl<D: DataRef> fmt::Display for GLWESwitchingKeyCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
@@ -81,12 +81,12 @@ impl<D: DataRef> fmt::Display for GGLWEKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWEKeyCompressed<Vec<u8>> {
|
||||
impl GLWESwitchingKeyCompressed<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
GGLWEKeyCompressed {
|
||||
GLWESwitchingKeyCompressed {
|
||||
key: GGLWECiphertextCompressed::alloc(infos),
|
||||
sk_in_n: 0,
|
||||
sk_out_n: 0,
|
||||
@@ -102,7 +102,7 @@ impl GGLWEKeyCompressed<Vec<u8>> {
|
||||
dnum: Dnum,
|
||||
dsize: Dsize,
|
||||
) -> Self {
|
||||
GGLWEKeyCompressed {
|
||||
GLWESwitchingKeyCompressed {
|
||||
key: GGLWECiphertextCompressed::alloc_with(n, base2k, k, rank_in, rank_out, dnum, dsize),
|
||||
sk_in_n: 0,
|
||||
sk_out_n: 0,
|
||||
@@ -121,7 +121,7 @@ impl GGLWEKeyCompressed<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGLWEKeyCompressed<D> {
|
||||
impl<D: DataMut> ReaderFrom for GLWESwitchingKeyCompressed<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.sk_in_n = reader.read_u64::<LittleEndian>()? as usize;
|
||||
self.sk_out_n = reader.read_u64::<LittleEndian>()? as usize;
|
||||
@@ -129,7 +129,7 @@ impl<D: DataMut> ReaderFrom for GGLWEKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGLWEKeyCompressed<D> {
|
||||
impl<D: DataRef> WriterTo for GLWESwitchingKeyCompressed<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write_u64::<LittleEndian>(self.sk_in_n as u64)?;
|
||||
writer.write_u64::<LittleEndian>(self.sk_out_n as u64)?;
|
||||
@@ -137,27 +137,27 @@ impl<D: DataRef> WriterTo for GGLWEKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, GGLWEKeyCompressed<DR>> for GGLWESwitchingKey<D>
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, GLWESwitchingKeyCompressed<DR>> for GLWESwitchingKey<D>
|
||||
where
|
||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
||||
{
|
||||
fn decompress(&mut self, module: &Module<B>, other: &GGLWEKeyCompressed<DR>) {
|
||||
fn decompress(&mut self, module: &Module<B>, other: &GLWESwitchingKeyCompressed<DR>) {
|
||||
self.key.decompress(module, &other.key);
|
||||
self.sk_in_n = other.sk_in_n;
|
||||
self.sk_out_n = other.sk_out_n;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEKeyCompressedToMut {
|
||||
fn to_mut(&mut self) -> GGLWEKeyCompressed<&mut [u8]>;
|
||||
pub trait GLWESwitchingKeyCompressedToMut {
|
||||
fn to_mut(&mut self) -> GLWESwitchingKeyCompressed<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWEKeyCompressedToMut for GGLWEKeyCompressed<D>
|
||||
impl<D: DataMut> GLWESwitchingKeyCompressedToMut for GLWESwitchingKeyCompressed<D>
|
||||
where
|
||||
GGLWECiphertextCompressed<D>: GGLWECiphertextCompressedToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> GGLWEKeyCompressed<&mut [u8]> {
|
||||
GGLWEKeyCompressed {
|
||||
fn to_mut(&mut self) -> GLWESwitchingKeyCompressed<&mut [u8]> {
|
||||
GLWESwitchingKeyCompressed {
|
||||
sk_in_n: self.sk_in_n,
|
||||
sk_out_n: self.sk_out_n,
|
||||
key: self.key.to_mut(),
|
||||
@@ -165,16 +165,16 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEKeyCompressedToRef {
|
||||
fn to_ref(&self) -> GGLWEKeyCompressed<&[u8]>;
|
||||
pub trait GLWESwitchingKeyCompressedToRef {
|
||||
fn to_ref(&self) -> GLWESwitchingKeyCompressed<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWEKeyCompressedToRef for GGLWEKeyCompressed<D>
|
||||
impl<D: DataRef> GLWESwitchingKeyCompressedToRef for GLWESwitchingKeyCompressed<D>
|
||||
where
|
||||
GGLWECiphertextCompressed<D>: GGLWECiphertextCompressedToRef,
|
||||
{
|
||||
fn to_ref(&self) -> GGLWEKeyCompressed<&[u8]> {
|
||||
GGLWEKeyCompressed {
|
||||
fn to_ref(&self) -> GLWESwitchingKeyCompressed<&[u8]> {
|
||||
GLWESwitchingKeyCompressed {
|
||||
sk_in_n: self.sk_in_n,
|
||||
sk_out_n: self.sk_out_n,
|
||||
key: self.key.to_ref(),
|
||||
|
||||
@@ -5,18 +5,18 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWETensorKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GGLWEKeyCompressed, GGLWEKeyCompressedToMut, GGLWEKeyCompressedToRef},
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TensorKey, TorusPrecision,
|
||||
compressed::{Decompress, GLWESwitchingKeyCompressed, GLWESwitchingKeyCompressedToMut, GLWESwitchingKeyCompressedToRef},
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGLWETensorKeyCompressed<D: Data> {
|
||||
pub(crate) keys: Vec<GGLWEKeyCompressed<D>>,
|
||||
pub struct TensorKeyCompressed<D: Data> {
|
||||
pub(crate) keys: Vec<GLWESwitchingKeyCompressed<D>>,
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: Data> LWEInfos for TensorKeyCompressed<D> {
|
||||
fn n(&self) -> Degree {
|
||||
self.keys[0].n()
|
||||
}
|
||||
@@ -32,13 +32,13 @@ impl<D: Data> LWEInfos for GGLWETensorKeyCompressed<D> {
|
||||
self.keys[0].size()
|
||||
}
|
||||
}
|
||||
impl<D: Data> GLWEInfos for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: Data> GLWEInfos for TensorKeyCompressed<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEInfos for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: Data> GGLWEInfos for TensorKeyCompressed<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
@@ -56,21 +56,21 @@ impl<D: Data> GGLWEInfos for GGLWETensorKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: DataRef> fmt::Debug for TensorKeyCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: DataMut> FillUniform for TensorKeyCompressed<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.keys
|
||||
.iter_mut()
|
||||
.for_each(|key: &mut GGLWEKeyCompressed<D>| key.fill_uniform(log_bound, source))
|
||||
.for_each(|key: &mut GLWESwitchingKeyCompressed<D>| key.fill_uniform(log_bound, source))
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: DataRef> fmt::Display for TensorKeyCompressed<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "(GLWETensorKeyCompressed)",)?;
|
||||
for (i, key) in self.keys.iter().enumerate() {
|
||||
@@ -80,7 +80,7 @@ impl<D: DataRef> fmt::Display for GGLWETensorKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWETensorKeyCompressed<Vec<u8>> {
|
||||
impl TensorKeyCompressed<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -101,10 +101,10 @@ impl GGLWETensorKeyCompressed<Vec<u8>> {
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
||||
let mut keys: Vec<GGLWEKeyCompressed<Vec<u8>>> = Vec::new();
|
||||
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(GGLWEKeyCompressed::alloc_with(
|
||||
keys.push(GLWESwitchingKeyCompressed::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -129,7 +129,7 @@ impl GGLWETensorKeyCompressed<Vec<u8>> {
|
||||
let rank_out: usize = infos.rank_out().into();
|
||||
let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1);
|
||||
pairs
|
||||
* GGLWEKeyCompressed::alloc_bytes_with(
|
||||
* GLWESwitchingKeyCompressed::alloc_bytes_with(
|
||||
infos.n(),
|
||||
infos.base2k(),
|
||||
infos.k(),
|
||||
@@ -141,11 +141,11 @@ impl GGLWETensorKeyCompressed<Vec<u8>> {
|
||||
|
||||
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;
|
||||
pairs * GGLWEKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, dsize)
|
||||
pairs * GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: DataMut> ReaderFrom for TensorKeyCompressed<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
let len: usize = reader.read_u64::<LittleEndian>()? as usize;
|
||||
if self.keys.len() != len {
|
||||
@@ -161,7 +161,7 @@ impl<D: DataMut> ReaderFrom for GGLWETensorKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGLWETensorKeyCompressed<D> {
|
||||
impl<D: DataRef> WriterTo for TensorKeyCompressed<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write_u64::<LittleEndian>(self.keys.len() as u64)?;
|
||||
for key in &self.keys {
|
||||
@@ -171,8 +171,8 @@ impl<D: DataRef> WriterTo for GGLWETensorKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWETensorKeyCompressed<D> {
|
||||
pub(crate) fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWEKeyCompressed<D> {
|
||||
impl<D: DataMut> TensorKeyCompressed<D> {
|
||||
pub(crate) fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GLWESwitchingKeyCompressed<D> {
|
||||
if i > j {
|
||||
std::mem::swap(&mut i, &mut j);
|
||||
};
|
||||
@@ -181,11 +181,11 @@ impl<D: DataMut> GGLWETensorKeyCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, GGLWETensorKeyCompressed<DR>> for GGLWETensorKey<D>
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Decompress<B, TensorKeyCompressed<DR>> for TensorKey<D>
|
||||
where
|
||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
||||
{
|
||||
fn decompress(&mut self, module: &Module<B>, other: &GGLWETensorKeyCompressed<DR>) {
|
||||
fn decompress(&mut self, module: &Module<B>, other: &TensorKeyCompressed<DR>) {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
assert_eq!(
|
||||
@@ -206,31 +206,31 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWETensorKeyCompressedToMut {
|
||||
fn to_mut(&mut self) -> GGLWETensorKeyCompressed<&mut [u8]>;
|
||||
pub trait TensorKeyCompressedToMut {
|
||||
fn to_mut(&mut self) -> TensorKeyCompressed<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWETensorKeyCompressedToMut for GGLWETensorKeyCompressed<D>
|
||||
impl<D: DataMut> TensorKeyCompressedToMut for TensorKeyCompressed<D>
|
||||
where
|
||||
GGLWEKeyCompressed<D>: GGLWEKeyCompressedToMut,
|
||||
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> GGLWETensorKeyCompressed<&mut [u8]> {
|
||||
GGLWETensorKeyCompressed {
|
||||
fn to_mut(&mut self) -> TensorKeyCompressed<&mut [u8]> {
|
||||
TensorKeyCompressed {
|
||||
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWETensorKeyCompressedToRef {
|
||||
fn to_ref(&self) -> GGLWETensorKeyCompressed<&[u8]>;
|
||||
pub trait TensorKeyCompressedToRef {
|
||||
fn to_ref(&self) -> TensorKeyCompressed<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWETensorKeyCompressedToRef for GGLWETensorKeyCompressed<D>
|
||||
impl<D: DataRef> TensorKeyCompressedToRef for TensorKeyCompressed<D>
|
||||
where
|
||||
GGLWEKeyCompressed<D>: GGLWEKeyCompressedToRef,
|
||||
GLWESwitchingKeyCompressed<D>: GLWESwitchingKeyCompressedToRef,
|
||||
{
|
||||
fn to_ref(&self) -> GGLWETensorKeyCompressed<&[u8]> {
|
||||
GGLWETensorKeyCompressed {
|
||||
fn to_ref(&self) -> TensorKeyCompressed<&[u8]> {
|
||||
TensorKeyCompressed {
|
||||
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGSWCiphertext, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
Base2K, Degree, Dnum, Dsize, GGSW, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GLWECiphertextCompressed},
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
@@ -217,7 +217,7 @@ impl<D: DataRef> WriterTo for GGSWCiphertextCompressed<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GGSWCiphertextCompressed<DR>> for GGSWCiphertext<D>
|
||||
impl<D: DataMut, B: Backend, DR: DataRef> Decompress<B, GGSWCiphertextCompressed<DR>> for GGSW<D>
|
||||
where
|
||||
Module<B>: VecZnxFillUniform + VecZnxCopy,
|
||||
{
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use poulpy_hal::{
|
||||
api::{VecZnxCopy, VecZnxFillUniform},
|
||||
layouts::{Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, VecZnx, WriterTo, ZnxInfos},
|
||||
layouts::{
|
||||
Backend, Data, DataMut, DataRef, FillUniform, Module, ReaderFrom, VecZnx, VecZnxToMut, VecZnxToRef, WriterTo, ZnxInfos,
|
||||
},
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::layouts::{Base2K, Degree, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::Decompress};
|
||||
use crate::layouts::{
|
||||
Base2K, BuildError, Degree, GLWECiphertext, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::Decompress,
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::fmt;
|
||||
|
||||
@@ -96,6 +100,101 @@ impl GLWECiphertextCompressed<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GLWECiphertextCompressedBuilder<D: Data> {
|
||||
data: Option<VecZnx<D>>,
|
||||
base2k: Option<Base2K>,
|
||||
k: Option<TorusPrecision>,
|
||||
rank: Option<Rank>,
|
||||
}
|
||||
|
||||
impl<D: Data> GLWECiphertextCompressed<D> {
|
||||
#[inline]
|
||||
pub fn builder() -> GLWECiphertextCompressedBuilder<D> {
|
||||
GLWECiphertextCompressedBuilder {
|
||||
data: None,
|
||||
base2k: None,
|
||||
k: None,
|
||||
rank: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GLWECiphertextCompressedBuilder<Vec<u8>> {
|
||||
#[inline]
|
||||
pub fn layout<A>(mut self, layout: &A) -> Self
|
||||
where
|
||||
A: GLWEInfos,
|
||||
{
|
||||
self.data = Some(VecZnx::alloc(layout.n().into(), 1, layout.size()));
|
||||
self.base2k = Some(layout.base2k());
|
||||
self.k = Some(layout.k());
|
||||
self.rank = Some(layout.rank());
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWECiphertextCompressedBuilder<D> {
|
||||
#[inline]
|
||||
pub fn data(mut self, data: VecZnx<D>) -> Self {
|
||||
self.data = Some(data);
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
pub fn base2k(mut self, base2k: Base2K) -> Self {
|
||||
self.base2k = Some(base2k);
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
pub fn k(mut self, k: TorusPrecision) -> Self {
|
||||
self.k = Some(k);
|
||||
self
|
||||
}
|
||||
#[inline]
|
||||
pub fn rank(mut self, rank: Rank) -> Self {
|
||||
self.rank = Some(rank);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<GLWECiphertextCompressed<D>, BuildError> {
|
||||
let data: VecZnx<D> = self.data.ok_or(BuildError::MissingData)?;
|
||||
let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?;
|
||||
let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?;
|
||||
let rank: Rank = self.rank.ok_or(BuildError::MissingK)?;
|
||||
|
||||
if base2k == 0_u32 {
|
||||
return Err(BuildError::ZeroBase2K);
|
||||
}
|
||||
|
||||
if k == 0_u32 {
|
||||
return Err(BuildError::ZeroTorusPrecision);
|
||||
}
|
||||
|
||||
if rank == 0_u32 {
|
||||
return Err(BuildError::ZeroRank);
|
||||
}
|
||||
|
||||
if data.n() == 0 {
|
||||
return Err(BuildError::ZeroDegree);
|
||||
}
|
||||
|
||||
if data.cols() != 1 {
|
||||
return Err(BuildError::VecZnxColsNotOne);
|
||||
}
|
||||
|
||||
if data.size() == 0 {
|
||||
return Err(BuildError::ZeroLimbs);
|
||||
}
|
||||
|
||||
Ok(GLWECiphertextCompressed {
|
||||
data,
|
||||
base2k,
|
||||
k,
|
||||
rank,
|
||||
seed: [0u8; 32],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GLWECiphertextCompressed<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||
@@ -176,3 +275,35 @@ impl<D: DataMut> GLWECiphertext<D> {
|
||||
self.k = other.k;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWECiphertextCompressedToRef {
|
||||
fn to_ref(&self) -> GLWECiphertextCompressed<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GLWECiphertextCompressedToRef for GLWECiphertextCompressed<D> {
|
||||
fn to_ref(&self) -> GLWECiphertextCompressed<&[u8]> {
|
||||
GLWECiphertextCompressed::builder()
|
||||
.k(self.k())
|
||||
.base2k(self.base2k())
|
||||
.rank(self.rank())
|
||||
.data(self.data.to_ref())
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWECiphertextCompressedToMut {
|
||||
fn to_mut(&mut self) -> GLWECiphertextCompressed<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GLWECiphertextCompressedToMut for GLWECiphertextCompressed<D> {
|
||||
fn to_mut(&mut self) -> GLWECiphertextCompressed<&mut [u8]> {
|
||||
GLWECiphertextCompressed::builder()
|
||||
.k(self.k())
|
||||
.base2k(self.base2k())
|
||||
.rank(self.rank())
|
||||
.data(self.data.to_mut())
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::GGLWEKeyCompressed,
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::GLWESwitchingKeyCompressed,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GLWEToLWESwitchingKeyCompressed<D: Data>(pub(crate) GGLWEKeyCompressed<D>);
|
||||
pub struct GLWEToLWESwitchingKeyCompressed<D: Data>(pub(crate) GLWESwitchingKeyCompressed<D>);
|
||||
|
||||
impl<D: Data> LWEInfos for GLWEToLWESwitchingKeyCompressed<D> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
@@ -98,11 +98,11 @@ impl GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
|
||||
1,
|
||||
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
||||
);
|
||||
Self(GGLWEKeyCompressed::alloc(infos))
|
||||
Self(GLWESwitchingKeyCompressed::alloc(infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self {
|
||||
Self(GGLWEKeyCompressed::alloc_with(
|
||||
Self(GLWESwitchingKeyCompressed::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -127,10 +127,10 @@ impl GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
|
||||
1,
|
||||
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
|
||||
);
|
||||
GGLWEKeyCompressed::alloc_bytes(infos)
|
||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_in: Rank) -> usize {
|
||||
GGLWEKeyCompressed::alloc_bytes_with(n, base2k, k, rank_in, dnum, Dsize(1))
|
||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rank_in, dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@ use poulpy_hal::{
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GGLWEKeyCompressed},
|
||||
compressed::{Decompress, GLWESwitchingKeyCompressed},
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct LWESwitchingKeyCompressed<D: Data>(pub(crate) GGLWEKeyCompressed<D>);
|
||||
pub struct LWESwitchingKeyCompressed<D: Data>(pub(crate) GLWESwitchingKeyCompressed<D>);
|
||||
|
||||
impl<D: Data> LWEInfos for LWESwitchingKeyCompressed<D> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
@@ -103,11 +103,11 @@ impl LWESwitchingKeyCompressed<Vec<u8>> {
|
||||
1,
|
||||
"rank_out > 1 is not supported for LWESwitchingKeyCompressed"
|
||||
);
|
||||
Self(GGLWEKeyCompressed::alloc(infos))
|
||||
Self(GLWESwitchingKeyCompressed::alloc(infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
|
||||
Self(GGLWEKeyCompressed::alloc_with(
|
||||
Self(GLWESwitchingKeyCompressed::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -137,11 +137,11 @@ impl LWESwitchingKeyCompressed<Vec<u8>> {
|
||||
1,
|
||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||
);
|
||||
GGLWEKeyCompressed::alloc_bytes(infos)
|
||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||
GGLWEKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
|
||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,12 @@ use poulpy_hal::{
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, Rank, TorusPrecision,
|
||||
compressed::{Decompress, GGLWEKeyCompressed},
|
||||
compressed::{Decompress, GLWESwitchingKeyCompressed},
|
||||
};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct LWEToGLWESwitchingKeyCompressed<D: Data>(pub(crate) GGLWEKeyCompressed<D>);
|
||||
pub struct LWEToGLWESwitchingKeyCompressed<D: Data>(pub(crate) GLWESwitchingKeyCompressed<D>);
|
||||
|
||||
impl<D: Data> LWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
|
||||
fn n(&self) -> Degree {
|
||||
@@ -98,11 +98,11 @@ impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
|
||||
1,
|
||||
"rank_in > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
|
||||
);
|
||||
Self(GGLWEKeyCompressed::alloc(infos))
|
||||
Self(GLWESwitchingKeyCompressed::alloc(infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
|
||||
Self(GGLWEKeyCompressed::alloc_with(
|
||||
Self(GLWESwitchingKeyCompressed::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -127,11 +127,11 @@ impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
|
||||
1,
|
||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||
);
|
||||
GGLWEKeyCompressed::alloc_bytes(infos)
|
||||
GLWESwitchingKeyCompressed::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||
GGLWEKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
|
||||
GLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,15 +4,15 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GGLWESwitchingKeyToMut, GLWECiphertext, GLWEInfos, LWEInfos,
|
||||
Rank, TorusPrecision,
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWECiphertext, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut,
|
||||
GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub struct GGLWEAutomorphismKeyLayout {
|
||||
pub struct AutomorphismKeyLayout {
|
||||
pub n: Degree,
|
||||
pub base2k: Base2K,
|
||||
pub k: TorusPrecision,
|
||||
@@ -22,18 +22,18 @@ pub struct GGLWEAutomorphismKeyLayout {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGLWEAutomorphismKey<D: Data> {
|
||||
pub(crate) key: GGLWESwitchingKey<D>,
|
||||
pub struct AutomorphismKey<D: Data> {
|
||||
pub(crate) key: GLWESwitchingKey<D>,
|
||||
pub(crate) p: i64,
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEAutomorphismKey<D> {
|
||||
impl<D: Data> AutomorphismKey<D> {
|
||||
pub fn p(&self) -> i64 {
|
||||
self.p
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGLWEAutomorphismKey<D> {
|
||||
impl<D: Data> LWEInfos for AutomorphismKey<D> {
|
||||
fn n(&self) -> Degree {
|
||||
self.key.n()
|
||||
}
|
||||
@@ -51,13 +51,13 @@ impl<D: Data> LWEInfos for GGLWEAutomorphismKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWEInfos for GGLWEAutomorphismKey<D> {
|
||||
impl<D: Data> GLWEInfos for AutomorphismKey<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEInfos for GGLWEAutomorphismKey<D> {
|
||||
impl<D: Data> GGLWEInfos for AutomorphismKey<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.key.rank_in()
|
||||
}
|
||||
@@ -75,7 +75,7 @@ impl<D: Data> GGLWEInfos for GGLWEAutomorphismKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl LWEInfos for GGLWEAutomorphismKeyLayout {
|
||||
impl LWEInfos for AutomorphismKeyLayout {
|
||||
fn base2k(&self) -> Base2K {
|
||||
self.base2k
|
||||
}
|
||||
@@ -89,13 +89,13 @@ impl LWEInfos for GGLWEAutomorphismKeyLayout {
|
||||
}
|
||||
}
|
||||
|
||||
impl GLWEInfos for GGLWEAutomorphismKeyLayout {
|
||||
impl GLWEInfos for AutomorphismKeyLayout {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWEInfos for GGLWEAutomorphismKeyLayout {
|
||||
impl GGLWEInfos for AutomorphismKeyLayout {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.rank
|
||||
}
|
||||
@@ -113,25 +113,25 @@ impl GGLWEInfos for GGLWEAutomorphismKeyLayout {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGLWEAutomorphismKey<D> {
|
||||
impl<D: DataRef> fmt::Debug for AutomorphismKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGLWEAutomorphismKey<D> {
|
||||
impl<D: DataMut> FillUniform for AutomorphismKey<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.key.fill_uniform(log_bound, source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGLWEAutomorphismKey<D> {
|
||||
impl<D: DataRef> fmt::Display for AutomorphismKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "(AutomorphismKey: p={}) {}", self.p, self.key)
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWEAutomorphismKey<Vec<u8>> {
|
||||
impl AutomorphismKey<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -141,15 +141,15 @@ impl GGLWEAutomorphismKey<Vec<u8>> {
|
||||
infos.rank_out(),
|
||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
|
||||
);
|
||||
GGLWEAutomorphismKey {
|
||||
key: GGLWESwitchingKey::alloc(infos),
|
||||
AutomorphismKey {
|
||||
key: GLWESwitchingKey::alloc(infos),
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
||||
GGLWEAutomorphismKey {
|
||||
key: GGLWESwitchingKey::alloc_with(n, base2k, k, rank, rank, dnum, dsize),
|
||||
AutomorphismKey {
|
||||
key: GLWESwitchingKey::alloc_with(n, base2k, k, rank, rank, dnum, dsize),
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
@@ -163,54 +163,66 @@ impl GGLWEAutomorphismKey<Vec<u8>> {
|
||||
infos.rank_out(),
|
||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKey"
|
||||
);
|
||||
GGLWESwitchingKey::alloc_bytes(infos)
|
||||
GLWESwitchingKey::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
|
||||
GGLWESwitchingKey::alloc_bytes_with(n, base2k, k, rank, rank, dnum, dsize)
|
||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, rank, rank, dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEAutomorphismKeyToMut {
|
||||
fn to_mut(&mut self) -> GGLWEAutomorphismKey<&mut [u8]>;
|
||||
pub trait AutomorphismKeyToMut {
|
||||
fn to_mut(&mut self) -> AutomorphismKey<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWEAutomorphismKeyToMut for GGLWEAutomorphismKey<D>
|
||||
impl<D: DataMut> AutomorphismKeyToMut for AutomorphismKey<D>
|
||||
where
|
||||
GGLWESwitchingKey<D>: GGLWESwitchingKeyToMut,
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> GGLWEAutomorphismKey<&mut [u8]> {
|
||||
GGLWEAutomorphismKey {
|
||||
fn to_mut(&mut self) -> AutomorphismKey<&mut [u8]> {
|
||||
AutomorphismKey {
|
||||
key: self.key.to_mut(),
|
||||
p: self.p,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEAutomorphismKeyToRef {
|
||||
fn to_ref(&self) -> GGLWEAutomorphismKey<&[u8]>;
|
||||
pub trait AutomorphismKeyToRef {
|
||||
fn to_ref(&self) -> AutomorphismKey<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWEAutomorphismKey<D> {
|
||||
impl<D: DataRef> AutomorphismKeyToRef for AutomorphismKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToRef,
|
||||
{
|
||||
fn to_ref(&self) -> AutomorphismKey<&[u8]> {
|
||||
AutomorphismKey {
|
||||
p: self.p,
|
||||
key: self.key.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> AutomorphismKey<D> {
|
||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
||||
self.key.at(row, col)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWEAutomorphismKey<D> {
|
||||
impl<D: DataMut> AutomorphismKey<D> {
|
||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
||||
self.key.at_mut(row, col)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGLWEAutomorphismKey<D> {
|
||||
impl<D: DataMut> ReaderFrom for AutomorphismKey<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.p = reader.read_u64::<LittleEndian>()? as i64;
|
||||
self.key.read_from(reader)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGLWEAutomorphismKey<D> {
|
||||
impl<D: DataRef> WriterTo for AutomorphismKey<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write_u64::<LittleEndian>(self.p as u64)?;
|
||||
self.key.write_to(writer)
|
||||
|
||||
@@ -29,6 +29,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SetGGLWEInfos {
|
||||
fn set_dsize(&mut self, dsize: usize);
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub struct GGLWECiphertextLayout {
|
||||
pub n: Degree,
|
||||
@@ -79,14 +83,14 @@ impl GGLWEInfos for GGLWECiphertextLayout {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGLWECiphertext<D: Data> {
|
||||
pub struct GGLWE<D: Data> {
|
||||
pub(crate) data: MatZnx<D>,
|
||||
pub(crate) k: TorusPrecision,
|
||||
pub(crate) base2k: Base2K,
|
||||
pub(crate) dsize: Dsize,
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGLWECiphertext<D> {
|
||||
impl<D: Data> LWEInfos for GGLWE<D> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
self.base2k
|
||||
}
|
||||
@@ -104,13 +108,13 @@ impl<D: Data> LWEInfos for GGLWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWEInfos for GGLWECiphertext<D> {
|
||||
impl<D: Data> GLWEInfos for GGLWE<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEInfos for GGLWECiphertext<D> {
|
||||
impl<D: Data> GGLWEInfos for GGLWE<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
Rank(self.data.cols_in() as u32)
|
||||
}
|
||||
@@ -135,7 +139,7 @@ pub struct GGLWECiphertextBuilder<D: Data> {
|
||||
dsize: Option<Dsize>,
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWECiphertext<D> {
|
||||
impl<D: Data> GGLWE<D> {
|
||||
#[inline]
|
||||
pub fn builder() -> GGLWECiphertextBuilder<D> {
|
||||
GGLWECiphertextBuilder {
|
||||
@@ -190,7 +194,7 @@ impl<D: Data> GGLWECiphertextBuilder<D> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<GGLWECiphertext<D>, BuildError> {
|
||||
pub fn build(self) -> Result<GGLWE<D>, BuildError> {
|
||||
let data: MatZnx<D> = self.data.ok_or(BuildError::MissingData)?;
|
||||
let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?;
|
||||
let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?;
|
||||
@@ -220,7 +224,7 @@ impl<D: Data> GGLWECiphertextBuilder<D> {
|
||||
return Err(BuildError::ZeroLimbs);
|
||||
}
|
||||
|
||||
Ok(GGLWECiphertext {
|
||||
Ok(GGLWE {
|
||||
data,
|
||||
base2k,
|
||||
k,
|
||||
@@ -229,31 +233,31 @@ impl<D: Data> GGLWECiphertextBuilder<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWECiphertext<D> {
|
||||
impl<D: DataRef> GGLWE<D> {
|
||||
pub fn data(&self) -> &MatZnx<D> {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWECiphertext<D> {
|
||||
impl<D: DataMut> GGLWE<D> {
|
||||
pub fn data_mut(&mut self) -> &mut MatZnx<D> {
|
||||
&mut self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGLWECiphertext<D> {
|
||||
impl<D: DataRef> fmt::Debug for GGLWE<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGLWECiphertext<D> {
|
||||
impl<D: DataMut> FillUniform for GGLWE<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.data.fill_uniform(log_bound, source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGLWECiphertext<D> {
|
||||
impl<D: DataRef> fmt::Display for GGLWE<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
@@ -266,7 +270,7 @@ impl<D: DataRef> fmt::Display for GGLWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWECiphertext<D> {
|
||||
impl<D: DataRef> GGLWE<D> {
|
||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
||||
GLWECiphertext::builder()
|
||||
.data(self.data.at(row, col))
|
||||
@@ -277,7 +281,7 @@ impl<D: DataRef> GGLWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWECiphertext<D> {
|
||||
impl<D: DataMut> GGLWE<D> {
|
||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
||||
GLWECiphertext::builder()
|
||||
.base2k(self.base2k())
|
||||
@@ -288,7 +292,7 @@ impl<D: DataMut> GGLWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWECiphertext<Vec<u8>> {
|
||||
impl GGLWE<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -390,12 +394,12 @@ impl GGLWECiphertext<Vec<u8>> {
|
||||
}
|
||||
|
||||
pub trait GGLWECiphertextToMut {
|
||||
fn to_mut(&mut self) -> GGLWECiphertext<&mut [u8]>;
|
||||
fn to_mut(&mut self) -> GGLWE<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWECiphertextToMut for GGLWECiphertext<D> {
|
||||
fn to_mut(&mut self) -> GGLWECiphertext<&mut [u8]> {
|
||||
GGLWECiphertext {
|
||||
impl<D: DataMut> GGLWECiphertextToMut for GGLWE<D> {
|
||||
fn to_mut(&mut self) -> GGLWE<&mut [u8]> {
|
||||
GGLWE {
|
||||
k: self.k(),
|
||||
base2k: self.base2k(),
|
||||
dsize: self.dsize(),
|
||||
@@ -404,13 +408,13 @@ impl<D: DataMut> GGLWECiphertextToMut for GGLWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWECiphertextToRef {
|
||||
fn to_ref(&self) -> GGLWECiphertext<&[u8]>;
|
||||
pub trait GGLWEToRef {
|
||||
fn to_ref(&self) -> GGLWE<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWECiphertextToRef for GGLWECiphertext<D> {
|
||||
fn to_ref(&self) -> GGLWECiphertext<&[u8]> {
|
||||
GGLWECiphertext {
|
||||
impl<D: DataRef> GGLWEToRef for GGLWE<D> {
|
||||
fn to_ref(&self) -> GGLWE<&[u8]> {
|
||||
GGLWE {
|
||||
k: self.k(),
|
||||
base2k: self.base2k(),
|
||||
dsize: self.dsize(),
|
||||
@@ -419,7 +423,7 @@ impl<D: DataMut> GGLWECiphertextToRef for GGLWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGLWECiphertext<D> {
|
||||
impl<D: DataMut> ReaderFrom for GGLWE<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||
@@ -428,7 +432,7 @@ impl<D: DataMut> ReaderFrom for GGLWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGLWECiphertext<D> {
|
||||
impl<D: DataRef> WriterTo for GGLWE<D> {
|
||||
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.base2k.0)?;
|
||||
|
||||
@@ -4,7 +4,7 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWECiphertext, GGLWECiphertextToMut, GGLWEInfos, GLWECiphertext, GLWEInfos, LWEInfos, Rank,
|
||||
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWECiphertextToMut, GGLWEInfos, GGLWEToRef, GLWECiphertext, GLWEInfos, LWEInfos, Rank,
|
||||
TorusPrecision,
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
@@ -12,7 +12,7 @@ use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub struct GGLWESwitchingKeyLayout {
|
||||
pub struct GLWESwitchingKeyLayout {
|
||||
pub n: Degree,
|
||||
pub base2k: Base2K,
|
||||
pub k: TorusPrecision,
|
||||
@@ -22,7 +22,7 @@ pub struct GGLWESwitchingKeyLayout {
|
||||
pub dsize: Dsize,
|
||||
}
|
||||
|
||||
impl LWEInfos for GGLWESwitchingKeyLayout {
|
||||
impl LWEInfos for GLWESwitchingKeyLayout {
|
||||
fn n(&self) -> Degree {
|
||||
self.n
|
||||
}
|
||||
@@ -36,13 +36,13 @@ impl LWEInfos for GGLWESwitchingKeyLayout {
|
||||
}
|
||||
}
|
||||
|
||||
impl GLWEInfos for GGLWESwitchingKeyLayout {
|
||||
impl GLWEInfos for GLWESwitchingKeyLayout {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWEInfos for GGLWESwitchingKeyLayout {
|
||||
impl GGLWEInfos for GLWESwitchingKeyLayout {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.rank_in
|
||||
}
|
||||
@@ -61,13 +61,13 @@ impl GGLWEInfos for GGLWESwitchingKeyLayout {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGLWESwitchingKey<D: Data> {
|
||||
pub(crate) key: GGLWECiphertext<D>,
|
||||
pub struct GLWESwitchingKey<D: Data> {
|
||||
pub(crate) key: GGLWE<D>,
|
||||
pub(crate) sk_in_n: usize, // Degree of sk_in
|
||||
pub(crate) sk_out_n: usize, // Degree of sk_out
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGLWESwitchingKey<D> {
|
||||
impl<D: Data> LWEInfos for GLWESwitchingKey<D> {
|
||||
fn n(&self) -> Degree {
|
||||
self.key.n()
|
||||
}
|
||||
@@ -85,13 +85,13 @@ impl<D: Data> LWEInfos for GGLWESwitchingKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWEInfos for GGLWESwitchingKey<D> {
|
||||
impl<D: Data> GLWEInfos for GLWESwitchingKey<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEInfos for GGLWESwitchingKey<D> {
|
||||
impl<D: Data> GGLWEInfos for GLWESwitchingKey<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.key.rank_in()
|
||||
}
|
||||
@@ -109,13 +109,13 @@ impl<D: Data> GGLWEInfos for GGLWESwitchingKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGLWESwitchingKey<D> {
|
||||
impl<D: DataRef> fmt::Debug for GLWESwitchingKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGLWESwitchingKey<D> {
|
||||
impl<D: DataRef> fmt::Display for GLWESwitchingKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
@@ -127,19 +127,19 @@ impl<D: DataRef> fmt::Display for GGLWESwitchingKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGLWESwitchingKey<D> {
|
||||
impl<D: DataMut> FillUniform for GLWESwitchingKey<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.key.fill_uniform(log_bound, source);
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWESwitchingKey<Vec<u8>> {
|
||||
impl GLWESwitchingKey<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
GGLWESwitchingKey {
|
||||
key: GGLWECiphertext::alloc(infos),
|
||||
GLWESwitchingKey {
|
||||
key: GGLWE::alloc(infos),
|
||||
sk_in_n: 0,
|
||||
sk_out_n: 0,
|
||||
}
|
||||
@@ -154,8 +154,8 @@ impl GGLWESwitchingKey<Vec<u8>> {
|
||||
dnum: Dnum,
|
||||
dsize: Dsize,
|
||||
) -> Self {
|
||||
GGLWESwitchingKey {
|
||||
key: GGLWECiphertext::alloc_with(n, base2k, k, rank_in, rank_out, dnum, dsize),
|
||||
GLWESwitchingKey {
|
||||
key: GGLWE::alloc_with(n, base2k, k, rank_in, rank_out, dnum, dsize),
|
||||
sk_in_n: 0,
|
||||
sk_out_n: 0,
|
||||
}
|
||||
@@ -165,7 +165,7 @@ impl GGLWESwitchingKey<Vec<u8>> {
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
GGLWECiphertext::alloc_bytes(infos)
|
||||
GGLWE::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(
|
||||
@@ -177,20 +177,20 @@ impl GGLWESwitchingKey<Vec<u8>> {
|
||||
dnum: Dnum,
|
||||
dsize: Dsize,
|
||||
) -> usize {
|
||||
GGLWECiphertext::alloc_bytes_with(n, base2k, k, rank_in, rank_out, dnum, dsize)
|
||||
GGLWE::alloc_bytes_with(n, base2k, k, rank_in, rank_out, dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWESwitchingKeyToMut {
|
||||
fn to_mut(&mut self) -> GGLWESwitchingKey<&mut [u8]>;
|
||||
pub trait GLWESwitchingKeyToMut {
|
||||
fn to_mut(&mut self) -> GLWESwitchingKey<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWESwitchingKeyToMut for GGLWESwitchingKey<D>
|
||||
impl<D: DataMut> GLWESwitchingKeyToMut for GLWESwitchingKey<D>
|
||||
where
|
||||
GGLWECiphertext<D>: GGLWECiphertextToMut,
|
||||
GGLWE<D>: GGLWECiphertextToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> GGLWESwitchingKey<&mut [u8]> {
|
||||
GGLWESwitchingKey {
|
||||
fn to_mut(&mut self) -> GLWESwitchingKey<&mut [u8]> {
|
||||
GLWESwitchingKey {
|
||||
key: self.key.to_mut(),
|
||||
sk_in_n: self.sk_in_n,
|
||||
sk_out_n: self.sk_out_n,
|
||||
@@ -198,19 +198,36 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWESwitchingKey<D> {
|
||||
pub trait GLWESwitchingKeyToRef {
|
||||
fn to_ref(&self) -> GLWESwitchingKey<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GLWESwitchingKeyToRef for GLWESwitchingKey<D>
|
||||
where
|
||||
GGLWE<D>: GGLWEToRef,
|
||||
{
|
||||
fn to_ref(&self) -> GLWESwitchingKey<&[u8]> {
|
||||
GLWESwitchingKey {
|
||||
key: self.key.to_ref(),
|
||||
sk_in_n: self.sk_in_n,
|
||||
sk_out_n: self.sk_out_n,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GLWESwitchingKey<D> {
|
||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
||||
self.key.at(row, col)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWESwitchingKey<D> {
|
||||
impl<D: DataMut> GLWESwitchingKey<D> {
|
||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
||||
self.key.at_mut(row, col)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGLWESwitchingKey<D> {
|
||||
impl<D: DataMut> ReaderFrom for GLWESwitchingKey<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.sk_in_n = reader.read_u64::<LittleEndian>()? as usize;
|
||||
self.sk_out_n = reader.read_u64::<LittleEndian>()? as usize;
|
||||
@@ -218,7 +235,7 @@ impl<D: DataMut> ReaderFrom for GGLWESwitchingKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGLWESwitchingKey<D> {
|
||||
impl<D: DataRef> WriterTo for GLWESwitchingKey<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write_u64::<LittleEndian>(self.sk_in_n as u64)?;
|
||||
writer.write_u64::<LittleEndian>(self.sk_out_n as u64)?;
|
||||
|
||||
@@ -3,13 +3,16 @@ use poulpy_hal::{
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision};
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
||||
Rank, TorusPrecision,
|
||||
};
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub struct GGLWETensorKeyLayout {
|
||||
pub struct TensorKeyLayout {
|
||||
pub n: Degree,
|
||||
pub base2k: Base2K,
|
||||
pub k: TorusPrecision,
|
||||
@@ -19,11 +22,11 @@ pub struct GGLWETensorKeyLayout {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGLWETensorKey<D: Data> {
|
||||
pub(crate) keys: Vec<GGLWESwitchingKey<D>>,
|
||||
pub struct TensorKey<D: Data> {
|
||||
pub(crate) keys: Vec<GLWESwitchingKey<D>>,
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGLWETensorKey<D> {
|
||||
impl<D: Data> LWEInfos for TensorKey<D> {
|
||||
fn n(&self) -> Degree {
|
||||
self.keys[0].n()
|
||||
}
|
||||
@@ -41,13 +44,13 @@ impl<D: Data> LWEInfos for GGLWETensorKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWEInfos for GGLWETensorKey<D> {
|
||||
impl<D: Data> GLWEInfos for TensorKey<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.keys[0].rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGLWEInfos for GGLWETensorKey<D> {
|
||||
impl<D: Data> GGLWEInfos for TensorKey<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
@@ -65,7 +68,7 @@ impl<D: Data> GGLWEInfos for GGLWETensorKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl LWEInfos for GGLWETensorKeyLayout {
|
||||
impl LWEInfos for TensorKeyLayout {
|
||||
fn n(&self) -> Degree {
|
||||
self.n
|
||||
}
|
||||
@@ -79,13 +82,13 @@ impl LWEInfos for GGLWETensorKeyLayout {
|
||||
}
|
||||
}
|
||||
|
||||
impl GLWEInfos for GGLWETensorKeyLayout {
|
||||
impl GLWEInfos for TensorKeyLayout {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWEInfos for GGLWETensorKeyLayout {
|
||||
impl GGLWEInfos for TensorKeyLayout {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.rank
|
||||
}
|
||||
@@ -103,21 +106,21 @@ impl GGLWEInfos for GGLWETensorKeyLayout {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGLWETensorKey<D> {
|
||||
impl<D: DataRef> fmt::Debug for TensorKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGLWETensorKey<D> {
|
||||
impl<D: DataMut> FillUniform for TensorKey<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.keys
|
||||
.iter_mut()
|
||||
.for_each(|key: &mut GGLWESwitchingKey<D>| key.fill_uniform(log_bound, source))
|
||||
.for_each(|key: &mut GLWESwitchingKey<D>| key.fill_uniform(log_bound, source))
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGLWETensorKey<D> {
|
||||
impl<D: DataRef> fmt::Display for TensorKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "(GLWETensorKey)",)?;
|
||||
for (i, key) in self.keys.iter().enumerate() {
|
||||
@@ -127,7 +130,7 @@ impl<D: DataRef> fmt::Display for GGLWETensorKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GGLWETensorKey<Vec<u8>> {
|
||||
impl TensorKey<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -148,10 +151,10 @@ impl GGLWETensorKey<Vec<u8>> {
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
|
||||
let mut keys: Vec<GGLWESwitchingKey<Vec<u8>>> = Vec::new();
|
||||
let mut keys: Vec<GLWESwitchingKey<Vec<u8>>> = Vec::new();
|
||||
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
|
||||
(0..pairs).for_each(|_| {
|
||||
keys.push(GGLWESwitchingKey::alloc_with(
|
||||
keys.push(GLWESwitchingKey::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -176,7 +179,7 @@ impl GGLWETensorKey<Vec<u8>> {
|
||||
let rank_out: usize = infos.rank_out().into();
|
||||
let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1);
|
||||
pairs
|
||||
* GGLWESwitchingKey::alloc_bytes_with(
|
||||
* GLWESwitchingKey::alloc_bytes_with(
|
||||
infos.n(),
|
||||
infos.base2k(),
|
||||
infos.k(),
|
||||
@@ -189,13 +192,13 @@ impl GGLWETensorKey<Vec<u8>> {
|
||||
|
||||
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;
|
||||
pairs * GGLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), rank, dnum, dsize)
|
||||
pairs * GLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), rank, dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGLWETensorKey<D> {
|
||||
impl<D: DataMut> TensorKey<D> {
|
||||
// Returns a mutable reference to GLWESwitchingKey_{s}(s[i] * s[j])
|
||||
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWESwitchingKey<D> {
|
||||
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GLWESwitchingKey<D> {
|
||||
if i > j {
|
||||
std::mem::swap(&mut i, &mut j);
|
||||
};
|
||||
@@ -204,9 +207,9 @@ impl<D: DataMut> GGLWETensorKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWETensorKey<D> {
|
||||
impl<D: DataRef> TensorKey<D> {
|
||||
// Returns a reference to GLWESwitchingKey_{s}(s[i] * s[j])
|
||||
pub fn at(&self, mut i: usize, mut j: usize) -> &GGLWESwitchingKey<D> {
|
||||
pub fn at(&self, mut i: usize, mut j: usize) -> &GLWESwitchingKey<D> {
|
||||
if i > j {
|
||||
std::mem::swap(&mut i, &mut j);
|
||||
};
|
||||
@@ -215,7 +218,7 @@ impl<D: DataRef> GGLWETensorKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGLWETensorKey<D> {
|
||||
impl<D: DataMut> ReaderFrom for TensorKey<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
let len: usize = reader.read_u64::<LittleEndian>()? as usize;
|
||||
if self.keys.len() != len {
|
||||
@@ -231,7 +234,7 @@ impl<D: DataMut> ReaderFrom for GGLWETensorKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGLWETensorKey<D> {
|
||||
impl<D: DataRef> WriterTo for TensorKey<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
writer.write_u64::<LittleEndian>(self.keys.len() as u64)?;
|
||||
for key in &self.keys {
|
||||
@@ -240,3 +243,33 @@ impl<D: DataRef> WriterTo for GGLWETensorKey<D> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TensorKeyToRef {
|
||||
fn to_ref(&self) -> TensorKey<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> TensorKeyToRef for TensorKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToRef,
|
||||
{
|
||||
fn to_ref(&self) -> TensorKey<&[u8]> {
|
||||
TensorKey {
|
||||
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TensorKeyToMut {
|
||||
fn to_ref(&mut self) -> TensorKey<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> TensorKeyToMut for TensorKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
|
||||
{
|
||||
fn to_ref(&mut self) -> TensorKey<&mut [u8]> {
|
||||
TensorKey {
|
||||
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,14 +64,14 @@ impl GGSWInfos for GGSWCiphertextLayout {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GGSWCiphertext<D: Data> {
|
||||
pub struct GGSW<D: Data> {
|
||||
pub(crate) data: MatZnx<D>,
|
||||
pub(crate) k: TorusPrecision,
|
||||
pub(crate) base2k: Base2K,
|
||||
pub(crate) dsize: Dsize,
|
||||
}
|
||||
|
||||
impl<D: Data> LWEInfos for GGSWCiphertext<D> {
|
||||
impl<D: Data> LWEInfos for GGSW<D> {
|
||||
fn n(&self) -> Degree {
|
||||
Degree(self.data.n() as u32)
|
||||
}
|
||||
@@ -89,13 +89,13 @@ impl<D: Data> LWEInfos for GGSWCiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWEInfos for GGSWCiphertext<D> {
|
||||
impl<D: Data> GLWEInfos for GGSW<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
Rank(self.data.cols_out() as u32 - 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GGSWInfos for GGSWCiphertext<D> {
|
||||
impl<D: Data> GGSWInfos for GGSW<D> {
|
||||
fn dsize(&self) -> Dsize {
|
||||
self.dsize
|
||||
}
|
||||
@@ -112,7 +112,7 @@ pub struct GGSWCiphertextBuilder<D: Data> {
|
||||
dsize: Option<Dsize>,
|
||||
}
|
||||
|
||||
impl<D: Data> GGSWCiphertext<D> {
|
||||
impl<D: Data> GGSW<D> {
|
||||
#[inline]
|
||||
pub fn builder() -> GGSWCiphertextBuilder<D> {
|
||||
GGSWCiphertextBuilder {
|
||||
@@ -182,7 +182,7 @@ impl<D: Data> GGSWCiphertextBuilder<D> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<GGSWCiphertext<D>, BuildError> {
|
||||
pub fn build(self) -> Result<GGSW<D>, BuildError> {
|
||||
let data: MatZnx<D> = self.data.ok_or(BuildError::MissingData)?;
|
||||
let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?;
|
||||
let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?;
|
||||
@@ -212,7 +212,7 @@ impl<D: Data> GGSWCiphertextBuilder<D> {
|
||||
return Err(BuildError::ZeroLimbs);
|
||||
}
|
||||
|
||||
Ok(GGSWCiphertext {
|
||||
Ok(GGSW {
|
||||
data,
|
||||
base2k,
|
||||
k,
|
||||
@@ -221,13 +221,13 @@ impl<D: Data> GGSWCiphertextBuilder<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GGSWCiphertext<D> {
|
||||
impl<D: DataRef> fmt::Debug for GGSW<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GGSWCiphertext<D> {
|
||||
impl<D: DataRef> fmt::Display for GGSW<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
@@ -240,13 +240,13 @@ impl<D: DataRef> fmt::Display for GGSWCiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GGSWCiphertext<D> {
|
||||
impl<D: DataMut> FillUniform for GGSW<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.data.fill_uniform(log_bound, source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGSWCiphertext<D> {
|
||||
impl<D: DataRef> GGSW<D> {
|
||||
pub fn at(&self, row: usize, col: usize) -> GLWECiphertext<&[u8]> {
|
||||
GLWECiphertext::builder()
|
||||
.data(self.data.at(row, col))
|
||||
@@ -257,7 +257,7 @@ impl<D: DataRef> GGSWCiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGSWCiphertext<D> {
|
||||
impl<D: DataMut> GGSW<D> {
|
||||
pub fn at_mut(&mut self, row: usize, col: usize) -> GLWECiphertext<&mut [u8]> {
|
||||
GLWECiphertext::builder()
|
||||
.base2k(self.base2k())
|
||||
@@ -268,7 +268,7 @@ impl<D: DataMut> GGSWCiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl GGSWCiphertext<Vec<u8>> {
|
||||
impl GGSW<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGSWInfos,
|
||||
@@ -353,7 +353,7 @@ impl GGSWCiphertext<Vec<u8>> {
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GGSWCiphertext<D> {
|
||||
impl<D: DataMut> ReaderFrom for GGSW<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||
self.base2k = Base2K(reader.read_u32::<LittleEndian>()?);
|
||||
@@ -362,7 +362,7 @@ impl<D: DataMut> ReaderFrom for GGSWCiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GGSWCiphertext<D> {
|
||||
impl<D: DataRef> WriterTo for GGSW<D> {
|
||||
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.base2k.into())?;
|
||||
@@ -371,34 +371,32 @@ impl<D: DataRef> WriterTo for GGSWCiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGSWCiphertextToMut {
|
||||
fn to_mut(&mut self) -> GGSWCiphertext<&mut [u8]>;
|
||||
pub trait GGSWToMut {
|
||||
fn to_mut(&mut self) -> GGSW<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GGSWCiphertextToMut for GGSWCiphertext<D> {
|
||||
fn to_mut(&mut self) -> GGSWCiphertext<&mut [u8]> {
|
||||
GGSWCiphertext::builder()
|
||||
.base2k(self.base2k())
|
||||
.dsize(self.dsize())
|
||||
.k(self.k())
|
||||
.data(self.data.to_mut())
|
||||
.build()
|
||||
.unwrap()
|
||||
impl<D: DataMut> GGSWToMut for GGSW<D> {
|
||||
fn to_mut(&mut self) -> GGSW<&mut [u8]> {
|
||||
GGSW {
|
||||
dsize: self.dsize,
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
data: self.data.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGSWCiphertextToRef {
|
||||
fn to_ref(&self) -> GGSWCiphertext<&[u8]>;
|
||||
pub trait GGSWToRef {
|
||||
fn to_ref(&self) -> GGSW<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGSWCiphertextToRef for GGSWCiphertext<D> {
|
||||
fn to_ref(&self) -> GGSWCiphertext<&[u8]> {
|
||||
GGSWCiphertext::builder()
|
||||
.base2k(self.base2k())
|
||||
.dsize(self.dsize())
|
||||
.k(self.k())
|
||||
.data(self.data.to_ref())
|
||||
.build()
|
||||
.unwrap()
|
||||
impl<D: DataRef> GGSWToRef for GGSW<D> {
|
||||
fn to_ref(&self) -> GGSW<&[u8]> {
|
||||
GGSW {
|
||||
dsize: self.dsize,
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
data: self.data.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,36 +253,6 @@ impl GLWECiphertext<Vec<u8>> {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWECiphertextToRef {
|
||||
fn to_ref(&self) -> GLWECiphertext<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GLWECiphertextToRef for GLWECiphertext<D> {
|
||||
fn to_ref(&self) -> GLWECiphertext<&[u8]> {
|
||||
GLWECiphertext::builder()
|
||||
.k(self.k())
|
||||
.base2k(self.base2k())
|
||||
.data(self.data.to_ref())
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWECiphertextToMut {
|
||||
fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GLWECiphertextToMut for GLWECiphertext<D> {
|
||||
fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]> {
|
||||
GLWECiphertext::builder()
|
||||
.k(self.k())
|
||||
.base2k(self.base2k())
|
||||
.data(self.data.to_mut())
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GLWECiphertext<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.k = TorusPrecision(reader.read_u32::<LittleEndian>()?);
|
||||
@@ -298,3 +268,31 @@ impl<D: DataRef> WriterTo for GLWECiphertext<D> {
|
||||
self.data.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWECiphertextToRef {
|
||||
fn to_ref(&self) -> GLWECiphertext<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GLWECiphertextToRef for GLWECiphertext<D> {
|
||||
fn to_ref(&self) -> GLWECiphertext<&[u8]> {
|
||||
GLWECiphertext {
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
data: self.data.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWECiphertextToMut {
|
||||
fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GLWECiphertextToMut for GLWECiphertext<D> {
|
||||
fn to_mut(&mut self) -> GLWECiphertext<&mut [u8]> {
|
||||
GLWECiphertext {
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
data: self.data.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ use poulpy_hal::{
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision};
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
||||
Rank, TorusPrecision,
|
||||
};
|
||||
|
||||
use std::fmt;
|
||||
|
||||
@@ -56,9 +59,9 @@ impl GGLWEInfos for GLWEToLWEKeyLayout {
|
||||
|
||||
/// A special [GLWESwitchingKey] required to for the conversion from [GLWECiphertext] to [LWECiphertext].
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct GLWEToLWEKey<D: Data>(pub(crate) GGLWESwitchingKey<D>);
|
||||
pub struct GLWEToLWESwitchingKey<D: Data>(pub(crate) GLWESwitchingKey<D>);
|
||||
|
||||
impl<D: Data> LWEInfos for GLWEToLWEKey<D> {
|
||||
impl<D: Data> LWEInfos for GLWEToLWESwitchingKey<D> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
self.0.base2k()
|
||||
}
|
||||
@@ -76,12 +79,12 @@ impl<D: Data> LWEInfos for GLWEToLWEKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> GLWEInfos for GLWEToLWEKey<D> {
|
||||
impl<D: Data> GLWEInfos for GLWEToLWESwitchingKey<D> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
impl<D: Data> GGLWEInfos for GLWEToLWEKey<D> {
|
||||
impl<D: Data> GGLWEInfos for GLWEToLWESwitchingKey<D> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.0.rank_in()
|
||||
}
|
||||
@@ -99,37 +102,37 @@ impl<D: Data> GGLWEInfos for GLWEToLWEKey<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Debug for GLWEToLWEKey<D> {
|
||||
impl<D: DataRef> fmt::Debug for GLWEToLWESwitchingKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{self}")
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> FillUniform for GLWEToLWEKey<D> {
|
||||
impl<D: DataMut> FillUniform for GLWEToLWESwitchingKey<D> {
|
||||
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
|
||||
self.0.fill_uniform(log_bound, source);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> fmt::Display for GLWEToLWEKey<D> {
|
||||
impl<D: DataRef> fmt::Display for GLWEToLWESwitchingKey<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "(GLWEToLWESwitchingKey) {}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut> ReaderFrom for GLWEToLWEKey<D> {
|
||||
impl<D: DataMut> ReaderFrom for GLWEToLWESwitchingKey<D> {
|
||||
fn read_from<R: std::io::Read>(&mut self, reader: &mut R) -> std::io::Result<()> {
|
||||
self.0.read_from(reader)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> WriterTo for GLWEToLWEKey<D> {
|
||||
impl<D: DataRef> WriterTo for GLWEToLWESwitchingKey<D> {
|
||||
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
|
||||
self.0.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl GLWEToLWEKey<Vec<u8>> {
|
||||
impl GLWEToLWESwitchingKey<Vec<u8>> {
|
||||
pub fn alloc<A>(infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -144,11 +147,11 @@ impl GLWEToLWEKey<Vec<u8>> {
|
||||
1,
|
||||
"dsize > 1 is not supported for GLWEToLWESwitchingKey"
|
||||
);
|
||||
Self(GGLWESwitchingKey::alloc(infos))
|
||||
Self(GLWESwitchingKey::alloc(infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self {
|
||||
Self(GGLWESwitchingKey::alloc_with(
|
||||
Self(GLWESwitchingKey::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -173,10 +176,36 @@ impl GLWEToLWEKey<Vec<u8>> {
|
||||
1,
|
||||
"dsize > 1 is not supported for GLWEToLWESwitchingKey"
|
||||
);
|
||||
GGLWESwitchingKey::alloc_bytes(infos)
|
||||
GLWESwitchingKey::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
|
||||
GGLWESwitchingKey::alloc_bytes_with(n, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWEToLWESwitchingKeyToRef {
|
||||
fn to_ref(&self) -> GLWEToLWESwitchingKey<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> GLWEToLWESwitchingKeyToRef for GLWEToLWESwitchingKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToRef,
|
||||
{
|
||||
fn to_ref(&self) -> GLWEToLWESwitchingKey<&[u8]> {
|
||||
GLWEToLWESwitchingKey(self.0.to_ref())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWEToLWESwitchingKeyToMut {
|
||||
fn to_mut(&mut self) -> GLWEToLWESwitchingKey<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> GLWEToLWESwitchingKeyToMut for GLWEToLWESwitchingKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> GLWEToLWESwitchingKey<&mut [u8]> {
|
||||
GLWEToLWESwitchingKey(self.0.to_mut())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,11 @@ pub trait LWEInfos {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SetLWEInfos {
|
||||
fn set_k(&mut self, k: TorusPrecision);
|
||||
fn set_base2k(&mut self, base2k: Base2K);
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub struct LWECiphertextLayout {
|
||||
pub n: Degree,
|
||||
@@ -47,7 +52,6 @@ impl LWEInfos for LWECiphertextLayout {
|
||||
self.n
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct LWECiphertext<D: Data> {
|
||||
pub(crate) data: Zn<D>,
|
||||
@@ -72,6 +76,16 @@ impl<D: Data> LWEInfos for LWECiphertext<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data> SetLWEInfos for LWECiphertext<D> {
|
||||
fn set_base2k(&mut self, base2k: Base2K) {
|
||||
self.base2k = base2k
|
||||
}
|
||||
|
||||
fn set_k(&mut self, k: TorusPrecision) {
|
||||
self.k = k
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> LWECiphertext<D> {
|
||||
pub fn data(&self) -> &Zn<D> {
|
||||
&self.data
|
||||
@@ -221,12 +235,11 @@ pub trait LWECiphertextToRef {
|
||||
|
||||
impl<D: DataRef> LWECiphertextToRef for LWECiphertext<D> {
|
||||
fn to_ref(&self) -> LWECiphertext<&[u8]> {
|
||||
LWECiphertext::builder()
|
||||
.base2k(self.base2k())
|
||||
.k(self.k())
|
||||
.data(self.data.to_ref())
|
||||
.build()
|
||||
.unwrap()
|
||||
LWECiphertext {
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
data: self.data.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,12 +250,11 @@ pub trait LWECiphertextToMut {
|
||||
|
||||
impl<D: DataMut> LWECiphertextToMut for LWECiphertext<D> {
|
||||
fn to_mut(&mut self) -> LWECiphertext<&mut [u8]> {
|
||||
LWECiphertext::builder()
|
||||
.base2k(self.base2k())
|
||||
.k(self.k())
|
||||
.data(self.data.to_mut())
|
||||
.build()
|
||||
.unwrap()
|
||||
LWECiphertext {
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
data: self.data.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ use poulpy_hal::{
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision};
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
||||
Rank, TorusPrecision,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub struct LWESwitchingKeyLayout {
|
||||
@@ -54,7 +57,7 @@ impl GGLWEInfos for LWESwitchingKeyLayout {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct LWESwitchingKey<D: Data>(pub(crate) GGLWESwitchingKey<D>);
|
||||
pub struct LWESwitchingKey<D: Data>(pub(crate) GLWESwitchingKey<D>);
|
||||
|
||||
impl<D: Data> LWEInfos for LWESwitchingKey<D> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
@@ -118,11 +121,11 @@ impl LWESwitchingKey<Vec<u8>> {
|
||||
1,
|
||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||
);
|
||||
Self(GGLWESwitchingKey::alloc(infos))
|
||||
Self(GLWESwitchingKey::alloc(infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
|
||||
Self(GGLWESwitchingKey::alloc_with(
|
||||
Self(GLWESwitchingKey::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -152,11 +155,11 @@ impl LWESwitchingKey<Vec<u8>> {
|
||||
1,
|
||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||
);
|
||||
GGLWESwitchingKey::alloc_bytes(infos)
|
||||
GLWESwitchingKey::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
|
||||
GGLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,3 +192,29 @@ impl<D: DataRef> WriterTo for LWESwitchingKey<D> {
|
||||
self.0.write_to(writer)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LWEToLWEKeyToRef {
|
||||
fn to_ref(&self) -> LWESwitchingKey<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> LWEToLWEKeyToRef for LWESwitchingKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToRef,
|
||||
{
|
||||
fn to_ref(&self) -> LWESwitchingKey<&[u8]> {
|
||||
LWESwitchingKey(self.0.to_ref())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LWEToLWEKeyToMut {
|
||||
fn to_mut(&mut self) -> LWESwitchingKey<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> LWEToLWEKeyToMut for LWESwitchingKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> LWESwitchingKey<&mut [u8]> {
|
||||
LWESwitchingKey(self.0.to_mut())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use poulpy_hal::{
|
||||
layouts::{Data, DataMut, DataRef, ScalarZnx, ZnxInfos, ZnxView, ZnxZero},
|
||||
layouts::{Data, DataMut, DataRef, ScalarZnx, ScalarZnxToMut, ScalarZnxToRef, ZnxInfos, ZnxView, ZnxZero},
|
||||
source::Source,
|
||||
};
|
||||
|
||||
@@ -84,3 +84,29 @@ impl<D: DataMut> LWESecret<D> {
|
||||
self.dist = Distribution::ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LWESecretToRef {
|
||||
fn to_ref(&self) -> LWESecret<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> LWESecretToRef for LWESecret<D> {
|
||||
fn to_ref(&self) -> LWESecret<&[u8]> {
|
||||
LWESecret {
|
||||
dist: self.dist,
|
||||
data: self.data.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LWESecretToMut {
|
||||
fn to_mut(&mut self) -> LWESecret<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> LWESecretToMut for LWESecret<D> {
|
||||
fn to_mut(&mut self) -> LWESecret<&mut [u8]> {
|
||||
LWESecret {
|
||||
dist: self.dist,
|
||||
data: self.data.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ use poulpy_hal::{
|
||||
source::Source,
|
||||
};
|
||||
|
||||
use crate::layouts::{Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision};
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToMut, GLWESwitchingKeyToRef, LWEInfos,
|
||||
Rank, TorusPrecision,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
||||
pub struct LWEToGLWESwitchingKeyLayout {
|
||||
@@ -55,7 +58,7 @@ impl GGLWEInfos for LWEToGLWESwitchingKeyLayout {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
pub struct LWEToGLWESwitchingKey<D: Data>(pub(crate) GGLWESwitchingKey<D>);
|
||||
pub struct LWEToGLWESwitchingKey<D: Data>(pub(crate) GLWESwitchingKey<D>);
|
||||
|
||||
impl<D: Data> LWEInfos for LWEToGLWESwitchingKey<D> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
@@ -143,11 +146,11 @@ impl LWEToGLWESwitchingKey<Vec<u8>> {
|
||||
1,
|
||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||
);
|
||||
Self(GGLWESwitchingKey::alloc(infos))
|
||||
Self(GLWESwitchingKey::alloc(infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
|
||||
Self(GGLWESwitchingKey::alloc_with(
|
||||
Self(GLWESwitchingKey::alloc_with(
|
||||
n,
|
||||
base2k,
|
||||
k,
|
||||
@@ -172,10 +175,36 @@ impl LWEToGLWESwitchingKey<Vec<u8>> {
|
||||
1,
|
||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||
);
|
||||
GGLWESwitchingKey::alloc_bytes(infos)
|
||||
GLWESwitchingKey::alloc_bytes(infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize {
|
||||
GGLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
||||
GLWESwitchingKey::alloc_bytes_with(n, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LWEToGLWESwitchingKeyToRef {
|
||||
fn to_ref(&self) -> LWEToGLWESwitchingKey<&[u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataRef> LWEToGLWESwitchingKeyToRef for LWEToGLWESwitchingKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToRef,
|
||||
{
|
||||
fn to_ref(&self) -> LWEToGLWESwitchingKey<&[u8]> {
|
||||
LWEToGLWESwitchingKey(self.0.to_ref())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LWEToGLWESwitchingKeyToMut {
|
||||
fn to_mut(&mut self) -> LWEToGLWESwitchingKey<&mut [u8]>;
|
||||
}
|
||||
|
||||
impl<D: DataMut> LWEToGLWESwitchingKeyToMut for LWEToGLWESwitchingKey<D>
|
||||
where
|
||||
GLWESwitchingKey<D>: GLWESwitchingKeyToMut,
|
||||
{
|
||||
fn to_mut(&mut self) -> LWEToGLWESwitchingKey<&mut [u8]> {
|
||||
LWEToGLWESwitchingKey(self.0.to_mut())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ pub enum BuildError {
|
||||
ZeroLimbs,
|
||||
ZeroRank,
|
||||
ZeroDigits,
|
||||
VecZnxColsNotOne,
|
||||
}
|
||||
|
||||
/// Newtype over `u32` with arithmetic and comparisons against same type and `u32`.
|
||||
|
||||
@@ -4,23 +4,25 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEAutomorphismKey, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
AutomorphismKeyToRef, Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{
|
||||
GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut, GLWESwitchingKeyPreparedToRef,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWEAutomorphismKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) key: GGLWESwitchingKeyPrepared<D, B>,
|
||||
pub struct AutomorphismKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) key: GLWESwitchingKeyPrepared<D, B>,
|
||||
pub(crate) p: i64,
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> AutomorphismKeyPrepared<D, B> {
|
||||
pub fn p(&self) -> i64 {
|
||||
self.p
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> LWEInfos for AutomorphismKeyPrepared<D, B> {
|
||||
fn n(&self) -> Degree {
|
||||
self.key.n()
|
||||
}
|
||||
@@ -38,13 +40,23 @@ impl<D: Data, B: Backend> LWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
pub trait SetP {
|
||||
fn set_p(&mut self, p: i64);
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> SetP for AutomorphismKeyPrepared<D, B> {
|
||||
fn set_p(&mut self, p: i64) {
|
||||
self.p = p
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEInfos for AutomorphismKeyPrepared<D, B> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GGLWEInfos for AutomorphismKeyPrepared<D, B> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.key.rank_in()
|
||||
}
|
||||
@@ -62,7 +74,7 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWEAutomorphismKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
|
||||
impl<B: Backend> AutomorphismKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -73,8 +85,8 @@ impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
|
||||
infos.rank_out(),
|
||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared"
|
||||
);
|
||||
GGLWEAutomorphismKeyPrepared::<Vec<u8>, B> {
|
||||
key: GGLWESwitchingKeyPrepared::alloc(module, infos),
|
||||
AutomorphismKeyPrepared::<Vec<u8>, B> {
|
||||
key: GLWESwitchingKeyPrepared::alloc(module, infos),
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
@@ -83,8 +95,8 @@ impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
GGLWEAutomorphismKeyPrepared {
|
||||
key: GGLWESwitchingKeyPrepared::alloc_with(module, base2k, k, rank, rank, dnum, dsize),
|
||||
AutomorphismKeyPrepared {
|
||||
key: GLWESwitchingKeyPrepared::alloc_with(module, base2k, k, rank, rank, dnum, dsize),
|
||||
p: 0,
|
||||
}
|
||||
}
|
||||
@@ -99,43 +111,104 @@ impl<B: Backend> GGLWEAutomorphismKeyPrepared<Vec<u8>, B> {
|
||||
infos.rank_out(),
|
||||
"rank_in != rank_out is not supported for GGLWEAutomorphismKeyPrepared"
|
||||
);
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank, rank, dnum, dsize)
|
||||
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank, rank, dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWEAutomorphismKeyPrepared<Vec<u8>, B>
|
||||
pub trait AutomorphismKeyPrepareTmpBytes {
|
||||
fn automorphism_key_prepare_tmp_bytes<A>(&self, infos: &A)
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
}
|
||||
|
||||
impl<B: Backend> AutomorphismKeyPrepareTmpBytes for Module<B>
|
||||
where
|
||||
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
Module<B>: GLWESwitchingKeyPrepareTmpBytes,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
fn automorphism_key_prepare_tmp_bytes<A>(&self, infos: &A)
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
self.glwe_switching_key_prepare_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
impl<D: DataRef, B: Backend> AutomorphismKeyPrepared<D, B> {
|
||||
pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize
|
||||
where
|
||||
Module<B>: AutomorphismKeyPrepareTmpBytes,
|
||||
{
|
||||
module.automorphism_key_prepare_tmp_bytes(self);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AutomorphismKeyPrepare<B: Backend> {
|
||||
fn automorphism_key_prepare<R, O>(&self, res: &R, other: &O, scratch: &Scratch<B>)
|
||||
where
|
||||
R: AutomorphismKeyPreparedToMut<B>,
|
||||
O: AutomorphismKeyToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> AutomorphismKeyPrepare<B> for Module<B> {
|
||||
fn automorphism_key_prepare<R, O>(&self, res: &R, other: &O, scratch: &Scratch<B>)
|
||||
where
|
||||
R: AutomorphismKeyPreparedToMut<B>,
|
||||
O: AutomorphismKeyToRef,
|
||||
{
|
||||
self.key.prepare(self, &other.to_ref().key, scratch);
|
||||
self.p = other.p;
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWEAutomorphismKeyPrepared<Vec<u8>, B>> for GGLWEAutomorphismKey<D>
|
||||
pub trait AutomorphismKeyPrepareAlloc<B: Backend> {
|
||||
fn automorphism_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> AutomorphismKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
O: AutomorphismKeyToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> AutomorphismKeyPrepareAlloc<B> for Module<B>
|
||||
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);
|
||||
atk_prepared.prepare(module, self, scratch);
|
||||
fn automorphism_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> AutomorphismKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
O: AutomorphismKeyToRef,
|
||||
{
|
||||
let mut atk_prepared: AutomorphismKeyPrepared<Vec<u8>, B> = AutomorphismKeyPrepared::alloc(self, &other.to_ref());
|
||||
atk_prepared.prepare(self, &other.to_ref(), scratch);
|
||||
atk_prepared
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AutomorphismKeyPreparedToMut<B: Backend> {
|
||||
fn to_mut(&mut self) -> AutomorphismKeyPrepared<&mut [u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> AutomorphismKeyPreparedToMut<B> for AutomorphismKeyPrepared<D, B> {
|
||||
fn to_mut(&mut self) -> AutomorphismKeyPrepared<&mut [u8], B> {
|
||||
AutomorphismKeyPrepared {
|
||||
p: self.p,
|
||||
key: self.key.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait AutomorphismKeyPreparedToRef<B: Backend> {
|
||||
fn to_ref(&self) -> AutomorphismKeyPrepared<&[u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> AutomorphismKeyPreparedToRef<B> for AutomorphismKeyPrepared<D, B> {
|
||||
fn to_ref(&self) -> AutomorphismKeyPrepared<&[u8], B> {
|
||||
AutomorphismKeyPrepared {
|
||||
p: self.p,
|
||||
key: self.key.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
use poulpy_hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare, VmpPrepareTmpBytes},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat, ZnxInfos},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch, VmpPMat, VmpPMatToMut, VmpPMatToRef, ZnxInfos},
|
||||
oep::VmpPMatAllocBytesImpl,
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, BuildError, Degree, Dnum, Dsize, GGLWECiphertext, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
Base2K, BuildError, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GGLWEToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWECiphertextPrepared<D: Data, B: Backend> {
|
||||
pub struct GGLWEPrepared<D: Data, B: Backend> {
|
||||
pub(crate) data: VmpPMat<D, B>,
|
||||
pub(crate) k: TorusPrecision,
|
||||
pub(crate) base2k: Base2K,
|
||||
pub(crate) dsize: Dsize,
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for GGLWECiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> LWEInfos for GGLWEPrepared<D, B> {
|
||||
fn n(&self) -> Degree {
|
||||
Degree(self.data.n() as u32)
|
||||
}
|
||||
@@ -35,13 +34,13 @@ impl<D: Data, B: Backend> LWEInfos for GGLWECiphertextPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEInfos for GGLWECiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GLWEInfos for GGLWEPrepared<D, B> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWEInfos for GGLWECiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GGLWEInfos for GGLWEPrepared<D, B> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
Rank(self.data.cols_in() as u32)
|
||||
}
|
||||
@@ -59,17 +58,17 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWECiphertextPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GGLWECiphertextPreparedBuilder<D: Data, B: Backend> {
|
||||
pub struct GGLWEPreparedBuilder<D: Data, B: Backend> {
|
||||
data: Option<VmpPMat<D, B>>,
|
||||
base2k: Option<Base2K>,
|
||||
k: Option<TorusPrecision>,
|
||||
dsize: Option<Dsize>,
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWECiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GGLWEPrepared<D, B> {
|
||||
#[inline]
|
||||
pub fn builder() -> GGLWECiphertextPreparedBuilder<D, B> {
|
||||
GGLWECiphertextPreparedBuilder {
|
||||
pub fn builder() -> GGLWEPreparedBuilder<D, B> {
|
||||
GGLWEPreparedBuilder {
|
||||
data: None,
|
||||
base2k: None,
|
||||
k: None,
|
||||
@@ -78,7 +77,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWECiphertextPreparedBuilder<Vec<u8>, B> {
|
||||
impl<B: Backend> GGLWEPreparedBuilder<Vec<u8>, B> {
|
||||
#[inline]
|
||||
pub fn layout<A>(mut self, infos: &A) -> Self
|
||||
where
|
||||
@@ -99,7 +98,7 @@ impl<B: Backend> GGLWECiphertextPreparedBuilder<Vec<u8>, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
|
||||
impl<D: Data, B: Backend> GGLWEPreparedBuilder<D, B> {
|
||||
#[inline]
|
||||
pub fn data(mut self, data: VmpPMat<D, B>) -> Self {
|
||||
self.data = Some(data);
|
||||
@@ -122,7 +121,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<GGLWECiphertextPrepared<D, B>, BuildError> {
|
||||
pub fn build(self) -> Result<GGLWEPrepared<D, B>, BuildError> {
|
||||
let data: VmpPMat<D, B> = self.data.ok_or(BuildError::MissingData)?;
|
||||
let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?;
|
||||
let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?;
|
||||
@@ -152,7 +151,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
|
||||
return Err(BuildError::ZeroLimbs);
|
||||
}
|
||||
|
||||
Ok(GGLWECiphertextPrepared {
|
||||
Ok(GGLWEPrepared {
|
||||
data,
|
||||
base2k,
|
||||
k,
|
||||
@@ -161,7 +160,7 @@ impl<D: Data, B: Backend> GGLWECiphertextPreparedBuilder<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWECiphertextPrepared<Vec<u8>, B> {
|
||||
impl<B: Backend> GGLWEPrepared<Vec<u8>, B> {
|
||||
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -260,12 +259,21 @@ impl<B: Backend> GGLWECiphertextPrepared<Vec<u8>, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWECiphertextPrepared<Vec<u8>, B>
|
||||
pub trait GGLWEPrepareTmpBytes {
|
||||
fn gglwe_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWEPrepareTmpBytes for Module<B>
|
||||
where
|
||||
Module<B>: VmpPrepareTmpBytes,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
module.vmp_prepare_tmp_bytes(
|
||||
fn gglwe_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
self.vmp_prepare_tmp_bytes(
|
||||
infos.dnum().into(),
|
||||
infos.rank_in().into(),
|
||||
(infos.rank() + 1).into(),
|
||||
@@ -274,25 +282,106 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
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.k = other.k;
|
||||
self.base2k = other.base2k;
|
||||
self.dsize = other.dsize;
|
||||
impl<B: Backend> GGLWEPrepared<Vec<u8>, B> {
|
||||
pub fn prepare_tmp_bytes(&self, module: &Module<B>)
|
||||
where
|
||||
Module<B>: GGLWEPrepareTmpBytes,
|
||||
{
|
||||
module.gglwe_prepare_tmp_bytes(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWECiphertextPrepared<Vec<u8>, B>> for GGLWECiphertext<D>
|
||||
pub trait GGLWEPrepare<B: Backend> {
|
||||
fn gglwe_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
R: GGLWEPreparedToMut<B>,
|
||||
O: GGLWEToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWEPrepare<B> for Module<B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
{
|
||||
fn gglwe_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
R: GGLWEPreparedToMut<B>,
|
||||
O: GGLWEToRef,
|
||||
{
|
||||
let mut res: GGLWEPrepared<&mut [u8], B> = self.to_mut();
|
||||
let other: GGLWE<&[u8]> = other.to_ref();
|
||||
|
||||
assert_eq!(res.n(), self.n() as u32);
|
||||
assert_eq!(other.n(), self.n() as u32);
|
||||
assert_eq!(res.base2k, other.base2k);
|
||||
assert_eq!(res.k, other.k);
|
||||
assert_eq!(res.dsize, other.dsize);
|
||||
|
||||
self.vmp_prepare(&mut res.data, &other.data, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GGLWEPrepared<D, B>
|
||||
where
|
||||
Module<B>: GGLWEPrepare<B>,
|
||||
{
|
||||
fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: GGLWEToRef,
|
||||
{
|
||||
module.gglwe_prepare(self, other, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEPrepareAlloc<B: Backend> {
|
||||
fn gglwe_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> GGLWEPrepared<Vec<u8>, B>;
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWEPrepareAlloc<B> for Module<B>
|
||||
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);
|
||||
atk_prepared.prepare(module, self, scratch);
|
||||
atk_prepared
|
||||
fn gglwe_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>) -> GGLWEPrepared<Vec<u8>, B> {
|
||||
let mut ct_prepared: GGLWEPrepared<Vec<u8>, B> = GGLWEPrepared::alloc(self, &other.to_ref());
|
||||
ct_prepared.prepare(self, &other.to_ref(), scratch);
|
||||
ct_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGLWE<D> {
|
||||
fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &Scratch<B>) -> GGLWEPrepared<Vec<u8>, B>
|
||||
where
|
||||
Module<B>: GGLWEPrepareAlloc<B>,
|
||||
{
|
||||
module.gglwe_prepare_alloc(self, scratch)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEPreparedToMut<B: Backend> {
|
||||
fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GGLWEPreparedToMut<B> for GGLWEPrepared<D, B> {
|
||||
fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], B> {
|
||||
GGLWEPrepared {
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
dsize: self.dsize,
|
||||
data: self.data.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGLWEPreparedToRef<B: Backend> {
|
||||
fn to_ref(&self) -> GGLWEPrepared<&[u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> GGLWEPreparedToRef<B> for GGLWEPrepared<D, B> {
|
||||
fn to_ref(&self) -> GGLWEPrepared<&[u8], B> {
|
||||
GGLWEPrepared {
|
||||
k: self.k,
|
||||
base2k: self.base2k,
|
||||
dsize: self.dsize,
|
||||
data: self.data.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,36 @@
|
||||
use poulpy_hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{GGLWECiphertextPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWESwitchingKey, GLWESwitchingKeyToRef, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{GGLWEPrepare, GGLWEPrepareTmpBytes, GGLWEPrepared, GGLWEPreparedToMut, GGLWEPreparedToRef},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWESwitchingKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) key: GGLWECiphertextPrepared<D, B>,
|
||||
pub struct GLWESwitchingKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) key: GGLWEPrepared<D, B>,
|
||||
pub(crate) sk_in_n: usize, // Degree of sk_in
|
||||
pub(crate) sk_out_n: usize, // Degree of sk_out
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for GGLWESwitchingKeyPrepared<D, B> {
|
||||
pub(crate) trait GLWESwitchingKeyPreparedSetMetaData {
|
||||
fn set_sk_in_n(&mut self, sk_in_n: usize);
|
||||
fn set_sk_out_n(&mut self, sk_out_n: usize);
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GLWESwitchingKeyPreparedSetMetaData for GLWESwitchingKeyPrepared<D, B> {
|
||||
fn set_sk_in_n(&mut self, sk_in_n: usize) {
|
||||
self.sk_in_n = sk_in_n
|
||||
}
|
||||
|
||||
fn set_sk_out_n(&mut self, sk_out_n: usize) {
|
||||
self.sk_out_n = self.sk_out_n
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for GLWESwitchingKeyPrepared<D, B> {
|
||||
fn n(&self) -> Degree {
|
||||
self.key.n()
|
||||
}
|
||||
@@ -33,13 +48,13 @@ impl<D: Data, B: Backend> LWEInfos for GGLWESwitchingKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEInfos for GGLWESwitchingKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GLWEInfos for GLWESwitchingKeyPrepared<D, B> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWEInfos for GGLWESwitchingKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GGLWEInfos for GLWESwitchingKeyPrepared<D, B> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.key.rank_in()
|
||||
}
|
||||
@@ -57,15 +72,15 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWESwitchingKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
debug_assert_eq!(module.n() as u32, infos.n(), "module.n() != infos.n()");
|
||||
GGLWESwitchingKeyPrepared::<Vec<u8>, B> {
|
||||
key: GGLWECiphertextPrepared::alloc(module, infos),
|
||||
GLWESwitchingKeyPrepared::<Vec<u8>, B> {
|
||||
key: GGLWEPrepared::alloc(module, infos),
|
||||
sk_in_n: 0,
|
||||
sk_out_n: 0,
|
||||
}
|
||||
@@ -83,8 +98,8 @@ impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::<Vec<u8>, B> {
|
||||
key: GGLWECiphertextPrepared::alloc_with(module, base2k, k, rank_in, rank_out, dnum, dsize),
|
||||
GLWESwitchingKeyPrepared::<Vec<u8>, B> {
|
||||
key: GGLWEPrepared::alloc_with(module, base2k, k, rank_in, rank_out, dnum, dsize),
|
||||
sk_in_n: 0,
|
||||
sk_out_n: 0,
|
||||
}
|
||||
@@ -96,7 +111,7 @@ impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
debug_assert_eq!(module.n() as u32, infos.n(), "module.n() != infos.n()");
|
||||
GGLWECiphertextPrepared::alloc_bytes(module, infos)
|
||||
GGLWEPrepared::alloc_bytes(module, infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(
|
||||
@@ -111,37 +126,122 @@ impl<B: Backend> GGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWECiphertextPrepared::alloc_bytes_with(module, base2k, k, rank_in, rank_out, dnum, dsize)
|
||||
GGLWEPrepared::alloc_bytes_with(module, base2k, k, rank_in, rank_out, dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWESwitchingKeyPrepared<Vec<u8>, B>
|
||||
pub trait GLWESwitchingKeyPrepareTmpBytes {
|
||||
fn glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos;
|
||||
}
|
||||
|
||||
impl<B: Backend> GLWESwitchingKeyPrepareTmpBytes for Module<B>
|
||||
where
|
||||
GGLWECiphertextPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
Module<B>: GGLWEPrepareTmpBytes,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
GGLWECiphertextPrepared::prepare_scratch_space(module, infos)
|
||||
fn glwe_switching_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
self.gglwe_prepare_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWESwitchingKey<DR>> for GGLWESwitchingKeyPrepared<D, B>
|
||||
impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
Module<B>: GGLWEPrepareTmpBytes,
|
||||
{
|
||||
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;
|
||||
pub fn prepare_tmp_bytes(&self, module: &Module<B>) -> usize {
|
||||
module.gglwe_prepare_tmp_bytes(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGLWESwitchingKeyPrepared<Vec<u8>, B>> for GGLWESwitchingKey<D>
|
||||
pub trait GLWESwitchingKeyPrepare<B: Backend> {
|
||||
fn glwe_switching_prepare<R, O>(&self, res: &R, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeyPreparedSetMetaData,
|
||||
O: GLWESwitchingKeyToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> GLWESwitchingKeyPrepare<B> for Module<B>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
Module<B>: GGLWEPrepare<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);
|
||||
atk_prepared.prepare(module, self, scratch);
|
||||
atk_prepared
|
||||
fn glwe_switching_prepare<R, O>(&self, res: &R, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
R: GLWESwitchingKeyPreparedToMut<B> + GLWESwitchingKeyPreparedSetMetaData,
|
||||
O: GLWESwitchingKeyToRef,
|
||||
{
|
||||
self.gglwe_prepare(&res.to_mut(), other, scratch);
|
||||
res.set_sk_in_n(other.sk_in_n);
|
||||
res.set_sk_out_n(other.sk_out_n);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GLWESwitchingKeyPrepared<D, B> {
|
||||
pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: GLWESwitchingKeyToRef,
|
||||
Module<B>: GLWESwitchingKeyPrepare<B>,
|
||||
{
|
||||
module.glwe_switching_prepare(self, other, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWESwitchingKeyPrepareAlloc<B: Backend> {
|
||||
fn glwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: GLWESwitchingKeyToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> GLWESwitchingKeyPrepareAlloc<B> for Module<B>
|
||||
where
|
||||
Module<B>: GLWESwitchingKeyPrepare<B>,
|
||||
{
|
||||
fn glwe_switching_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: GLWESwitchingKeyToRef,
|
||||
{
|
||||
let mut ct_prepared: GLWESwitchingKeyPrepared<Vec<u8>, B> = GLWESwitchingKeyPrepared::alloc(self, self);
|
||||
self.glwe_switching_prepare(&mut ct_prepared, other, scratch);
|
||||
ct_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GLWESwitchingKey<D> {
|
||||
pub fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &mut Scratch<B>) -> GLWESwitchingKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
Module<B>: GLWESwitchingKeyPrepareAlloc<B>,
|
||||
{
|
||||
module.glwe_switching_key_prepare_alloc(self, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWESwitchingKeyPreparedToMut<B: Backend> {
|
||||
fn to_mut(&mut self) -> GLWESwitchingKeyPrepared<&mut [u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GLWESwitchingKeyPreparedToMut<B> for GLWESwitchingKeyPrepared<D, B> {
|
||||
fn to_mut(&mut self) -> GLWESwitchingKeyPrepared<&mut [u8], B> {
|
||||
GLWESwitchingKeyPrepared {
|
||||
sk_in_n: self.sk_in_n,
|
||||
sk_out_n: self.sk_out_n,
|
||||
key: self.key.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GLWESwitchingKeyPreparedToRef<B: Backend> {
|
||||
fn to_ref(&self) -> GLWESwitchingKeyPrepared<&[u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> GLWESwitchingKeyPreparedToRef<B> for GLWESwitchingKeyPrepared<D, B> {
|
||||
fn to_ref(&self) -> GLWESwitchingKeyPrepared<&[u8], B> {
|
||||
GLWESwitchingKeyPrepared {
|
||||
sk_in_n: self.sk_in_n,
|
||||
sk_out_n: self.sk_out_n,
|
||||
key: self.key.to_ref(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
use poulpy_hal::{
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes, VmpPrepare},
|
||||
api::{VmpPMatAlloc, VmpPMatAllocBytes},
|
||||
layouts::{Backend, Data, DataMut, DataRef, Module, Scratch},
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWETensorKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TensorKey, TensorKeyToRef, TorusPrecision,
|
||||
compressed::TensorKeyCompressedToMut,
|
||||
prepared::{
|
||||
GLWESwitchingKeyPrepare, GLWESwitchingKeyPrepareTmpBytes, GLWESwitchingKeyPrepared, GLWESwitchingKeyPreparedToMut,
|
||||
GLWESwitchingKeyPreparedToRef,
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGLWETensorKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) keys: Vec<GGLWESwitchingKeyPrepared<D, B>>,
|
||||
pub struct TensorKeyPrepared<D: Data, B: Backend> {
|
||||
pub(crate) keys: Vec<GLWESwitchingKeyPrepared<D, B>>,
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for GGLWETensorKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> LWEInfos for TensorKeyPrepared<D, B> {
|
||||
fn n(&self) -> Degree {
|
||||
self.keys[0].n()
|
||||
}
|
||||
@@ -31,13 +35,13 @@ impl<D: Data, B: Backend> LWEInfos for GGLWETensorKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEInfos for GGLWETensorKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GLWEInfos for TensorKeyPrepared<D, B> {
|
||||
fn rank(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGLWEInfos for GGLWETensorKeyPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GGLWEInfos for TensorKeyPrepared<D, B> {
|
||||
fn rank_in(&self) -> Rank {
|
||||
self.rank_out()
|
||||
}
|
||||
@@ -55,7 +59,7 @@ impl<D: Data, B: Backend> GGLWEInfos for GGLWETensorKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
|
||||
impl<B: Backend> TensorKeyPrepared<Vec<u8>, B> {
|
||||
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
@@ -80,10 +84,10 @@ impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
let mut keys: Vec<GGLWESwitchingKeyPrepared<Vec<u8>, B>> = Vec::new();
|
||||
let mut keys: Vec<GLWESwitchingKeyPrepared<Vec<u8>, B>> = Vec::new();
|
||||
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
|
||||
(0..pairs).for_each(|_| {
|
||||
keys.push(GGLWESwitchingKeyPrepared::alloc_with(
|
||||
keys.push(GLWESwitchingKeyPrepared::alloc_with(
|
||||
module,
|
||||
base2k,
|
||||
k,
|
||||
@@ -109,7 +113,7 @@ impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
|
||||
let rank_out: usize = infos.rank_out().into();
|
||||
let pairs: usize = (((rank_out + 1) * rank_out) >> 1).max(1);
|
||||
pairs
|
||||
* GGLWESwitchingKeyPrepared::alloc_bytes_with(
|
||||
* GLWESwitchingKeyPrepared::alloc_bytes_with(
|
||||
module,
|
||||
infos.base2k(),
|
||||
infos.k(),
|
||||
@@ -125,13 +129,13 @@ impl<B: Backend> GGLWETensorKeyPrepared<Vec<u8>, B> {
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
|
||||
pairs * GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank, dnum, dsize)
|
||||
pairs * GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank, dnum, dsize)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GGLWETensorKeyPrepared<D, B> {
|
||||
impl<D: DataMut, B: Backend> TensorKeyPrepared<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> {
|
||||
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GLWESwitchingKeyPrepared<D, B> {
|
||||
if i > j {
|
||||
std::mem::swap(&mut i, &mut j);
|
||||
};
|
||||
@@ -140,9 +144,9 @@ impl<D: DataMut, B: Backend> GGLWETensorKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> GGLWETensorKeyPrepared<D, B> {
|
||||
impl<D: DataRef, B: Backend> TensorKeyPrepared<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> {
|
||||
pub fn at(&self, mut i: usize, mut j: usize) -> &GLWESwitchingKeyPrepared<D, B> {
|
||||
if i > j {
|
||||
std::mem::swap(&mut i, &mut j);
|
||||
};
|
||||
@@ -151,40 +155,125 @@ impl<D: DataRef, B: Backend> GGLWETensorKeyPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GGLWETensorKeyPrepared<Vec<u8>, B>
|
||||
pub trait TensorKeyPrepareTmpBytes {
|
||||
fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize;
|
||||
}
|
||||
|
||||
impl<B: Backend> TensorKeyPrepareTmpBytes for Module<B>
|
||||
where
|
||||
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
Module<B>: GLWESwitchingKeyPrepareTmpBytes,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
fn tensor_key_prepare_tmp_bytes<A>(&self, infos: &A) -> usize {
|
||||
self.glwe_switching_key_prepare_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGLWETensorKey<DR>> for GGLWETensorKeyPrepared<D, B>
|
||||
impl<B: Backend> TensorKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
Module<B>: VmpPrepare<B>,
|
||||
Module<B>: TensorKeyPrepareTmpBytes,
|
||||
{
|
||||
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());
|
||||
fn prepare_tmp_bytes<A>(&self, module: &Module<B>, infos: &A) -> usize
|
||||
where
|
||||
A: GGLWEInfos,
|
||||
{
|
||||
module.tensor_key_prepare_tmp_bytes(infos)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TensorKeyPrepare<B: Backend> {
|
||||
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
|
||||
where
|
||||
R: TensorKeyPreparedToMut<B>,
|
||||
O: TensorKeyToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> TensorKeyPrepare<B> for Module<B>
|
||||
where
|
||||
Module<B>: GLWESwitchingKeyPrepare<B>,
|
||||
{
|
||||
fn tensor_key_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &Scratch<B>)
|
||||
where
|
||||
R: TensorKeyPreparedToMut<B>,
|
||||
O: TensorKeyToRef,
|
||||
{
|
||||
let res = res.to_mut();
|
||||
let other = other.to_ref();
|
||||
|
||||
assert_eq!(self.keys.len(), other.keys.len());
|
||||
|
||||
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
|
||||
self.glwe_switching_prepare(a, b, scratch);
|
||||
}
|
||||
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>
|
||||
impl<D: DataMut, B: Backend> TensorKeyPrepared<D, B>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
Module<B>: TensorKeyPrepare<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);
|
||||
tsk_prepared.prepare(module, self, scratch);
|
||||
tsk_prepared
|
||||
fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: TensorKeyToRef,
|
||||
{
|
||||
module.tensor_key_prepare(self, other, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TensorKeyPrepareAlloc<B: Backend> {
|
||||
fn tensor_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: TensorKeyToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> TensorKeyPrepareAlloc<B> for Module<B>
|
||||
where
|
||||
Module<B>: TensorKeyPrepare<B>,
|
||||
{
|
||||
fn tensor_key_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: TensorKeyToRef,
|
||||
{
|
||||
let mut ct_prepared: TensorKeyPrepared<Vec<u8>, B> = TensorKeyPrepared::alloc(self, other);
|
||||
self.tensor_key_prepare(ct_prepared, other, scratch);
|
||||
ct_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> TensorKey<D> {
|
||||
pub fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &Scratch<B>)
|
||||
where
|
||||
Module<B>: TensorKeyPrepareAlloc<B>,
|
||||
{
|
||||
module.tensor_key_prepare_alloc(self, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TensorKeyPreparedToMut<B: Backend> {
|
||||
fn to_mut(&mut self) -> TensorKeyPrepared<&mut [u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> TensorKeyPreparedToMut<B> for TensorKeyPrepared<D, B>
|
||||
where
|
||||
GLWESwitchingKeyPrepared<D, B>: GLWESwitchingKeyPreparedToMut<B>,
|
||||
{
|
||||
fn to_mut(&mut self) -> TensorKeyPrepared<&mut [u8], B> {
|
||||
TensorKeyPrepared {
|
||||
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait TensorKeyPreparedToRef<B: Backend> {
|
||||
fn to_ref(&self) -> TensorKeyPrepared<&[u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> TensorKeyPreparedToRef<B> for TensorKeyPrepared<D, B>
|
||||
where
|
||||
GLWESwitchingKeyPrepared<D, B>: GLWESwitchingKeyPreparedToRef<B>,
|
||||
{
|
||||
fn to_ref(&self) -> TensorKeyPrepared<&[u8], B> {
|
||||
TensorKeyPrepared {
|
||||
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,19 +5,18 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, BuildError, Degree, Dnum, Dsize, GGSWCiphertext, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
Base2K, BuildError, Degree, Dnum, Dsize, GGSW, GGSWInfos, GGSWToMut, GGSWToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GGSWCiphertextPrepared<D: Data, B: Backend> {
|
||||
pub struct GGSWPrepared<D: Data, B: Backend> {
|
||||
pub(crate) data: VmpPMat<D, B>,
|
||||
pub(crate) k: TorusPrecision,
|
||||
pub(crate) base2k: Base2K,
|
||||
pub(crate) dsize: Dsize,
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for GGSWCiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> LWEInfos for GGSWPrepared<D, B> {
|
||||
fn n(&self) -> Degree {
|
||||
Degree(self.data.n() as u32)
|
||||
}
|
||||
@@ -35,13 +34,13 @@ impl<D: Data, B: Backend> LWEInfos for GGSWCiphertextPrepared<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GLWEInfos for GGSWCiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GLWEInfos for GGSWPrepared<D, B> {
|
||||
fn rank(&self) -> Rank {
|
||||
Rank(self.data.cols_out() as u32 - 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGSWInfos for GGSWCiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GGSWInfos for GGSWPrepared<D, B> {
|
||||
fn dsize(&self) -> Dsize {
|
||||
self.dsize
|
||||
}
|
||||
@@ -58,7 +57,7 @@ pub struct GGSWCiphertextPreparedBuilder<D: Data, B: Backend> {
|
||||
dsize: Option<Dsize>,
|
||||
}
|
||||
|
||||
impl<D: Data, B: Backend> GGSWCiphertextPrepared<D, B> {
|
||||
impl<D: Data, B: Backend> GGSWPrepared<D, B> {
|
||||
#[inline]
|
||||
pub fn builder() -> GGSWCiphertextPreparedBuilder<D, B> {
|
||||
GGSWCiphertextPreparedBuilder {
|
||||
@@ -129,7 +128,7 @@ impl<D: Data, B: Backend> GGSWCiphertextPreparedBuilder<D, B> {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<GGSWCiphertextPrepared<D, B>, BuildError> {
|
||||
pub fn build(self) -> Result<GGSWPrepared<D, B>, BuildError> {
|
||||
let data: VmpPMat<D, B> = self.data.ok_or(BuildError::MissingData)?;
|
||||
let base2k: Base2K = self.base2k.ok_or(BuildError::MissingBase2K)?;
|
||||
let k: TorusPrecision = self.k.ok_or(BuildError::MissingK)?;
|
||||
@@ -159,7 +158,7 @@ impl<D: Data, B: Backend> GGSWCiphertextPreparedBuilder<D, B> {
|
||||
return Err(BuildError::ZeroLimbs);
|
||||
}
|
||||
|
||||
Ok(GGSWCiphertextPrepared {
|
||||
Ok(GGSWPrepared {
|
||||
data,
|
||||
base2k,
|
||||
k,
|
||||
@@ -168,7 +167,7 @@ impl<D: Data, B: Backend> GGSWCiphertextPreparedBuilder<D, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> GGSWCiphertextPrepared<Vec<u8>, B> {
|
||||
impl<B: Backend> GGSWPrepared<Vec<u8>, B> {
|
||||
pub fn alloc<A>(module: &Module<B>, infos: &A) -> Self
|
||||
where
|
||||
A: GGSWInfos,
|
||||
@@ -252,18 +251,27 @@ impl<B: Backend> GGSWCiphertextPrepared<Vec<u8>, B> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> GGSWCiphertextPrepared<D, B> {
|
||||
impl<D: DataRef, B: Backend> GGSWPrepared<D, B> {
|
||||
pub fn data(&self) -> &VmpPMat<D, B> {
|
||||
&self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGSWInfos> PrepareScratchSpace<B, A> for GGSWCiphertextPrepared<Vec<u8>, B>
|
||||
pub trait GGSWPrepareTmpBytes {
|
||||
fn ggsw_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGSWInfos;
|
||||
}
|
||||
|
||||
impl<B: Backend> GGSWPrepareTmpBytes for Module<B>
|
||||
where
|
||||
Module<B>: VmpPrepareTmpBytes,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
module.vmp_prepare_tmp_bytes(
|
||||
fn ggsw_prepare_tmp_bytes<A>(&self, infos: &A) -> usize
|
||||
where
|
||||
A: GGSWInfos,
|
||||
{
|
||||
self.vmp_prepare_tmp_bytes(
|
||||
infos.dnum().into(),
|
||||
(infos.rank() + 1).into(),
|
||||
(infos.rank() + 1).into(),
|
||||
@@ -272,57 +280,110 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataMut, DR: DataRef, B: Backend> Prepare<B, GGSWCiphertext<DR>> for GGSWCiphertextPrepared<D, B>
|
||||
impl<B: Backend> GGSWPrepared<Vec<u8>, B>
|
||||
where
|
||||
Module<B>: GGSWPrepareTmpBytes,
|
||||
{
|
||||
pub fn prepare_tmp_bytes<A>(&self, module: Module<B>, infos: &A) -> usize
|
||||
where
|
||||
A: GGSWInfos,
|
||||
{
|
||||
module.ggsw_prepare_tmp_bytes(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGSWPrepare<B: Backend> {
|
||||
fn ggsw_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
R: GGSWPreparedToMut<B>,
|
||||
O: GGSWToRef;
|
||||
}
|
||||
|
||||
impl<B: Backend> GGSWPrepare<B> for Module<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.base2k = other.base2k;
|
||||
self.dsize = other.dsize;
|
||||
fn ggsw_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
R: GGSWPreparedToMut<B>,
|
||||
O: GGSWToRef,
|
||||
{
|
||||
let mut res: GGSWPrepared<&mut [u8], B> = res.to_mut();
|
||||
let other: GGSW<&[u8]> = other.to_ref();
|
||||
assert_eq!(res.k, other.k);
|
||||
assert_eq!(res.base2k, other.base2k);
|
||||
assert_eq!(res.dsize, other.dsize);
|
||||
self.vmp_prepare(&mut res.data, &other.data, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GGSWCiphertextPrepared<Vec<u8>, B>> for GGSWCiphertext<D>
|
||||
impl<D: DataMut, B: Backend> GGSWPrepared<D, B>
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B> + VmpPrepare<B>,
|
||||
Module<B>: GGSWPrepare<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);
|
||||
ggsw_prepared.prepare(module, self, scratch);
|
||||
ggsw_prepared
|
||||
pub fn prepare<O>(&mut self, module: &Module<B>, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: GGSWToRef,
|
||||
{
|
||||
module.ggsw_prepare(self, other, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGSWCiphertextPreparedToMut<B: Backend> {
|
||||
fn to_ref(&mut self) -> GGSWCiphertextPrepared<&mut [u8], B>;
|
||||
pub trait GGSWPrepareAlloc<B: Backend> {
|
||||
fn ggsw_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: GGSWToRef;
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GGSWCiphertextPreparedToMut<B> for GGSWCiphertextPrepared<D, B> {
|
||||
fn to_ref(&mut self) -> GGSWCiphertextPrepared<&mut [u8], B> {
|
||||
GGSWCiphertextPrepared::builder()
|
||||
.base2k(self.base2k())
|
||||
.dsize(self.dsize())
|
||||
.k(self.k())
|
||||
.data(self.data.to_mut())
|
||||
.build()
|
||||
.unwrap()
|
||||
impl<B: Backend> GGSWPrepareAlloc<B> for Module<B>
|
||||
where
|
||||
Module<B>: GGSWPrepare<B>,
|
||||
{
|
||||
fn ggsw_prepare_alloc<O>(&self, other: &O, scratch: &mut Scratch<B>)
|
||||
where
|
||||
O: GGSWToRef,
|
||||
{
|
||||
let mut ct_prepared: GGSWPrepared<Vec<u8>, B> = GGSWPrepared::alloc(self, other);
|
||||
self.ggsw_prepare(&mut ct_prepared, other, scratch);
|
||||
ct_prepared
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef> GGSW<D> {
|
||||
fn prepare_alloc<B: Backend>(&self, module: &Module<B>, scratch: &mut Scratch<B>)
|
||||
where
|
||||
Module<B>: GGSWPrepareAlloc<B>,
|
||||
{
|
||||
module.ggsw_prepare_alloc(self, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGSWPreparedToMut<B: Backend> {
|
||||
fn to_mut(&mut self) -> GGSWPrepared<&mut [u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GGSWPreparedToMut<B> for GGSWPrepared<D, B> {
|
||||
fn to_mut(&mut self) -> GGSWPrepared<&mut [u8], B> {
|
||||
GGSWPrepared {
|
||||
base2k: self.base2k,
|
||||
k: self.k,
|
||||
dsize: self.dsize,
|
||||
data: self.data.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GGSWCiphertextPreparedToRef<B: Backend> {
|
||||
fn to_ref(&self) -> GGSWCiphertextPrepared<&[u8], B>;
|
||||
fn to_ref(&self) -> GGSWPrepared<&[u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> GGSWCiphertextPreparedToRef<B> for GGSWCiphertextPrepared<D, B> {
|
||||
fn to_ref(&self) -> GGSWCiphertextPrepared<&[u8], B> {
|
||||
GGSWCiphertextPrepared::builder()
|
||||
.base2k(self.base2k())
|
||||
.dsize(self.dsize())
|
||||
.k(self.k())
|
||||
.data(self.data.to_ref())
|
||||
.build()
|
||||
.unwrap()
|
||||
impl<D: DataRef, B: Backend> GGSWCiphertextPreparedToRef<B> for GGSWPrepared<D, B> {
|
||||
fn to_ref(&self) -> GGSWPrepared<&[u8], B> {
|
||||
GGSWPrepared {
|
||||
base2k: self.base2k,
|
||||
k: self.k,
|
||||
dsize: self.dsize,
|
||||
data: self.data.to_mut(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,7 @@ use poulpy_hal::{
|
||||
|
||||
use crate::{
|
||||
dist::Distribution,
|
||||
layouts::{
|
||||
Base2K, BuildError, Degree, GLWEInfos, GLWEPublicKey, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
},
|
||||
layouts::{Base2K, BuildError, Degree, GLWEInfos, GLWEPublicKey, LWEInfos, Rank, TorusPrecision},
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
|
||||
@@ -5,10 +5,7 @@ use poulpy_hal::{
|
||||
|
||||
use crate::{
|
||||
dist::Distribution,
|
||||
layouts::{
|
||||
Base2K, Degree, GLWEInfos, GLWESecret, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
},
|
||||
layouts::{Base2K, Degree, GLWEInfos, GLWESecret, LWEInfos, Rank, TorusPrecision},
|
||||
};
|
||||
|
||||
pub struct GLWESecretPrepared<D: Data, B: Backend> {
|
||||
@@ -128,11 +125,11 @@ impl<D: DataRef, B: Backend> GLWESecretPreparedToRef<B> for GLWESecretPrepared<D
|
||||
}
|
||||
|
||||
pub trait GLWESecretPreparedToMut<B: Backend> {
|
||||
fn to_ref(&mut self) -> GLWESecretPrepared<&mut [u8], B>;
|
||||
fn to_mut(&mut self) -> GLWESecretPrepared<&mut [u8], B>;
|
||||
}
|
||||
|
||||
impl<D: DataMut, B: Backend> GLWESecretPreparedToMut<B> for GLWESecretPrepared<D, B> {
|
||||
fn to_ref(&mut self) -> GLWESecretPrepared<&mut [u8], B> {
|
||||
fn to_mut(&mut self) -> GLWESecretPrepared<&mut [u8], B> {
|
||||
GLWESecretPrepared {
|
||||
dist: self.dist,
|
||||
data: self.data.to_mut(),
|
||||
|
||||
@@ -4,12 +4,12 @@ use poulpy_hal::{
|
||||
};
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWEKey, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, GLWEToLWESwitchingKey, LWEInfos, Rank, TorusPrecision,
|
||||
prepared::GLWESwitchingKeyPrepared,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct GLWEToLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
|
||||
pub struct GLWEToLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
@@ -69,14 +69,14 @@ impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
1,
|
||||
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
|
||||
);
|
||||
Self(GGLWESwitchingKeyPrepared::alloc(module, infos))
|
||||
Self(GLWESwitchingKeyPrepared::alloc(module, infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
Self(GGLWESwitchingKeyPrepared::alloc_with(
|
||||
Self(GLWESwitchingKeyPrepared::alloc_with(
|
||||
module,
|
||||
base2k,
|
||||
k,
|
||||
@@ -102,27 +102,27 @@ impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
1,
|
||||
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
|
||||
);
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
||||
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, rank_in, Rank(1), dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
GLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>> for GLWEToLWEKey<D>
|
||||
impl<D: DataRef, B: Backend> PrepareAlloc<B, GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>> for GLWEToLWESwitchingKey<D>
|
||||
where
|
||||
Module<B>: VmpPrepare<B> + VmpPMatAlloc<B>,
|
||||
{
|
||||
@@ -133,11 +133,11 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<DM: DataMut, DR: DataRef, B: Backend> Prepare<B, GLWEToLWEKey<DR>> for GLWEToLWESwitchingKeyPrepared<DM, B>
|
||||
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: &GLWEToLWEKey<DR>, scratch: &mut Scratch<B>) {
|
||||
fn prepare(&mut self, module: &Module<B>, other: &GLWEToLWESwitchingKey<DR>, scratch: &mut Scratch<B>) {
|
||||
self.0.prepare(module, &other.0, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ use poulpy_hal::{
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, TorusPrecision,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
prepared::GLWESwitchingKeyPrepared,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct LWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWESwitchingKeyPrepared<D, B>);
|
||||
pub struct LWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for LWESwitchingKeyPrepared<D, B> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
@@ -73,14 +73,14 @@ impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
1,
|
||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||
);
|
||||
Self(GGLWESwitchingKeyPrepared::alloc(module, infos))
|
||||
Self(GLWESwitchingKeyPrepared::alloc(module, infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
Self(GGLWESwitchingKeyPrepared::alloc_with(
|
||||
Self(GLWESwitchingKeyPrepared::alloc_with(
|
||||
module,
|
||||
base2k,
|
||||
k,
|
||||
@@ -111,23 +111,23 @@ impl<B: Backend> LWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
1,
|
||||
"rank_out > 1 is not supported for LWESwitchingKey"
|
||||
);
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
||||
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for LWESwitchingKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
GLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@ use poulpy_hal::{
|
||||
|
||||
use crate::layouts::{
|
||||
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, Rank, TorusPrecision,
|
||||
prepared::{GGLWESwitchingKeyPrepared, Prepare, PrepareAlloc, PrepareScratchSpace},
|
||||
prepared::GLWESwitchingKeyPrepared,
|
||||
};
|
||||
|
||||
/// 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>);
|
||||
pub struct LWEToGLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
|
||||
|
||||
impl<D: Data, B: Backend> LWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
|
||||
fn base2k(&self) -> Base2K {
|
||||
@@ -70,14 +70,14 @@ impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
1,
|
||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||
);
|
||||
Self(GGLWESwitchingKeyPrepared::alloc(module, infos))
|
||||
Self(GLWESwitchingKeyPrepared::alloc(module, infos))
|
||||
}
|
||||
|
||||
pub fn alloc_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self
|
||||
where
|
||||
Module<B>: VmpPMatAlloc<B>,
|
||||
{
|
||||
Self(GGLWESwitchingKeyPrepared::alloc_with(
|
||||
Self(GLWESwitchingKeyPrepared::alloc_with(
|
||||
module,
|
||||
base2k,
|
||||
k,
|
||||
@@ -103,23 +103,23 @@ impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
|
||||
1,
|
||||
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
|
||||
);
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
GLWESwitchingKeyPrepared::alloc_bytes(module, infos)
|
||||
}
|
||||
|
||||
pub fn alloc_bytes_with(module: &Module<B>, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_out: Rank) -> usize
|
||||
where
|
||||
Module<B>: VmpPMatAllocBytes,
|
||||
{
|
||||
GGLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
||||
GLWESwitchingKeyPrepared::alloc_bytes_with(module, base2k, k, Rank(1), rank_out, dnum, Dsize(1))
|
||||
}
|
||||
}
|
||||
|
||||
impl<B: Backend, A: GGLWEInfos> PrepareScratchSpace<B, A> for LWEToGLWESwitchingKeyPrepared<Vec<u8>, B>
|
||||
where
|
||||
GGLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
GLWESwitchingKeyPrepared<Vec<u8>, B>: PrepareScratchSpace<B, A>,
|
||||
{
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &A) -> usize {
|
||||
GGLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
GLWESwitchingKeyPrepared::prepare_scratch_space(module, infos)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,16 +19,3 @@ pub use glwe_sk::*;
|
||||
pub use glwe_to_lwe_ksk::*;
|
||||
pub use lwe_ksk::*;
|
||||
pub use lwe_to_glwe_ksk::*;
|
||||
use poulpy_hal::layouts::{Backend, Module, Scratch};
|
||||
|
||||
pub trait PrepareScratchSpace<B: Backend, T> {
|
||||
fn prepare_scratch_space(module: &Module<B>, infos: &T) -> usize;
|
||||
}
|
||||
|
||||
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