diff --git a/Cargo.lock b/Cargo.lock index 860018265..c33f4e453 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -362,7 +362,7 @@ version = "0.1.0-pre.1" [[package]] name = "kem" -version = "0.3.0-rc.2" +version = "0.3.0-rc.3" dependencies = [ "crypto-common", "rand_core", diff --git a/kem/Cargo.toml b/kem/Cargo.toml index 0381ff78a..130eda63c 100644 --- a/kem/Cargo.toml +++ b/kem/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "kem" -version = "0.3.0-rc.2" +version = "0.3.0-rc.3" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" @@ -25,7 +25,3 @@ getrandom = ["common/getrandom"] [package.metadata.docs.rs] all-features = true - -# TODO(tarcieri): make README.md an actually valid example -[lib] -doctest = false diff --git a/kem/README.md b/kem/README.md index d1cb8d001..45c92a607 100644 --- a/kem/README.md +++ b/kem/README.md @@ -7,68 +7,14 @@ ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] -This crate provides a common set of traits for [key encapsulation mechanisms][1]—algorithms for non-interactively establishing secrets between peers. This is intended to be implemented by libraries which produce or contain implementations of key encapsulation mechanisms, and used by libraries which want to produce or consume encapsulated secrets while generically supporting any compatible backend. +## About -The crate exposes two traits, `Encapsulate` and `Decapsulate`, which are both generic over the encapsulated key type and the shared secret type. They are also agnostic about the structure of `Self`. For example, a simple Saber implementation may just impl `Encapsulate` for a single public key: -```rust -// Must make a newtype to implement the trait -struct MyPubkey(SaberPublicKey); +This crate provides a common set of traits for [key encapsulation mechanisms][1]—algorithms for +non-interactively establishing secrets between peers. -impl Encapsulate for MyPubkey { - // Encapsulation is infallible - type Error = !; - - fn encapsulate_with_rng( - &self, - csprng: &mut R, - ) -> Result<(SaberEncappedKey, SaberSharedSecret), !> { - let (ss, ek) = saber_encapsulate(&csprng, &self.0); - Ok((ek, ss)) - } -} -``` -And on the other end of complexity, an [X3DH](https://www.signal.org/docs/specifications/x3dh/) implementation might impl `Encapsulate` for a public key bundle plus a sender identity key: -```rust -struct PubkeyBundle { - ik: IdentityPubkey, - spk: SignedPrePubkey, - sig: Signature, - opk: OneTimePrePubkey, -} - -// Encap context is the recipient's pubkeys and the sender's identity key -struct EncapContext(PubkeyBundle, IdentityPrivkey); - -impl Encapsulate for EncapContext { - // Encapsulation fails if signature verification fails - type Error = SigError; - - fn encapsulate_with_rng( - &self, - csprng: &mut R, - ) -> Result<(EphemeralKey, SharedSecret), Self::Error> { - // Make a new ephemeral key. This will be the encapped key - let ek = EphemeralKey::gen(&mut csprng); - - // Deconstruct the recipient's pubkey bundle - let PubkeyBundle { - ref ik, - ref spk, - ref sig, - ref opk, - } = self.0; - let my_ik = &self.1; - - // Verify the signature - self.0.verify(&sig, &some_sig_pubkey)?; - - // Do the X3DH operation to get the shared secret - let shared_secret = x3dh_a(sig, my_ik, spk, &ek, ik, opk)?; - - Ok((ek, shared_secret)) - } -} -``` +This is intended to be implemented by libraries which produce or contain implementations of key +encapsulation mechanisms, and used by libraries which want to produce or consume encapsulated +secrets while generically supporting any compatible backend. ## License