diff --git a/CHANGELOG.md b/CHANGELOG.md index bd4b886..a38eb85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,37 @@ # CHANGELOG -## [0.3.2] - 2025-10-27 +## [0.4.0] - 2025-10-27 + +### Summary +- Full support for base2k operations. +- Many improvments to BDD arithmetic. +- Removal of **poulpy-backend** & spqlios backend. +- Addition of individual crates for each specific backend. +- Some minor bug fixes. + +### `poulpy-hal` +- Add cross-base2k normalization + +### `poulpy-core` +- Add full support for automatic cross-base2k operations & updated tests accordingly. +- Updated noise helper API. +- Fixed many tests that didn't assess noise correctly. +- Fixed decoding function to use arithmetic rounded division instead of arithmetic right shift. +- Fixed packing to clean values correctly. + +### `poulpy-schemes` +- Renamed `tfhe` crate to `bin_fhe`. +- Improved support & API for BDD arithmetic, including multi-thread acceleration. +- Updated crate to support cross-base2k operations. +- Add additional operations, such as splice_u8, splice_u16 and sign extension. +- Add `GLWEBlindRetriever` and `GLWEBlindRetrieval`: a `GGSW`-based blind reversible retrieval (enables to instantiate encrypted ROM/RAM like object). +- Improved Cmux speed + +### `poulpy-cpu-ref` +- A new crate that provides the refernce CPU implementation of **poulpy-hal**. This replaces the previous **poulpy-backend/cpu_ref**. + +### `poulpy-cpu-avx` +- A new crate that provides an AVX/FMA accelerated CPU implementation of **poulpy-hal**. This replaces the previous **poulpy-backend/cpu_avx**. ### `poulpy-schemes` - Added `sign` argument to GGSW-based blind rotation, which enables to choose the rotation direction of the test vector. diff --git a/README.md b/README.md index 3edfba2..66ef4f6 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,9 @@ - **`poulpy-hal`**: a crate providing layouts and a trait-based hardware acceleration layer with open extension points, matching the API and types of spqlios-arithmetic. This crate does not provide concrete implementations other than the layouts (e.g. `VecZnx`, `VmpPmat`). - **`poulpy-core`**: a backend agnostic crate implementing scheme agnostic RLWE arithmetic for LWE, GLWE, GGLWE and GGSW ciphertexts using **`poulpy-hal`**. Can be instantiated with any backend provided by **`poulpy-backend`**. -- **`poulpy-schemes`**: a backend agnostic crate implementing mainstream FHE schemes using **`poulpy-core`** and **`poulpy-hal`**. The crate can be instantiated with any backend provided by **`poulpy-backend`**. -- **`poulpy-backend`**: a crate providing concrete implementations of **`poulpy-hal`** for various representations and hardwares. +- **`poulpy-schemes`**: a backend agnostic crate implementing mainstream FHE schemes using **`poulpy-core`** and **`poulpy-hal`**. +- **`poulpy-cpu-ref`**: the reference CPU implementatin of **`poulpy-hal`**. +- **`poulpy-cpu-ref`**: an AVX accelerated CPU implementation of **`poulpy-hal`**. ## Bivariate Polynomial Representation @@ -43,7 +44,8 @@ This provides the following benefits: - **`poulpy-hal`**: https://crates.io/crates/poulpy-hal - **`poulpy-core`**: https://crates.io/crates/poulpy-core - **`poulpy-schemes`**: https://crates.io/crates/poulpy-schemes -- **`poulpy-backend`**: https://crates.io/crates/poulpy-backend +- **`poulpy-cpu-ref`**: https://crates.io/crates/poulpy-cpu-ref +- **`poulpy-cpu-avx`**: https://crates.io/crates/poulpy-cpu-avx ## Documentation @@ -70,9 +72,9 @@ Poulpy is licensed under the Apache-2.0 License. See [NOTICE](./NOTICE) & [LICEN Please use the following BibTex entry for citing Poulpy @misc{poulpy, - title = {Poulpy v0.3.0}, + title = {Poulpy v0.4.0}, howpublished = {Online: \url{https://github.com/phantomzone-org/poulpy}}, - month = Oct, + month = Nov, year = 2025, note = {Phantom Zone} } diff --git a/docs/lib_diagram.png b/docs/lib_diagram.png index 924ccf8..13c7e44 100644 Binary files a/docs/lib_diagram.png and b/docs/lib_diagram.png differ diff --git a/docs/poulpy_arch.svg b/docs/poulpy_arch.svg index 9290715..c8169a0 100644 --- a/docs/poulpy_arch.svg +++ b/docs/poulpy_arch.svg @@ -28,15 +28,15 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:connector-spacing="0" - inkscape:zoom="1.4702523" - inkscape:cx="387.0084" - inkscape:cy="179.56101" + inkscape:zoom="1.0396254" + inkscape:cx="409.76299" + inkscape:cy="148.13028" inkscape:window-width="1781" inkscape:window-height="1214" - inkscape:window-x="1623" - inkscape:window-y="25" + inkscape:window-x="238" + inkscape:window-y="48" inkscape:window-maximized="0" - inkscape:current-layer="layer2" />LATTICE ARITHMETICspqlios- -arithmeticBackend AgnosticBackend Agnostic ApplicationsApplicationspoulpy-backendpoulpy-halpoulpy-halpoulpy-cpu-refpoulpy-cpu-avxZNX APIZNX API DEF.ZNX APIZNX API IMPL.RLWE APIRLWE API IMPL.SCHEME APISCHEME API IMPL.poulpy-corepoulpy-corepoulpy-schemespoulpy-schemes = Module::::new(n as u64); + let module: Module = Module::::new(n.0 as u64); + + let glwe_ct_infos: GLWELayout = GLWELayout { + n, + base2k, + k: k_ct, + rank, + }; + + let glwe_pt_infos: GLWEPlaintextLayout = GLWEPlaintextLayout { n, base2k, k: k_pt }; // Allocates ciphertext & plaintexts - let mut ct: GLWECiphertext> = GLWECiphertext::alloc(n, base2k, k_ct, rank); - let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc(n, base2k, k_pt); - let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc(n, base2k, k_pt); + let mut ct: GLWE> = GLWE::alloc_from_infos(&glwe_ct_infos); + let mut pt_want: GLWEPlaintext> = GLWEPlaintext::alloc_from_infos(&glwe_pt_infos); + let mut pt_have: GLWEPlaintext> = GLWEPlaintext::alloc_from_infos(&glwe_pt_infos); // CPRNG let mut source_xs: Source = Source::new([0u8; 32]); @@ -51,20 +60,20 @@ fn main() { let mut source_xa: Source = Source::new([2u8; 32]); // Scratch space - let mut scratch: ScratchOwned = ScratchOwned::alloc( - GLWECiphertext::encrypt_sk_tmp_bytes(&module, n, base2k, ct.k()) - | GLWECiphertext::decrypt_tmp_bytes(&module, n, base2k, ct.k()), + let mut scratch: ScratchOwned = ScratchOwned::alloc( + GLWE::encrypt_sk_tmp_bytes(&module, &glwe_ct_infos) | GLWE::decrypt_tmp_bytes(&module, &glwe_ct_infos), ); // Generate secret-key - let mut sk: GLWESecret> = GLWESecret::alloc(n, rank); + let mut sk: GLWESecret> = GLWESecret::alloc_from_infos(&glwe_ct_infos); sk.fill_ternary_prob(0.5, &mut source_xs); // Backend-prepared secret - let sk_prepared: GLWESecretPrepared, FFT64> = sk.prepare_alloc(&module, scratch.borrow()); + let mut sk_prepared: GLWESecretPrepared, FFT64Ref> = GLWESecretPrepared::alloc(&module, rank); + sk_prepared.prepare(&module, &sk); // Uniform plaintext - module.vec_znx_fill_uniform(base2k, &mut pt_want.data, 0, k_pt, &mut source_xa); + module.vec_znx_fill_uniform(base2k.into(), &mut pt_want.data, 0, &mut source_xa); // Encryption ct.encrypt_sk( @@ -80,10 +89,10 @@ fn main() { ct.decrypt(&module, &mut pt_have, &sk_prepared, scratch.borrow()); // Diff between pt - Dec(Enc(pt)) - pt_want.sub_inplace_ab(&module, &pt_have); + module.glwe_sub_inplace(&mut pt_want, &pt_have); // Ideal vs. actual noise - let noise_have: f64 = pt_want.data.std(base2k, 0) * (ct.k() as f64).exp2(); + let noise_have: f64 = pt_want.data.stats(base2k.into(), 0).std() * (ct.k().as_u32() as f64).exp2(); let noise_want: f64 = SIGMA; // Check @@ -169,4 +178,4 @@ ggsw.automorphism(...); ## Tests -A fully generic test suite is available in [`src/tests/generics`](./src/tests/generics). \ No newline at end of file +A fully generic test suite is available in [`src/tests/test_suite`](./src/tests/test_suite). \ No newline at end of file diff --git a/poulpy-cpu-avx/README.md b/poulpy-cpu-avx/README.md index 2cb4d6a..9d7be01 100644 --- a/poulpy-cpu-avx/README.md +++ b/poulpy-cpu-avx/README.md @@ -1,6 +1,6 @@ -# 🐙 Poulpy-Backend +# 🐙 Poulpy-CPU-REF -**Poulpy-Backend-CPU-AVX** is a Rust crate that provides concrete implementations of **`poulpy-hal`**. This crate is used to instantiate projects implemented with **`poulpy-hal`**, **`poulpy-core`** and/or **`poulpy-schemes`**. +**Poulpy-Backend-CPU-AVX** is a Rust crate that provides an AVX accelerated CPU implementation of **`poulpy-hal`**. This crate is used to instantiate projects implemented with **`poulpy-hal`**, **`poulpy-core`** and/or **`poulpy-schemes`**. ## Example @@ -14,5 +14,5 @@ let module = Module = Module::new(1< = Module::new(1< = Module::new(1<VecZnxDft-->|IDFT|VecZnxBig-->|Normalize|VecZnx ``` -## Testing +## Tests -A full generic and backend agnostic testing suit for the layouts and public API is planned. This will allow to test the correctness of any backend easily. \ No newline at end of file +A fully generic cross-backend test suite is available in [`src/test_suite`](./src/test_suite). \ No newline at end of file diff --git a/poulpy-schemes/README.md b/poulpy-schemes/README.md index bcf1b89..8701a6d 100644 --- a/poulpy-schemes/README.md +++ b/poulpy-schemes/README.md @@ -8,5 +8,8 @@ See [./examples/circuit_bootstrapping.rs](./examples/circuit_bootstrapping.rs) ## Available Schemes -- TFHE/FHEW: under construction. Blind rotation & circuit bootstrapping implemented. -- CKKS: planned \ No newline at end of file +- **BIN FHE**: + - **bdd_arithmetic**: high level API for u32 arithmetic (u8 to u256 planned) using binary decision circuits. Also provides API for blind retrieval, blind rotation (using encpypted integers) and blind selection. + - **blind_rotation**: API for blind rotation (LWE(m) -> GLWE(X^m)) + - **circuit_bootstrapping**: API for circuit bootstrapping (LWE(m) -> GGSW(m) or GGSW(X^m)). +- **CKKS**: planned \ No newline at end of file