| License | BSD-style |
|---|---|
| Maintainer | Kazu Yamamoto <kazu@iij.ad.jp> |
| Stability | experimental |
| Portability | unknown |
| Safe Haskell | None |
| Language | Haskell2010 |
Crypto.KEM
Description
Key encapsulation: one side publishes a key, the other draws a secret and returns something only the first side can turn back into it.
The shape is not ML-KEM's alone, which is why this is a class in a module
of its own rather than part of any one algorithm: MLKEM
is one instance of it, and a caller that does not care which it has can
be written against this.
A bare Diffie-Hellman exchange is deliberately not an instance, even though the shapes line up. The KEM a Diffie-Hellman group gives is DHKEM, of RFC 9180 section 4.1, and that is not the raw exchange: its shared secret is the exchange's output run through HKDF with the ephemeral and the recipient public keys as context, under labels that name the ciphersuite. The binding to those two keys, and the separation between suites, are what the KEM security argument rests on; the raw value has neither. A protocol can supply the binding at its own level -- TLS 1.3 does, in the key schedule -- but then the binding belongs to the protocol, not to this class, and offering the raw exchange here would invite its use somewhere that supplies nothing.
DHKEM proper is an instance, and it is not here either: the labels it
derives under carry the HPKE ciphersuite identifier, which is an IANA
registry value rather than anything a primitive knows, so the instances
live beside the registry in the hpke package.
Synopsis
- class KEM kem where
- type EncapsulationKey kem
- type DecapsulationKey kem
- type Ciphertext kem
- type Coins kem
- generateKeyPair :: MonadRandom m => proxy kem -> m (EncapsulationKey kem, DecapsulationKey kem)
- encapsulate :: MonadRandom m => proxy kem -> EncapsulationKey kem -> m (CryptoFailable (Ciphertext kem, SharedSecret))
- encapsulateWith :: proxy kem -> EncapsulationKey kem -> Coins kem -> CryptoFailable (Ciphertext kem, SharedSecret)
- decapsulate :: proxy kem -> DecapsulationKey kem -> Ciphertext kem -> CryptoFailable SharedSecret
- newtype SharedSecret = SharedSecret ScrubbedBytes
Documentation
A key encapsulation mechanism.
The three values are named for what they do rather than for what they are in any one algorithm. In ML-KEM the encapsulation key and the ciphertext are what the names say; in a Diffie-Hellman exchange both are public values of the group, and the "ciphertext" is the ephemeral one the encapsulating side generates. Keeping them apart in the types is what stops one being passed where the other belongs, which they are not interchangeable for even where they have the same representation.
Associated Types
type EncapsulationKey kem Source #
What the encapsulating side is given.
type DecapsulationKey kem Source #
What the decapsulating side keeps.
type Ciphertext kem Source #
What travels back, and is decapsulated.
The randomness encapsulate draws, for the instances that let a
caller supply it. In ML-KEM it is m of FIPS 203, a string of
bytes; in DHKEM it is the ephemeral secret key, a scalar of the
group. Both are secret, and both determine the shared secret
completely.
Methods
generateKeyPair :: MonadRandom m => proxy kem -> m (EncapsulationKey kem, DecapsulationKey kem) Source #
Generate a key pair for the decapsulating side.
encapsulate :: MonadRandom m => proxy kem -> EncapsulationKey kem -> m (CryptoFailable (Ciphertext kem, SharedSecret)) Source #
Draw a secret and encapsulate it against the key.
This can fail, and does for some instances: a Diffie-Hellman exchange refuses a peer value that would make the secret degenerate, where ML-KEM has nothing to refuse.
encapsulateWith :: proxy kem -> EncapsulationKey kem -> Coins kem -> CryptoFailable (Ciphertext kem, SharedSecret) Source #
Encapsulate with the randomness supplied rather than drawn.
The secret this produces is a deterministic function of the key and
these coins, so they must come from a source no other party can
predict or repeat, and must not be used twice. encapsulate is the
entry point for ordinary use; this one is for test vectors, and for a
protocol that has to name the ephemeral value it used -- HPKE lets a
sender supply its own, and the RFC 9180 vectors are written that way.
decapsulate :: proxy kem -> DecapsulationKey kem -> Ciphertext kem -> CryptoFailable SharedSecret Source #
Recover the secret.
Instances
newtype SharedSecret Source #
Secret shared via key exchange.
Constructors
| SharedSecret ScrubbedBytes |