Distinguish between gglwe_to_ggsw key and tensor_key + update key repreentation

This commit is contained in:
Pro7ech
2025-10-27 11:28:53 +01:00
parent 41ca5aafcc
commit 8d4c19a304
59 changed files with 2812 additions and 1596 deletions

View File

@@ -0,0 +1,237 @@
use poulpy_hal::{
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
source::Source,
};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWECompressed, GGLWECompressedToMut, GGLWECompressedToRef, GGLWEDecompress, GGLWEInfos,
GGLWEToGGSWKey, GGLWEToGGSWKeyToMut, GLWEInfos, LWEInfos, Rank, TorusPrecision,
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::fmt;
#[derive(PartialEq, Eq, Clone)]
pub struct GGLWEToGGSWKeyCompressed<D: Data> {
pub(crate) keys: Vec<GGLWECompressed<D>>,
}
impl<D: Data> LWEInfos for GGLWEToGGSWKeyCompressed<D> {
fn n(&self) -> Degree {
self.keys[0].n()
}
fn base2k(&self) -> Base2K {
self.keys[0].base2k()
}
fn k(&self) -> TorusPrecision {
self.keys[0].k()
}
fn size(&self) -> usize {
self.keys[0].size()
}
}
impl<D: Data> GLWEInfos for GGLWEToGGSWKeyCompressed<D> {
fn rank(&self) -> Rank {
self.keys[0].rank_out()
}
}
impl<D: Data> GGLWEInfos for GGLWEToGGSWKeyCompressed<D> {
fn rank_in(&self) -> Rank {
self.rank_out()
}
fn rank_out(&self) -> Rank {
self.keys[0].rank_out()
}
fn dsize(&self) -> Dsize {
self.keys[0].dsize()
}
fn dnum(&self) -> Dnum {
self.keys[0].dnum()
}
}
impl<D: DataRef> fmt::Debug for GGLWEToGGSWKeyCompressed<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl<D: DataMut> FillUniform for GGLWEToGGSWKeyCompressed<D> {
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
self.keys
.iter_mut()
.for_each(|key: &mut GGLWECompressed<D>| key.fill_uniform(log_bound, source))
}
}
impl<D: DataRef> fmt::Display for GGLWEToGGSWKeyCompressed<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "(GGLWEToGGSWKeyCompressed)",)?;
for (i, key) in self.keys.iter().enumerate() {
write!(f, "{i}: {key}")?;
}
Ok(())
}
}
impl GGLWEToGGSWKeyCompressed<Vec<u8>> {
pub fn alloc_from_infos<A>(infos: &A) -> Self
where
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEToGGSWKeyCompressed"
);
Self::alloc(
infos.n(),
infos.base2k(),
infos.k(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
GGLWEToGGSWKeyCompressed {
keys: (0..rank.as_usize())
.map(|_| GGLWECompressed::alloc(n, base2k, k, rank, rank, dnum, dsize))
.collect(),
}
}
pub fn bytes_of_from_infos<A>(infos: &A) -> usize
where
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEToGGSWKeyCompressed"
);
Self::bytes_of(
infos.n(),
infos.base2k(),
infos.k(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
rank.as_usize() * GGLWECompressed::bytes_of(n, base2k, k, rank, dnum, dsize)
}
}
impl<D: DataMut> GGLWEToGGSWKeyCompressed<D> {
// Returns a mutable reference to GGLWE_{s}([s[i]*s[0], s[i]*s[1], ..., s[i]*s[rank]])
pub fn at_mut(&mut self, i: usize) -> &mut GGLWECompressed<D> {
assert!((i as u32) < self.rank());
&mut self.keys[i]
}
}
impl<D: DataRef> GGLWEToGGSWKeyCompressed<D> {
// Returns a reference to GGLWE_{s}(s[i] * s[j])
pub fn at(&self, i: usize) -> &GGLWECompressed<D> {
assert!((i as u32) < self.rank());
&self.keys[i]
}
}
impl<D: DataMut> ReaderFrom for GGLWEToGGSWKeyCompressed<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 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("self.keys.len()={} != read len={}", self.keys.len(), len),
));
}
for key in &mut self.keys {
key.read_from(reader)?;
}
Ok(())
}
}
impl<D: DataRef> WriterTo for GGLWEToGGSWKeyCompressed<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 {
key.write_to(writer)?;
}
Ok(())
}
}
pub trait GGLWEToGGSWKeyDecompress
where
Self: GGLWEDecompress,
{
fn decompress_gglwe_to_ggsw_key<R, O>(&self, res: &mut R, other: &O)
where
R: GGLWEToGGSWKeyToMut,
O: GGLWEToGGSWKeyCompressedToRef,
{
let res: &mut GGLWEToGGSWKey<&mut [u8]> = &mut res.to_mut();
let other: &GGLWEToGGSWKeyCompressed<&[u8]> = &other.to_ref();
assert_eq!(res.keys.len(), other.keys.len());
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
self.decompress_gglwe(a, b);
}
}
}
impl<D: DataMut> GGLWEToGGSWKey<D> {
pub fn decompress<O, M>(&mut self, module: &M, other: &O)
where
M: GGLWEToGGSWKeyDecompress,
O: GGLWEToGGSWKeyCompressedToRef,
{
module.decompress_gglwe_to_ggsw_key(self, other);
}
}
pub trait GGLWEToGGSWKeyCompressedToRef {
fn to_ref(&self) -> GGLWEToGGSWKeyCompressed<&[u8]>;
}
impl<D: DataRef> GGLWEToGGSWKeyCompressedToRef for GGLWEToGGSWKeyCompressed<D>
where
GGLWECompressed<D>: GGLWECompressedToRef,
{
fn to_ref(&self) -> GGLWEToGGSWKeyCompressed<&[u8]> {
GGLWEToGGSWKeyCompressed {
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
}
}
}
pub trait GGLWEToGGSWKeyCompressedToMut {
fn to_mut(&mut self) -> GGLWEToGGSWKeyCompressed<&mut [u8]>;
}
impl<D: DataMut> GGLWEToGGSWKeyCompressedToMut for GGLWEToGGSWKeyCompressed<D>
where
GGLWECompressed<D>: GGLWECompressedToMut,
{
fn to_mut(&mut self) -> GGLWEToGGSWKeyCompressed<&mut [u8]> {
GGLWEToGGSWKeyCompressed {
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
}
}
}

View File

@@ -4,31 +4,34 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWECompressed, GGLWECompressedToMut, GGLWECompressedToRef, GGLWEDecompress, GGLWEInfos,
GLWEInfos, GLWETensorKey, GLWETensorKeyToMut, LWEInfos, Rank, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGLWECompressed, GGLWECompressedSeedMut, GGLWECompressedToMut, GGLWECompressedToRef,
GGLWEDecompress, GGLWEInfos, GGLWEToMut, GLWEInfos, GLWETensorKey, LWEInfos, Rank, TorusPrecision,
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::fmt;
#[derive(PartialEq, Eq, Clone)]
pub struct GLWETensorKeyCompressed<D: Data> {
pub(crate) keys: Vec<GGLWECompressed<D>>,
pub struct GLWETensorKeyCompressed<D: Data>(pub(crate) GGLWECompressed<D>);
impl<D: DataMut> GGLWECompressedSeedMut for GLWETensorKeyCompressed<D> {
fn seed_mut(&mut self) -> &mut Vec<[u8; 32]> {
&mut self.0.seed
}
}
impl<D: Data> LWEInfos for GLWETensorKeyCompressed<D> {
fn n(&self) -> Degree {
self.keys[0].n()
self.0.n()
}
fn base2k(&self) -> Base2K {
self.keys[0].base2k()
self.0.base2k()
}
fn k(&self) -> TorusPrecision {
self.keys[0].k()
self.0.k()
}
fn size(&self) -> usize {
self.keys[0].size()
self.0.size()
}
}
impl<D: Data> GLWEInfos for GLWETensorKeyCompressed<D> {
@@ -43,15 +46,15 @@ impl<D: Data> GGLWEInfos for GLWETensorKeyCompressed<D> {
}
fn rank_out(&self) -> Rank {
self.keys[0].rank_out()
self.0.rank_out()
}
fn dsize(&self) -> Dsize {
self.keys[0].dsize()
self.0.dsize()
}
fn dnum(&self) -> Dnum {
self.keys[0].dnum()
self.0.dnum()
}
}
@@ -63,18 +66,14 @@ impl<D: DataRef> fmt::Debug for GLWETensorKeyCompressed<D> {
impl<D: DataMut> FillUniform for GLWETensorKeyCompressed<D> {
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
self.keys
.iter_mut()
.for_each(|key: &mut GGLWECompressed<D>| key.fill_uniform(log_bound, source))
self.0.fill_uniform(log_bound, source);
}
}
impl<D: DataRef> fmt::Display for GLWETensorKeyCompressed<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "(GLWETensorKeyCompressed)",)?;
for (i, key) in self.keys.iter().enumerate() {
write!(f, "{i}: {key}")?;
}
write!(f, "{}", self.0)?;
Ok(())
}
}
@@ -96,11 +95,15 @@ impl GLWETensorKeyCompressed<Vec<u8>> {
pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1);
GLWETensorKeyCompressed {
keys: (0..pairs)
.map(|_| GGLWECompressed::alloc(n, base2k, k, Rank(1), rank, dnum, dsize))
.collect(),
}
GLWETensorKeyCompressed(GGLWECompressed::alloc(
n,
base2k,
k,
Rank(pairs),
rank,
dnum,
dsize,
))
}
pub fn bytes_of_from_infos<A>(infos: &A) -> usize
@@ -118,88 +121,35 @@ impl GLWETensorKeyCompressed<Vec<u8>> {
}
pub fn bytes_of(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 * GGLWECompressed::bytes_of(n, base2k, k, Rank(1), dnum, dsize)
let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1);
GGLWECompressed::bytes_of(n, base2k, k, Rank(pairs), dnum, dsize)
}
}
impl<D: DataMut> ReaderFrom for GLWETensorKeyCompressed<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 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("self.keys.len()={} != read len={}", self.keys.len(), len),
));
}
for key in &mut self.keys {
key.read_from(reader)?;
}
self.0.read_from(reader)?;
Ok(())
}
}
impl<D: DataRef> WriterTo for GLWETensorKeyCompressed<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 {
key.write_to(writer)?;
}
self.0.write_to(writer)?;
Ok(())
}
}
pub trait GLWETensorKeyCompressedAtRef<D: DataRef> {
fn at(&self, i: usize, j: usize) -> &GGLWECompressed<D>;
}
impl<D: DataRef> GLWETensorKeyCompressedAtRef<D> for GLWETensorKeyCompressed<D> {
fn at(&self, mut i: usize, mut j: usize) -> &GGLWECompressed<D> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank_out().into();
&self.keys[i * rank + j - (i * (i + 1) / 2)]
}
}
pub trait GLWETensorKeyCompressedAtMut<D: DataMut> {
fn at_mut(&mut self, i: usize, j: usize) -> &mut GGLWECompressed<D>;
}
impl<D: DataMut> GLWETensorKeyCompressedAtMut<D> for GLWETensorKeyCompressed<D> {
fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWECompressed<D> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank_out().into();
&mut self.keys[i * rank + j - (i * (i + 1) / 2)]
}
}
pub trait GLWETensorKeyDecompress
where
Self: GGLWEDecompress,
{
fn decompress_tensor_key<R, O>(&self, res: &mut R, other: &O)
where
R: GLWETensorKeyToMut,
O: GLWETensorKeyCompressedToRef,
R: GGLWEToMut,
O: GGLWECompressedToRef,
{
let res: &mut GLWETensorKey<&mut [u8]> = &mut res.to_mut();
let other: &GLWETensorKeyCompressed<&[u8]> = &other.to_ref();
assert_eq!(
res.keys.len(),
other.keys.len(),
"invalid receiver: res.keys.len()={} != other.keys.len()={}",
res.keys.len(),
other.keys.len()
);
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
self.decompress_gglwe(a, b);
}
self.decompress_gglwe(res, other);
}
}
@@ -208,39 +158,27 @@ impl<B: Backend> GLWETensorKeyDecompress for Module<B> where Self: GGLWEDecompre
impl<D: DataMut> GLWETensorKey<D> {
pub fn decompress<O, M>(&mut self, module: &M, other: &O)
where
O: GLWETensorKeyCompressedToRef,
O: GGLWECompressedToRef,
M: GLWETensorKeyDecompress,
{
module.decompress_tensor_key(self, other);
}
}
pub trait GLWETensorKeyCompressedToMut {
fn to_mut(&mut self) -> GLWETensorKeyCompressed<&mut [u8]>;
}
impl<D: DataMut> GLWETensorKeyCompressedToMut for GLWETensorKeyCompressed<D>
impl<D: DataMut> GGLWECompressedToMut for GLWETensorKeyCompressed<D>
where
GGLWECompressed<D>: GGLWECompressedToMut,
{
fn to_mut(&mut self) -> GLWETensorKeyCompressed<&mut [u8]> {
GLWETensorKeyCompressed {
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
}
fn to_mut(&mut self) -> GGLWECompressed<&mut [u8]> {
self.0.to_mut()
}
}
pub trait GLWETensorKeyCompressedToRef {
fn to_ref(&self) -> GLWETensorKeyCompressed<&[u8]>;
}
impl<D: DataRef> GLWETensorKeyCompressedToRef for GLWETensorKeyCompressed<D>
impl<D: DataRef> GGLWECompressedToRef for GLWETensorKeyCompressed<D>
where
GGLWECompressed<D>: GGLWECompressedToRef,
{
fn to_ref(&self) -> GLWETensorKeyCompressed<&[u8]> {
GLWETensorKeyCompressed {
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
}
fn to_ref(&self) -> GGLWECompressed<&[u8]> {
self.0.to_ref()
}
}

View File

@@ -7,7 +7,7 @@ use poulpy_hal::{
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWECompressed, GGLWECompressedToMut, GGLWECompressedToRef, GGLWEInfos, GGLWEToMut, GLWEInfos,
GLWESwitchingKeyDegrees, GLWESwitchingKeyDegreesMut, GLWEToLWESwitchingKey, LWEInfos, Rank, TorusPrecision,
GLWESwitchingKeyDegrees, GLWESwitchingKeyDegreesMut, GLWEToLWEKey, LWEInfos, Rank, TorusPrecision,
compressed::{GLWESwitchingKeyCompressed, GLWESwitchingKeyDecompress},
};
@@ -147,7 +147,7 @@ pub trait GLWEToLWESwitchingKeyDecompress
where
Self: GLWESwitchingKeyDecompress,
{
fn decompress_glwe_to_lwe_switching_key<R, O>(&self, res: &mut R, other: &O)
fn decompress_glwe_to_lwe_key<R, O>(&self, res: &mut R, other: &O)
where
R: GGLWEToMut + GLWESwitchingKeyDegreesMut,
O: GGLWECompressedToRef + GLWESwitchingKeyDegrees,
@@ -158,13 +158,13 @@ where
impl<B: Backend> GLWEToLWESwitchingKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
impl<D: DataMut> GLWEToLWESwitchingKey<D> {
impl<D: DataMut> GLWEToLWEKey<D> {
pub fn decompress<O, M>(&mut self, module: &M, other: &O)
where
O: GGLWECompressedToRef + GLWESwitchingKeyDegrees,
M: GLWEToLWESwitchingKeyDecompress,
{
module.decompress_glwe_to_lwe_switching_key(self, other);
module.decompress_glwe_to_lwe_key(self, other);
}
}

View File

@@ -5,15 +5,15 @@ use poulpy_hal::{
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWECompressed, GGLWECompressedToMut, GGLWECompressedToRef, GGLWEInfos, GGLWEToMut, GLWEInfos,
GLWESwitchingKeyDegrees, GLWESwitchingKeyDegreesMut, LWEInfos, LWEToGLWESwitchingKey, Rank, TorusPrecision,
GLWESwitchingKeyDegrees, GLWESwitchingKeyDegreesMut, LWEInfos, LWEToGLWEKey, Rank, TorusPrecision,
compressed::{GLWESwitchingKeyCompressed, GLWESwitchingKeyDecompress},
};
use std::fmt;
#[derive(PartialEq, Eq, Clone)]
pub struct LWEToGLWESwitchingKeyCompressed<D: Data>(pub(crate) GLWESwitchingKeyCompressed<D>);
pub struct LWEToGLWEKeyCompressed<D: Data>(pub(crate) GLWESwitchingKeyCompressed<D>);
impl<D: Data> LWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: Data> LWEInfos for LWEToGLWEKeyCompressed<D> {
fn n(&self) -> Degree {
self.0.n()
}
@@ -29,13 +29,13 @@ impl<D: Data> LWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
self.0.size()
}
}
impl<D: Data> GLWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: Data> GLWEInfos for LWEToGLWEKeyCompressed<D> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data> GGLWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: Data> GGLWEInfos for LWEToGLWEKeyCompressed<D> {
fn dsize(&self) -> Dsize {
self.0.dsize()
}
@@ -53,37 +53,37 @@ impl<D: Data> GGLWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
}
}
impl<D: DataRef> fmt::Debug for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: DataRef> fmt::Debug for LWEToGLWEKeyCompressed<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl<D: DataMut> FillUniform for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: DataMut> FillUniform for LWEToGLWEKeyCompressed<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 LWEToGLWESwitchingKeyCompressed<D> {
impl<D: DataRef> fmt::Display for LWEToGLWEKeyCompressed<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(LWEToGLWESwitchingKeyCompressed) {}", self.0)
}
}
impl<D: DataMut> ReaderFrom for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: DataMut> ReaderFrom for LWEToGLWEKeyCompressed<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 LWEToGLWESwitchingKeyCompressed<D> {
impl<D: DataRef> WriterTo for LWEToGLWEKeyCompressed<D> {
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
self.0.write_to(writer)
}
}
impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
impl LWEToGLWEKeyCompressed<Vec<u8>> {
pub fn alloc_from_infos<A>(infos: &A) -> Self
where
A: GGLWEInfos,
@@ -108,7 +108,7 @@ impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
}
pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
LWEToGLWESwitchingKeyCompressed(GLWESwitchingKeyCompressed::alloc(
LWEToGLWEKeyCompressed(GLWESwitchingKeyCompressed::alloc(
n,
base2k,
k,
@@ -141,11 +141,11 @@ impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
}
}
pub trait LWEToGLWESwitchingKeyDecompress
pub trait LWEToGLWEKeyDecompress
where
Self: GLWESwitchingKeyDecompress,
{
fn decompress_lwe_to_glwe_switching_key<R, O>(&self, res: &mut R, other: &O)
fn decompress_lwe_to_glwe_key<R, O>(&self, res: &mut R, other: &O)
where
R: GGLWEToMut + GLWESwitchingKeyDegreesMut,
O: GGLWECompressedToRef + GLWESwitchingKeyDegrees,
@@ -154,25 +154,25 @@ where
}
}
impl<B: Backend> LWEToGLWESwitchingKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
impl<B: Backend> LWEToGLWEKeyDecompress for Module<B> where Self: GLWESwitchingKeyDecompress {}
impl<D: DataMut> LWEToGLWESwitchingKey<D> {
impl<D: DataMut> LWEToGLWEKey<D> {
pub fn decompress<O, M>(&mut self, module: &M, other: &O)
where
O: GGLWECompressedToRef + GLWESwitchingKeyDegrees,
M: LWEToGLWESwitchingKeyDecompress,
M: LWEToGLWEKeyDecompress,
{
module.decompress_lwe_to_glwe_switching_key(self, other);
module.decompress_lwe_to_glwe_key(self, other);
}
}
impl<D: DataRef> GGLWECompressedToRef for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: DataRef> GGLWECompressedToRef for LWEToGLWEKeyCompressed<D> {
fn to_ref(&self) -> GGLWECompressed<&[u8]> {
self.0.to_ref()
}
}
impl<D: DataMut> GGLWECompressedToMut for LWEToGLWESwitchingKeyCompressed<D> {
impl<D: DataMut> GGLWECompressedToMut for LWEToGLWEKeyCompressed<D> {
fn to_mut(&mut self) -> GGLWECompressed<&mut [u8]> {
self.0.to_mut()
}

View File

@@ -1,21 +1,23 @@
mod gglwe;
mod gglwe_to_ggsw_key;
mod ggsw;
mod glwe;
mod glwe_automorphism_key;
mod glwe_switching_key;
mod glwe_tensor_key;
mod glwe_to_lwe_switching_key;
mod glwe_to_lwe_key;
mod lwe;
mod lwe_switching_key;
mod lwe_to_glwe_switching_key;
mod lwe_to_glwe_key;
pub use gglwe::*;
pub use gglwe_to_ggsw_key::*;
pub use ggsw::*;
pub use glwe::*;
pub use glwe_automorphism_key::*;
pub use glwe_switching_key::*;
pub use glwe_tensor_key::*;
pub use glwe_to_lwe_switching_key::*;
pub use glwe_to_lwe_key::*;
pub use lwe::*;
pub use lwe_switching_key::*;
pub use lwe_to_glwe_switching_key::*;
pub use lwe_to_glwe_key::*;

View File

@@ -0,0 +1,254 @@
use poulpy_hal::{
layouts::{Data, DataMut, DataRef, FillUniform, ReaderFrom, WriterTo},
source::Source,
};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GGLWEToMut, GGLWEToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::fmt;
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct GGLWEToGGSWKeyLayout {
pub n: Degree,
pub base2k: Base2K,
pub k: TorusPrecision,
pub rank: Rank,
pub dnum: Dnum,
pub dsize: Dsize,
}
#[derive(PartialEq, Eq, Clone)]
pub struct GGLWEToGGSWKey<D: Data> {
pub(crate) keys: Vec<GGLWE<D>>,
}
impl<D: Data> LWEInfos for GGLWEToGGSWKey<D> {
fn n(&self) -> Degree {
self.keys[0].n()
}
fn base2k(&self) -> Base2K {
self.keys[0].base2k()
}
fn k(&self) -> TorusPrecision {
self.keys[0].k()
}
fn size(&self) -> usize {
self.keys[0].size()
}
}
impl<D: Data> GLWEInfos for GGLWEToGGSWKey<D> {
fn rank(&self) -> Rank {
self.keys[0].rank_out()
}
}
impl<D: Data> GGLWEInfos for GGLWEToGGSWKey<D> {
fn rank_in(&self) -> Rank {
self.rank_out()
}
fn rank_out(&self) -> Rank {
self.keys[0].rank_out()
}
fn dsize(&self) -> Dsize {
self.keys[0].dsize()
}
fn dnum(&self) -> Dnum {
self.keys[0].dnum()
}
}
impl LWEInfos for GGLWEToGGSWKeyLayout {
fn n(&self) -> Degree {
self.n
}
fn base2k(&self) -> Base2K {
self.base2k
}
fn k(&self) -> TorusPrecision {
self.k
}
}
impl GLWEInfos for GGLWEToGGSWKeyLayout {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl GGLWEInfos for GGLWEToGGSWKeyLayout {
fn rank_in(&self) -> Rank {
self.rank
}
fn dsize(&self) -> Dsize {
self.dsize
}
fn rank_out(&self) -> Rank {
self.rank
}
fn dnum(&self) -> Dnum {
self.dnum
}
}
impl<D: DataRef> fmt::Debug for GGLWEToGGSWKey<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl<D: DataMut> FillUniform for GGLWEToGGSWKey<D> {
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
self.keys
.iter_mut()
.for_each(|key: &mut GGLWE<D>| key.fill_uniform(log_bound, source))
}
}
impl<D: DataRef> fmt::Display for GGLWEToGGSWKey<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "(GGLWEToGGSWKey)",)?;
for (i, key) in self.keys.iter().enumerate() {
write!(f, "{i}: {key}")?;
}
Ok(())
}
}
impl GGLWEToGGSWKey<Vec<u8>> {
pub fn alloc_from_infos<A>(infos: &A) -> Self
where
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEToGGSWKey"
);
Self::alloc(
infos.n(),
infos.base2k(),
infos.k(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
GGLWEToGGSWKey {
keys: (0..rank.as_usize())
.map(|_| GGLWE::alloc(n, base2k, k, rank, rank, dnum, dsize))
.collect(),
}
}
pub fn bytes_of_from_infos<A>(infos: &A) -> usize
where
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEToGGSWKey"
);
Self::bytes_of(
infos.n(),
infos.base2k(),
infos.k(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
pub fn bytes_of(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
rank.as_usize() * GGLWE::bytes_of(n, base2k, k, rank, rank, dnum, dsize)
}
}
impl<D: DataMut> GGLWEToGGSWKey<D> {
// Returns a mutable reference to GGLWE_{s}([s[i]*s[0], s[i]*s[1], ..., s[i]*s[rank]])
pub fn at_mut(&mut self, i: usize) -> &mut GGLWE<D> {
assert!((i as u32) < self.rank());
&mut self.keys[i]
}
}
impl<D: DataRef> GGLWEToGGSWKey<D> {
// Returns a reference to GGLWE_{s}(s[i] * s[j])
pub fn at(&self, i: usize) -> &GGLWE<D> {
assert!((i as u32) < self.rank());
&self.keys[i]
}
}
impl<D: DataMut> ReaderFrom for GGLWEToGGSWKey<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 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("self.keys.len()={} != read len={}", self.keys.len(), len),
));
}
for key in &mut self.keys {
key.read_from(reader)?;
}
Ok(())
}
}
impl<D: DataRef> WriterTo for GGLWEToGGSWKey<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 {
key.write_to(writer)?;
}
Ok(())
}
}
pub trait GGLWEToGGSWKeyToRef {
fn to_ref(&self) -> GGLWEToGGSWKey<&[u8]>;
}
impl<D: DataRef> GGLWEToGGSWKeyToRef for GGLWEToGGSWKey<D>
where
GGLWE<D>: GGLWEToRef,
{
fn to_ref(&self) -> GGLWEToGGSWKey<&[u8]> {
GGLWEToGGSWKey {
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
}
}
}
pub trait GGLWEToGGSWKeyToMut {
fn to_mut(&mut self) -> GGLWEToGGSWKey<&mut [u8]>;
}
impl<D: DataMut> GGLWEToGGSWKeyToMut for GGLWEToGGSWKey<D>
where
GGLWE<D>: GGLWEToMut,
{
fn to_mut(&mut self) -> GGLWEToGGSWKey<&mut [u8]> {
GGLWEToGGSWKey {
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
}
}
}

View File

@@ -0,0 +1,221 @@
use poulpy_hal::{
api::{
ModuleN, ScratchTakeBasic, SvpApplyDftToDft, VecZnxBigBytesOf, VecZnxBigNormalize, VecZnxBigNormalizeTmpBytes,
VecZnxDftApply, VecZnxDftBytesOf, VecZnxIdftApplyTmpA,
},
layouts::{
Backend, Data, DataMut, DataRef, Module, ScalarZnx, ScalarZnxToMut, ScalarZnxToRef, Scratch, ZnxInfos, ZnxView,
ZnxViewMut,
},
};
use crate::{
ScratchTakeCore,
dist::Distribution,
layouts::{
Base2K, Degree, GLWEInfos, GLWESecret, GLWESecretPreparedFactory, GLWESecretToMut, GLWESecretToRef, LWEInfos, Rank,
TorusPrecision,
},
};
pub struct GLWESecretTensor<D: Data> {
pub(crate) data: ScalarZnx<D>,
pub(crate) rank: Rank,
pub(crate) dist: Distribution,
}
impl GLWESecretTensor<Vec<u8>> {
pub(crate) fn pairs(rank: usize) -> usize {
(((rank + 1) * rank) >> 1).max(1)
}
}
impl<D: Data> LWEInfos for GLWESecretTensor<D> {
fn base2k(&self) -> Base2K {
Base2K(0)
}
fn k(&self) -> TorusPrecision {
TorusPrecision(0)
}
fn n(&self) -> Degree {
Degree(self.data.n() as u32)
}
fn size(&self) -> usize {
1
}
}
impl<D: DataRef> GLWESecretTensor<D> {
pub fn at(&self, mut i: usize, mut j: usize) -> ScalarZnx<&[u8]> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank().into();
ScalarZnx {
data: bytemuck::cast_slice(self.data.at(i * rank + j - (i * (i + 1) / 2), 0)),
n: self.n().into(),
cols: 1,
}
}
}
impl<D: DataMut> GLWESecretTensor<D> {
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> ScalarZnx<&mut [u8]> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank().into();
ScalarZnx {
n: self.n().into(),
data: bytemuck::cast_slice_mut(self.data.at_mut(i * rank + j - (i * (i + 1) / 2), 0)),
cols: 1,
}
}
}
impl<D: Data> GLWEInfos for GLWESecretTensor<D> {
fn rank(&self) -> Rank {
self.rank
}
}
impl<D: DataRef> GLWESecretToRef for GLWESecretTensor<D> {
fn to_ref(&self) -> GLWESecret<&[u8]> {
GLWESecret {
data: self.data.to_ref(),
dist: self.dist,
}
}
}
impl<D: DataMut> GLWESecretToMut for GLWESecretTensor<D> {
fn to_mut(&mut self) -> GLWESecret<&mut [u8]> {
GLWESecret {
dist: self.dist,
data: self.data.to_mut(),
}
}
}
impl GLWESecretTensor<Vec<u8>> {
pub fn alloc_from_infos<A>(infos: &A) -> Self
where
A: GLWEInfos,
{
Self::alloc(infos.n(), infos.rank())
}
pub fn alloc(n: Degree, rank: Rank) -> Self {
GLWESecretTensor {
data: ScalarZnx::alloc(n.into(), Self::pairs(rank.into())),
rank,
dist: Distribution::NONE,
}
}
pub fn bytes_of_from_infos<A>(infos: &A) -> usize
where
A: GLWEInfos,
{
Self::bytes_of(infos.n(), Self::pairs(infos.rank().into()).into())
}
pub fn bytes_of(n: Degree, rank: Rank) -> usize {
ScalarZnx::bytes_of(n.into(), Self::pairs(rank.into()))
}
}
impl<D: DataMut> GLWESecretTensor<D> {
pub fn prepare<M, S, BE: Backend>(&mut self, module: &M, other: &S, scratch: &mut Scratch<BE>)
where
M: GLWESecretTensorFactory<BE>,
S: GLWESecretToRef + GLWEInfos,
Scratch<BE>: ScratchTakeCore<BE>,
{
module.glwe_secret_tensor_prepare(self, other, scratch);
}
}
pub trait GLWESecretTensorFactory<BE: Backend> {
fn glwe_secret_tensor_prepare_tmp_bytes(&self, rank: Rank) -> usize;
fn glwe_secret_tensor_prepare<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<BE>)
where
R: GLWESecretToMut + GLWEInfos,
O: GLWESecretToRef + GLWEInfos;
}
impl<BE: Backend> GLWESecretTensorFactory<BE> for Module<BE>
where
Self: ModuleN
+ GLWESecretPreparedFactory<BE>
+ VecZnxBigNormalize<BE>
+ VecZnxDftApply<BE>
+ SvpApplyDftToDft<BE>
+ VecZnxIdftApplyTmpA<BE>
+ VecZnxBigNormalize<BE>
+ VecZnxDftBytesOf
+ VecZnxBigBytesOf
+ VecZnxBigNormalizeTmpBytes,
Scratch<BE>: ScratchTakeCore<BE>,
{
fn glwe_secret_tensor_prepare_tmp_bytes(&self, rank: Rank) -> usize {
self.bytes_of_glwe_secret_prepared(rank)
+ self.bytes_of_vec_znx_dft(rank.into(), 1)
+ self.bytes_of_vec_znx_dft(1, 1)
+ self.bytes_of_vec_znx_big(1, 1)
+ self.vec_znx_big_normalize_tmp_bytes()
}
fn glwe_secret_tensor_prepare<R, A>(&self, res: &mut R, a: &A, scratch: &mut Scratch<BE>)
where
R: GLWESecretToMut + GLWEInfos,
A: GLWESecretToRef + GLWEInfos,
{
let res: &mut GLWESecret<&mut [u8]> = &mut res.to_mut();
let a: &GLWESecret<&[u8]> = &a.to_ref();
println!("res.rank: {} a.rank: {}", res.rank(), a.rank());
assert_eq!(res.rank(), GLWESecretTensor::pairs(a.rank().into()) as u32);
assert_eq!(res.n(), self.n() as u32);
assert_eq!(a.n(), self.n() as u32);
let rank: usize = a.rank().into();
let (mut a_prepared, scratch_1) = scratch.take_glwe_secret_prepared(self, rank.into());
a_prepared.prepare(self, a);
let base2k: usize = 17;
let (mut a_dft, scratch_2) = scratch_1.take_vec_znx_dft(self, rank, 1);
for i in 0..rank {
self.vec_znx_dft_apply(1, 0, &mut a_dft, i, &a.data.as_vec_znx(), i);
}
let (mut a_ij_big, scratch_3) = scratch_2.take_vec_znx_big(self, 1, 1);
let (mut a_ij_dft, scratch_4) = scratch_3.take_vec_znx_dft(self, 1, 1);
// sk_tensor = sk (x) sk
// For example: (s0, s1) (x) (s0, s1) = (s0^2, s0s1, s1^2)
for i in 0..rank {
for j in i..rank {
let idx: usize = i * rank + j - (i * (i + 1) / 2);
self.svp_apply_dft_to_dft(&mut a_ij_dft, 0, &a_prepared.data, j, &a_dft, i);
self.vec_znx_idft_apply_tmpa(&mut a_ij_big, 0, &mut a_ij_dft, 0);
self.vec_znx_big_normalize(
base2k,
&mut res.data.as_vec_znx_mut(),
idx,
base2k,
&a_ij_big,
0,
scratch_4,
);
}
}
}
}

View File

@@ -6,7 +6,6 @@ use poulpy_hal::{
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWE, GGLWEInfos, GGLWEToMut, GGLWEToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use std::fmt;
@@ -21,31 +20,29 @@ pub struct GLWETensorKeyLayout {
}
#[derive(PartialEq, Eq, Clone)]
pub struct GLWETensorKey<D: Data> {
pub(crate) keys: Vec<GGLWE<D>>,
}
pub struct GLWETensorKey<D: Data>(pub(crate) GGLWE<D>);
impl<D: Data> LWEInfos for GLWETensorKey<D> {
fn n(&self) -> Degree {
self.keys[0].n()
self.0.n()
}
fn base2k(&self) -> Base2K {
self.keys[0].base2k()
self.0.base2k()
}
fn k(&self) -> TorusPrecision {
self.keys[0].k()
self.0.k()
}
fn size(&self) -> usize {
self.keys[0].size()
self.0.size()
}
}
impl<D: Data> GLWEInfos for GLWETensorKey<D> {
fn rank(&self) -> Rank {
self.keys[0].rank_out()
self.0.rank_out()
}
}
@@ -55,15 +52,15 @@ impl<D: Data> GGLWEInfos for GLWETensorKey<D> {
}
fn rank_out(&self) -> Rank {
self.keys[0].rank_out()
self.0.rank_out()
}
fn dsize(&self) -> Dsize {
self.keys[0].dsize()
self.0.dsize()
}
fn dnum(&self) -> Dnum {
self.keys[0].dnum()
self.0.dnum()
}
}
@@ -113,18 +110,14 @@ impl<D: DataRef> fmt::Debug for GLWETensorKey<D> {
impl<D: DataMut> FillUniform for GLWETensorKey<D> {
fn fill_uniform(&mut self, log_bound: usize, source: &mut Source) {
self.keys
.iter_mut()
.for_each(|key: &mut GGLWE<D>| key.fill_uniform(log_bound, source))
self.0.fill_uniform(log_bound, source)
}
}
impl<D: DataRef> fmt::Display for GLWETensorKey<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "(GLWETensorKey)",)?;
for (i, key) in self.keys.iter().enumerate() {
write!(f, "{i}: {key}")?;
}
write!(f, "{}", self.0)?;
Ok(())
}
}
@@ -151,11 +144,7 @@ impl GLWETensorKey<Vec<u8>> {
pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
GLWETensorKey {
keys: (0..pairs)
.map(|_| GGLWE::alloc(n, base2k, k, Rank(1), rank, dnum, dsize))
.collect(),
}
GLWETensorKey(GGLWE::alloc(n, base2k, k, Rank(pairs), rank, dnum, dsize))
}
pub fn bytes_of_from_infos<A>(infos: &A) -> usize
@@ -178,85 +167,39 @@ impl GLWETensorKey<Vec<u8>> {
}
pub fn bytes_of(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 * GGLWE::bytes_of(n, base2k, k, Rank(1), rank, dnum, dsize)
}
}
impl<D: DataMut> GLWETensorKey<D> {
// Returns a mutable reference to GGLWE_{s}(s[i] * s[j])
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWE<D> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank_out().into();
&mut self.keys[i * rank + j - (i * (i + 1) / 2)]
}
}
impl<D: DataRef> GLWETensorKey<D> {
// Returns a reference to GGLWE_{s}(s[i] * s[j])
pub fn at(&self, mut i: usize, mut j: usize) -> &GGLWE<D> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank_out().into();
&self.keys[i * rank + j - (i * (i + 1) / 2)]
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
GGLWE::bytes_of(n, base2k, k, Rank(pairs), rank, dnum, dsize)
}
}
impl<D: DataMut> ReaderFrom for GLWETensorKey<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 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
format!("self.keys.len()={} != read len={}", self.keys.len(), len),
));
}
for key in &mut self.keys {
key.read_from(reader)?;
}
self.0.read_from(reader)?;
Ok(())
}
}
impl<D: DataRef> WriterTo for GLWETensorKey<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 {
key.write_to(writer)?;
}
self.0.write_to(writer)?;
Ok(())
}
}
pub trait GLWETensorKeyToRef {
fn to_ref(&self) -> GLWETensorKey<&[u8]>;
}
impl<D: DataRef> GLWETensorKeyToRef for GLWETensorKey<D>
impl<D: DataRef> GGLWEToRef for GLWETensorKey<D>
where
GGLWE<D>: GGLWEToRef,
{
fn to_ref(&self) -> GLWETensorKey<&[u8]> {
GLWETensorKey {
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
}
fn to_ref(&self) -> GGLWE<&[u8]> {
self.0.to_ref()
}
}
pub trait GLWETensorKeyToMut {
fn to_mut(&mut self) -> GLWETensorKey<&mut [u8]>;
}
impl<D: DataMut> GLWETensorKeyToMut for GLWETensorKey<D>
impl<D: DataMut> GGLWEToMut for GLWETensorKey<D>
where
GGLWE<D>: GGLWEToMut,
{
fn to_mut(&mut self) -> GLWETensorKey<&mut [u8]> {
GLWETensorKey {
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
}
fn to_mut(&mut self) -> GGLWE<&mut [u8]> {
self.0.to_mut()
}
}

View File

@@ -59,9 +59,9 @@ impl GGLWEInfos for GLWEToLWEKeyLayout {
/// A special [GLWESwitchingKey] required to for the conversion from [GLWE] to [LWE].
#[derive(PartialEq, Eq, Clone)]
pub struct GLWEToLWESwitchingKey<D: Data>(pub(crate) GLWESwitchingKey<D>);
pub struct GLWEToLWEKey<D: Data>(pub(crate) GLWESwitchingKey<D>);
impl<D: Data> LWEInfos for GLWEToLWESwitchingKey<D> {
impl<D: Data> LWEInfos for GLWEToLWEKey<D> {
fn base2k(&self) -> Base2K {
self.0.base2k()
}
@@ -79,12 +79,12 @@ impl<D: Data> LWEInfos for GLWEToLWESwitchingKey<D> {
}
}
impl<D: Data> GLWEInfos for GLWEToLWESwitchingKey<D> {
impl<D: Data> GLWEInfos for GLWEToLWEKey<D> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data> GGLWEInfos for GLWEToLWESwitchingKey<D> {
impl<D: Data> GGLWEInfos for GLWEToLWEKey<D> {
fn rank_in(&self) -> Rank {
self.0.rank_in()
}
@@ -102,37 +102,37 @@ impl<D: Data> GGLWEInfos for GLWEToLWESwitchingKey<D> {
}
}
impl<D: DataRef> fmt::Debug for GLWEToLWESwitchingKey<D> {
impl<D: DataRef> fmt::Debug for GLWEToLWEKey<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl<D: DataMut> FillUniform for GLWEToLWESwitchingKey<D> {
impl<D: DataMut> FillUniform for GLWEToLWEKey<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 GLWEToLWESwitchingKey<D> {
impl<D: DataRef> fmt::Display for GLWEToLWEKey<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(GLWEToLWESwitchingKey) {}", self.0)
write!(f, "(GLWEToLWEKey) {}", self.0)
}
}
impl<D: DataMut> ReaderFrom for GLWEToLWESwitchingKey<D> {
impl<D: DataMut> ReaderFrom for GLWEToLWEKey<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 GLWEToLWESwitchingKey<D> {
impl<D: DataRef> WriterTo for GLWEToLWEKey<D> {
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
self.0.write_to(writer)
}
}
impl GLWEToLWESwitchingKey<Vec<u8>> {
impl GLWEToLWEKey<Vec<u8>> {
pub fn alloc_from_infos<A>(infos: &A) -> Self
where
A: GGLWEInfos,
@@ -140,12 +140,12 @@ impl GLWEToLWESwitchingKey<Vec<u8>> {
assert_eq!(
infos.rank_out().0,
1,
"rank_out > 1 is not supported for GLWEToLWESwitchingKey"
"rank_out > 1 is not supported for GLWEToLWEKey"
);
assert_eq!(
infos.dsize().0,
1,
"dsize > 1 is not supported for GLWEToLWESwitchingKey"
"dsize > 1 is not supported for GLWEToLWEKey"
);
Self::alloc(
infos.n(),
@@ -157,7 +157,7 @@ impl GLWEToLWESwitchingKey<Vec<u8>> {
}
pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self {
GLWEToLWESwitchingKey(GLWESwitchingKey::alloc(
GLWEToLWEKey(GLWESwitchingKey::alloc(
n,
base2k,
k,
@@ -196,19 +196,19 @@ impl GLWEToLWESwitchingKey<Vec<u8>> {
}
}
impl<D: DataRef> GGLWEToRef for GLWEToLWESwitchingKey<D> {
impl<D: DataRef> GGLWEToRef for GLWEToLWEKey<D> {
fn to_ref(&self) -> GGLWE<&[u8]> {
self.0.to_ref()
}
}
impl<D: DataMut> GGLWEToMut for GLWEToLWESwitchingKey<D> {
impl<D: DataMut> GGLWEToMut for GLWEToLWEKey<D> {
fn to_mut(&mut self) -> GGLWE<&mut [u8]> {
self.0.to_mut()
}
}
impl<D: DataMut> GLWESwitchingKeyDegreesMut for GLWEToLWESwitchingKey<D> {
impl<D: DataMut> GLWESwitchingKeyDegreesMut for GLWEToLWEKey<D> {
fn input_degree(&mut self) -> &mut Degree {
&mut self.0.input_degree
}
@@ -218,7 +218,7 @@ impl<D: DataMut> GLWESwitchingKeyDegreesMut for GLWEToLWESwitchingKey<D> {
}
}
impl<D: DataRef> GLWESwitchingKeyDegrees for GLWEToLWESwitchingKey<D> {
impl<D: DataRef> GLWESwitchingKeyDegrees for GLWEToLWEKey<D> {
fn input_degree(&self) -> &Degree {
&self.0.input_degree
}

View File

@@ -11,7 +11,7 @@ use crate::layouts::{
};
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub struct LWEToGLWESwitchingKeyLayout {
pub struct LWEToGLWEKeyLayout {
pub n: Degree,
pub base2k: Base2K,
pub k: TorusPrecision,
@@ -19,7 +19,7 @@ pub struct LWEToGLWESwitchingKeyLayout {
pub dnum: Dnum,
}
impl LWEInfos for LWEToGLWESwitchingKeyLayout {
impl LWEInfos for LWEToGLWEKeyLayout {
fn base2k(&self) -> Base2K {
self.base2k
}
@@ -33,13 +33,13 @@ impl LWEInfos for LWEToGLWESwitchingKeyLayout {
}
}
impl GLWEInfos for LWEToGLWESwitchingKeyLayout {
impl GLWEInfos for LWEToGLWEKeyLayout {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl GGLWEInfos for LWEToGLWESwitchingKeyLayout {
impl GGLWEInfos for LWEToGLWEKeyLayout {
fn rank_in(&self) -> Rank {
Rank(1)
}
@@ -58,9 +58,9 @@ impl GGLWEInfos for LWEToGLWESwitchingKeyLayout {
}
#[derive(PartialEq, Eq, Clone)]
pub struct LWEToGLWESwitchingKey<D: Data>(pub(crate) GLWESwitchingKey<D>);
pub struct LWEToGLWEKey<D: Data>(pub(crate) GLWESwitchingKey<D>);
impl<D: Data> LWEInfos for LWEToGLWESwitchingKey<D> {
impl<D: Data> LWEInfos for LWEToGLWEKey<D> {
fn base2k(&self) -> Base2K {
self.0.base2k()
}
@@ -78,12 +78,12 @@ impl<D: Data> LWEInfos for LWEToGLWESwitchingKey<D> {
}
}
impl<D: Data> GLWEInfos for LWEToGLWESwitchingKey<D> {
impl<D: Data> GLWEInfos for LWEToGLWEKey<D> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data> GGLWEInfos for LWEToGLWESwitchingKey<D> {
impl<D: Data> GGLWEInfos for LWEToGLWEKey<D> {
fn dsize(&self) -> Dsize {
self.0.dsize()
}
@@ -101,37 +101,37 @@ impl<D: Data> GGLWEInfos for LWEToGLWESwitchingKey<D> {
}
}
impl<D: DataRef> fmt::Debug for LWEToGLWESwitchingKey<D> {
impl<D: DataRef> fmt::Debug for LWEToGLWEKey<D> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{self}")
}
}
impl<D: DataMut> FillUniform for LWEToGLWESwitchingKey<D> {
impl<D: DataMut> FillUniform for LWEToGLWEKey<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 LWEToGLWESwitchingKey<D> {
impl<D: DataRef> fmt::Display for LWEToGLWEKey<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "(LWEToGLWESwitchingKey) {}", self.0)
write!(f, "(LWEToGLWEKey) {}", self.0)
}
}
impl<D: DataMut> ReaderFrom for LWEToGLWESwitchingKey<D> {
impl<D: DataMut> ReaderFrom for LWEToGLWEKey<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 LWEToGLWESwitchingKey<D> {
impl<D: DataRef> WriterTo for LWEToGLWEKey<D> {
fn write_to<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
self.0.write_to(writer)
}
}
impl LWEToGLWESwitchingKey<Vec<u8>> {
impl LWEToGLWEKey<Vec<u8>> {
pub fn alloc_from_infos<A>(infos: &A) -> Self
where
A: GGLWEInfos,
@@ -139,12 +139,12 @@ impl LWEToGLWESwitchingKey<Vec<u8>> {
assert_eq!(
infos.rank_in().0,
1,
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
"rank_in > 1 is not supported for LWEToGLWEKey"
);
assert_eq!(
infos.dsize().0,
1,
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
"dsize > 1 is not supported for LWEToGLWEKey"
);
Self::alloc(
@@ -157,7 +157,7 @@ impl LWEToGLWESwitchingKey<Vec<u8>> {
}
pub fn alloc(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
LWEToGLWESwitchingKey(GLWESwitchingKey::alloc(
LWEToGLWEKey(GLWESwitchingKey::alloc(
n,
base2k,
k,
@@ -175,12 +175,12 @@ impl LWEToGLWESwitchingKey<Vec<u8>> {
assert_eq!(
infos.rank_in().0,
1,
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
"rank_in > 1 is not supported for LWEToGLWEKey"
);
assert_eq!(
infos.dsize().0,
1,
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
"dsize > 1 is not supported for LWEToGLWEKey"
);
Self::bytes_of(
infos.n(),
@@ -196,19 +196,19 @@ impl LWEToGLWESwitchingKey<Vec<u8>> {
}
}
impl<D: DataRef> GGLWEToRef for LWEToGLWESwitchingKey<D> {
impl<D: DataRef> GGLWEToRef for LWEToGLWEKey<D> {
fn to_ref(&self) -> GGLWE<&[u8]> {
self.0.to_ref()
}
}
impl<D: DataMut> GGLWEToMut for LWEToGLWESwitchingKey<D> {
impl<D: DataMut> GGLWEToMut for LWEToGLWEKey<D> {
fn to_mut(&mut self) -> GGLWE<&mut [u8]> {
self.0.to_mut()
}
}
impl<D: DataMut> GLWESwitchingKeyDegreesMut for LWEToGLWESwitchingKey<D> {
impl<D: DataMut> GLWESwitchingKeyDegreesMut for LWEToGLWEKey<D> {
fn input_degree(&mut self) -> &mut Degree {
&mut self.0.input_degree
}
@@ -218,7 +218,7 @@ impl<D: DataMut> GLWESwitchingKeyDegreesMut for LWEToGLWESwitchingKey<D> {
}
}
impl<D: DataRef> GLWESwitchingKeyDegrees for LWEToGLWESwitchingKey<D> {
impl<D: DataRef> GLWESwitchingKeyDegrees for LWEToGLWEKey<D> {
fn input_degree(&self) -> &Degree {
&self.0.input_degree
}

View File

@@ -1,40 +1,44 @@
mod gglwe;
mod gglwe_to_ggsw_key;
mod ggsw;
mod glwe;
mod glwe_automorphism_key;
mod glwe_plaintext;
mod glwe_public_key;
mod glwe_secret;
mod glwe_secret_tensor;
mod glwe_switching_key;
mod glwe_tensor;
mod glwe_tensor_key;
mod glwe_to_lwe_switching_key;
mod glwe_to_lwe_key;
mod lwe;
mod lwe_plaintext;
mod lwe_secret;
mod lwe_switching_key;
mod lwe_to_glwe_switching_key;
mod lwe_to_glwe_key;
pub mod compressed;
pub mod prepared;
pub use compressed::*;
pub use gglwe::*;
pub use gglwe_to_ggsw_key::*;
pub use ggsw::*;
pub use glwe::*;
pub use glwe_automorphism_key::*;
pub use glwe_plaintext::*;
pub use glwe_public_key::*;
pub use glwe_secret::*;
pub use glwe_secret_tensor::*;
pub use glwe_switching_key::*;
pub use glwe_tensor::*;
pub use glwe_tensor_key::*;
pub use glwe_to_lwe_switching_key::*;
pub use glwe_to_lwe_key::*;
pub use lwe::*;
pub use lwe_plaintext::*;
pub use lwe_secret::*;
pub use lwe_switching_key::*;
pub use lwe_to_glwe_switching_key::*;
pub use lwe_to_glwe_key::*;
pub use prepared::*;
use poulpy_hal::layouts::{Backend, Module};

View File

@@ -0,0 +1,252 @@
use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWEPrepared, GGLWEPreparedFactory, GGLWEPreparedToMut, GGLWEPreparedToRef,
GGLWEToGGSWKey, GGLWEToGGSWKeyToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
};
pub struct GGLWEToGGSWKeyPrepared<D: Data, BE: Backend> {
pub(crate) keys: Vec<GGLWEPrepared<D, BE>>,
}
impl<D: Data, BE: Backend> LWEInfos for GGLWEToGGSWKeyPrepared<D, BE> {
fn n(&self) -> Degree {
self.keys[0].n()
}
fn base2k(&self) -> Base2K {
self.keys[0].base2k()
}
fn k(&self) -> TorusPrecision {
self.keys[0].k()
}
fn size(&self) -> usize {
self.keys[0].size()
}
}
impl<D: Data, BE: Backend> GLWEInfos for GGLWEToGGSWKeyPrepared<D, BE> {
fn rank(&self) -> Rank {
self.keys[0].rank_out()
}
}
impl<D: Data, BE: Backend> GGLWEInfos for GGLWEToGGSWKeyPrepared<D, BE> {
fn rank_in(&self) -> Rank {
self.rank_out()
}
fn rank_out(&self) -> Rank {
self.keys[0].rank_out()
}
fn dsize(&self) -> Dsize {
self.keys[0].dsize()
}
fn dnum(&self) -> Dnum {
self.keys[0].dnum()
}
}
pub trait GGLWEToGGSWKeyPreparedFactory<BE: Backend> {
fn alloc_gglwe_to_ggsw_key_prepared_from_infos<A>(&self, infos: &A) -> GGLWEToGGSWKeyPrepared<Vec<u8>, BE>
where
A: GGLWEInfos;
fn alloc_gglwe_to_ggsw_key_prepared(
&self,
base2k: Base2K,
k: TorusPrecision,
rank: Rank,
dnum: Dnum,
dsize: Dsize,
) -> GGLWEToGGSWKeyPrepared<Vec<u8>, BE>;
fn bytes_of_gglwe_to_ggsw_from_infos<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos;
fn bytes_of_gglwe_to_ggsw(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize;
fn prepare_gglwe_to_ggsw_key_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos;
fn prepare_gglwe_to_ggsw_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<BE>)
where
R: GGLWEToGGSWKeyPreparedToMut<BE>,
O: GGLWEToGGSWKeyToRef;
}
impl<BE: Backend> GGLWEToGGSWKeyPreparedFactory<BE> for Module<BE>
where
Self: GGLWEPreparedFactory<BE>,
{
fn alloc_gglwe_to_ggsw_key_prepared_from_infos<A>(&self, infos: &A) -> GGLWEToGGSWKeyPrepared<Vec<u8>, BE>
where
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEToGGSWKeyPrepared"
);
self.alloc_gglwe_to_ggsw_key_prepared(
infos.base2k(),
infos.k(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
fn alloc_gglwe_to_ggsw_key_prepared(
&self,
base2k: Base2K,
k: TorusPrecision,
rank: Rank,
dnum: Dnum,
dsize: Dsize,
) -> GGLWEToGGSWKeyPrepared<Vec<u8>, BE> {
GGLWEToGGSWKeyPrepared {
keys: (0..rank.as_usize())
.map(|_| self.alloc_gglwe_prepared(base2k, k, rank, rank, dnum, dsize))
.collect(),
}
}
fn bytes_of_gglwe_to_ggsw_from_infos<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
infos.rank_out(),
"rank_in != rank_out is not supported for GGLWEToGGSWKeyPrepared"
);
self.bytes_of_gglwe_to_ggsw(
infos.base2k(),
infos.k(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
fn bytes_of_gglwe_to_ggsw(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
rank.as_usize() * self.bytes_of_gglwe_prepared(base2k, k, rank, rank, dnum, dsize)
}
fn prepare_gglwe_to_ggsw_key_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
self.prepare_gglwe_tmp_bytes(infos)
}
fn prepare_gglwe_to_ggsw_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<BE>)
where
R: GGLWEToGGSWKeyPreparedToMut<BE>,
O: GGLWEToGGSWKeyToRef,
{
let res: &mut GGLWEToGGSWKeyPrepared<&mut [u8], BE> = &mut res.to_mut();
let other: &GGLWEToGGSWKey<&[u8]> = &other.to_ref();
assert_eq!(res.keys.len(), other.keys.len());
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
self.prepare_gglwe(a, b, scratch);
}
}
}
impl<BE: Backend> GGLWEToGGSWKeyPrepared<Vec<u8>, BE> {
pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> Self
where
A: GGLWEInfos,
M: GGLWEToGGSWKeyPreparedFactory<BE>,
{
module.alloc_gglwe_to_ggsw_key_prepared_from_infos(infos)
}
pub fn alloc<M>(module: &M, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self
where
M: GGLWEToGGSWKeyPreparedFactory<BE>,
{
module.alloc_gglwe_to_ggsw_key_prepared(base2k, k, rank, dnum, dsize)
}
pub fn bytes_of_from_infos<A, M>(module: &M, infos: &A) -> usize
where
A: GGLWEInfos,
M: GGLWEToGGSWKeyPreparedFactory<BE>,
{
module.bytes_of_gglwe_to_ggsw_from_infos(infos)
}
pub fn bytes_of<M>(module: &M, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize
where
M: GGLWEToGGSWKeyPreparedFactory<BE>,
{
module.bytes_of_gglwe_to_ggsw(base2k, k, rank, dnum, dsize)
}
}
impl<D: DataMut, BE: Backend> GGLWEToGGSWKeyPrepared<D, BE> {
pub fn prepare<M, O>(&mut self, module: &M, other: &O, scratch: &mut Scratch<BE>)
where
M: GGLWEToGGSWKeyPreparedFactory<BE>,
O: GGLWEToGGSWKeyToRef,
{
module.prepare_gglwe_to_ggsw_key(self, other, scratch);
}
}
impl<D: DataMut, BE: Backend> GGLWEToGGSWKeyPrepared<D, BE> {
// Returns a mutable reference to GGLWEPrepared_{s}([s[i]*s[0], s[i]*s[1], ..., s[i]*s[rank]])
pub fn at_mut(&mut self, i: usize) -> &mut GGLWEPrepared<D, BE> {
assert!((i as u32) < self.rank());
&mut self.keys[i]
}
}
impl<D: DataRef, BE: Backend> GGLWEToGGSWKeyPrepared<D, BE> {
// Returns a reference to GGLWEPrepared_{s}([s[i]*s[0], s[i]*s[1], ..., s[i]*s[rank]])
pub fn at(&self, i: usize) -> &GGLWEPrepared<D, BE> {
assert!((i as u32) < self.rank());
&self.keys[i]
}
}
pub trait GGLWEToGGSWKeyPreparedToRef<BE: Backend> {
fn to_ref(&self) -> GGLWEToGGSWKeyPrepared<&[u8], BE>;
}
impl<D: DataRef, BE: Backend> GGLWEToGGSWKeyPreparedToRef<BE> for GGLWEToGGSWKeyPrepared<D, BE>
where
GGLWEPrepared<D, BE>: GGLWEPreparedToRef<BE>,
{
fn to_ref(&self) -> GGLWEToGGSWKeyPrepared<&[u8], BE> {
GGLWEToGGSWKeyPrepared {
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
}
}
}
pub trait GGLWEToGGSWKeyPreparedToMut<BE: Backend> {
fn to_mut(&mut self) -> GGLWEToGGSWKeyPrepared<&mut [u8], BE>;
}
impl<D: DataMut, BE: Backend> GGLWEToGGSWKeyPreparedToMut<BE> for GGLWEToGGSWKeyPrepared<D, BE>
where
GGLWEPrepared<D, BE>: GGLWEPreparedToMut<BE>,
{
fn to_mut(&mut self) -> GGLWEToGGSWKeyPrepared<&mut [u8], BE> {
GGLWEToGGSWKeyPrepared {
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
}
}
}

View File

@@ -109,7 +109,7 @@ where
)
}
fn bytes_of_glwe_switching_key_prepared(
fn bytes_of_glwe_key_prepared(
&self,
base2k: Base2K,
k: TorusPrecision,
@@ -125,7 +125,7 @@ where
where
A: GGLWEInfos,
{
self.bytes_of_glwe_switching_key_prepared(
self.bytes_of_glwe_key_prepared(
infos.base2k(),
infos.k(),
infos.rank_in(),
@@ -199,7 +199,7 @@ impl<B: Backend> GLWESwitchingKeyPrepared<Vec<u8>, B> {
where
M: GLWESwitchingKeyPreparedFactory<B>,
{
module.bytes_of_glwe_switching_key_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
module.bytes_of_glwe_key_prepared(base2k, k, rank_in, rank_out, dnum, dsize)
}
}

View File

@@ -2,29 +2,27 @@ use poulpy_hal::layouts::{Backend, Data, DataMut, DataRef, Module, Scratch};
use crate::layouts::{
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWEPrepared, GGLWEPreparedFactory, GGLWEPreparedToMut, GGLWEPreparedToRef,
GLWEInfos, GLWETensorKey, GLWETensorKeyToRef, LWEInfos, Rank, TorusPrecision,
GGLWEToRef, GLWEInfos, LWEInfos, Rank, TorusPrecision,
};
#[derive(PartialEq, Eq)]
pub struct GLWETensorKeyPrepared<D: Data, B: Backend> {
pub(crate) keys: Vec<GGLWEPrepared<D, B>>,
}
pub struct GLWETensorKeyPrepared<D: Data, B: Backend>(pub(crate) GGLWEPrepared<D, B>);
impl<D: Data, B: Backend> LWEInfos for GLWETensorKeyPrepared<D, B> {
fn n(&self) -> Degree {
self.keys[0].n()
self.0.n()
}
fn base2k(&self) -> Base2K {
self.keys[0].base2k()
self.0.base2k()
}
fn k(&self) -> TorusPrecision {
self.keys[0].k()
self.0.k()
}
fn size(&self) -> usize {
self.keys[0].size()
self.0.size()
}
}
@@ -40,15 +38,15 @@ impl<D: Data, B: Backend> GGLWEInfos for GLWETensorKeyPrepared<D, B> {
}
fn rank_out(&self) -> Rank {
self.keys[0].rank_out()
self.0.rank_out()
}
fn dsize(&self) -> Dsize {
self.keys[0].dsize()
self.0.dsize()
}
fn dnum(&self) -> Dnum {
self.keys[0].dnum()
self.0.dnum()
}
}
@@ -65,11 +63,7 @@ where
rank: Rank,
) -> GLWETensorKeyPrepared<Vec<u8>, B> {
let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1);
GLWETensorKeyPrepared {
keys: (0..pairs)
.map(|_| self.alloc_gglwe_prepared(base2k, k, Rank(1), rank, dnum, dsize))
.collect(),
}
GLWETensorKeyPrepared(self.alloc_gglwe_prepared(base2k, k, Rank(pairs), rank, dnum, dsize))
}
fn alloc_tensor_key_prepared_from_infos<A>(&self, infos: &A) -> GLWETensorKeyPrepared<Vec<u8>, B>
@@ -91,8 +85,8 @@ where
}
fn bytes_of_tensor_key_prepared(&self, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
let pairs: usize = (((rank.0 + 1) * rank.0) >> 1).max(1) as usize;
pairs * self.bytes_of_gglwe_prepared(base2k, k, Rank(1), rank, dnum, dsize)
let pairs: u32 = (((rank.as_u32() + 1) * rank.as_u32()) >> 1).max(1);
self.bytes_of_gglwe_prepared(base2k, k, Rank(pairs), rank, dnum, dsize)
}
fn bytes_of_tensor_key_prepared_from_infos<A>(&self, infos: &A) -> usize
@@ -117,17 +111,10 @@ where
fn prepare_tensor_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GLWETensorKeyPreparedToMut<B>,
O: GLWETensorKeyToRef,
R: GGLWEPreparedToMut<B>,
O: GGLWEToRef,
{
let mut res: GLWETensorKeyPrepared<&mut [u8], B> = res.to_mut();
let other: GLWETensorKey<&[u8]> = other.to_ref();
assert_eq!(res.keys.len(), other.keys.len());
for (a, b) in res.keys.iter_mut().zip(other.keys.iter()) {
self.prepare_gglwe(a, b, scratch);
}
self.prepare_gglwe(res, other, scratch);
}
}
@@ -165,28 +152,6 @@ impl<B: Backend> GLWETensorKeyPrepared<Vec<u8>, B> {
}
}
impl<D: DataMut, B: Backend> GLWETensorKeyPrepared<D, B> {
// Returns a mutable reference to GGLWE_{s}(s[i] * s[j])
pub fn at_mut(&mut self, mut i: usize, mut j: usize) -> &mut GGLWEPrepared<D, B> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank_out().into();
&mut self.keys[i * rank + j - (i * (i + 1) / 2)]
}
}
impl<D: DataRef, B: Backend> GLWETensorKeyPrepared<D, B> {
// Returns a reference to GGLWE_{s}(s[i] * s[j])
pub fn at(&self, mut i: usize, mut j: usize) -> &GGLWEPrepared<D, B> {
if i > j {
std::mem::swap(&mut i, &mut j);
};
let rank: usize = self.rank_out().into();
&self.keys[i * rank + j - (i * (i + 1) / 2)]
}
}
impl<B: Backend> GLWETensorKeyPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes<A, M>(&self, module: &M, infos: &A) -> usize
where
@@ -200,39 +165,27 @@ impl<B: Backend> GLWETensorKeyPrepared<Vec<u8>, B> {
impl<D: DataMut, B: Backend> GLWETensorKeyPrepared<D, B> {
pub fn prepare<O, M>(&mut self, module: &M, other: &O, scratch: &mut Scratch<B>)
where
O: GLWETensorKeyToRef,
O: GGLWEToRef,
M: GLWETensorKeyPreparedFactory<B>,
{
module.prepare_tensor_key(self, other, scratch);
}
}
pub trait GLWETensorKeyPreparedToMut<B: Backend> {
fn to_mut(&mut self) -> GLWETensorKeyPrepared<&mut [u8], B>;
}
impl<D: DataMut, B: Backend> GLWETensorKeyPreparedToMut<B> for GLWETensorKeyPrepared<D, B>
impl<D: DataMut, B: Backend> GGLWEPreparedToMut<B> for GLWETensorKeyPrepared<D, B>
where
GGLWEPrepared<D, B>: GGLWEPreparedToMut<B>,
{
fn to_mut(&mut self) -> GLWETensorKeyPrepared<&mut [u8], B> {
GLWETensorKeyPrepared {
keys: self.keys.iter_mut().map(|c| c.to_mut()).collect(),
}
fn to_mut(&mut self) -> GGLWEPrepared<&mut [u8], B> {
self.0.to_mut()
}
}
pub trait GLWETensorKeyPreparedToRef<B: Backend> {
fn to_ref(&self) -> GLWETensorKeyPrepared<&[u8], B>;
}
impl<D: DataRef, B: Backend> GLWETensorKeyPreparedToRef<B> for GLWETensorKeyPrepared<D, B>
impl<D: DataRef, B: Backend> GGLWEPreparedToRef<B> for GLWETensorKeyPrepared<D, B>
where
GGLWEPrepared<D, B>: GGLWEPreparedToRef<B>,
{
fn to_ref(&self) -> GLWETensorKeyPrepared<&[u8], B> {
GLWETensorKeyPrepared {
keys: self.keys.iter().map(|c| c.to_ref()).collect(),
}
fn to_ref(&self) -> GGLWEPrepared<&[u8], B> {
self.0.to_ref()
}
}

View File

@@ -7,9 +7,9 @@ use crate::layouts::{
};
#[derive(PartialEq, Eq)]
pub struct GLWEToLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
pub struct GLWEToLWEKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
impl<D: Data, B: Backend> LWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> LWEInfos for GLWEToLWEKeyPrepared<D, B> {
fn base2k(&self) -> Base2K {
self.0.base2k()
}
@@ -27,13 +27,13 @@ impl<D: Data, B: Backend> LWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
}
}
impl<D: Data, B: Backend> GLWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> GLWEInfos for GLWEToLWEKeyPrepared<D, B> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data, B: Backend> GGLWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> GGLWEInfos for GLWEToLWEKeyPrepared<D, B> {
fn rank_in(&self) -> Rank {
self.0.rank_in()
}
@@ -51,65 +51,65 @@ impl<D: Data, B: Backend> GGLWEInfos for GLWEToLWESwitchingKeyPrepared<D, B> {
}
}
pub trait GLWEToLWESwitchingKeyPreparedFactory<B: Backend>
pub trait GLWEToLWEKeyPreparedFactory<B: Backend>
where
Self: GLWESwitchingKeyPreparedFactory<B>,
{
fn alloc_glwe_to_lwe_switching_key_prepared(
fn alloc_glwe_to_lwe_key_prepared(
&self,
base2k: Base2K,
k: TorusPrecision,
rank_in: Rank,
dnum: Dnum,
) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
GLWEToLWESwitchingKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, rank_in, Rank(1), dnum, Dsize(1)))
) -> GLWEToLWEKeyPrepared<Vec<u8>, B> {
GLWEToLWEKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, rank_in, Rank(1), dnum, Dsize(1)))
}
fn alloc_glwe_to_lwe_switching_key_prepared_from_infos<A>(&self, infos: &A) -> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B>
fn alloc_glwe_to_lwe_key_prepared_from_infos<A>(&self, infos: &A) -> GLWEToLWEKeyPrepared<Vec<u8>, B>
where
A: GGLWEInfos,
{
debug_assert_eq!(
infos.rank_out().0,
1,
"rank_out > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
"rank_out > 1 is not supported for GLWEToLWEKeyPrepared"
);
debug_assert_eq!(
infos.dsize().0,
1,
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
"dsize > 1 is not supported for GLWEToLWEKeyPrepared"
);
self.alloc_glwe_to_lwe_switching_key_prepared(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
self.alloc_glwe_to_lwe_key_prepared(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
}
fn bytes_of_glwe_to_lwe_switching_key_prepared(&self, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
self.bytes_of_glwe_switching_key_prepared(base2k, k, rank_in, Rank(1), dnum, Dsize(1))
fn bytes_of_glwe_to_lwe_key_prepared(&self, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize {
self.bytes_of_glwe_key_prepared(base2k, k, rank_in, Rank(1), dnum, Dsize(1))
}
fn bytes_of_glwe_to_lwe_switching_key_prepared_from_infos<A>(&self, infos: &A) -> usize
fn bytes_of_glwe_to_lwe_key_prepared_from_infos<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
debug_assert_eq!(
infos.rank_out().0,
1,
"rank_out > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
"rank_out > 1 is not supported for GLWEToLWEKeyPrepared"
);
debug_assert_eq!(
infos.dsize().0,
1,
"dsize > 1 is not supported for GLWEToLWESwitchingKeyPrepared"
"dsize > 1 is not supported for GLWEToLWEKeyPrepared"
);
self.bytes_of_glwe_to_lwe_switching_key_prepared(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
self.bytes_of_glwe_to_lwe_key_prepared(infos.base2k(), infos.k(), infos.rank_in(), infos.dnum())
}
fn prepare_glwe_to_lwe_switching_key_tmp_bytes<A>(&self, infos: &A) -> usize
fn prepare_glwe_to_lwe_key_tmp_bytes<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
self.prepare_glwe_switching_key_tmp_bytes(infos)
}
fn prepare_glwe_to_lwe_switching_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
fn prepare_glwe_to_lwe_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GGLWEPreparedToMut<B> + GLWESwitchingKeyDegreesMut,
O: GGLWEToRef + GLWESwitchingKeyDegrees,
@@ -118,61 +118,61 @@ where
}
}
impl<B: Backend> GLWEToLWESwitchingKeyPreparedFactory<B> for Module<B> where Self: GLWESwitchingKeyPreparedFactory<B> {}
impl<B: Backend> GLWEToLWEKeyPreparedFactory<B> for Module<B> where Self: GLWESwitchingKeyPreparedFactory<B> {}
impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
impl<B: Backend> GLWEToLWEKeyPrepared<Vec<u8>, B> {
pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> Self
where
A: GGLWEInfos,
M: GLWEToLWESwitchingKeyPreparedFactory<B>,
M: GLWEToLWEKeyPreparedFactory<B>,
{
module.alloc_glwe_to_lwe_switching_key_prepared_from_infos(infos)
module.alloc_glwe_to_lwe_key_prepared_from_infos(infos)
}
pub fn alloc<M>(module: &M, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self
where
M: GLWEToLWESwitchingKeyPreparedFactory<B>,
M: GLWEToLWEKeyPreparedFactory<B>,
{
module.alloc_glwe_to_lwe_switching_key_prepared(base2k, k, rank_in, dnum)
module.alloc_glwe_to_lwe_key_prepared(base2k, k, rank_in, dnum)
}
pub fn bytes_of_from_infos<A, M>(module: &M, infos: &A) -> usize
where
A: GGLWEInfos,
M: GLWEToLWESwitchingKeyPreparedFactory<B>,
M: GLWEToLWEKeyPreparedFactory<B>,
{
module.bytes_of_glwe_to_lwe_switching_key_prepared_from_infos(infos)
module.bytes_of_glwe_to_lwe_key_prepared_from_infos(infos)
}
pub fn bytes_of<M>(module: &M, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> usize
where
M: GLWEToLWESwitchingKeyPreparedFactory<B>,
M: GLWEToLWEKeyPreparedFactory<B>,
{
module.bytes_of_glwe_to_lwe_switching_key_prepared(base2k, k, rank_in, dnum)
module.bytes_of_glwe_to_lwe_key_prepared(base2k, k, rank_in, dnum)
}
}
impl<B: Backend> GLWEToLWESwitchingKeyPrepared<Vec<u8>, B> {
impl<B: Backend> GLWEToLWEKeyPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes<A, M>(&self, module: &M, infos: &A)
where
A: GGLWEInfos,
M: GLWEToLWESwitchingKeyPreparedFactory<B>,
M: GLWEToLWEKeyPreparedFactory<B>,
{
module.prepare_glwe_to_lwe_switching_key_tmp_bytes(infos);
module.prepare_glwe_to_lwe_key_tmp_bytes(infos);
}
}
impl<D: DataMut, B: Backend> GLWEToLWESwitchingKeyPrepared<D, B> {
impl<D: DataMut, B: Backend> GLWEToLWEKeyPrepared<D, B> {
pub fn prepare<O, M>(&mut self, module: &M, other: &O, scratch: &mut Scratch<B>)
where
O: GGLWEToRef + GLWESwitchingKeyDegrees,
M: GLWEToLWESwitchingKeyPreparedFactory<B>,
M: GLWEToLWEKeyPreparedFactory<B>,
{
module.prepare_glwe_to_lwe_switching_key(self, other, scratch);
module.prepare_glwe_to_lwe_key(self, other, scratch);
}
}
impl<D: DataRef, B: Backend> GGLWEPreparedToRef<B> for GLWEToLWESwitchingKeyPrepared<D, B>
impl<D: DataRef, B: Backend> GGLWEPreparedToRef<B> for GLWEToLWEKeyPrepared<D, B>
where
GLWESwitchingKeyPrepared<D, B>: GGLWEPreparedToRef<B>,
{
@@ -181,7 +181,7 @@ where
}
}
impl<D: DataMut, B: Backend> GGLWEPreparedToMut<B> for GLWEToLWESwitchingKeyPrepared<D, B>
impl<D: DataMut, B: Backend> GGLWEPreparedToMut<B> for GLWEToLWEKeyPrepared<D, B>
where
GLWESwitchingKeyPrepared<D, B>: GGLWEPreparedToRef<B>,
{
@@ -190,7 +190,7 @@ where
}
}
impl<D: DataMut, B: Backend> GLWESwitchingKeyDegreesMut for GLWEToLWESwitchingKeyPrepared<D, B> {
impl<D: DataMut, B: Backend> GLWESwitchingKeyDegreesMut for GLWEToLWEKeyPrepared<D, B> {
fn input_degree(&mut self) -> &mut Degree {
&mut self.0.input_degree
}
@@ -200,7 +200,7 @@ impl<D: DataMut, B: Backend> GLWESwitchingKeyDegreesMut for GLWEToLWESwitchingKe
}
}
impl<D: DataRef, B: Backend> GLWESwitchingKeyDegrees for GLWEToLWESwitchingKeyPrepared<D, B> {
impl<D: DataRef, B: Backend> GLWESwitchingKeyDegrees for GLWEToLWEKeyPrepared<D, B> {
fn input_degree(&self) -> &Degree {
&self.0.input_degree
}

View File

@@ -86,7 +86,7 @@ where
}
fn bytes_of_lwe_switching_key_prepared(&self, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
self.bytes_of_glwe_switching_key_prepared(base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
self.bytes_of_glwe_key_prepared(base2k, k, Rank(1), Rank(1), dnum, Dsize(1))
}
fn bytes_of_lwe_switching_key_prepared_from_infos<A>(&self, infos: &A) -> usize

View File

@@ -8,9 +8,9 @@ use crate::layouts::{
/// A special [GLWESwitchingKey] required to for the conversion from [LWE] to [GLWE].
#[derive(PartialEq, Eq)]
pub struct LWEToGLWESwitchingKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
pub struct LWEToGLWEKeyPrepared<D: Data, B: Backend>(pub(crate) GLWESwitchingKeyPrepared<D, B>);
impl<D: Data, B: Backend> LWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> LWEInfos for LWEToGLWEKeyPrepared<D, B> {
fn base2k(&self) -> Base2K {
self.0.base2k()
}
@@ -28,13 +28,13 @@ impl<D: Data, B: Backend> LWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
}
}
impl<D: Data, B: Backend> GLWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> GLWEInfos for LWEToGLWEKeyPrepared<D, B> {
fn rank(&self) -> Rank {
self.rank_out()
}
}
impl<D: Data, B: Backend> GGLWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
impl<D: Data, B: Backend> GGLWEInfos for LWEToGLWEKeyPrepared<D, B> {
fn dsize(&self) -> Dsize {
self.0.dsize()
}
@@ -52,71 +52,65 @@ impl<D: Data, B: Backend> GGLWEInfos for LWEToGLWESwitchingKeyPrepared<D, B> {
}
}
pub trait LWEToGLWESwitchingKeyPreparedFactory<B: Backend>
pub trait LWEToGLWEKeyPreparedFactory<B: Backend>
where
Self: GLWESwitchingKeyPreparedFactory<B>,
{
fn alloc_lwe_to_glwe_switching_key_prepared(
fn alloc_lwe_to_glwe_key_prepared(
&self,
base2k: Base2K,
k: TorusPrecision,
rank_out: Rank,
dnum: Dnum,
) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
LWEToGLWESwitchingKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, Rank(1), rank_out, dnum, Dsize(1)))
) -> LWEToGLWEKeyPrepared<Vec<u8>, B> {
LWEToGLWEKeyPrepared(self.alloc_glwe_switching_key_prepared(base2k, k, Rank(1), rank_out, dnum, Dsize(1)))
}
fn alloc_lwe_to_glwe_switching_key_prepared_from_infos<A>(&self, infos: &A) -> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B>
fn alloc_lwe_to_glwe_key_prepared_from_infos<A>(&self, infos: &A) -> LWEToGLWEKeyPrepared<Vec<u8>, B>
where
A: GGLWEInfos,
{
debug_assert_eq!(
infos.rank_in().0,
1,
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
"rank_in > 1 is not supported for LWEToGLWEKey"
);
debug_assert_eq!(
infos.dsize().0,
1,
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
"dsize > 1 is not supported for LWEToGLWEKey"
);
self.alloc_lwe_to_glwe_switching_key_prepared(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
self.alloc_lwe_to_glwe_key_prepared(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
}
fn bytes_of_lwe_to_glwe_switching_key_prepared(
&self,
base2k: Base2K,
k: TorusPrecision,
rank_out: Rank,
dnum: Dnum,
) -> usize {
self.bytes_of_glwe_switching_key_prepared(base2k, k, Rank(1), rank_out, dnum, Dsize(1))
fn bytes_of_lwe_to_glwe_key_prepared(&self, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> usize {
self.bytes_of_glwe_key_prepared(base2k, k, Rank(1), rank_out, dnum, Dsize(1))
}
fn bytes_of_lwe_to_glwe_switching_key_prepared_from_infos<A>(&self, infos: &A) -> usize
fn bytes_of_lwe_to_glwe_key_prepared_from_infos<A>(&self, infos: &A) -> usize
where
A: GGLWEInfos,
{
debug_assert_eq!(
infos.rank_in().0,
1,
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
"rank_in > 1 is not supported for LWEToGLWEKey"
);
debug_assert_eq!(
infos.dsize().0,
1,
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
"dsize > 1 is not supported for LWEToGLWEKey"
);
self.bytes_of_lwe_to_glwe_switching_key_prepared(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
self.bytes_of_lwe_to_glwe_key_prepared(infos.base2k(), infos.k(), infos.rank_out(), infos.dnum())
}
fn prepare_lwe_to_glwe_switching_key_tmp_bytes<A>(&self, infos: &A)
fn prepare_lwe_to_glwe_key_tmp_bytes<A>(&self, infos: &A)
where
A: GGLWEInfos,
{
self.prepare_glwe_switching_key_tmp_bytes(infos);
}
fn prepare_lwe_to_glwe_switching_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
fn prepare_lwe_to_glwe_key<R, O>(&self, res: &mut R, other: &O, scratch: &mut Scratch<B>)
where
R: GGLWEPreparedToMut<B> + GLWESwitchingKeyDegreesMut,
O: GGLWEToRef + GLWESwitchingKeyDegrees,
@@ -125,61 +119,61 @@ where
}
}
impl<B: Backend> LWEToGLWESwitchingKeyPreparedFactory<B> for Module<B> where Self: GLWESwitchingKeyPreparedFactory<B> {}
impl<B: Backend> LWEToGLWEKeyPreparedFactory<B> for Module<B> where Self: GLWESwitchingKeyPreparedFactory<B> {}
impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
impl<B: Backend> LWEToGLWEKeyPrepared<Vec<u8>, B> {
pub fn alloc_from_infos<A, M>(module: &M, infos: &A) -> Self
where
A: GGLWEInfos,
M: LWEToGLWESwitchingKeyPreparedFactory<B>,
M: LWEToGLWEKeyPreparedFactory<B>,
{
module.alloc_lwe_to_glwe_switching_key_prepared_from_infos(infos)
module.alloc_lwe_to_glwe_key_prepared_from_infos(infos)
}
pub fn alloc<M>(module: &M, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self
where
M: LWEToGLWESwitchingKeyPreparedFactory<B>,
M: LWEToGLWEKeyPreparedFactory<B>,
{
module.alloc_lwe_to_glwe_switching_key_prepared(base2k, k, rank_out, dnum)
module.alloc_lwe_to_glwe_key_prepared(base2k, k, rank_out, dnum)
}
pub fn bytes_of_from_infos<A, M>(module: &M, infos: &A) -> usize
where
A: GGLWEInfos,
M: LWEToGLWESwitchingKeyPreparedFactory<B>,
M: LWEToGLWEKeyPreparedFactory<B>,
{
module.bytes_of_lwe_to_glwe_switching_key_prepared_from_infos(infos)
module.bytes_of_lwe_to_glwe_key_prepared_from_infos(infos)
}
pub fn bytes_of<M>(module: &M, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> usize
where
M: LWEToGLWESwitchingKeyPreparedFactory<B>,
M: LWEToGLWEKeyPreparedFactory<B>,
{
module.bytes_of_lwe_to_glwe_switching_key_prepared(base2k, k, rank_out, dnum)
module.bytes_of_lwe_to_glwe_key_prepared(base2k, k, rank_out, dnum)
}
}
impl<B: Backend> LWEToGLWESwitchingKeyPrepared<Vec<u8>, B> {
impl<B: Backend> LWEToGLWEKeyPrepared<Vec<u8>, B> {
pub fn prepare_tmp_bytes<A, M>(&self, module: &M, infos: &A)
where
A: GGLWEInfos,
M: LWEToGLWESwitchingKeyPreparedFactory<B>,
M: LWEToGLWEKeyPreparedFactory<B>,
{
module.prepare_lwe_to_glwe_switching_key_tmp_bytes(infos);
module.prepare_lwe_to_glwe_key_tmp_bytes(infos);
}
}
impl<D: DataMut, B: Backend> LWEToGLWESwitchingKeyPrepared<D, B> {
impl<D: DataMut, B: Backend> LWEToGLWEKeyPrepared<D, B> {
pub fn prepare<O, M>(&mut self, module: &M, other: &O, scratch: &mut Scratch<B>)
where
O: GGLWEToRef + GLWESwitchingKeyDegrees,
M: LWEToGLWESwitchingKeyPreparedFactory<B>,
M: LWEToGLWEKeyPreparedFactory<B>,
{
module.prepare_lwe_to_glwe_switching_key(self, other, scratch);
module.prepare_lwe_to_glwe_key(self, other, scratch);
}
}
impl<D: DataRef, B: Backend> GGLWEPreparedToRef<B> for LWEToGLWESwitchingKeyPrepared<D, B>
impl<D: DataRef, B: Backend> GGLWEPreparedToRef<B> for LWEToGLWEKeyPrepared<D, B>
where
GLWESwitchingKeyPrepared<D, B>: GGLWEPreparedToRef<B>,
{
@@ -188,7 +182,7 @@ where
}
}
impl<D: DataMut, B: Backend> GGLWEPreparedToMut<B> for LWEToGLWESwitchingKeyPrepared<D, B>
impl<D: DataMut, B: Backend> GGLWEPreparedToMut<B> for LWEToGLWEKeyPrepared<D, B>
where
GLWESwitchingKeyPrepared<D, B>: GGLWEPreparedToMut<B>,
{
@@ -197,7 +191,7 @@ where
}
}
impl<D: DataMut, B: Backend> GLWESwitchingKeyDegreesMut for LWEToGLWESwitchingKeyPrepared<D, B> {
impl<D: DataMut, B: Backend> GLWESwitchingKeyDegreesMut for LWEToGLWEKeyPrepared<D, B> {
fn input_degree(&mut self) -> &mut Degree {
&mut self.0.input_degree
}

View File

@@ -1,4 +1,5 @@
mod gglwe;
mod gglwe_to_ggsw_key;
mod ggsw;
mod glwe;
mod glwe_automorphism_key;
@@ -6,11 +7,12 @@ mod glwe_public_key;
mod glwe_secret;
mod glwe_switching_key;
mod glwe_tensor_key;
mod glwe_to_lwe_switching_key;
mod glwe_to_lwe_key;
mod lwe_switching_key;
mod lwe_to_glwe_switching_key;
mod lwe_to_glwe_key;
pub use gglwe::*;
pub use gglwe_to_ggsw_key::*;
pub use ggsw::*;
pub use glwe::*;
pub use glwe_automorphism_key::*;
@@ -18,6 +20,6 @@ pub use glwe_public_key::*;
pub use glwe_secret::*;
pub use glwe_switching_key::*;
pub use glwe_tensor_key::*;
pub use glwe_to_lwe_switching_key::*;
pub use glwe_to_lwe_key::*;
pub use lwe_switching_key::*;
pub use lwe_to_glwe_switching_key::*;
pub use lwe_to_glwe_key::*;