kem-0.3.0/.cargo_vcs_info.json0000644000000001411046102023000116260ustar { "git": { "sha1": "23118eab10a60fb31ee81785bd02dac7ccb12681" }, "path_in_vcs": "kem" }kem-0.3.0/CHANGELOG.md000064400000000000000000000043521046102023000122150ustar 00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## 0.3.0 (2026-02-04) This release is effectively a complete rewrite of the `kem` crate. Any similarities between trait names in this release and previous releases is coincidental. The log below highlights some of the new parts of the API but will provide an incomplete picture of changes. ### Added - `Encapsulate` and `Decapsulate` traits ([#1509]) - `getrandom` feature ([#2140]) - Re-exports from `crypto-common` ([#2222]) - re-exports `crypto-common` itself as `common` - re-exports `KeyInit`, which is useful for seeds - re-exports `Key` as the type for representing serialized encapsulation and decapsulation keys - re-exports `InvalidKey` as the error when `TryKeyInit` fails - `TryDecapsulate` trait ([#2220], [#2235]) - `Kem` trait for the whole algorithm type family ([#2243]) - `FromSeed` trait and `Seed` type alias ([#2284]) ### Changed - `Decapsulator` trait replaced with new implementation ([#2282]) ### Removed - Previous implementation ([#1509]) [#1509]: https://github.com/RustCrypto/traits/pull/1509 [#2140]: https://github.com/RustCrypto/traits/pull/2140 [#2140]: https://github.com/RustCrypto/traits/pull/2140 [#2222]: https://github.com/RustCrypto/traits/pull/2222 [#2220]: https://github.com/RustCrypto/traits/pull/2220 [#2235]: https://github.com/RustCrypto/traits/pull/2235 [#2243]: https://github.com/RustCrypto/traits/pull/2243 [#2284]: https://github.com/RustCrypto/traits/pull/2284 ### Changed - Edition changed to 2024 and MSRV bumped to 1.85 ([#1759]) - Bump `rand_core` to v0.10 ([#2250]) [#1759]: https://github.com/RustCrypto/traits/pull/1759 [#2250]: https://github.com/RustCrypto/traits/pull/2250 ## 0.2.0 (2022-05-26) ### Added - Generic `SharedSecret` type ([#982]) - `EncappedKey::EncappedKeySize` associated constant ([#982]) ### Changed - Rename `EncappedKey::NSecret` => `EncappedKey::SharedSecretSize` ([#982]) - Add `EncappedKey::{from_bytes, as_bytes}` methods ([#982]) [#982]: https://github.com/RustCrypto/traits/pull/982 ## 0.1.0 (2022-01-03) - Initial release kem-0.3.0/Cargo.lock0000644000000242131046102023000076070ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 4 [[package]] name = "anyhow" version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "bitflags" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "crypto-common" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" dependencies = [ "getrandom", "hybrid-array", "rand_core", ] [[package]] name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "foldhash" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "getrandom" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", "r-efi", "rand_core", "wasip2", "wasip3", ] [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "foldhash", ] [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hybrid-array" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" dependencies = [ "typenum", ] [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" [[package]] name = "indexmap" version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", "serde", "serde_core", ] [[package]] name = "itoa" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "kem" version = "0.3.0" dependencies = [ "crypto-common", "rand_core", ] [[package]] name = "leb128fmt" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "log" version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "memchr" version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "prettyplease" version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", "syn", ] [[package]] name = "proc-macro2" version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "quote" version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] [[package]] name = "r-efi" version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand_core" version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" [[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ "serde_core", ] [[package]] name = "serde_core" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn", ] [[package]] name = "serde_json" version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", "serde", "serde_core", "zmij", ] [[package]] name = "syn" version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] [[package]] name = "typenum" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "wasip2" version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasip3" version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen", ] [[package]] name = "wasm-encoder" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" dependencies = [ "leb128fmt", "wasmparser", ] [[package]] name = "wasm-metadata" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", "indexmap", "wasm-encoder", "wasmparser", ] [[package]] name = "wasmparser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags", "hashbrown 0.15.5", "indexmap", "semver", ] [[package]] name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" dependencies = [ "wit-bindgen-rust-macro", ] [[package]] name = "wit-bindgen-core" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" dependencies = [ "anyhow", "heck", "wit-parser", ] [[package]] name = "wit-bindgen-rust" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", "indexmap", "prettyplease", "syn", "wasm-metadata", "wit-bindgen-core", "wit-component", ] [[package]] name = "wit-bindgen-rust-macro" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" dependencies = [ "anyhow", "prettyplease", "proc-macro2", "quote", "syn", "wit-bindgen-core", "wit-bindgen-rust", ] [[package]] name = "wit-component" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags", "indexmap", "log", "serde", "serde_derive", "serde_json", "wasm-encoder", "wasm-metadata", "wasmparser", "wit-parser", ] [[package]] name = "wit-parser" version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", "indexmap", "log", "semver", "serde", "serde_derive", "serde_json", "unicode-xid", "wasmparser", ] [[package]] name = "zmij" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" kem-0.3.0/Cargo.toml0000644000000026201046102023000076300ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2024" rust-version = "1.85" name = "kem" version = "0.3.0" authors = ["RustCrypto Developers"] build = false autolib = false autobins = false autoexamples = false autotests = false autobenches = false description = """ Traits for Key Encapsulation Mechanisms (KEMs): public-key cryptosystems designed to enable a sender (a.k.a. encapsulator) to generate and encrypt a short secret key and transmit it to a receiver (a.k.a. decapsulator) confidentially """ documentation = "https://docs.rs/kem" readme = "README.md" keywords = ["crypto"] categories = [ "cryptography", "no-std", ] license = "Apache-2.0 OR MIT" repository = "https://github.com/RustCrypto/traits" [package.metadata.docs.rs] all-features = true [features] getrandom = ["common/getrandom"] [lib] name = "kem" path = "src/lib.rs" [dependencies.common] version = "0.2" features = ["rand_core"] package = "crypto-common" [dependencies.rand_core] version = "0.10" kem-0.3.0/Cargo.toml.orig000064400000000000000000000014201046102023000132640ustar 00000000000000[package] name = "kem" version = "0.3.0" authors = ["RustCrypto Developers"] edition = "2024" rust-version = "1.85" documentation = "https://docs.rs/kem" readme = "README.md" repository = "https://github.com/RustCrypto/traits" license = "Apache-2.0 OR MIT" keywords = ["crypto"] categories = ["cryptography", "no-std"] description = """ Traits for Key Encapsulation Mechanisms (KEMs): public-key cryptosystems designed to enable a sender (a.k.a. encapsulator) to generate and encrypt a short secret key and transmit it to a receiver (a.k.a. decapsulator) confidentially """ [dependencies] common = { package = "crypto-common", version = "0.2", features = ["rand_core"] } rand_core = "0.10" [features] getrandom = ["common/getrandom"] [package.metadata.docs.rs] all-features = true kem-0.3.0/LICENSE-APACHE000064400000000000000000000010611046102023000123220ustar 00000000000000Copyright 2021 RustCrypto Developers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. kem-0.3.0/LICENSE-MIT000064400000000000000000000020561046102023000120370ustar 00000000000000Copyright (c) 2021-2026 RustCrypto Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. kem-0.3.0/README.md000064400000000000000000000036011046102023000116570ustar 00000000000000# [RustCrypto]: Key Encapsulation Mechanisms (KEMs) [![crate][crate-image]][crate-link] [![Docs][docs-image]][docs-link] [![Build Status][build-image]][build-link] ![Apache2/MIT licensed][license-image] ![Rust Version][rustc-image] [![Project Chat][chat-image]][chat-link] ## About 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. ## License Licensed under either of * [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0) * [MIT license](http://opensource.org/licenses/MIT) at your option. ### Contribution Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. [//]: # (badges) [crate-image]: https://img.shields.io/crates/v/kem.svg [crate-link]: https://crates.io/crates/kem [docs-image]: https://docs.rs/kem/badge.svg [docs-link]: https://docs.rs/kem/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg [rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260048-signatures [build-image]: https://github.com/RustCrypto/traits/actions/workflows/kem.yml/badge.svg?branch=master [build-link]: https://github.com/RustCrypto/traits/actions/workflows/kem.yml?query=branch:master [//]: # (links) [RustCrypto]: https://github.com/RustCrypto [1]: https://en.wikipedia.org/wiki/Key_encapsulation kem-0.3.0/src/lib.rs000064400000000000000000000236121046102023000123070ustar 00000000000000#![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![forbid(unsafe_code)] #![warn(missing_docs, unused_qualifications, missing_debug_implementations)] //! # Usage //! //! There are two roles in a KEM: //! //! - Encapsulator: the holder of the public key (a.k.a. encapsulation key), which provides an //! operation that simultaneously generates both the plaintext and ciphertext of a random //! "shared key" whose ciphertext (a.k.a. encapsulation) can be sent to the party with the //! decapsulator key. //! - Decapsulator: holder secret/private key (a.k.a. decapsulation key), which can be used to //! decrypt the encrypted (a.k.a. encapsulated) "shared key" which was randomly generated by //! the encapsulator. //! //! The following example illustrates the workflow of using this crate's traits with a hypothetical //! KEM named `K` : //! #![cfg_attr(feature = "getrandom", doc = "```")] #![cfg_attr(not(feature = "getrandom"), doc = "```ignore")] //! // NOTE: requires the `getrandom` feature is enabled //! //! use kem::{Decapsulate, Encapsulate, Kem}; //! //! # pub fn kem_workflow_example>() { //! // Generate a decapsulation/encapsulation keypair. The first one is the secret one. //! let (dk, ek) = K::generate_keypair(); //! //! // Encapsulator: //! // //! // Randomly generates and encapsulates/encrypts a shared key which can be decrypted by the //! // holder of the decapsulation key, obtaining the ciphertext and plaintext of the shared key. //! let (ct, k_send) = ek.encapsulate(); //! //! // Decapsulator: //! // //! // Decapsulates the encrypted/encapsulated shared key, obtaining its plaintext. //! let k_recv = dk.decapsulate(&ct); //! //! // We've now established a shared key. //! assert_eq!(k_send, k_recv); //! # } //! ``` //! //! ## Serialization //! //! The [`KeyInit`] and [`KeyExport`] traits can be used to load and store encoded decapsulation //! and encapsulation keys from their byte serialization. //! //! Decapsulation keys are often initialized from a compact representation known as a [`Seed`]. //! The [`FromSeed`] trait provides an extension to the [`Kem`] trait for initializing keypairs //! from a seed value. We recommend the [`KeyInit`] and [`KeyExport`] trait impls on //! decapsulation keys operate on seed values when there is a choice of multiple key formats //! (e.g. expanded decapsulation keys). //! //! [RFC 9180]: https://www.rfc-editor.org/info/rfc9180 pub use common::{ self, Generate, InvalidKey, Key, KeyExport, KeyInit, KeySizeUser, TryKeyInit, typenum::consts, }; use common::array::{self, ArraySize}; use core::fmt::Debug; use core::{array::TryFromSliceError, convert::Infallible}; use rand_core::CryptoRng; #[cfg(feature = "getrandom")] use common::getrandom::{SysRng, rand_core::UnwrapErr}; /// Seed value which can be used to deterministically initialize a KEM keypair. pub type Seed = array::Array::SeedSize>; /// KEM decryption key (i.e. private key) which can decrypt encrypted shared secret ciphertexts /// which were encrypted by [`EncapsulationKey`]. pub type DecapsulationKey = ::DecapsulationKey; /// KEM encryption key (i.e. public key) which encrypts shared secrets into ciphertexts which /// can be decrypted by [`DecapsulationKey`]. pub type EncapsulationKey = ::EncapsulationKey; /// Shared key: plaintext produced after decapsulation by [`Decapsulate::decapsulate`] which is /// also returned by [`Encapsulate::encapsulate`], which is the shared secret resulting from the /// key encapsulation algorithm. pub type SharedKey = array::Array::SharedKeySize>; /// Ciphertext message (a.k.a. "encapsulated key") produced by [`Encapsulate::encapsulate`] which is /// an encrypted [`SharedKey`] that can be decrypted using [`Decapsulate::decapsulate`]. pub type Ciphertext = array::Array::CiphertextSize>; /// Key encapsulation mechanism. /// /// This trait describes the entire type family used by a KEM. pub trait Kem: Copy + Clone + Debug + Default + Eq + Ord + Send + Sync + 'static { /// KEM decryption key (i.e. private key) which can decrypt encrypted shared secret ciphertexts /// which were encrypted by [`Kem::EncapsulationKey`]. type DecapsulationKey: TryDecapsulate + Generate; /// KEM encryption key (i.e. public key) which encrypts shared secrets into ciphertexts which /// can be decrypted by [`Kem::DecapsulationKey`]. type EncapsulationKey: Encapsulate + Clone + Debug + Eq; /// Size of the shared key/secret returned by both encapsulation and decapsulation. type SharedKeySize: ArraySize; /// Size of the ciphertext (a.k.a. "encapsulated key") produced by [`Self::EncapsulationKey`]. type CiphertextSize: ArraySize; /// Generate a random KEM keypair using the provided random number generator. fn generate_keypair_from_rng( rng: &mut R, ) -> (DecapsulationKey, EncapsulationKey) { let dk = DecapsulationKey::::generate_from_rng(rng); let ek = dk.encapsulation_key().clone(); (dk, ek) } /// Generate a random KEM keypair using the system's secure RNG. #[cfg(feature = "getrandom")] fn generate_keypair() -> (DecapsulationKey, EncapsulationKey) { Self::generate_keypair_from_rng(&mut UnwrapErr(SysRng)) } } /// Initialize a KEM from a [`Seed`]. /// /// Many KEMs support a fully deterministic and infallible initialization from a short seed value. /// /// This trait is blanket impl'd for any [`Kem`] whose [`DecapsulationKey`] impls the [`KeyInit`] /// trait. pub trait FromSeed: Kem { /// Size of the seed value in bytes. type SeedSize: ArraySize; /// Using the provided seed value, create a KEM keypair. fn from_seed(seed: &Seed) -> (DecapsulationKey, EncapsulationKey); } impl FromSeed for K where K: Kem, K::DecapsulationKey: KeyInit, { type SeedSize = ::KeySize; fn from_seed(seed: &Seed) -> (DecapsulationKey, EncapsulationKey) { let dk = DecapsulationKey::::new(seed); let ek = dk.encapsulation_key().clone(); (dk, ek) } } /// Decapsulator with an associated encapsulation key which can be used for encrypting shared keys /// that this decapsulator can decrypt. pub trait Decapsulator { /// KEM algorithm this decapsulator is for. type Kem: Kem; /// Encapsulation key which can encrypt ciphertexts this decapsulator can decrypt. fn encapsulation_key(&self) -> &EncapsulationKey; } /// Decapsulator for encapsulated keys, with an associated `Encapsulator` bounded by the /// [`Encapsulate`] trait. /// /// Often, this will just be a secret key. But, as with [`Encapsulate`], it can be a bundle /// of secret keys, or it can include a sender's private key for authenticated encapsulation. /// It could also be a hardware device like an HSM, TPM, or SEP. /// /// When possible (i.e. for software / non-HSM implementations) types which impl this trait should /// also impl the [`Generate`] trait to support key generation. pub trait Decapsulate: TryDecapsulate { /// Decapsulates the given [`Ciphertext`] a.k.a. "encapsulated key". fn decapsulate(&self, ct: &Ciphertext) -> SharedKey; /// Decapsulate the given byte slice containing a [`Ciphertext`] a.k.a. "encapsulated key". /// /// # Errors /// - If the length of `ct` is not equal to `::CiphertextSize`. fn decapsulate_slice(&self, ct: &[u8]) -> Result, TryFromSliceError> { ct.try_into().map(|ct| self.decapsulate(&ct)) } } /// Decapsulator for encapsulated keys with failure handling, with an associated `Encapsulator` /// bounded by the [`Encapsulate`] trait. /// /// Prefer to implement the [`Decapsulate`] trait if possible. See that trait's documentation for /// more information. pub trait TryDecapsulate: Decapsulator { /// Decapsulation error type Error: core::error::Error; /// Decapsulates the given [`Ciphertext`] a.k.a. "encapsulated key". fn try_decapsulate( &self, ct: &Ciphertext, ) -> Result, Self::Error>; /// Decapsulate the given byte slice containing a [`Ciphertext`] a.k.a. "encapsulated key". /// /// # Errors /// - If the length of `ct` is not equal to `::CiphertextSize`. fn try_decapsulate_slice(&self, ct: &[u8]) -> Result, Self::Error> where Self::Error: From, { self.try_decapsulate(ct.try_into()?) } } impl TryDecapsulate for D where D: Decapsulate + Decapsulator, { type Error = Infallible; fn try_decapsulate( &self, ct: &Ciphertext, ) -> Result, Infallible> { Ok(self.decapsulate(ct)) } } /// Encapsulator for shared secrets. /// /// Often, this will just be a public key. However, it can also be a bundle of public keys, or it /// can include a sender's private key for authenticated encapsulation. pub trait Encapsulate: TryKeyInit + KeyExport { /// KEM algorithm this encapsulator is for. type Kem: Kem; /// Encapsulates a fresh [`SharedKey`] generated using the supplied random number /// generator `R`. fn encapsulate_with_rng(&self, rng: &mut R) -> (Ciphertext, SharedKey) where R: CryptoRng + ?Sized; /// Encapsulate a fresh shared secret generated using the system's secure RNG. #[cfg(feature = "getrandom")] fn encapsulate(&self) -> (Ciphertext, SharedKey) { self.encapsulate_with_rng(&mut UnwrapErr(SysRng)) } }