@lib-q/cb-kem 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,303 @@
1
+ # lib-q-cb-kem (Classic McEliece–family CB-KEM)
2
+
3
+ This directory is the **`lib-q-cb-kem`** workspace crate (see `Cargo.toml`). It vendors/adapts the **classic-mceliece-rust**-style implementation below for use behind the **`cb-kem`** feature of [**lib-q-kem**](../lib-q-kem). In `Cargo.toml`, depend on `lib-q-cb-kem`, not the crates.io name shown in the historical sections of this file.
4
+
5
+ ---
6
+
7
+ ## Upstream-oriented documentation (Classic McEliece)
8
+
9
+ This is a pure-rust safe-rust implementation of the Classic McEliece post-quantum scheme.
10
+
11
+ * Classic McEliece is a code-based key encapsulation mechanism (KEM)
12
+ * The implementation is based on the Classic McEliece reference implementation of [NIST round 4](https://csrc.nist.gov/Projects/post-quantum-cryptography/round-4-submissions)
13
+ * The implementation does not utilize any concurrency techniques (SIMD/threading/…, except maybe auto-vectorization on your CPU)
14
+ * It depends on `sha3` as SHA-3 implementation and `aes` as AES block cipher (used as RNG) implementation
15
+ * It passes the 100 testcases of the C reference implementation
16
+ * It implements all 10 variants of the Classic McEliece KEM
17
+ * The implementation takes between 100 milliseconds (`mceliece348864`) and 500 milliseconds (`mceliece8192128f`) to run on a modern computer
18
+ * The implementation is constant-time on software instruction level
19
+ * The random number generator is based on AES256 in counter mode
20
+ * First described in 1978, the cryptographic scheme has a rich history in security analysis. Its large public key size, however, often limits adoption.
21
+
22
+ The 10 variants have the following designated identifiers:
23
+
24
+ * `mceliece348864`
25
+ * `mceliece348864f`
26
+ * `mceliece460896`
27
+ * `mceliece460896f`
28
+ * `mceliece6688128`
29
+ * `mceliece6688128f`
30
+ * `mceliece6960119`
31
+ * `mceliece6960119f`
32
+ * `mceliece8192128`
33
+ * `mceliece8192128f`
34
+
35
+ ## Who should use it?
36
+
37
+ Anyone, how wants to use Classic McEliece to negotiate a key between two parties.
38
+
39
+ ## How does one use it storing keys on the heap (default feature `alloc`)?
40
+
41
+ Add this to your `Cargo.toml`:
42
+ ```toml
43
+ [dependencies]
44
+ lib-q-cb-kem = { version = "0.0.2", path = "../lib-q-cb-kem" } # from workspace root
45
+ ```
46
+
47
+ To use a specific Classic McEliece variant, you need to import it with the corresponding feature flag:
48
+
49
+ ```toml
50
+ [dependencies]
51
+ lib-q-cb-kem = { version = "0.0.2", features = ["mceliece6960119"] }
52
+ ```
53
+
54
+ Assuming this dependency, the simplest and most ergonomic way of using the library
55
+ is with heap allocated keys and the `*_boxed` KEM step functions. First, we import them:
56
+
57
+ ```rust
58
+ #[cfg(feature = "alloc")]
59
+ use lib_q_cb_kem::{keypair_boxed, encapsulate_boxed, decapsulate_boxed};
60
+ ```
61
+
62
+ Followingly, we run the KEM and provide generated keys accordingly.
63
+ Here, we consider an example where we run it in a separate thread (be aware that the example also depends on the rand crate):
64
+
65
+ ```rust
66
+ #[cfg(feature = "alloc")] {
67
+ use lib_q_cb_kem::{keypair_boxed, encapsulate_boxed, decapsulate_boxed};
68
+
69
+ fn run_kem() {
70
+ let mut rng = lib_q_cb_kem::LibQRng::new();
71
+
72
+ // Alice computes the keypair
73
+ let (public_key, secret_key) = keypair_boxed(&mut rng);
74
+
75
+ // Send `secret_key` over to Bob.
76
+ // Bob computes the shared secret and a ciphertext
77
+ let (ciphertext, shared_secret_bob) = encapsulate_boxed(&public_key, &mut rng);
78
+
79
+ // Send `ciphertext` back to Alice.
80
+ // Alice decapsulates the ciphertext...
81
+ let shared_secret_alice = decapsulate_boxed(&ciphertext, &secret_key);
82
+
83
+ // ... and ends up with the same key material as Bob.
84
+ assert_eq!(shared_secret_bob.as_array(), shared_secret_alice.as_array());
85
+ }
86
+
87
+ fn main() {
88
+ std::thread::Builder::new()
89
+ // This library needs quite a lot of stack space to work
90
+ .stack_size(2 * 1024 * 1024)
91
+ .spawn(run_kem)
92
+ .unwrap()
93
+ .join()
94
+ .unwrap();
95
+ }
96
+ }
97
+ ```
98
+
99
+ Pay attention that public keys in Classic McEliece are huge (between 255 KB and 1.3 MB). As a result, running the algorithm requires a lot of memory. You need to consider where you store it. In case of this API, the advantages are …
100
+
101
+ * you don't need to handle the memory manually
102
+ * on Windows, the call to `keypair` uses more stack than is available by default. Such stack size limitations can be avoided with the heap-allocation API (see Windows remark below).
103
+
104
+ ## How does one use it storing keys on the stack (disabled feature `alloc`)?
105
+
106
+ The other option is that you exclude the heap-allocation API and use the provided stack-allocation API. Its advantages are:
107
+
108
+ * stack allocation also works in a `no_std` environment.
109
+ * on some microcontroller platforms, a heap is not available.
110
+ * stack (de-)allocation in general is faster than heap (de-)allocation
111
+
112
+ Thus, in this section we want to show you how to use this API without the heap. For this, you need to disable feature `alloc` which is enabled per default (this line retains default feature `zeroize` but removes default feature `alloc`):
113
+
114
+ ```toml
115
+ classic-mceliece-rust = { version = "3.0", default-features = false, features = ["zeroize"] }
116
+ ```
117
+
118
+ How does one use the API then (be aware that the example also depends on the rand crate)?
119
+
120
+ ```rust,no_run
121
+ use lib_q_cb_kem::{keypair, encapsulate, decapsulate};
122
+ use lib_q_cb_kem::{CRYPTO_BYTES, CRYPTO_PUBLICKEYBYTES, CRYPTO_SECRETKEYBYTES};
123
+
124
+ fn main() {
125
+ let mut rng = lib_q_cb_kem::LibQRng::new();
126
+
127
+ // Please mind that `public_key_buf` is very large.
128
+ let mut public_key_buf = [0u8; CRYPTO_PUBLICKEYBYTES];
129
+ let mut secret_key_buf = [0u8; CRYPTO_SECRETKEYBYTES];
130
+ let (public_key, secret_key) = keypair(&mut public_key_buf, &mut secret_key_buf, &mut rng);
131
+
132
+ let mut shared_secret_bob_buf = [0u8; CRYPTO_BYTES];
133
+ let (ciphertext, shared_secret_bob) = encapsulate(&public_key, &mut shared_secret_bob_buf, &mut rng);
134
+
135
+ let mut shared_secret_alice_buf = [0u8; CRYPTO_BYTES];
136
+ let shared_secret_alice = decapsulate(&ciphertext, &secret_key, &mut shared_secret_alice_buf);
137
+
138
+ assert_eq!(shared_secret_bob.as_array(), shared_secret_alice.as_array());
139
+ }
140
+ ```
141
+
142
+ Here, you can see how the keys are allocated explicitly.
143
+
144
+ #### A remark on Windows
145
+
146
+ If you want your program to be portable with stack allocation and not unexpectedly crash, you should probably run the entire key exchange in a dedicated thread with a large enough stack size. This code snippet shows the idea:
147
+
148
+ ```rust,no_run
149
+ std::thread::Builder::new()
150
+ .stack_size(4 * 1024 * 1024)
151
+ .spawn(|| {/* Run the KEM here */})
152
+ .unwrap();
153
+ ```
154
+
155
+ ### libQ Integration
156
+
157
+ This crate is fully integrated with the libQ cryptography library, providing a secure,
158
+ production-ready implementation of Classical McEliece KEM with comprehensive security validation.
159
+
160
+ ### Feature zeroize: Clear out secrets from memory
161
+
162
+ If the `zeroize` feature is enabled (it is by default), all key types that contain anything secret
163
+ implements `Zeroize` and `ZeroizeOnDrop`. This makes them clear their memory when they go out of
164
+ scope, and lowers the risk of secret key material leaking in one way or another.
165
+
166
+ Please mind that this of course makes any buffers you pass into the library useless for reading
167
+ out the key from. Instead of trying to fetch the key material from the buffers you pass in,
168
+ get it from the `as_array` method.
169
+
170
+ ```rust
171
+ #[cfg(not(windows))] {
172
+ use lib_q_cb_kem::keypair;
173
+ use lib_q_cb_kem::{CRYPTO_PUBLICKEYBYTES, CRYPTO_SECRETKEYBYTES};
174
+
175
+ let mut rng = lib_q_cb_kem::LibQRng::new();
176
+
177
+ let mut pk_buf = [0u8; CRYPTO_PUBLICKEYBYTES];
178
+ // Initialize to non-zero to show that it has been set to zero by the drop later
179
+ let mut sk_buf = [255u8; CRYPTO_SECRETKEYBYTES];
180
+
181
+ // This is the WRONG way of accessing your keys. The buffer will
182
+ // be cleared once the `PrivateKey` returned from `keypair` goes out of scope.
183
+ // You should not rely on that array for anything except providing a temporary storage
184
+ // location to this library.
185
+ #[cfg(feature = "zeroize")]
186
+ {
187
+ let (_, secret_key) = keypair(&mut pk_buf, &mut sk_buf, &mut rng);
188
+ drop(secret_key);
189
+ // Ouch! The array only has zeroes now.
190
+ assert_eq!(sk_buf, [0; CRYPTO_SECRETKEYBYTES]);
191
+ }
192
+
193
+ // Correct way of getting the secret key bytes if you do need them. However,
194
+ // if you want the secrets to stay secret, you should try to not read them out of their
195
+ // storage at all
196
+ {
197
+ let (_, secret_key) = keypair(&mut pk_buf, &mut sk_buf, &mut rng);
198
+ assert_ne!(secret_key.as_array(), &[0; CRYPTO_SECRETKEYBYTES]);
199
+ }
200
+ }
201
+ ```
202
+
203
+ ## How does one run it?
204
+
205
+ This library comes with two examples:
206
+
207
+ ```bash
208
+ $ cargo run --example basic
209
+ ```
210
+
211
+ The output annotates messages with Alice/Bob to illustrate which data is processed by which party.
212
+ The `katkem` example implements the classic request/response file structure which is part of the NIST PQC framework.
213
+
214
+ In order to validate a generated repsonse file, the corresponding Classic McEliece variant feature flag
215
+ needs to be passed as `cargo run` parameter.
216
+
217
+ ```bash
218
+ $ cargo run --example katkem PQCkemKAT_935.req PQCkemKAT_935.rsp
219
+ $ cargo run --example katkem PQCkemKAT_935.rsp
220
+ ```
221
+
222
+ The different variants can be enabled through feature flags:
223
+
224
+ ```bash
225
+ $ cargo test --release --features "mceliece6960119" --package lib-q-cb-kem --lib -- tests::test_katkem PQCkemKAT_1450.req PQCkemKAT_1450.rsp
226
+ ```
227
+
228
+ `mceliece348864` is the default variant. You cannot enable two variants simultaneously.
229
+
230
+ ## How fast is it?
231
+
232
+ All data uses clock cycles as unit (the smaller the better).
233
+ The rust implementation v2.0.0 yielded the following runtime results:
234
+
235
+ <table>
236
+ <thead>
237
+ <tr><td></td><td>complete KEM</td><td>keypair</td><td>enc</td><td>dec</td></tr>
238
+ </thead><tbody>
239
+ <tr><td>mceliece348864</td><td>460,062,191</td><td>439,682,143</td><td>222,424</td><td>42,046,357</td></tr>
240
+ <tr><td>mceliece348864f</td><td>244,943,900</td><td>203,564,820</td><td>215,971</td><td>41,648,773</td></tr>
241
+ <tr><td>mceliece460896</td><td>1,326,425,784</td><td>1,434,864,061</td><td>487,522</td><td>111,547,716</td></tr>
242
+ <tr><td>mceliece460896f</td><td>789,636,856</td><td>652,117,200</td><td>553,301</td><td>106,521,703</td></tr>
243
+ <tr><td>mceliece6688128</td><td>3,188,205,266</td><td>2,596,052,574</td><td>785,763</td><td>202,774,928</td></tr>
244
+ <tr><td>mceliece6688128f</td><td>1,236,809,020</td><td>1,059,087,715</td><td>826,899</td><td>203,907,226</td></tr>
245
+ <tr><td>mceliece6960119</td><td>2,639,852,573</td><td>2,532,146,126</td><td>3,864,285</td><td>203,959,009</td></tr>
246
+ <tr><td>mceliece6960119f</td><td>1,165,079,187</td><td>965,134,546</td><td>3,416,795</td><td>197,089,546</td></tr>
247
+ <tr><td>mceliece8192128</td><td>3,129,183,262</td><td>2,754,933,130</td><td>965,822</td><td>247,083,745</td></tr>
248
+ <tr><td>mceliece8192128f</td><td>1,342,438,451</td><td>1,150,297,595</td><td>1,068,317</td><td>242,545,160</td></tr>
249
+ </tbody>
250
+ </table>
251
+
252
+ The C reference implementation yielded the following runtime results:
253
+
254
+ <table>
255
+ <thead>
256
+ <tr><td></td><td>complete KEM</td><td>keypair</td><td>enc</td><td>dec</td></tr>
257
+ </thead><tbody>
258
+ <tr><td>mceliece348864</td><td>434,103,000</td><td>437,187,000</td><td>187,557</td><td>73,801,300</td></tr>
259
+ <tr><td>mceliece348864f</td><td>252,423,000</td><td>180,235,000</td><td>189,522</td><td>73,668,000</td></tr>
260
+ <tr><td>mceliece460896</td><td>760,993,000</td><td>894,497,000</td><td>298,041</td><td>154,507,000</td></tr>
261
+ <tr><td>mceliece460896f</td><td>606,225,000</td><td>44,906,000</td><td>297,743</td><td>154,013,000</td></tr>
262
+ <tr><td>mceliece6688128</td><td>1,568,900,000</td><td>1,780,660,000</td><td>425,504</td><td>29,575,000</td></tr>
263
+ <tr><td>mceliece6688128f</td><td>109,471,000</td><td>760,298,000</td><td>414,358</td><td>298,173,000</td></tr>
264
+ <tr><td>mceliece6960119</td><td>3,405,730,000</td><td>1,694,410,000</td><td>840,598</td><td>287,154,000</td></tr>
265
+ <tr><td>mceliece6960119f</td><td>1,311,130,000</td><td>942,987,000</td><td>984,660</td><td>303,543,000</td></tr>
266
+ <tr><td>mceliece8192128</td><td>1,635,550,000</td><td>760,619,000</td><td>428,112</td><td>361,999,000</td></tr>
267
+ <tr><td>mceliece8192128f</td><td>1,772,530,000</td><td>1,222,720,000</td><td>534,503</td><td>392,729,000</td></tr>
268
+ </tbody>
269
+ </table>
270
+
271
+ The tests were done on a Lenovo Thinkpad x260 (Intel Core i5-6200U CPU @ 2.30GHz). In the case of rust, [criterion 0.3.5](https://crates.io/crates/criterion) has been used as given in `benches/` and in case of C, Google's [benchmark](https://github.com/google/benchmark/blob/v1.6.1/docs/perf_counters.md) with PFM support and disabled CPU frequency scaling. You can run the benchmark suite yourself with the `bench` subcommand and optionally some variant feature flag:
272
+
273
+ ```bash
274
+ $ cargo bench --features mceliece348864
275
+ ```
276
+
277
+ For optimal benchmark results you can run the rust benchmarks with CPU optimization using `RUSTFLAGS="-C target-cpu=native"`, setting the cargo bench optimization profile to `opt-level = 3` and set link time optimizations to `lto = "fat"`. For further insight into the cargo bench settings refer to the official [cargo bench profile](https://doc.rust-lang.org/cargo/reference/profiles.html) documentation.
278
+
279
+ ## Is it correct?
280
+
281
+ Yes, besides passing unittests (derived from the C implementation), the generated KAT KEM test files have equivalent MD5 hashes. Namely …
282
+
283
+ <table>
284
+ <thead>
285
+ <tr><td>variant</td><td>expected MD5 hash</td></tr>
286
+ </thead><tbody>
287
+ <tr><td>mceliece348864</td><td><code>f932d4f75d1a788ad58e7d20af8defe9</code></td></tr>
288
+ <tr><td>mceliece348864f</td><td><code>70e10264d735abe77a509d853bfc6f6d</code></td></tr>
289
+ <tr><td>mceliece460896</td><td><code>7d2d60f492a8e74a33696a0616f61746</code></td></tr>
290
+ <tr><td>mceliece460896f</td><td><code>5ce8c2ecbb8c94082b475ff090f457c4</code></td></tr>
291
+ <tr><td>mceliece6688128</td><td><code>e7ad02c431ac9019820b7ce96654b240</code></td></tr>
292
+ <tr><td>mceliece6688128f</td><td><code>39984724cdabb810cdc76ade08a9bf52</code></td></tr>
293
+ <tr><td>mceliece6960119</td><td><code>819e4a4748f201e47d70f28f5b639303</code></td></tr>
294
+ <tr><td>mceliece6960119f</td><td><code>59426af22ec3a5e5dddc0969782832a6</code></td></tr>
295
+ <tr><td>mceliece8192128</td><td><code>9dc71f8a9f8a6492e2b7c341b8a0801b</code></td></tr>
296
+ <tr><td>mceliece8192128f</td><td><code>8022c8ffd8d938e56840261c91d1e59a</code></td></tr>
297
+ </tbody>
298
+ </table>
299
+
300
+
301
+
302
+ ## Subresource integrity (SHA-384)
303
+ Paths in `integrity-manifest.json` are relative to the package root.
@@ -0,0 +1,6 @@
1
+ {
2
+ "integrity": {
3
+ "nodejs/lib_q_cb_kem_bg.wasm": "sha384-WSHdZyuiR5l0+TXBboofuVFeetvxFgp4cgojUeNChpRTNhBJaOhAtzaIMy450xSF",
4
+ "web/lib_q_cb_kem_bg.wasm": "sha384-WSHdZyuiR5l0+TXBboofuVFeetvxFgp4cgojUeNChpRTNhBJaOhAtzaIMy450xSF"
5
+ }
6
+ }
@@ -0,0 +1,322 @@
1
+ # lib-Q - Post-Quantum Cryptography Library
2
+
3
+ A Rust cryptography workspace focused on **NIST-standardized post-quantum** key exchange and signatures, **SHA-3-family** hashes and XOFs, and a **transparent STARK**–based zero-knowledge stack. CI enforces `cargo check --workspace --exclude lib-q-examples --exclude lib-q-sca-test --target wasm32-unknown-unknown` (with the `getrandom` wasm_js cfg) so the **publishable library workspace** compiles for the WebAssembly target; npm bundles are produced for the `@lib-q/*` packages listed below (see [docs/npm-packages.md](docs/npm-packages.md)). For build modes, feature flags, and browser baselines, see [docs/wasm-compilation.md](docs/wasm-compilation.md).
4
+
5
+ ## Mission
6
+
7
+ lib-Q provides a coherent Rust API surface over NIST-track post-quantum primitives, SHA-3–family hashing, Saturnin AEAD, HPKE, and optional STARK-based proofs, with the goal of keeping advanced cryptography approachable without hiding residual implementation risk.
8
+
9
+ ## Key features
10
+
11
+ - **Post-quantum first**: Post-quantum KEMs and signatures with tiered symmetric options
12
+ - **Standards-aligned**: PQC KEMs and signatures track NIST-standardized modules (e.g. FIPS 203/204/205/206, HQC, Classic McEliece–family CB-KEM); hashes and XOFs use the SHA-3 family; symmetric design centers on Saturnin; ZKPs use a transparent STARK stack (complementary to the NIST PQC algorithm set)
13
+ - **Memory safe**: Built in Rust with zero-cost abstractions
14
+ - **Cross-platform**: Native Rust + WASM compilation
15
+ - **Intuitive API**: Clean, consistent interface designed for modern development
16
+ - **Self-contained algorithms**: No external non-Rust tooling required for core use
17
+ - **Three security tiers**: Ultra-secure, balanced, and performance-optimized options
18
+ - **Modular design**: Use only what you need with individual crates and npm packages
19
+
20
+ ## no_std, embedded, and WebAssembly
21
+
22
+ - **Umbrella `lib-q` crate**: Disabling default features applies `#![no_std]` to this crate's own code, but some path dependencies are still declared with `std` enabled (for example unified signature support via `lib-q-sig`). The final artifact may still link the standard library. For a **true** `no_std` + `alloc` dependency tree, use the **workspace crates you need** (`lib-q-core`, `lib-q-kem`, `lib-q-ml-dsa`, etc.) with `--no-default-features` and each crate's `alloc` / algorithm features. Per-crate READMEs describe WASM and `no_std` where relevant (for example [lib-q-saturnin/README.md](lib-q-saturnin/README.md)).
23
+
24
+ - **WASM and `getrandom`**: Match CI when compiling for `wasm32-unknown-unknown`: set `CARGO_TARGET_WASM32_UNKNOWN_UNKNOWN_RUSTFLAGS` to `--cfg getrandom_backend="wasm_js" -C panic=abort` (see [.github/actions/wasm-build/action.yml](.github/actions/wasm-build/action.yml), [scripts/build-wasm.ps1](scripts/build-wasm.ps1), [scripts/security-check.ps1](scripts/security-check.ps1)).
25
+
26
+ - **`lib-q-zkp`**: Ships a `cdylib` + `wasm` feature for `wasm-pack` / `@lib-q/zkp`; CI also `cargo check`s the ZKP stack on `wasm32-unknown-unknown`.
27
+
28
+ ### Browser example
29
+
30
+ The minimal browser demo in [`examples/wasm-browser-demo`](examples/wasm-browser-demo) exposes an ML-DSA-44 smoke API:
31
+
32
+ ```javascript
33
+ import init, { wasm_smoke_ml_dsa_sign_verify } from "./pkg/wasm_browser_demo.js";
34
+
35
+ await init();
36
+ const ok = await wasm_smoke_ml_dsa_sign_verify();
37
+ console.log("ML-DSA wasm smoke:", ok);
38
+ ```
39
+
40
+ ## Package structure
41
+
42
+ lib-Q is organized as a Rust workspace with individual crates and npm packages:
43
+
44
+ ### Rust workspace crates
45
+
46
+ Publishing to [crates.io](https://crates.io/) is driven by [`.github/workflows/cd.yml`](.github/workflows/cd.yml) in dependency order. The `examples` umbrella and `examples/wasm-browser-demo` are integration harnesses (`publish = false` where set); other members follow `[workspace].members` in [Cargo.toml](Cargo.toml). The workspace-wide WASM compile gate excludes those example crates and `lib-q-sca-test`.
47
+
48
+ | Crate | Role |
49
+ |-------|------|
50
+ | **`lib-q`** | Umbrella library (feature-gated re-exports) |
51
+ | **`lib-q-types`** | Shared type definitions |
52
+ | **`lib-q-core`** | Core types, traits, provider surface, validation |
53
+ | **`lib-q-keccak`** | Keccak-f / sponge building blocks |
54
+ | **`lib-q-k12`** | KangarooTwelve (K12) |
55
+ | **`lib-q-sha3`** | SHA-3 / SHAKE / cSHAKE core |
56
+ | **`lib-q-keccak-digest`** | Digest adapter over Keccak |
57
+ | **`lib-q-kem`** | KEM façade (ML-KEM, CB-KEM, HQC integration) |
58
+ | **`lib-q-ml-kem`** | ML-KEM (FIPS 203) |
59
+ | **`lib-q-ml-dsa`** | ML-DSA (FIPS 204) |
60
+ | **`lib-q-ring`** | Negacyclic ring / NTT layer for ML-DSA |
61
+ | **`lib-q-sca-test`** | Statistical side-channel harness (TVLA-style) |
62
+ | **`lib-q-lattice-zkp`** | Module-lattice commitments / sigma research |
63
+ | **`lib-q-ring-sig`** | Ring-style openings / DualRing pilots |
64
+ | **`lib-q-prf`** | Legendre / Gold PRF building blocks |
65
+ | **`lib-q-platform`** | Platform helpers |
66
+ | **`lib-q-intrinsics`** | SIMD / intrinsics helpers |
67
+ | **`lib-q-sig`** | Signature façade (ML-DSA, SLH-DSA) |
68
+ | **`lib-q-hash`** | Hash façade (SHAKE, KMAC, TupleHash, etc.) |
69
+ | **`lib-q-aead`** | AEAD façade (Saturnin, Romulus, duplex, tweak) |
70
+ | **`lib-q-saturnin`** | Saturnin suite |
71
+ | **`lib-q-duplex-aead`** | Duplex-sponge AEAD |
72
+ | **`lib-q-tweak-aead`** | Tweakable CTR AEAD over Keccak |
73
+ | **`lib-q-romulus`** | Romulus AEAD (Skinny-based) |
74
+ | **`lib-q-hpke`** | HPKE (RFC 9180) |
75
+ | **`lib-q-utils`** | Shared utilities |
76
+ | **`lib-q-zkp`** | ZKP public API (STARK-backed) |
77
+ | **`lib-q-fn-dsa`** | FN-DSA (FIPS 206) |
78
+ | **`lib-q-slh-dsa`** | SLH-DSA (FIPS 205) |
79
+ | **`lib-q-cb-kem`** | Classic McEliece–family CB-KEM |
80
+ | **`lib-q-random`** | Randomness / entropy helpers |
81
+ | **`lib-q-hqc`** | HQC KEM |
82
+ | **`lib-q-hqc-traits`** | HQC shared traits (`lib-q-hqc/traits`) |
83
+ | **`lib-q-stark`** | STARK prover stack (top-level) |
84
+ | **`lib-q-stark-air`** | AIR definitions |
85
+ | **`lib-q-stark-challenger`** | Fiat–Shamir challenger |
86
+ | **`lib-q-stark-commit`** | Commitment layer |
87
+ | **`lib-q-stark-dft`** | DFT / NTT for STARKs |
88
+ | **`lib-q-stark-field`** | Field arithmetic |
89
+ | **`lib-q-stark-field-testing`** | Field test helpers |
90
+ | **`lib-q-stark-fri`** | FRI |
91
+ | **`lib-q-stark-interpolation`** | Interpolation |
92
+ | **`lib-q-stark-matrix`** | Matrix ops |
93
+ | **`lib-q-stark-mds`** | MDS layer |
94
+ | **`lib-q-stark-merkle`** | Merkle trees |
95
+ | **`lib-q-stark-mersenne31`** | Mersenne-31 field |
96
+ | **`lib-q-stark-monty31`** | Monty-31 field |
97
+ | **`lib-q-stark-rayon`** | Optional Rayon parallelism |
98
+ | **`lib-q-stark-symmetric`** | Symmetric primitives for STARKs |
99
+ | **`lib-q-stark-util`** | STARK utilities |
100
+ | **`lib-q-stark-shake256`** | SHAKE256 bindings |
101
+ | **`lib-q-stark-shake128`** | SHAKE128 bindings |
102
+ | **`lib-q-stark-sha3-256`** | SHA3-256 bindings |
103
+ | **`lib-q-poseidon`** | Poseidon permutation |
104
+ | **`lib-q-plonky-multilinear-util`** | Plonky3 multilinear utilities |
105
+ | **`lib-q-plonky-keccak-air`** | Keccak AIR |
106
+ | **`lib-q-plonky-lookup`** | Lookup argument support |
107
+ | **`lib-q-plonky-uni-stark`** | Univariate STARK |
108
+ | **`lib-q-plonky-batch-stark`** | Batch STARK |
109
+ | **`lib-q-plonky`** | Plonky3-derived integration |
110
+
111
+ ### npm packages (npmjs.com)
112
+
113
+ These packages are built with `wasm-pack` in CD and correspond to stable JS entry points; other crates are **Rust-only** on crates.io but still participate in the workspace wasm compile gate.
114
+
115
+ - **`@lib-q/core`** — Umbrella WASM bundle (all algorithms path used in CD)
116
+ - **`@lib-q/ml-kem`** — ML-KEM (FIPS 203) only
117
+ - **`@lib-q/kem`** — Post-quantum KEM façade
118
+ - **`@lib-q/sig`** — Post-quantum signatures (ML-DSA path in CD)
119
+ - **`@lib-q/fn-dsa`** — FN-DSA (FIPS 206)
120
+ - **`@lib-q/hash`** — SHA-3–family hash façade
121
+ - **`@lib-q/utils`** — Utilities
122
+ - **`@lib-q/aead`** — Post-quantum AEAD (Saturnin, Romulus, duplex-sponge)
123
+ - **`@lib-q/hpke`** — Post-quantum HPKE (RFC 9180)
124
+ - **`@lib-q/zkp`** — ZKP / STARK proofs (high-level JSON API)
125
+ - **`@lib-q/random`** — Secure random bytes (`getrandom` / wasm_js)
126
+ - **`@lib-q/hqc`** — HQC KEM
127
+ - **`@lib-q/slh-dsa`** — SLH-DSA (FIPS 205)
128
+ - **`@lib-q/cb-kem`** — Classic McEliece CB-KEM (single compile-time parameter set per build)
129
+ - **`@lib-q/ring-sig`** — Federation / DualRing-LB pilot bindings
130
+ - **`@lib-q/prf`** — Legendre / Gold PRF pilots
131
+
132
+ ## Installation
133
+
134
+ ### Rust (Complete Library)
135
+ ```bash
136
+ cargo add lib-q
137
+ ```
138
+
139
+ ### Rust (Individual Crates)
140
+ ```bash
141
+ # For KEM operations only
142
+ cargo add lib-q-kem
143
+
144
+ # For signatures only
145
+ cargo add lib-q-sig
146
+
147
+ # For FN-DSA signatures only
148
+ cargo add lib-q-fn-dsa
149
+
150
+ # For hash functions only
151
+ cargo add lib-q-hash
152
+
153
+ # For utilities only
154
+ cargo add lib-q-utils
155
+ ```
156
+
157
+ ### Node.js (Complete Library)
158
+ ```bash
159
+ npm install @lib-q/core
160
+ ```
161
+
162
+ ### Node.js (Individual Packages)
163
+ ```bash
164
+ # For ML-KEM only
165
+ npm install @lib-q/ml-kem
166
+
167
+ # For KEM operations only
168
+ npm install @lib-q/kem
169
+
170
+ # For signatures only
171
+ npm install @lib-q/sig
172
+
173
+ # For FN-DSA signatures only
174
+ npm install @lib-q/fn-dsa
175
+
176
+ # For hash functions only
177
+ npm install @lib-q/hash
178
+
179
+ # For utilities only
180
+ npm install @lib-q/utils
181
+
182
+ # AEAD, HPKE, ZKP, RNG, HQC, SLH-DSA, CB-KEM, ring-sig, PRF
183
+ npm install @lib-q/aead @lib-q/hpke @lib-q/zkp @lib-q/random @lib-q/hqc @lib-q/slh-dsa @lib-q/cb-kem @lib-q/ring-sig @lib-q/prf
184
+ ```
185
+
186
+ ## Supported algorithms
187
+
188
+ ### Key encapsulation mechanisms (KEMs)
189
+ - **ML-KEM** (FIPS 203; security levels 1, 3, and 5)
190
+ - **CB-KEM** (code-based KEM in the Classic McEliece family; five NIST parameter sets, selectable via crate features)
191
+ - **HQC** (NIST-standardized code-based KEM; parameter sets HQC-128, HQC-192, and HQC-256, corresponding to levels 1, 3, and 5)
192
+
193
+ ### Digital signatures
194
+ - **ML-DSA** (FIPS 204; levels 1, 3, and 5)
195
+ - **FN-DSA** (FIPS 206; levels 1 and 5)
196
+ - **SLH-DSA** (FIPS 205; levels 1, 3, and 5)
197
+
198
+ ### Hash functions
199
+ - **SHAKE256**, **SHAKE128**, **cSHAKE256** (SHA-3 family; used across signatures, KDFs, and protocols)
200
+ - Additional SHA-3–family APIs where exposed by `lib-q-hash` and related workspace crates (see crate documentation)
201
+
202
+ ### Authenticated encryption
203
+ - **Saturnin** (post-quantum symmetric suite: AEAD, block cipher, hash, and stream modes)
204
+
205
+ ### Hybrid public-key encryption (HPKE)
206
+ - **Tier 1: Ultra-Secure** (Pure post-quantum with SHAKE256-based AEAD)
207
+ - **Tier 2: Balanced** (Post-quantum KEM + Saturnin AEAD)
208
+ - **Tier 3: Performance** (Post-quantum KEM + optimized Saturnin)
209
+
210
+ ### Zero-knowledge proofs (ZKPs)
211
+ - **zk-STARKs** (transparent, post-quantum-friendly proof system used in this stack)
212
+ - **Proof generation and verification** via `lib-q-zkp` (built on the workspace STARK crates)
213
+ - **WASM**: `lib-q-zkp` is checked for `wasm32-unknown-unknown` in CI when the relevant features are enabled
214
+ - **Deeper stack**: `lib-q-plonky` and related crates host the Plonky3-derived STARK pipeline (including univariate and batch STARK, Keccak AIR, and lookup support), gated by features for selective compilation
215
+
216
+ ## Architecture
217
+
218
+ The workspace is centered on the umbrella **`lib-q`** crate and splits algorithms and infrastructure across focused crates. Conceptually:
219
+
220
+ ```
221
+ lib-Q/ (repository root)
222
+ ├── lib-q/ # Umbrella library (feature-gated re-exports)
223
+ ├── lib-q-core/ # Types, traits, provider surface, validation
224
+ ├── lib-q-kem/ # KEM façade and integrations
225
+ ├── lib-q-ml-kem/, lib-q-cb-kem/, lib-q-hqc/ # Concrete KEM implementations
226
+ ├── lib-q-ring/ # ML-DSA field / NTT shared layer
227
+ ├── lib-q-prf/, lib-q-ring-sig/ # PRF pilots + lattice-backed ring-style openings (research)
228
+ ├── lib-q-sig/, lib-q-ml-dsa/, lib-q-slh-dsa/, lib-q-fn-dsa/
229
+ ├── lib-q-lattice-zkp/ # Module-lattice ZKP research (sigma, commitments)
230
+ ├── lib-q-sca-test/ # SCA screening tooling
231
+ ├── lib-q-hash/, lib-q-sha3/, lib-q-keccak/, lib-q-k12/
232
+ ├── lib-q-aead/, lib-q-saturnin/
233
+ ├── lib-q-hpke/
234
+ ├── lib-q-zkp/, lib-q-stark*/, lib-q-plonky*/
235
+ ├── lib-q-utils/, lib-q-random/, lib-q-platform/, …
236
+ └── examples/
237
+ ```
238
+
239
+ The table above is the authoritative crate list; the `[workspace].members` table in [Cargo.toml](Cargo.toml) is the same set plus the non-published `examples` member.
240
+
241
+ ## Security model
242
+
243
+ - **Post-quantum asymmetric**: No classical public-key schemes (RSA, ECC, etc.) for those roles; asymmetric modules track NIST PQC (see [SECURITY.md](SECURITY.md)).
244
+ - **Hashes / XOFs**: Cryptographic design targets the SHA-3 family; symmetric constructions center on Saturnin and SHAKE-based options as documented per crate.
245
+ - **Constant-time intent**: Critical paths are written for constant-time behavior; full guarantees require platform-specific review and tooling (see [ROADMAP.md](ROADMAP.md)).
246
+ - **Secure memory**: Sensitive buffers use explicit zeroization where the type system allows.
247
+ - **Side-channel awareness**: Design and review target timing and cache behavior; formal side-channel certification is not yet claimed.
248
+
249
+ ## Development status
250
+
251
+ **Active development.** Major algorithms are implemented and covered by automated tests; the library remains **pre-production** until independent audit and release hardening (see [SECURITY.md](SECURITY.md)).
252
+
253
+ ### Implemented capabilities
254
+ - **ML-DSA** (FIPS 204; parameter sets ML-DSA-44, ML-DSA-65, ML-DSA-87) with provider-style integration
255
+ - **FN-DSA** (FIPS 206) with CI coverage
256
+ - **SLH-DSA** (FIPS 205) including all twelve SLH-DSA parameter sets
257
+ - **ML-KEM** (FIPS 203; levels 1, 3, and 5)
258
+ - **CB-KEM** (Classic McEliece–family; five parameter sets, feature-selected)
259
+ - **HQC** (HQC-128, HQC-192, HQC-256)
260
+ - **Saturnin** (AEAD, block, hash, stream modes)
261
+ - **HPKE** (RFC 9180) with post-quantum KEM and AEAD options
262
+ - **Hash and XOF suite** (SHA-3 family, including SHAKE and cSHAKE, as exposed by workspace crates)
263
+ - **ZKP / STARK stack** (`lib-q-zkp` and supporting `lib-q-stark*` / `lib-q-plonky*` crates)
264
+ - **Lattice infrastructure** (`lib-q-ring` for ML-DSA field arithmetic; `lib-q-lattice-zkp` for research-grade module-lattice proofs, separate from STARKs)
265
+ - **PRF and ring-style opening pilots** (`lib-q-prf`, `lib-q-ring-sig`; research crates layered on lattice commitments—see per-crate READMEs)
266
+ - **Side-channel tooling** (`lib-q-sca-test` for statistical leakage screening, not a certification claim)
267
+ - **WASM** build paths for core scenarios (see CI and scripts referenced in the [no_std and WASM](#no_std-embedded-and-webassembly) section)
268
+ - **Engineering**: consistent error types, security validation utilities, and GitHub Actions for build, test, coverage, and security checks
269
+
270
+ ### Near-term focus
271
+ - **Performance and ergonomics** for CB-KEM and other large-key KEMs
272
+ - **Assurance**: expanded fuzzing, constant-time verification where feasible, and third-party security review
273
+ - **ZKP**: documentation, API stability, and production-oriented hardening of the STARK pipeline
274
+
275
+ ## Testing
276
+
277
+ ### `lib-q-sig` and SLH-DSA features
278
+
279
+ `lib-q-sig` separates **algorithm enablement** from **who supplies randomness**:
280
+
281
+ - **`slh-dsa`**: SLH-DSA with caller-supplied randomness (suitable for `no_std` and tests that pass explicit buffers).
282
+ - **`slh-dsa-std`**: The above plus OS-backed entropy when APIs use `None` for randomness on std targets.
283
+
284
+ Run crate integration tests accordingly:
285
+
286
+ ```bash
287
+ cargo test -p lib-q-sig --features slh-dsa
288
+ cargo test -p lib-q-sig --features slh-dsa-std
289
+ ```
290
+
291
+ The second command includes end-to-end tests that rely on implicit RNG wiring (`lib-q-random`); the first is appropriate when you only need explicit-randomness coverage.
292
+
293
+ ## Documentation
294
+
295
+ - [ROADMAP](ROADMAP.md)
296
+ - [Security policy](SECURITY.md)
297
+ - [Security model (technical)](docs/security.md)
298
+ - [ZKP Implementation and Library Layout](docs/zkp-implementation.md) (includes STARK stack and `lib-q-lattice-zkp`)
299
+ - [API Design](docs/api-design.md)
300
+ - [HPKE Architecture](docs/hpke-architecture.md)
301
+ - [Memory Architecture](docs/memory-architecture.md)
302
+ - [Interoperability](docs/interoperability.md)
303
+ - [Entropy Validation](docs/entropy-validation.md)
304
+ - [Test Coverage](docs/test-coverage.md)
305
+ - [AI-Generated Wiki](https://deepwiki.com/Enkom-Tech/libQ)
306
+
307
+ ## License
308
+
309
+ Apache 2.0 License - see [LICENSE](LICENSE) for details.
310
+
311
+ ## Contributing
312
+
313
+ We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
314
+
315
+ ## Security notice
316
+
317
+ This project ships real cryptographic code but is **not positioned as production-ready**. Treat it as suitable for research, education, interoperability experiments, and internal prototypes until:
318
+
319
+ - An independent security audit of the code you enable has been completed, and
320
+ - Your own integration testing, threat modeling, and operational controls are in place.
321
+
322
+ Absence of a published vulnerability report does not constitute a warranty. Track [SECURITY.md](SECURITY.md) for supported branches, reporting, and update policy.