diff --git a/Cargo.lock b/Cargo.lock index 87093de82..3e3cf5590 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,7 +102,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "benchmarks" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "chacha20poly1305", "criterion", @@ -182,9 +182,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.101" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" dependencies = [ "jobserver", "libc", @@ -281,9 +281,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", "clap_derive", @@ -291,9 +291,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -303,9 +303,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck", "proc-macro2", @@ -693,7 +693,7 @@ dependencies = [ [[package]] name = "hax-lib" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/?branch=main#352af59fd2ba9b838588f9134f7cb8f50c586ac2" +source = "git+https://github.com/hacspec/hax/?branch=main#7be21f59fb68a39041dd135e3e6c8b23ad22b4ea" dependencies = [ "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", "num-bigint", @@ -703,7 +703,7 @@ dependencies = [ [[package]] name = "hax-lib" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/#352af59fd2ba9b838588f9134f7cb8f50c586ac2" +source = "git+https://github.com/hacspec/hax/#7be21f59fb68a39041dd135e3e6c8b23ad22b4ea" dependencies = [ "hax-lib-macros 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", "num-bigint", @@ -713,7 +713,7 @@ dependencies = [ [[package]] name = "hax-lib-macros" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/?branch=main#352af59fd2ba9b838588f9134f7cb8f50c586ac2" +source = "git+https://github.com/hacspec/hax/?branch=main#7be21f59fb68a39041dd135e3e6c8b23ad22b4ea" dependencies = [ "hax-lib-macros-types 0.1.0-pre.1 (git+https://github.com/hacspec/hax/?branch=main)", "proc-macro-error", @@ -725,7 +725,7 @@ dependencies = [ [[package]] name = "hax-lib-macros" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/#352af59fd2ba9b838588f9134f7cb8f50c586ac2" +source = "git+https://github.com/hacspec/hax/#7be21f59fb68a39041dd135e3e6c8b23ad22b4ea" dependencies = [ "hax-lib-macros-types 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", "proc-macro-error", @@ -737,7 +737,7 @@ dependencies = [ [[package]] name = "hax-lib-macros-types" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/?branch=main#352af59fd2ba9b838588f9134f7cb8f50c586ac2" +source = "git+https://github.com/hacspec/hax/?branch=main#7be21f59fb68a39041dd135e3e6c8b23ad22b4ea" dependencies = [ "proc-macro2", "quote", @@ -749,7 +749,7 @@ dependencies = [ [[package]] name = "hax-lib-macros-types" version = "0.1.0-pre.1" -source = "git+https://github.com/hacspec/hax/#352af59fd2ba9b838588f9134f7cb8f50c586ac2" +source = "git+https://github.com/hacspec/hax/#7be21f59fb68a39041dd135e3e6c8b23ad22b4ea" dependencies = [ "proc-macro2", "quote", @@ -903,7 +903,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "lib25519" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "bindgen", "cc", @@ -919,7 +919,7 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libcrux" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "clap", "getrandom", @@ -948,7 +948,7 @@ dependencies = [ [[package]] name = "libcrux-ecdh" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "hex", "libcrux", @@ -970,7 +970,7 @@ dependencies = [ [[package]] name = "libcrux-hacl" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "bindgen", "cc", @@ -981,14 +981,14 @@ dependencies = [ [[package]] name = "libcrux-hkdf" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "libcrux-hacl", ] [[package]] name = "libcrux-hmac" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "libcrux-hacl", "libcrux-hkdf", @@ -996,11 +996,11 @@ dependencies = [ [[package]] name = "libcrux-intrinsics" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" [[package]] name = "libcrux-kem" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "hex", "libcrux", @@ -1013,7 +1013,7 @@ dependencies = [ [[package]] name = "libcrux-ml-dsa" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "criterion", "hex", @@ -1026,7 +1026,7 @@ dependencies = [ [[package]] name = "libcrux-ml-kem" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "criterion", "hax-lib 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", @@ -1042,14 +1042,14 @@ dependencies = [ [[package]] name = "libcrux-platform" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "libc", ] [[package]] name = "libcrux-pqclean" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "bindgen", "cc", @@ -1058,7 +1058,7 @@ dependencies = [ [[package]] name = "libcrux-psq" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "classic-mceliece-rust", "criterion", @@ -1070,7 +1070,7 @@ dependencies = [ [[package]] name = "libcrux-sha3" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "criterion", "hax-lib 0.1.0-pre.1 (git+https://github.com/hacspec/hax/)", @@ -1093,7 +1093,7 @@ dependencies = [ [[package]] name = "libjade-sys" -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" dependencies = [ "bindgen", "cc", @@ -1119,9 +1119,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "memchr" @@ -1147,9 +1147,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -1643,9 +1643,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.118" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", diff --git a/Cargo.toml b/Cargo.toml index 01ccd1388..30bedaa97 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ members = [ ] [workspace.package] -version = "0.0.2-pre.2" +version = "0.0.2-alpha.1" authors = ["Cryspen"] license = "Apache-2.0" homepage = "https://github.com/cryspen/libcrux" @@ -27,6 +27,10 @@ edition = "2021" repository = "https://github.com/cryspen/libcrux" readme = "Readme.md" +[workspace.metadata.release] +# TODO: drop dev as soon as we merged everything back to main. +allow-branch = ["main", "dev"] + [package] name = "libcrux" version.workspace = true @@ -44,16 +48,16 @@ exclude = ["/tests", "/specs"] crate-type = ["staticlib", "cdylib", "lib"] [build-dependencies] -libcrux-platform = { version = "=0.0.2-pre.2", path = "sys/platform" } +libcrux-platform = { version = "=0.0.2-alpha.1", path = "sys/platform" } [dependencies] -libcrux-hacl = { version = "=0.0.2-pre.2", path = "sys/hacl" } -libcrux-platform = { version = "=0.0.2-pre.2", path = "sys/platform" } -libcrux-hkdf = { version = "=0.0.2-pre.2", path = "libcrux-hkdf" } -libcrux-hmac = { version = "=0.0.2-pre.2", path = "libcrux-hmac" } -libcrux-ecdh = { version = "=0.0.2-pre.2", path = "libcrux-ecdh" } -libcrux-ml-kem = { version = "=0.0.2-pre.2", path = "libcrux-ml-kem" } -libcrux-kem = { version = "=0.0.2-pre.2", path = "libcrux-kem" } +libcrux-hacl = { version = "=0.0.2-alpha.1", path = "sys/hacl" } +libcrux-platform = { version = "=0.0.2-alpha.1", path = "sys/platform" } +libcrux-hkdf = { version = "=0.0.2-alpha.1", path = "libcrux-hkdf" } +libcrux-hmac = { version = "=0.0.2-alpha.1", path = "libcrux-hmac" } +libcrux-ecdh = { version = "=0.0.2-alpha.1", path = "libcrux-ecdh" } +libcrux-ml-kem = { version = "=0.0.2-alpha.1", path = "libcrux-ml-kem" } +libcrux-kem = { version = "=0.0.2-alpha.1", path = "libcrux-kem" } rand = { version = "0.8" } log = { version = "0.4", optional = true } # WASM API @@ -62,8 +66,8 @@ wasm-bindgen = { version = "0.2.87", optional = true } # When using the hax toolchain, we have more dependencies. # This is only required when doing proofs. [target.'cfg(hax)'.dependencies] -hax-lib-macros = { version = "0.1.0-pre.1", git = "https://github.com/hacspec/hax", branch = "main" } -hax-lib = { version = "0.1.0-pre.1", git = "https://github.com/hacspec/hax/", branch = "main" } +hax-lib-macros = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax", branch = "main" } +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/", branch = "main" } [dev-dependencies] libcrux = { path = ".", features = ["rand", "tests"] } diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml index 7aef2cbcd..0040df7ca 100644 --- a/benchmarks/Cargo.toml +++ b/benchmarks/Cargo.toml @@ -37,7 +37,7 @@ lib25519 = { path = "../sys/lib25519" } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] criterion = "0.5" -# libcrux-pqclean = { version = "0.0.2-pre.1", path = "sys/pqclean" } +# libcrux-pqclean = { version = "0.0.2-alpha.1", path = "sys/pqclean" } pqcrypto-kyber = { version = "0.8.0" } # Benchmarking "OpenSSL" @@ -47,7 +47,7 @@ pqcrypto-kyber = { version = "0.8.0" } openssl = "0.10" [target.'cfg(all(not(target_os = "windows"), target_arch = "x86_64"))'.dev-dependencies] -libjade-sys = { version = "=0.0.2-pre.2", path = "../sys/libjade" } +libjade-sys = { version = "=0.0.2-alpha.1", path = "../sys/libjade" } [[bench]] name = "sha2" diff --git a/libcrux-ecdh/Cargo.toml b/libcrux-ecdh/Cargo.toml index 68ed71519..a5635f12e 100644 --- a/libcrux-ecdh/Cargo.toml +++ b/libcrux-ecdh/Cargo.toml @@ -13,10 +13,10 @@ path = "src/ecdh.rs" [dependencies] rand = { version = "0.8" } -libcrux-hacl = { version = "=0.0.2-pre.2", path = "../sys/hacl" } +libcrux-hacl = { version = "=0.0.2-alpha.1", path = "../sys/hacl" } [dev-dependencies] -libcrux = { version = "=0.0.2-pre.2", path = "../", features = ["rand"] } +libcrux = { version = "=0.0.2-alpha.1", path = "../", features = ["rand"] } hex = { version = "0.4.3", features = ["serde"] } serde_json = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } diff --git a/libcrux-hkdf/Cargo.toml b/libcrux-hkdf/Cargo.toml index 65de2d0ca..b4de29cf5 100644 --- a/libcrux-hkdf/Cargo.toml +++ b/libcrux-hkdf/Cargo.toml @@ -12,5 +12,5 @@ readme.workspace = true path = "src/hkdf.rs" [dependencies] -libcrux-hacl = { version = "=0.0.2-pre.2", path = "../sys/hacl" } +libcrux-hacl = { version = "=0.0.2-alpha.1", path = "../sys/hacl" } diff --git a/libcrux-hmac/Cargo.toml b/libcrux-hmac/Cargo.toml index 3e86f6e4b..e3a30c628 100644 --- a/libcrux-hmac/Cargo.toml +++ b/libcrux-hmac/Cargo.toml @@ -12,5 +12,5 @@ readme.workspace = true path = "src/hmac.rs" [dependencies] -libcrux-hkdf = { version = "=0.0.2-pre.2", path = "../libcrux-hkdf" } -libcrux-hacl = { version = "=0.0.2-pre.2", path = "../sys/hacl" } +libcrux-hkdf = { version = "=0.0.2-alpha.1", path = "../libcrux-hkdf" } +libcrux-hacl = { version = "=0.0.2-alpha.1", path = "../sys/hacl" } diff --git a/libcrux-kem/Cargo.toml b/libcrux-kem/Cargo.toml index b04979223..b0f748966 100644 --- a/libcrux-kem/Cargo.toml +++ b/libcrux-kem/Cargo.toml @@ -12,9 +12,9 @@ readme.workspace = true path = "src/kem.rs" [dependencies] -libcrux-ml-kem = { version = "0.0.2-pre.2", path = "../libcrux-ml-kem" } -libcrux-sha3 = { version = "0.0.2-pre.2", path = "../libcrux-sha3" } -libcrux-ecdh = { version = "0.0.2-pre.2", path = "../libcrux-ecdh" } +libcrux-ml-kem = { version = "0.0.2-alpha.1", path = "../libcrux-ml-kem" } +libcrux-sha3 = { version = "0.0.2-alpha.1", path = "../libcrux-sha3" } +libcrux-ecdh = { version = "0.0.2-alpha.1", path = "../libcrux-ecdh" } rand = { version = "0.8" } [features] @@ -23,6 +23,6 @@ kyber = ["libcrux-ml-kem/kyber"] pre-verification = ["libcrux-ml-kem/pre-verification"] [dev-dependencies] -libcrux-kem = { version = "0.0.2-pre.2", path = "./", features = ["tests"] } -libcrux = { version = "0.0.2-pre.2", path = "../", features = ["rand"] } +libcrux-kem = { version = "0.0.2-alpha.1", path = "./", features = ["tests"] } +libcrux = { version = "0.0.2-alpha.1", path = "../", features = ["rand"] } hex = { version = "0.4.3", features = ["serde"] } diff --git a/libcrux-ml-dsa/Cargo.toml b/libcrux-ml-dsa/Cargo.toml index a0c64135d..f8f99fabf 100644 --- a/libcrux-ml-dsa/Cargo.toml +++ b/libcrux-ml-dsa/Cargo.toml @@ -11,7 +11,7 @@ readme.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -libcrux-sha3 = { version = "0.0.2-pre.2", path = "../libcrux-sha3" } +libcrux-sha3 = { version = "0.0.2-alpha.1", path = "../libcrux-sha3" } [dev-dependencies] rand = { version = "0.8" } diff --git a/libcrux-ml-kem/Cargo.toml b/libcrux-ml-kem/Cargo.toml index 972207efc..3f2ef956e 100644 --- a/libcrux-ml-kem/Cargo.toml +++ b/libcrux-ml-kem/Cargo.toml @@ -6,7 +6,7 @@ license.workspace = true homepage.workspace = true edition.workspace = true repository.workspace = true -readme.workspace = true +readme = "Readme.md" exclude = [ "/tests", "/implementation_notes.pdf", @@ -19,14 +19,14 @@ exclude = [ [dependencies] rand_core = { version = "0.6" } -libcrux-platform = { version = "0.0.2-pre.2", path = "../sys/platform" } -libcrux-sha3 = { version = "0.0.2-pre.2", path = "../libcrux-sha3" } -libcrux-intrinsics = { version = "0.0.2-pre.2", path = "../libcrux-intrinsics" } +libcrux-platform = { version = "0.0.2-alpha.1", path = "../sys/platform" } +libcrux-sha3 = { version = "0.0.2-alpha.1", path = "../libcrux-sha3" } +libcrux-intrinsics = { version = "0.0.2-alpha.1", path = "../libcrux-intrinsics" } # This is only required for verification. # The hax config is set by the hax toolchain. [target.'cfg(hax)'.dependencies] -hax-lib = { version = "0.1.0-pre.1", git = "https://github.com/hacspec/hax/" } +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/" } [features] # By default all variants and std are enabled. diff --git a/libcrux-ml-kem/README.md b/libcrux-ml-kem/README.md new file mode 100644 index 000000000..d0ff7b35d --- /dev/null +++ b/libcrux-ml-kem/README.md @@ -0,0 +1,61 @@ +# ML-KEM + +This crate implements all three ML-KEM ([FIPS 203](https://csrc.nist.gov/pubs/fips/203/ipd) (Initial Public Draft)) variants 512, 768, and 1024. It is +formally verified using [hax](https://cryspen.com/hax) and + [F*](https://fstar-lang.org). + +Functions in this crate use CPU feature detection to pick the most efficient version +on each platform. To use a specific version with your own feature detection +use e.g. one of the following +- `mlkem768::avx2::generate_key_pair`, +- `mlkem768::neon::generate_key_pair`, +- `mlkem768::portable::generate_key_pair`, + +analogously for encapsulation and decapsulation. + +```Rust + use rand::{rngs::OsRng, RngCore}; + + // Ensure you use good randomness. + // It is not recommended to use OsRng directly! + // Instead it is highly encouraged to use RNGs like NISTs DRBG to account for + // bad system entropy. + fn random_array() -> [u8; L] { + let mut rng = OsRng; + let mut seed = [0; L]; + rng.try_fill_bytes(&mut seed).unwrap(); + seed + } + + use libcrux_ml_kem::*; + + // This example uses ML-KEM 768. The other variants can be used the same way. + + // Generate a key pair. + let randomness = random_array(); + let key_pair = mlkem768::generate_key_pair(randomness); + + // Encapsulating a shared secret to a public key. + let randomness = random_array(); + let (ciphertext, shared_secret) = mlkem768::encapsulate(key_pair.public_key(), randomness); + + // Decapsulating a shared secret with a private key. + let shared_secret_decapsulated = mlkem768::decapsulate(key_pair.private_key(), &ciphertext); +``` + + +## Features + +By default, all ML-KEM parameter sets are enabled. If required, they are +available individually under feature flags `mlkem512`, `mlkem768`, +`mlkem1024`. + +In addition to the verified implementations of the ML-KEM variants, the +feature flag `pre-verification` gives access to, as yet, unverified +implementations of ML-KEM that are optimized for SIMD instruction sets. + +### Kyber Round 3 +The `kyber` flag (in combination with `pre-verification`) also gives access +to an, as yet, unverified implementation of Kyber as submitted in Round 3 of +the NIST PQ competition. + diff --git a/libcrux-ml-kem/src/kem/kyber/kyber1024.rs b/libcrux-ml-kem/src/kem/kyber/kyber1024.rs index f67682fe5..35faf4b4a 100644 --- a/libcrux-ml-kem/src/kem/kyber/kyber1024.rs +++ b/libcrux-ml-kem/src/kem/kyber/kyber1024.rs @@ -34,8 +34,11 @@ const ETA2_RANDOMNESS_SIZE: usize = ETA2 * 64; const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = SHARED_SECRET_SIZE + CPA_PKE_CIPHERTEXT_SIZE_1024; // Kyber 1024 types +/// An ML-KEM 1024 Ciphertext pub type MlKem1024Ciphertext = MlKemCiphertext; +/// An ML-KEM 1024 Private key pub type MlKem1024PrivateKey = MlKemPrivateKey; +/// An ML-KEM 1024 Public key pub type MlKem1024PublicKey = MlKemPublicKey; /// Validate a public key. @@ -55,6 +58,9 @@ pub fn validate_public_key(public_key: MlKem1024PublicKey) -> Option MlKemKeyPair { @@ -69,9 +75,11 @@ pub fn generate_key_pair( >(randomness) } -pub type MlKem1024State = MlKemState; +#[allow(unused)] +pub(crate) type MlKem1024State = MlKemState; -pub fn generate_key_pair_unpacked( +#[allow(unused)] +pub(crate) fn generate_key_pair_unpacked( randomness: [u8; KEY_GENERATION_SEED_SIZE], ) -> (MlKem1024State, MlKem1024PublicKey) { generate_keypair_unpacked::< @@ -86,6 +94,10 @@ pub fn generate_key_pair_unpacked( } /// Encapsulate ML-KEM 1024 +/// +/// Generates an ([`MlKem1024Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem1024PublicKey`] and [`crate::SHARED_SECRET_SIZE`] +/// bytes of `randomness`. pub fn encapsulate( public_key: &MlKemPublicKey, randomness: [u8; SHARED_SECRET_SIZE], @@ -111,6 +123,9 @@ pub fn encapsulate( } /// Decapsulate ML-KEM 1024 +/// +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`]. pub fn decapsulate( secret_key: &MlKemPrivateKey, ciphertext: &MlKemCiphertext, @@ -135,7 +150,8 @@ pub fn decapsulate( >(secret_key, ciphertext) } -pub fn decapsulate_unpacked( +#[allow(unused)] +pub(crate) fn decapsulate_unpacked( state: &MlKem1024State, ciphertext: &MlKemCiphertext, ) -> [u8; SHARED_SECRET_SIZE] { diff --git a/libcrux-ml-kem/src/kem/kyber/kyber512.rs b/libcrux-ml-kem/src/kem/kyber/kyber512.rs index 8edce7f47..0e9ece26e 100644 --- a/libcrux-ml-kem/src/kem/kyber/kyber512.rs +++ b/libcrux-ml-kem/src/kem/kyber/kyber512.rs @@ -32,8 +32,11 @@ const ETA2_RANDOMNESS_SIZE: usize = ETA2 * 64; const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = SHARED_SECRET_SIZE + CPA_PKE_CIPHERTEXT_SIZE_512; // Kyber 512 types +/// An ML-KEM 512 Ciphertext pub type MlKem512Ciphertext = MlKemCiphertext; +/// An ML-KEM 512 Private key pub type MlKem512PrivateKey = MlKemPrivateKey; +/// An ML-KEM 512 Public key pub type MlKem512PublicKey = MlKemPublicKey; /// Validate a public key. @@ -53,6 +56,9 @@ pub fn validate_public_key(public_key: MlKem512PublicKey) -> Option MlKemKeyPair { @@ -67,9 +73,11 @@ pub fn generate_key_pair( >(randomness) } -pub type MlKem512State = MlKemState; +#[allow(unused)] +pub(crate) type MlKem512State = MlKemState; -pub fn generate_key_pair_unpacked( +#[allow(unused)] +pub(crate) fn generate_key_pair_unpacked( randomness: [u8; KEY_GENERATION_SEED_SIZE], ) -> (MlKem512State, MlKem512PublicKey) { generate_keypair_unpacked::< @@ -84,6 +92,9 @@ pub fn generate_key_pair_unpacked( } /// Encapsulate ML-KEM 512 +/// +/// Generates an ([`MlKem512Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem512PublicKey`] and [`crate::SHARED_SECRET_SIZE`] pub fn encapsulate( public_key: &MlKemPublicKey, randomness: [u8; SHARED_SECRET_SIZE], @@ -109,6 +120,9 @@ pub fn encapsulate( } /// Decapsulate ML-KEM 512 +/// +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. pub fn decapsulate( secret_key: &MlKemPrivateKey, ciphertext: &MlKemCiphertext, @@ -133,7 +147,8 @@ pub fn decapsulate( >(secret_key, ciphertext) } -pub fn decapsulate_unpacked( +#[allow(unused)] +pub(crate) fn decapsulate_unpacked( state: &MlKem512State, ciphertext: &MlKemCiphertext, ) -> [u8; SHARED_SECRET_SIZE] { diff --git a/libcrux-ml-kem/src/kem/kyber/kyber768.rs b/libcrux-ml-kem/src/kem/kyber/kyber768.rs index 7d9f5b131..a1bfb4c19 100644 --- a/libcrux-ml-kem/src/kem/kyber/kyber768.rs +++ b/libcrux-ml-kem/src/kem/kyber/kyber768.rs @@ -33,8 +33,11 @@ const ETA2_RANDOMNESS_SIZE: usize = ETA2 * 64; const IMPLICIT_REJECTION_HASH_INPUT_SIZE: usize = SHARED_SECRET_SIZE + CPA_PKE_CIPHERTEXT_SIZE_768; // Kyber 768 types +/// An ML-KEM 768 Ciphertext pub type MlKem768Ciphertext = MlKemCiphertext; +/// An ML-KEM 768 Private key pub type MlKem768PrivateKey = MlKemPrivateKey; +/// An ML-KEM 768 Public key pub type MlKem768PublicKey = MlKemPublicKey; /// Validate a public key. @@ -54,6 +57,9 @@ pub fn validate_public_key(public_key: MlKem768PublicKey) -> Option MlKemKeyPair { @@ -68,9 +74,11 @@ pub fn generate_key_pair( >(randomness) } -pub type MlKem768State = MlKemState; +#[allow(unused)] +pub(crate) type MlKem768State = MlKemState; -pub fn generate_key_pair_unpacked( +#[allow(unused)] +pub(crate) fn generate_key_pair_unpacked( randomness: [u8; KEY_GENERATION_SEED_SIZE], ) -> (MlKem768State, MlKem768PublicKey) { generate_keypair_unpacked::< @@ -85,6 +93,10 @@ pub fn generate_key_pair_unpacked( } /// Encapsulate ML-KEM 768 +/// +/// Generates an ([`MlKem768Ciphertext`], [`MlKemSharedSecret`]) tuple. +/// The input is a reference to an [`MlKem768PublicKey`] and [`crate::SHARED_SECRET_SIZE`] +/// bytes of `randomness`. pub fn encapsulate( public_key: &MlKemPublicKey, randomness: [u8; SHARED_SECRET_SIZE], @@ -110,6 +122,9 @@ pub fn encapsulate( } /// Decapsulate ML-KEM 768 +/// +/// Generates an [`MlKemSharedSecret`]. +/// The input is a reference to an [`MlKem768PrivateKey`] and an [`MlKem768Ciphertext`]. pub fn decapsulate( secret_key: &MlKemPrivateKey, ciphertext: &MlKemCiphertext, @@ -134,7 +149,8 @@ pub fn decapsulate( >(secret_key, ciphertext) } -pub fn decapsulate_unpacked( +#[allow(unused)] +pub(crate) fn decapsulate_unpacked( state: &MlKem768State, ciphertext: &MlKemCiphertext, ) -> [u8; SHARED_SECRET_SIZE] { diff --git a/libcrux-ml-kem/src/kem/kyber/types.rs b/libcrux-ml-kem/src/kem/kyber/types.rs index a3856827d..f4909fd84 100644 --- a/libcrux-ml-kem/src/kem/kyber/types.rs +++ b/libcrux-ml-kem/src/kem/kyber/types.rs @@ -1,5 +1,6 @@ macro_rules! impl_generic_struct { - ($name:ident) => { + ($name:ident, $doc:expr) => { + #[doc = $doc] pub struct $name { pub(super) value: [u8; SIZE], } @@ -42,14 +43,18 @@ macro_rules! impl_generic_struct { } impl $name { + /// A reference to the raw byte slice. pub fn as_slice(&self) -> &[u8; SIZE] { &self.value } - pub fn split_at(&self, mid: usize) -> (&[u8], &[u8]) { + // This is only used for some of the macro callers. + #[allow(dead_code)] + // /// Split this value and return the raw byte slices. + pub(crate) fn split_at(&self, mid: usize) -> (&[u8], &[u8]) { self.value.split_at(mid) } - + /// The number of bytes pub const fn len() -> usize { SIZE } @@ -92,9 +97,9 @@ macro_rules! impl_index_impls_for_generic_struct { }; } -impl_generic_struct!(MlKemCiphertext); -impl_generic_struct!(MlKemPrivateKey); -impl_generic_struct!(MlKemPublicKey); +impl_generic_struct!(MlKemCiphertext, "An ML-KEM Ciphertext"); +impl_generic_struct!(MlKemPrivateKey, "An ML-KEM Private key"); +impl_generic_struct!(MlKemPublicKey, "An ML-KEM Public key"); // These traits are used only in `ind_cpa` for kyber cipher text. mod index_impls { @@ -121,6 +126,7 @@ impl } } + /// Create a new [`MlKemKeyPair`] from the secret and public key. pub fn from( sk: MlKemPrivateKey, pk: MlKemPublicKey, @@ -128,22 +134,27 @@ impl Self { sk, pk } } + /// Get a reference to the [`MlKemPublicKey`]. pub fn public_key(&self) -> &MlKemPublicKey { &self.pk } + /// Get a reference to the [`MlKemPrivateKey`]. pub fn private_key(&self) -> &MlKemPrivateKey { &self.sk } + /// Get a reference to the raw public key bytes. pub fn pk(&self) -> &[u8; PUBLIC_KEY_SIZE] { self.pk.as_slice() } + /// Get a reference to the raw private key bytes. pub fn sk(&self) -> &[u8; PRIVATE_KEY_SIZE] { self.sk.as_slice() } - + + /// Separate this key into the public and private key. pub fn into_parts( self, ) -> ( diff --git a/libcrux-ml-kem/src/lib.rs b/libcrux-ml-kem/src/lib.rs index 7099d8953..191043524 100644 --- a/libcrux-ml-kem/src/lib.rs +++ b/libcrux-ml-kem/src/lib.rs @@ -4,7 +4,18 @@ //! formally verified using [hax](https://cryspen.com/hax) and //! [F*](https://fstar-lang.org). //! - +#![cfg_attr( + feature = "pre-verification", + doc = r##" +Functions in this crate use CPU feature detection to pick the most efficient version +on each platform. To use a specific version with your own feature detection +use e.g. one of the following +- `mlkem768::avx2::generate_key_pair`, +- `mlkem768::neon::generate_key_pair`, +- `mlkem768::portable::generate_key_pair`, + +analogously for encapsulation and decapsulation."## +)] #![cfg_attr( feature = "mlkem768", doc = r##" @@ -24,7 +35,7 @@ use libcrux_ml_kem::*; - // This example use ML-KEM 768. The other variants can be used the same way. + // This example uses ML-KEM 768. The other variants can be used the same way. // Generate a key pair. let randomness = random_array(); @@ -170,24 +181,33 @@ cfg_verified! { #[cfg(feature = "mlkem512")] #[cfg_attr(docsrs, doc(cfg(feature = "mlkem512")))] pub mod mlkem512 { + //! ML-KEM 512 pub use crate::kem::kyber::kyber512::*; } #[cfg(feature = "mlkem768")] #[cfg_attr(docsrs, doc(cfg(feature = "mlkem768")))] pub mod mlkem768 { + //! ML-KEM 768 pub use crate::kem::kyber::kyber768::*; } #[cfg(feature = "mlkem1024")] #[cfg_attr(docsrs, doc(cfg(feature = "mlkem1024")))] pub mod mlkem1024 { + //! ML-KEM 1024 pub use crate::kem::kyber::kyber1024::*; } + /// The size of an ML-KEM shared secret. pub const SHARED_SECRET_SIZE: usize = kem::kyber::constants::SHARED_SECRET_SIZE; + /// An ML-KEM shared secret. + /// + /// A byte array of size [`SHARED_SECRET_SIZE`]. pub use kem::kyber::MlKemSharedSecret; + /// Seed size for encapsulation pub const ENCAPS_SEED_SIZE: usize = kem::kyber::constants::SHARED_SECRET_SIZE; + /// Seed size for key generation pub const KEY_GENERATION_SEED_SIZE: usize = kem::kyber::KEY_GENERATION_SEED_SIZE; // These types all have type aliases for the different variants. pub use kem::kyber::{MlKemCiphertext, MlKemKeyPair, MlKemPrivateKey, MlKemPublicKey}; diff --git a/libcrux-ml-kem/src/mlkem512.rs b/libcrux-ml-kem/src/mlkem512.rs index 9dadfc704..448d97c68 100644 --- a/libcrux-ml-kem/src/mlkem512.rs +++ b/libcrux-ml-kem/src/mlkem512.rs @@ -163,7 +163,7 @@ macro_rules! instantiate { >(private_key, ciphertext) } - /// Decapsulate ML-KEM 512 + /// Decapsulate Kyber 512 /// /// Generates an [`MlKemSharedSecret`]. /// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`]. @@ -222,7 +222,7 @@ pub fn validate_public_key(public_key: MlKem512PublicKey) -> Option Option MlKem768KeyPair { diff --git a/libcrux-psq/Cargo.toml b/libcrux-psq/Cargo.toml index 8a555329a..febdf023b 100644 --- a/libcrux-psq/Cargo.toml +++ b/libcrux-psq/Cargo.toml @@ -12,9 +12,9 @@ readme.workspace = true path = "src/psq.rs" [dependencies] -libcrux-kem = { version = "0.0.2-pre.2", path = "../libcrux-kem", features = ["pre-verification"] } -libcrux-hkdf = { version = "=0.0.2-pre.2", path = "../libcrux-hkdf" } -libcrux-hmac = { version = "=0.0.2-pre.2", path = "../libcrux-hmac" } +libcrux-kem = { version = "0.0.2-alpha.1", path = "../libcrux-kem", features = ["pre-verification"] } +libcrux-hkdf = { version = "=0.0.2-alpha.1", path = "../libcrux-hkdf" } +libcrux-hmac = { version = "=0.0.2-alpha.1", path = "../libcrux-hmac" } classic-mceliece-rust = { version = "2.0.0", features = [ "mceliece460896f", "zeroize", diff --git a/libcrux-sha3/Cargo.toml b/libcrux-sha3/Cargo.toml index 5f13d2d92..70e608225 100644 --- a/libcrux-sha3/Cargo.toml +++ b/libcrux-sha3/Cargo.toml @@ -10,13 +10,13 @@ readme.workspace = true exclude = ["/proofs", "/c.sh", "/c.yaml"] [dependencies] -libcrux-platform = { version = "0.0.2-pre.2", path = "../sys/platform" } -libcrux-intrinsics = { version = "0.0.2-pre.2", path = "../libcrux-intrinsics" } +libcrux-platform = { version = "0.0.2-alpha.1", path = "../sys/platform" } +libcrux-intrinsics = { version = "0.0.2-alpha.1", path = "../libcrux-intrinsics" } # This is only required for verification. # The hax config is set by the hax toolchain. [target.'cfg(hax)'.dependencies] -hax-lib = { version = "0.1.0-pre.1", git = "https://github.com/hacspec/hax/" } +hax-lib = { version = "0.1.0-alpha.1", git = "https://github.com/hacspec/hax/" } [features] simd128 = [] diff --git a/specs/kyber/Cargo.toml b/specs/kyber/Cargo.toml index 7a798cdea..7dbc19e9a 100644 --- a/specs/kyber/Cargo.toml +++ b/specs/kyber/Cargo.toml @@ -4,11 +4,11 @@ version = "0.1.0" edition = "2021" [dependencies] -libcrux = { version = "=0.0.2-pre.2", path = "../../" } +libcrux = { version = "=0.0.2-alpha.1", path = "../../" } hacspec-lib = { version = "0.0.1", path = "../hacspec-lib" } [dev-dependencies] -libcrux-kem = { version = "=0.0.2-pre.2", path = "../../libcrux-kem", features = [ +libcrux-kem = { version = "=0.0.2-alpha.1", path = "../../libcrux-kem", features = [ "tests", ] } hex = { version = "0.4.3", features = ["serde"] } diff --git a/sys/hacl/Cargo.toml b/sys/hacl/Cargo.toml index 8db2ecb60..2cf176944 100644 --- a/sys/hacl/Cargo.toml +++ b/sys/hacl/Cargo.toml @@ -16,7 +16,7 @@ crate-type = ["cdylib", "rlib"] [build-dependencies] cc = { version = "1.0", features = ["parallel"] } -libcrux-platform = { version = "=0.0.2-pre.2", path = "../platform" } +libcrux-platform = { version = "=0.0.2-alpha.1", path = "../platform" } bindgen = { version = "0.69", optional = true } [features] diff --git a/sys/libjade/Cargo.toml b/sys/libjade/Cargo.toml index 36635ac01..6fbc1322e 100644 --- a/sys/libjade/Cargo.toml +++ b/sys/libjade/Cargo.toml @@ -13,7 +13,7 @@ description = "Rust bindings for libjade, a formally verified cryptographic libr [build-dependencies] cc = { version = "1.0", features = ["parallel"] } -libcrux-platform = { version = "=0.0.2-pre.2", path = "../platform" } +libcrux-platform = { version = "=0.0.2-alpha.1", path = "../platform" } [target.'cfg(not(windows))'.build-dependencies] bindgen = { version = "0.69", optional = true }