arnaucube
arnaucube/poulpyPublic Self-hosted repository
Bug fixes

- fixed `encoding.rs/decode_coeff_i64` for the case `k < basek2`
- `glwe/external_product.rs/external_product_scratch_space` did not allocate enough space for [`a_dft`](https://github.com/phantomzone-org/poulpy/blob/829b8be610bb518765be3eb857e58ffe09683c2d/core/src/glwe/external_product.rs#L83) when `k_out < k_ggsw`. Fixed by replacing `in_size` with `ggsw_size`.
- `glwe/ops.rs/add` sets `basek` and `k`of `self` GLWECiphertext whic is invalid because the `size` which depends on `inner` data remains unchanged.
- (not a fix) expose `backend` from `core`.
Janmajaya Mall janmajayamall@protonmail.com
Sun, 06 Jul 2025 12:40:08 +0530
commit

463731948de4a9a920e1889fbe479adcbab68199

parent

2a5e0e7dc30f3b62b02371c68e7b9f52ba93d0ed

4 files changed, 10 insertions(+), 8 deletions(-)

jump to
M backend/src/encoding.rs → backend/src/encoding.rs

@@ -269,12 +269,12 @@ }

let size: usize = (k + basek - 1) / basek; let data: &[i64] = a.raw(); - let mut res: i64 = data[i]; + let mut res: i64 = 0; let rem: usize = basek - (k % basek); let slice_size: usize = a.n() * a.cols(); - (0..size).for_each(|i| { - let x: i64 = data[i * slice_size]; - if i == size - 1 && rem != basek { + (0..size).for_each(|j| { + let x: i64 = data[j * slice_size + i]; + if j == size - 1 && rem != basek { let k_rem: usize = basek - rem; res = (res << k_rem) + (x >> rem); } else {

@@ -320,7 +320,7 @@ let n: usize = 8;

let module: Module<FFT64> = Module::<FFT64>::new(n); let basek: usize = 17; let size: usize = 5; - for k in [size * basek - 5] { + for k in [1, basek / 2, size * basek - 5] { let mut a: VecZnx<_> = module.new_vec_znx(2, size); let mut source = Source::new([0u8; 32]); let raw: &mut [i64] = a.raw_mut();
M core/src/glwe/external_product.rs → core/src/glwe/external_product.rs

@@ -18,7 +18,7 @@ let res_dft: usize = FourierGLWECiphertext::bytes_of(module, basek, k_out, rank);

let in_size: usize = k_in.div_ceil(basek).div_ceil(digits); let out_size: usize = k_out.div_ceil(basek); let ggsw_size: usize = k_ggsw.div_ceil(basek); - let vmp: usize = module.bytes_of_vec_znx_dft(rank + 1, in_size) + let vmp: usize = module.bytes_of_vec_znx_dft(rank + 1, ggsw_size) + module.vmp_apply_tmp_bytes( out_size, in_size,
M core/src/glwe/ops.rs → core/src/glwe/ops.rs

@@ -14,6 +14,7 @@ assert_eq!(a.n(), module.n());

assert_eq!(b.n(), module.n()); assert_eq!(self.n(), module.n()); assert_eq!(a.basek(), b.basek()); + assert_eq!(self.basek(), a.basek()); assert!(self.rank() >= a.rank().max(b.rank())); }

@@ -46,8 +47,8 @@ self_mut.data.zero_at(i, j);

}); }); - self.set_basek(a.basek()); - self.set_k(a.k().max(b.k())); + // self.set_basek(a.basek()); + // self.set_k(a.k().max(b.k())); } fn add_inplace<A>(&mut self, module: &Module<FFT64>, a: &A)
M core/src/lib.rs → core/src/lib.rs

@@ -19,6 +19,7 @@ pub use glwe::{GLWECiphertext, GLWEOps, GLWEPacker, GLWEPlaintext, GLWEPublicKey, GLWESecret};

pub(crate) use glwe::{GLWECiphertextToMut, GLWECiphertextToRef}; pub use lwe::{LWECiphertext, LWESecret}; +pub use backend; pub use backend::Scratch; pub use backend::ScratchOwned;