Skip to content

Commit

Permalink
PQ-PSK prototype (#310)
Browse files Browse the repository at this point in the history
* Make ML-KEM-768 constants public

So they can be used by hybrid KEMs in the `libcrux-kem` crate.

* Change `libcrux::ecdh` submodule and item visibility to public

So they can be used in the `libcrux-kem` crate

* Change visibility of `libcrux-ml-kem::MlKemKeyPair` fields to `pub`

So they can be accessed in the `libcrux-kem` crate.

* Extract `libcrux::kem` module to its own crate

* Update KEM crate documentation

* Format

* Provide `.len()` on ML-KEM structs and use that instead of constants

* Use `.into_parts()` on `MlKemKeyPair` instead of direct access

* Add CI run for `libcrux-kem`

* Fix ML-KEM tests

* CI: Use Rust stable and exclude Win32 (linker issue)

* Revert CI change to now install Rust nightly again

* Pull out `ecdh` module into its own crate

* Make `libcrux-kem` use `libcrux-ecdh` instead of `libcrux`

* Make `libcrux` use standalone `libcrux-ecdh` crate

* WIP: PQ-PSK prototype

* Copied CI workflow for ECDH crate

* Merge imports

* Option to use Curve25519, ML-KEM768 or Classic McEliece

* Move P256 ECDSA signature API back to libcrux

* Move ECDH tests to the `libcrux-ecdh` crate

* Make PSK lifetime a parameter of PSK generation

* Update Cargo.lock

* Reduce public API

* Make `libcrux` depend on `libcrux-kem`

* Make spec libcrux interop tests use standalone crate

* Update benchmarks to use `libcrux-ml-kem` (resp. `libcrux-kem`)

* Remove dead code

* Simple benchmarks for PQ-PSK

* Basic PSK message size measurement

* Include raw KEM operations in benchmark

* Include public key sizes in size comparison

* Include XWing in size comparison

* Include XWing in benchmarks

* wip; no chrono and encaps example

* std::time timestamp

* Simple timestamp tests

* Minor rewrites for PV extraction

* Format

* Add documentation

* Add `README.md`

---------

Co-authored-by: Franziskus Kiefer <[email protected]>
  • Loading branch information
jschneider-bensch and franziskuskiefer committed Jun 27, 2024
1 parent 5611bb3 commit 7d40ffc
Show file tree
Hide file tree
Showing 10 changed files with 1,487 additions and 2 deletions.
23 changes: 23 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ members = [
"libcrux-kem",
"libcrux-hmac",
"libcrux-hkdf",
"libcrux-ecdh",
"libcrux-ecdh", "libcrux-psq",
]

[workspace.package]
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/benches/sha2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ macro_rules! impl_comp {
($fun:ident, $libcrux:expr, $ring:expr, $rust_crypto:ty, $openssl:expr) => {
// Comparing libcrux performance for different payload sizes and other implementations.
fn $fun(c: &mut Criterion) {
const PAYLOAD_SIZES: [usize; 1] = [1024 * 1024 * 10];
const PAYLOAD_SIZES: [usize; 5] = [100, 1024, 2048, 4096, 8192];

let mut group = c.benchmark_group(stringify!($fun).replace("_", " "));

Expand Down
29 changes: 29 additions & 0 deletions libcrux-psq/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "libcrux-psq"
version.workspace = true
authors.workspace = true
license.workspace = true
homepage.workspace = true
edition.workspace = true
repository.workspace = true
readme.workspace = true

[lib]
path = "src/psq.rs"

[dependencies]
libcrux-kem = { version = "0.0.2-pre.2", path = "../libcrux-kem" }
libcrux-hkdf = { version = "=0.0.2-pre.2", path = "../libcrux-hkdf" }
libcrux-hmac = { version = "=0.0.2-pre.2", path = "../libcrux-hmac" }
classic-mceliece-rust = { version = "2.0.0", features = [
"mceliece460896f",
"zeroize",
] }
rand = { version = "0.8" }

[dev-dependencies]
criterion = "0.5"

[[bench]]
name = "psq"
harness = false
32 changes: 32 additions & 0 deletions libcrux-psq/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Post-Quantum Pre-Shared-Key Protocol (PSQ) #

This crate implements a protocol for agreeing on a pre-shared key such
that the protocol messages are secure against
harvest-now-decrypt-later (HNDL) passive quantum attackers.

The protocol between initator `A` and receiver `B` roughly works as follows:
```
A: (ik, enc) <- PQ-KEM(pk_B)
K_0 <- KDF(ik, pk_B || enc || sctxt)
K_m <- KDF(K_0, "Confirmation")
K <- KDF(K_0, "PSK")
mac_ttl <- MAC(K_m, psk_ttl)
A -> B: (enc, psk_ttl, mac_ttl)
```
Where
* `pk_B` is the receiver's KEM public key,
* `sctx` is context information for the given session of the protocol,
* `psk_ttl` specifies for how long the PSK should be considered valid, and
* `K` is the final PSK that is derived from the decapsulated shared
secret based on the internal KEM.

The crate implements the protocol based on several different internal
KEMs:
* `X25519`, an elliptic-curve Diffie-Hellman KEM (not post-quantum
secure; for performance comparison)
* `ML-KEM 768`, a lattice-based post-quantum KEM, in the process
of being standardized by NIST
* `Classic McEliece`, a code-based post-quantum KEM & Round 4
candidate in the NIST PQ competition,
* `XWingKemDraft02`, a hybrid post-quantum KEM, combining `X25519`
and `ML-KEM 768` based KEMs
Loading

0 comments on commit 7d40ffc

Please sign in to comment.