Add BDD Arithmetic (#98)

* Added some circuit, evaluation + some layouts

* Refactor + memory reduction

* Rows -> Dnum, Digits -> Dsize

* fix #96 + glwe_packing (indirectly CBT)

* clippy
This commit is contained in:
Jean-Philippe Bossuat
2025-10-08 17:52:03 +02:00
committed by GitHub
parent 37e13b965c
commit 6357a05509
119 changed files with 15996 additions and 1659 deletions

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGLWEAutomorphismKey, GGLWELayoutInfos, GLWEInfos, LWEInfos, Rank, Rows, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGLWEAutomorphismKey, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
compressed::{Decompress, GGLWESwitchingKeyCompressed},
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@@ -40,7 +40,7 @@ impl<D: Data> GLWEInfos for GGLWEAutomorphismKeyCompressed<D> {
}
}
impl<D: Data> GGLWELayoutInfos for GGLWEAutomorphismKeyCompressed<D> {
impl<D: Data> GGLWEInfos for GGLWEAutomorphismKeyCompressed<D> {
fn rank_in(&self) -> Rank {
self.key.rank_in()
}
@@ -49,12 +49,12 @@ impl<D: Data> GGLWELayoutInfos for GGLWEAutomorphismKeyCompressed<D> {
self.key.rank_out()
}
fn digits(&self) -> Digits {
self.key.digits()
fn dsize(&self) -> Dsize {
self.key.dsize()
}
fn rows(&self) -> Rows {
self.key.rows()
fn dnum(&self) -> Dnum {
self.key.dnum()
}
}
@@ -79,7 +79,7 @@ impl<D: DataRef> fmt::Display for GGLWEAutomorphismKeyCompressed<D> {
impl GGLWEAutomorphismKeyCompressed<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(infos.rank_in(), infos.rank_out());
Self {
@@ -88,23 +88,23 @@ impl GGLWEAutomorphismKeyCompressed<Vec<u8>> {
}
}
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, digits: Digits, rank: Rank) -> Self {
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
Self {
key: GGLWESwitchingKeyCompressed::alloc_with(n, base2k, k, rows, digits, rank, rank),
key: GGLWESwitchingKeyCompressed::alloc_with(n, base2k, k, rank, rank, dnum, dsize),
p: 0,
}
}
pub fn alloc_bytes<A>(infos: &A) -> usize
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(infos.rank_in(), infos.rank_out());
GGLWESwitchingKeyCompressed::alloc_bytes(infos)
}
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, digits: Digits, rank: Rank) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rows, digits, rank, rank)
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rank, dnum, dsize)
}
}

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGLWECiphertext, GGLWELayoutInfos, GLWEInfos, LWEInfos, Rank, Rows, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGLWECiphertext, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
compressed::{Decompress, GLWECiphertextCompressed},
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@@ -17,7 +17,7 @@ pub struct GGLWECiphertextCompressed<D: Data> {
pub(crate) base2k: Base2K,
pub(crate) k: TorusPrecision,
pub(crate) rank_out: Rank,
pub(crate) digits: Digits,
pub(crate) dsize: Dsize,
pub(crate) seed: Vec<[u8; 32]>,
}
@@ -44,7 +44,7 @@ impl<D: Data> GLWEInfos for GGLWECiphertextCompressed<D> {
}
}
impl<D: Data> GGLWELayoutInfos for GGLWECiphertextCompressed<D> {
impl<D: Data> GGLWEInfos for GGLWECiphertextCompressed<D> {
fn rank_in(&self) -> Rank {
Rank(self.data.cols_in() as u32)
}
@@ -53,12 +53,12 @@ impl<D: Data> GGLWELayoutInfos for GGLWECiphertextCompressed<D> {
self.rank_out
}
fn digits(&self) -> Digits {
self.digits
fn dsize(&self) -> Dsize {
self.dsize
}
fn rows(&self) -> Rows {
Rows(self.data.rows() as u32)
fn dnum(&self) -> Dnum {
Dnum(self.data.rows() as u32)
}
}
@@ -78,8 +78,8 @@ impl<D: DataRef> fmt::Display for GGLWECiphertextCompressed<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"(GGLWECiphertextCompressed: base2k={} k={} digits={}) {}",
self.base2k.0, self.k.0, self.digits.0, self.data
"(GGLWECiphertextCompressed: base2k={} k={} dsize={}) {}",
self.base2k.0, self.k.0, self.dsize.0, self.data
)
}
}
@@ -87,16 +87,16 @@ impl<D: DataRef> fmt::Display for GGLWECiphertextCompressed<D> {
impl GGLWECiphertextCompressed<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
Self::alloc_with(
infos.n(),
infos.base2k(),
infos.k(),
infos.rows(),
infos.digits(),
infos.rank_in(),
infos.rank_out(),
infos.dnum(),
infos.dsize(),
)
}
@@ -104,82 +104,73 @@ impl GGLWECiphertextCompressed<Vec<u8>> {
n: Degree,
base2k: Base2K,
k: TorusPrecision,
rows: Rows,
digits: Digits,
rank_in: Rank,
rank_out: Rank,
dnum: Dnum,
dsize: Dsize,
) -> Self {
let size: usize = k.0.div_ceil(base2k.0) as usize;
debug_assert!(
size as u32 > digits.0,
"invalid gglwe: ceil(k/base2k): {size} <= digits: {}",
digits.0
size as u32 > dsize.0,
"invalid gglwe: ceil(k/base2k): {size} <= dsize: {}",
dsize.0
);
assert!(
rows.0 * digits.0 <= size as u32,
"invalid gglwe: rows: {} * digits:{} > ceil(k/base2k): {size}",
rows.0,
digits.0,
dnum.0 * dsize.0 <= size as u32,
"invalid gglwe: dnum: {} * dsize:{} > ceil(k/base2k): {size}",
dnum.0,
dsize.0,
);
Self {
data: MatZnx::alloc(
n.into(),
rows.into(),
dnum.into(),
rank_in.into(),
1,
k.0.div_ceil(base2k.0) as usize,
),
k,
base2k,
digits,
dsize,
rank_out,
seed: vec![[0u8; 32]; (rows.0 * rank_in.0) as usize],
seed: vec![[0u8; 32]; (dnum.0 * rank_in.0) as usize],
}
}
pub fn alloc_bytes<A>(infos: &A) -> usize
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
Self::alloc_bytes_with(
infos.n(),
infos.base2k(),
infos.k(),
infos.rows(),
infos.digits(),
infos.rank_in(),
infos.rank_out(),
infos.dnum(),
infos.dsize(),
)
}
pub fn alloc_bytes_with(
n: Degree,
base2k: Base2K,
k: TorusPrecision,
rows: Rows,
digits: Digits,
rank_in: Rank,
_rank_out: Rank,
) -> usize {
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum, dsize: Dsize) -> usize {
let size: usize = k.0.div_ceil(base2k.0) as usize;
debug_assert!(
size as u32 > digits.0,
"invalid gglwe: ceil(k/base2k): {size} <= digits: {}",
digits.0
size as u32 > dsize.0,
"invalid gglwe: ceil(k/base2k): {size} <= dsize: {}",
dsize.0
);
assert!(
rows.0 * digits.0 <= size as u32,
"invalid gglwe: rows: {} * digits:{} > ceil(k/base2k): {size}",
rows.0,
digits.0,
dnum.0 * dsize.0 <= size as u32,
"invalid gglwe: dnum: {} * dsize:{} > ceil(k/base2k): {size}",
dnum.0,
dsize.0,
);
MatZnx::alloc_bytes(
n.into(),
rows.into(),
dnum.into(),
rank_in.into(),
1,
k.0.div_ceil(base2k.0) as usize,
@@ -217,7 +208,7 @@ impl<D: DataMut> ReaderFrom for GGLWECiphertextCompressed<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>()?);
self.digits = Digits(reader.read_u32::<LittleEndian>()?);
self.dsize = Dsize(reader.read_u32::<LittleEndian>()?);
self.rank_out = Rank(reader.read_u32::<LittleEndian>()?);
let seed_len: u32 = reader.read_u32::<LittleEndian>()?;
self.seed = vec![[0u8; 32]; seed_len as usize];
@@ -232,7 +223,7 @@ impl<D: DataRef> WriterTo for GGLWECiphertextCompressed<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())?;
writer.write_u32::<LittleEndian>(self.digits.into())?;
writer.write_u32::<LittleEndian>(self.dsize.into())?;
writer.write_u32::<LittleEndian>(self.rank_out.into())?;
writer.write_u32::<LittleEndian>(self.seed.len() as u32)?;
for s in &self.seed {
@@ -279,19 +270,19 @@ where
);
assert_eq!(
self.rows(),
other.rows(),
"invalid receiver: self.rows()={} != other.rows()={}",
self.rows(),
other.rows()
self.dnum(),
other.dnum(),
"invalid receiver: self.dnum()={} != other.dnum()={}",
self.dnum(),
other.dnum()
);
}
let rank_in: usize = self.rank_in().into();
let rows: usize = self.rows().into();
let dnum: usize = self.dnum().into();
(0..rank_in).for_each(|col_i| {
(0..rows).for_each(|row_i| {
(0..dnum).for_each(|row_i| {
self.at_mut(row_i, col_i)
.decompress(module, &other.at(row_i, col_i));
});

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGLWELayoutInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, Rows, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWESwitchingKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
compressed::{Decompress, GGLWECiphertextCompressed},
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@@ -41,7 +41,7 @@ impl<D: Data> GLWEInfos for GGLWESwitchingKeyCompressed<D> {
}
}
impl<D: Data> GGLWELayoutInfos for GGLWESwitchingKeyCompressed<D> {
impl<D: Data> GGLWEInfos for GGLWESwitchingKeyCompressed<D> {
fn rank_in(&self) -> Rank {
self.key.rank_in()
}
@@ -50,12 +50,12 @@ impl<D: Data> GGLWELayoutInfos for GGLWESwitchingKeyCompressed<D> {
self.key.rank_out()
}
fn digits(&self) -> Digits {
self.key.digits()
fn dsize(&self) -> Dsize {
self.key.dsize()
}
fn rows(&self) -> Rows {
self.key.rows()
fn dnum(&self) -> Dnum {
self.key.dnum()
}
}
@@ -84,7 +84,7 @@ impl<D: DataRef> fmt::Display for GGLWESwitchingKeyCompressed<D> {
impl GGLWESwitchingKeyCompressed<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
GGLWESwitchingKeyCompressed {
key: GGLWECiphertextCompressed::alloc(infos),
@@ -97,13 +97,13 @@ impl GGLWESwitchingKeyCompressed<Vec<u8>> {
n: Degree,
base2k: Base2K,
k: TorusPrecision,
rows: Rows,
digits: Digits,
rank_in: Rank,
rank_out: Rank,
dnum: Dnum,
dsize: Dsize,
) -> Self {
GGLWESwitchingKeyCompressed {
key: GGLWECiphertextCompressed::alloc_with(n, base2k, k, rows, digits, rank_in, rank_out),
key: GGLWECiphertextCompressed::alloc_with(n, base2k, k, rank_in, rank_out, dnum, dsize),
sk_in_n: 0,
sk_out_n: 0,
}
@@ -111,21 +111,13 @@ impl GGLWESwitchingKeyCompressed<Vec<u8>> {
pub fn alloc_bytes<A>(infos: &A) -> usize
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
GGLWECiphertextCompressed::alloc_bytes(infos)
}
pub fn alloc_bytes_with(
n: Degree,
base2k: Base2K,
k: TorusPrecision,
rows: Rows,
digits: Digits,
rank_in: Rank,
rank_out: Rank,
) -> usize {
GGLWECiphertextCompressed::alloc_bytes_with(n, base2k, k, rows, digits, rank_in, rank_out)
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum, dsize: Dsize) -> usize {
GGLWECiphertextCompressed::alloc_bytes_with(n, base2k, k, rank_in, dnum, dsize)
}
}

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGLWELayoutInfos, GGLWETensorKey, GLWEInfos, LWEInfos, Rank, Rows, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GGLWETensorKey, GLWEInfos, LWEInfos, Rank, TorusPrecision,
compressed::{Decompress, GGLWESwitchingKeyCompressed},
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@@ -38,7 +38,7 @@ impl<D: Data> GLWEInfos for GGLWETensorKeyCompressed<D> {
}
}
impl<D: Data> GGLWELayoutInfos for GGLWETensorKeyCompressed<D> {
impl<D: Data> GGLWEInfos for GGLWETensorKeyCompressed<D> {
fn rank_in(&self) -> Rank {
self.rank_out()
}
@@ -47,12 +47,12 @@ impl<D: Data> GGLWELayoutInfos for GGLWETensorKeyCompressed<D> {
self.keys[0].rank_out()
}
fn digits(&self) -> Digits {
self.keys[0].digits()
fn dsize(&self) -> Dsize {
self.keys[0].dsize()
}
fn rows(&self) -> Rows {
self.keys[0].rows()
fn dnum(&self) -> Dnum {
self.keys[0].dnum()
}
}
@@ -83,7 +83,7 @@ impl<D: DataRef> fmt::Display for GGLWETensorKeyCompressed<D> {
impl GGLWETensorKeyCompressed<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
@@ -94,13 +94,13 @@ impl GGLWETensorKeyCompressed<Vec<u8>> {
infos.n(),
infos.base2k(),
infos.k(),
infos.rows(),
infos.digits(),
infos.rank_out(),
infos.dnum(),
infos.dsize(),
)
}
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, digits: Digits, rank: Rank) -> Self {
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
let mut keys: Vec<GGLWESwitchingKeyCompressed<Vec<u8>>> = Vec::new();
let pairs: u32 = (((rank.0 + 1) * rank.0) >> 1).max(1);
(0..pairs).for_each(|_| {
@@ -108,10 +108,10 @@ impl GGLWETensorKeyCompressed<Vec<u8>> {
n,
base2k,
k,
rows,
digits,
Rank(1),
rank,
dnum,
dsize,
));
});
Self { keys }
@@ -119,7 +119,7 @@ impl GGLWETensorKeyCompressed<Vec<u8>> {
pub fn alloc_bytes<A>(infos: &A) -> usize
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
assert_eq!(
infos.rank_in(),
@@ -133,16 +133,15 @@ impl GGLWETensorKeyCompressed<Vec<u8>> {
infos.n(),
infos.base2k(),
infos.k(),
infos.rows(),
infos.digits(),
Rank(1),
infos.rank_out(),
infos.dnum(),
infos.dsize(),
)
}
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, digits: Digits, rank: Rank) -> usize {
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 * GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rows, digits, Rank(1), rank)
pairs * GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, dsize)
}
}

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGSWCiphertext, GGSWInfos, GLWEInfos, LWEInfos, Rank, Rows, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGSWCiphertext, GGSWInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision,
compressed::{Decompress, GLWECiphertextCompressed},
};
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
@@ -16,7 +16,7 @@ pub struct GGSWCiphertextCompressed<D: Data> {
pub(crate) data: MatZnx<D>,
pub(crate) k: TorusPrecision,
pub(crate) base2k: Base2K,
pub(crate) digits: Digits,
pub(crate) dsize: Dsize,
pub(crate) rank: Rank,
pub(crate) seed: Vec<[u8; 32]>,
}
@@ -44,12 +44,12 @@ impl<D: Data> GLWEInfos for GGSWCiphertextCompressed<D> {
}
impl<D: Data> GGSWInfos for GGSWCiphertextCompressed<D> {
fn digits(&self) -> Digits {
self.digits
fn dsize(&self) -> Dsize {
self.dsize
}
fn rows(&self) -> Rows {
Rows(self.data.rows() as u32)
fn dnum(&self) -> Dnum {
Dnum(self.data.rows() as u32)
}
}
@@ -63,8 +63,8 @@ impl<D: DataRef> fmt::Display for GGSWCiphertextCompressed<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"(GGSWCiphertextCompressed: base2k={} k={} digits={}) {}",
self.base2k, self.k, self.digits, self.data
"(GGSWCiphertextCompressed: base2k={} k={} dsize={}) {}",
self.base2k, self.k, self.dsize, self.data
)
}
}
@@ -84,38 +84,38 @@ impl GGSWCiphertextCompressed<Vec<u8>> {
infos.n(),
infos.base2k(),
infos.k(),
infos.rows(),
infos.digits(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, digits: Digits, rank: Rank) -> Self {
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> Self {
let size: usize = k.0.div_ceil(base2k.0) as usize;
debug_assert!(
size as u32 > digits.0,
"invalid ggsw: ceil(k/base2k): {size} <= digits: {}",
digits.0
size as u32 > dsize.0,
"invalid ggsw: ceil(k/base2k): {size} <= dsize: {}",
dsize.0
);
assert!(
rows.0 * digits.0 <= size as u32,
"invalid ggsw: rows: {} * digits:{} > ceil(k/base2k): {size}",
rows.0,
digits.0,
dnum.0 * dsize.0 <= size as u32,
"invalid ggsw: dnum: {} * dsize:{} > ceil(k/base2k): {size}",
dnum.0,
dsize.0,
);
Self {
data: MatZnx::alloc(
n.into(),
rows.into(),
dnum.into(),
(rank + 1).into(),
1,
k.0.div_ceil(base2k.0) as usize,
),
k,
base2k,
digits,
dsize,
rank,
seed: Vec::new(),
}
@@ -129,30 +129,30 @@ impl GGSWCiphertextCompressed<Vec<u8>> {
infos.n(),
infos.base2k(),
infos.k(),
infos.rows(),
infos.digits(),
infos.rank(),
infos.dnum(),
infos.dsize(),
)
}
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, digits: Digits, rank: Rank) -> usize {
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank: Rank, dnum: Dnum, dsize: Dsize) -> usize {
let size: usize = k.0.div_ceil(base2k.0) as usize;
debug_assert!(
size as u32 > digits.0,
"invalid ggsw: ceil(k/base2k): {size} <= digits: {}",
digits.0
size as u32 > dsize.0,
"invalid ggsw: ceil(k/base2k): {size} <= dsize: {}",
dsize.0
);
assert!(
rows.0 * digits.0 <= size as u32,
"invalid ggsw: rows: {} * digits:{} > ceil(k/base2k): {size}",
rows.0,
digits.0,
dnum.0 * dsize.0 <= size as u32,
"invalid ggsw: dnum: {} * dsize:{} > ceil(k/base2k): {size}",
dnum.0,
dsize.0,
);
MatZnx::alloc_bytes(
n.into(),
rows.into(),
dnum.into(),
(rank + 1).into(),
1,
k.0.div_ceil(base2k.0) as usize,
@@ -190,7 +190,7 @@ impl<D: DataMut> ReaderFrom for GGSWCiphertextCompressed<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>()?);
self.digits = Digits(reader.read_u32::<LittleEndian>()?);
self.dsize = Dsize(reader.read_u32::<LittleEndian>()?);
self.rank = Rank(reader.read_u32::<LittleEndian>()?);
let seed_len: usize = reader.read_u32::<LittleEndian>()? as usize;
self.seed = vec![[0u8; 32]; seed_len];
@@ -205,7 +205,7 @@ impl<D: DataRef> WriterTo for GGSWCiphertextCompressed<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())?;
writer.write_u32::<LittleEndian>(self.digits.into())?;
writer.write_u32::<LittleEndian>(self.dsize.into())?;
writer.write_u32::<LittleEndian>(self.rank.into())?;
writer.write_u32::<LittleEndian>(self.seed.len() as u32)?;
for s in &self.seed {
@@ -225,9 +225,9 @@ where
assert_eq!(self.rank(), other.rank())
}
let rows: usize = self.rows().into();
let dnum: usize = self.dnum().into();
let rank: usize = self.rank().into();
(0..rows).for_each(|row_i| {
(0..dnum).for_each(|row_i| {
(0..rank + 1).for_each(|col_j| {
self.at_mut(row_i, col_j)
.decompress(module, &other.at(row_i, col_j));

View File

@@ -6,8 +6,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGLWELayoutInfos, GLWEInfos, LWEInfos, Rank, Rows, TorusPrecision,
compressed::GGLWESwitchingKeyCompressed,
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, Rank, TorusPrecision, compressed::GGLWESwitchingKeyCompressed,
};
#[derive(PartialEq, Eq, Clone)]
@@ -36,21 +35,21 @@ impl<D: Data> GLWEInfos for GLWEToLWESwitchingKeyCompressed<D> {
}
}
impl<D: Data> GGLWELayoutInfos for GLWEToLWESwitchingKeyCompressed<D> {
impl<D: Data> GGLWEInfos for GLWEToLWESwitchingKeyCompressed<D> {
fn rank_in(&self) -> Rank {
self.0.rank_in()
}
fn digits(&self) -> Digits {
self.0.digits()
fn dsize(&self) -> Dsize {
self.0.dsize()
}
fn rank_out(&self) -> Rank {
self.0.rank_out()
}
fn rows(&self) -> Rows {
self.0.rows()
fn dnum(&self) -> Dnum {
self.0.dnum()
}
}
@@ -87,7 +86,7 @@ impl<D: DataRef> WriterTo for GLWEToLWESwitchingKeyCompressed<D> {
impl GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(
infos.rank_out().0,
@@ -95,28 +94,28 @@ impl GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
"rank_out > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
);
debug_assert_eq!(
infos.digits().0,
infos.dsize().0,
1,
"digits > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
);
Self(GGLWESwitchingKeyCompressed::alloc(infos))
}
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, rank_in: Rank) -> Self {
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_in: Rank, dnum: Dnum) -> Self {
Self(GGLWESwitchingKeyCompressed::alloc_with(
n,
base2k,
k,
rows,
Digits(1),
rank_in,
Rank(1),
dnum,
Dsize(1),
))
}
pub fn alloc_bytes<A>(infos: &A) -> usize
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(
infos.rank_out().0,
@@ -124,14 +123,14 @@ impl GLWEToLWESwitchingKeyCompressed<Vec<u8>> {
"rank_out > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
);
debug_assert_eq!(
infos.digits().0,
infos.dsize().0,
1,
"digits > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
"dsize > 1 is unsupported for GLWEToLWESwitchingKeyCompressed"
);
GGLWESwitchingKeyCompressed::alloc_bytes(infos)
}
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, rank_in: Rank) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rows, Digits(1), rank_in, Rank(1))
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum, rank_in: Rank) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rank_in, dnum, Dsize(1))
}
}

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGLWELayoutInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, Rows, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWESwitchingKey, Rank, TorusPrecision,
compressed::{Decompress, GGLWESwitchingKeyCompressed},
};
use std::fmt;
@@ -35,9 +35,9 @@ impl<D: Data> GLWEInfos for LWESwitchingKeyCompressed<D> {
}
}
impl<D: Data> GGLWELayoutInfos for LWESwitchingKeyCompressed<D> {
fn digits(&self) -> Digits {
self.0.digits()
impl<D: Data> GGLWEInfos for LWESwitchingKeyCompressed<D> {
fn dsize(&self) -> Dsize {
self.0.dsize()
}
fn rank_in(&self) -> Rank {
@@ -48,8 +48,8 @@ impl<D: Data> GGLWELayoutInfos for LWESwitchingKeyCompressed<D> {
self.0.rank_out()
}
fn rows(&self) -> Rows {
self.0.rows()
fn dnum(&self) -> Dnum {
self.0.dnum()
}
}
@@ -86,12 +86,12 @@ impl<D: DataRef> WriterTo for LWESwitchingKeyCompressed<D> {
impl LWESwitchingKeyCompressed<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(
infos.digits().0,
infos.dsize().0,
1,
"digits > 1 is not supported for LWESwitchingKeyCompressed"
"dsize > 1 is not supported for LWESwitchingKeyCompressed"
);
debug_assert_eq!(
infos.rank_in().0,
@@ -106,26 +106,26 @@ impl LWESwitchingKeyCompressed<Vec<u8>> {
Self(GGLWESwitchingKeyCompressed::alloc(infos))
}
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows) -> Self {
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> Self {
Self(GGLWESwitchingKeyCompressed::alloc_with(
n,
base2k,
k,
rows,
Digits(1),
Rank(1),
Rank(1),
dnum,
Dsize(1),
))
}
pub fn alloc_bytes<A>(infos: &A) -> usize
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(
infos.digits().0,
infos.dsize().0,
1,
"digits > 1 is not supported for LWESwitchingKey"
"dsize > 1 is not supported for LWESwitchingKey"
);
debug_assert_eq!(
infos.rank_in().0,
@@ -140,8 +140,8 @@ impl LWESwitchingKeyCompressed<Vec<u8>> {
GGLWESwitchingKeyCompressed::alloc_bytes(infos)
}
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rows, Digits(1), Rank(1), Rank(1))
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
}
}

View File

@@ -5,7 +5,7 @@ use poulpy_hal::{
};
use crate::layouts::{
Base2K, Degree, Digits, GGLWELayoutInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, Rank, Rows, TorusPrecision,
Base2K, Degree, Dnum, Dsize, GGLWEInfos, GLWEInfos, LWEInfos, LWEToGLWESwitchingKey, Rank, TorusPrecision,
compressed::{Decompress, GGLWESwitchingKeyCompressed},
};
use std::fmt;
@@ -35,9 +35,9 @@ impl<D: Data> GLWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
}
}
impl<D: Data> GGLWELayoutInfos for LWEToGLWESwitchingKeyCompressed<D> {
fn digits(&self) -> Digits {
self.0.digits()
impl<D: Data> GGLWEInfos for LWEToGLWESwitchingKeyCompressed<D> {
fn dsize(&self) -> Dsize {
self.0.dsize()
}
fn rank_in(&self) -> Rank {
@@ -48,8 +48,8 @@ impl<D: Data> GGLWELayoutInfos for LWEToGLWESwitchingKeyCompressed<D> {
self.0.rank_out()
}
fn rows(&self) -> Rows {
self.0.rows()
fn dnum(&self) -> Dnum {
self.0.dnum()
}
}
@@ -86,12 +86,12 @@ impl<D: DataRef> WriterTo for LWEToGLWESwitchingKeyCompressed<D> {
impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
pub fn alloc<A>(infos: &A) -> Self
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(
infos.digits().0,
infos.dsize().0,
1,
"digits > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
"dsize > 1 is not supported for LWEToGLWESwitchingKeyCompressed"
);
debug_assert_eq!(
infos.rank_in().0,
@@ -101,21 +101,21 @@ impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
Self(GGLWESwitchingKeyCompressed::alloc(infos))
}
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, rank_out: Rank) -> Self {
pub fn alloc_with(n: Degree, base2k: Base2K, k: TorusPrecision, rank_out: Rank, dnum: Dnum) -> Self {
Self(GGLWESwitchingKeyCompressed::alloc_with(
n,
base2k,
k,
rows,
Digits(1),
Rank(1),
rank_out,
dnum,
Dsize(1),
))
}
pub fn alloc_bytes<A>(infos: &A) -> usize
where
A: GGLWELayoutInfos,
A: GGLWEInfos,
{
debug_assert_eq!(
infos.rank_in().0,
@@ -123,15 +123,15 @@ impl LWEToGLWESwitchingKeyCompressed<Vec<u8>> {
"rank_in > 1 is not supported for LWEToGLWESwitchingKey"
);
debug_assert_eq!(
infos.digits().0,
infos.dsize().0,
1,
"digits > 1 is not supported for LWEToGLWESwitchingKey"
"dsize > 1 is not supported for LWEToGLWESwitchingKey"
);
GGLWESwitchingKeyCompressed::alloc_bytes(infos)
}
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, rows: Rows, rank_out: Rank) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, rows, Digits(1), Rank(1), rank_out)
pub fn alloc_bytes_with(n: Degree, base2k: Base2K, k: TorusPrecision, dnum: Dnum) -> usize {
GGLWESwitchingKeyCompressed::alloc_bytes_with(n, base2k, k, Rank(1), dnum, Dsize(1))
}
}