| License | BSD-style |
|---|---|
| Maintainer | Kazu Yamamoto <kazu@iij.ad.jp> |
| Stability | experimental |
| Portability | unknown |
| Safe Haskell | None |
| Language | Haskell2010 |
Crypto.PubKey.MLKEM
Description
ML-KEM, the Module-Lattice-Based Key-Encapsulation Mechanism of FIPS 203, in all three parameter sets.
A key encapsulation mechanism is not a Diffie-Hellman: there is no shared
secret to be computed from two key pairs. One side publishes an
EncapsulationKey; the other calls encapsulate on it, which draws a
fresh secret and returns it along with a Ciphertext that only the holder
of the matching DecapsulationKey can turn back into that secret.
(ek, dk) <- generateKeyPair MLKEM768 -- the receiver (ct, ss) <- encapsulate ek -- the sender let ss' = decapsulate dk ct -- the receiver, again ss == ss'
What generateKeyPair and encapsulate draw their randomness from is
the MonadRandom instance in use. Its documentation says
what an instance of your own has to be.
The parameter set is a type, so an ML-KEM-768 key cannot be passed where an ML-KEM-1024 one is expected. The three are fixed by FIPS 203 and the class has no other instances.
Synopsis
- data MLKEM512 = MLKEM512
- data MLKEM768 = MLKEM768
- data MLKEM1024 = MLKEM1024
- class (KEM p, EncapsulationKey p ~ MLKEMEncapsulationKey p, DecapsulationKey p ~ MLKEMDecapsulationKey p, Ciphertext p ~ MLKEMCiphertext p, Coins p ~ ScrubbedBytes) => MLKEM p where
- encapsulationKeySize :: proxy p -> Int
- decapsulationKeySize :: proxy p -> Int
- ciphertextSize :: proxy p -> Int
- 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
- encapsulationKey :: (MLKEM p, ByteArrayAccess ba) => ba -> CryptoFailable (EncapsulationKey p)
- decapsulationKey :: (MLKEM p, ByteArrayAccess ba) => ba -> CryptoFailable (DecapsulationKey p)
- ciphertext :: (MLKEM p, ByteArrayAccess ba) => ba -> CryptoFailable (Ciphertext p)
- generateKeyPairAndSeed :: forall p proxy m. (MLKEM p, MonadRandom m) => proxy p -> m (MLKEMEncapsulationKey p, DecapsulationKey p, ScrubbedBytes)
- keyPairFromSeed :: forall p proxy ba. (MLKEM p, ByteArrayAccess ba) => proxy p -> ba -> CryptoFailable (MLKEMEncapsulationKey p, DecapsulationKey p)
- seedSize :: Int
- encapsulationCoinsSize :: Int
- sharedSecretSize :: Int
Parameter sets
ML-KEM-512.
Constructors
| MLKEM512 |
Instances
ML-KEM-768. This is the set TLS uses, on its own and as the lattice half of the hybrid groups.
Constructors
| MLKEM768 |
Instances
| Show MLKEM768 Source # | |||||||||||||||||
| KEM MLKEM768 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM Associated Types
Methods generateKeyPair :: MonadRandom m => proxy MLKEM768 -> m (EncapsulationKey MLKEM768, DecapsulationKey MLKEM768) Source # encapsulate :: MonadRandom m => proxy MLKEM768 -> EncapsulationKey MLKEM768 -> m (CryptoFailable (Ciphertext MLKEM768, SharedSecret)) Source # encapsulateWith :: proxy MLKEM768 -> EncapsulationKey MLKEM768 -> Coins MLKEM768 -> CryptoFailable (Ciphertext MLKEM768, SharedSecret) Source # decapsulate :: proxy MLKEM768 -> DecapsulationKey MLKEM768 -> Ciphertext MLKEM768 -> CryptoFailable SharedSecret Source # | |||||||||||||||||
| MLKEM MLKEM768 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM Methods encapsulationKeySize :: proxy MLKEM768 -> Int Source # decapsulationKeySize :: proxy MLKEM768 -> Int Source # ciphertextSize :: proxy MLKEM768 -> Int Source # c_keypair :: proxy MLKEM768 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_enc :: proxy MLKEM768 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_dec :: proxy MLKEM768 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |||||||||||||||||
| Eq MLKEM768 Source # | |||||||||||||||||
| type Ciphertext MLKEM768 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
| type Coins MLKEM768 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
| type DecapsulationKey MLKEM768 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
| type EncapsulationKey MLKEM768 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
ML-KEM-1024.
Constructors
| MLKEM1024 |
Instances
| Show MLKEM1024 Source # | |||||||||||||||||
| KEM MLKEM1024 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM Associated Types
Methods generateKeyPair :: MonadRandom m => proxy MLKEM1024 -> m (EncapsulationKey MLKEM1024, DecapsulationKey MLKEM1024) Source # encapsulate :: MonadRandom m => proxy MLKEM1024 -> EncapsulationKey MLKEM1024 -> m (CryptoFailable (Ciphertext MLKEM1024, SharedSecret)) Source # encapsulateWith :: proxy MLKEM1024 -> EncapsulationKey MLKEM1024 -> Coins MLKEM1024 -> CryptoFailable (Ciphertext MLKEM1024, SharedSecret) Source # decapsulate :: proxy MLKEM1024 -> DecapsulationKey MLKEM1024 -> Ciphertext MLKEM1024 -> CryptoFailable SharedSecret Source # | |||||||||||||||||
| MLKEM MLKEM1024 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM Methods encapsulationKeySize :: proxy MLKEM1024 -> Int Source # decapsulationKeySize :: proxy MLKEM1024 -> Int Source # ciphertextSize :: proxy MLKEM1024 -> Int Source # c_keypair :: proxy MLKEM1024 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_enc :: proxy MLKEM1024 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_dec :: proxy MLKEM1024 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |||||||||||||||||
| Eq MLKEM1024 Source # | |||||||||||||||||
| type Ciphertext MLKEM1024 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
| type Coins MLKEM1024 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
| type DecapsulationKey MLKEM1024 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
| type EncapsulationKey MLKEM1024 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM | |||||||||||||||||
class (KEM p, EncapsulationKey p ~ MLKEMEncapsulationKey p, DecapsulationKey p ~ MLKEMDecapsulationKey p, Ciphertext p ~ MLKEMCiphertext p, Coins p ~ ScrubbedBytes) => MLKEM p where Source #
The three parameter sets of FIPS 203.
This is not an abstract KEM interface and does not try to be: it is the three sets FIPS 203 defines, closed, carrying their sizes and the calls into the implementation. Only the sizes are exported. If crypton grows a second KEM and an interface common to both is wanted, that belongs in a module of its own, with this as one of its instances.
Minimal complete definition
encapsulationKeySize, decapsulationKeySize, ciphertextSize, c_keypair, c_enc, c_dec, c_checkPk, c_checkSk
Methods
encapsulationKeySize :: proxy p -> Int Source #
Size in bytes of an EncapsulationKey of this parameter set.
decapsulationKeySize :: proxy p -> Int Source #
Size in bytes of a DecapsulationKey of this parameter set.
ciphertextSize :: proxy p -> Int Source #
Size in bytes of a Ciphertext of this parameter set.
Instances
| MLKEM MLKEM1024 Source # | |
Defined in Crypto.PubKey.MLKEM Methods encapsulationKeySize :: proxy MLKEM1024 -> Int Source # decapsulationKeySize :: proxy MLKEM1024 -> Int Source # ciphertextSize :: proxy MLKEM1024 -> Int Source # c_keypair :: proxy MLKEM1024 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_enc :: proxy MLKEM1024 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_dec :: proxy MLKEM1024 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |
| MLKEM MLKEM512 Source # | |
Defined in Crypto.PubKey.MLKEM Methods encapsulationKeySize :: proxy MLKEM512 -> Int Source # decapsulationKeySize :: proxy MLKEM512 -> Int Source # ciphertextSize :: proxy MLKEM512 -> Int Source # c_keypair :: proxy MLKEM512 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_enc :: proxy MLKEM512 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_dec :: proxy MLKEM512 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |
| MLKEM MLKEM768 Source # | |
Defined in Crypto.PubKey.MLKEM Methods encapsulationKeySize :: proxy MLKEM768 -> Int Source # decapsulationKeySize :: proxy MLKEM768 -> Int Source # ciphertextSize :: proxy MLKEM768 -> Int Source # c_keypair :: proxy MLKEM768 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_enc :: proxy MLKEM768 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt c_dec :: proxy MLKEM768 -> Ptr Word8 -> Ptr Word8 -> Ptr Word8 -> IO CInt | |
Keys, ciphertexts and shared secrets
These are the associated types of KEM, re-exported so that a
caller of this module alone has them.
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
| KEM MLKEM1024 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM Associated Types
Methods generateKeyPair :: MonadRandom m => proxy MLKEM1024 -> m (EncapsulationKey MLKEM1024, DecapsulationKey MLKEM1024) Source # encapsulate :: MonadRandom m => proxy MLKEM1024 -> EncapsulationKey MLKEM1024 -> m (CryptoFailable (Ciphertext MLKEM1024, SharedSecret)) Source # encapsulateWith :: proxy MLKEM1024 -> EncapsulationKey MLKEM1024 -> Coins MLKEM1024 -> CryptoFailable (Ciphertext MLKEM1024, SharedSecret) Source # decapsulate :: proxy MLKEM1024 -> DecapsulationKey MLKEM1024 -> Ciphertext MLKEM1024 -> CryptoFailable SharedSecret Source # | |||||||||||||||||
| KEM MLKEM512 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM Associated Types
Methods generateKeyPair :: MonadRandom m => proxy MLKEM512 -> m (EncapsulationKey MLKEM512, DecapsulationKey MLKEM512) Source # encapsulate :: MonadRandom m => proxy MLKEM512 -> EncapsulationKey MLKEM512 -> m (CryptoFailable (Ciphertext MLKEM512, SharedSecret)) Source # encapsulateWith :: proxy MLKEM512 -> EncapsulationKey MLKEM512 -> Coins MLKEM512 -> CryptoFailable (Ciphertext MLKEM512, SharedSecret) Source # decapsulate :: proxy MLKEM512 -> DecapsulationKey MLKEM512 -> Ciphertext MLKEM512 -> CryptoFailable SharedSecret Source # | |||||||||||||||||
| KEM MLKEM768 Source # | |||||||||||||||||
Defined in Crypto.PubKey.MLKEM Associated Types
Methods generateKeyPair :: MonadRandom m => proxy MLKEM768 -> m (EncapsulationKey MLKEM768, DecapsulationKey MLKEM768) Source # encapsulate :: MonadRandom m => proxy MLKEM768 -> EncapsulationKey MLKEM768 -> m (CryptoFailable (Ciphertext MLKEM768, SharedSecret)) Source # encapsulateWith :: proxy MLKEM768 -> EncapsulationKey MLKEM768 -> Coins MLKEM768 -> CryptoFailable (Ciphertext MLKEM768, SharedSecret) Source # decapsulate :: proxy MLKEM768 -> DecapsulationKey MLKEM768 -> Ciphertext MLKEM768 -> CryptoFailable SharedSecret Source # | |||||||||||||||||
newtype SharedSecret Source #
Secret shared via key exchange.
Constructors
| SharedSecret ScrubbedBytes |
Instances
Smart constructors
encapsulationKey :: (MLKEM p, ByteArrayAccess ba) => ba -> CryptoFailable (EncapsulationKey p) Source #
Try to read an encapsulation key.
Beyond the length this runs the check of FIPS 203 section 7.2: the key must be the encoding of coefficients that are all in range, which is to say it must survive a decode and re-encode unchanged. A key that fails it is not one any honest party produced.
decapsulationKey :: (MLKEM p, ByteArrayAccess ba) => ba -> CryptoFailable (DecapsulationKey p) Source #
Try to read a decapsulation key.
Beyond the length this runs the check of FIPS 203 section 7.3: the hash of the encapsulation key the private key embeds must match the copy of that hash it also embeds. The two disagreeing means the key was not produced as a pair, and decapsulating with it would silently answer with the implicit rejection every time.
ciphertext :: (MLKEM p, ByteArrayAccess ba) => ba -> CryptoFailable (Ciphertext p) Source #
Try to read a ciphertext. Only the length is checked; every string of
the right length is a ciphertext that decapsulate will answer.
What ML-KEM has beyond the class
generateKeyPairAndSeed :: forall p proxy m. (MLKEM p, MonadRandom m) => proxy p -> m (MLKEMEncapsulationKey p, DecapsulationKey p, ScrubbedBytes) Source #
Generate a key pair and hand back the seed it was derived from, d
and z of FIPS 203 one after the other.
A DecapsulationKey is the expanded key and nothing else, so the seed
cannot be recovered from a pair afterwards. An application that has to
write the key out in a form that keeps the seed has to generate it here:
(ek, dk, seed) <- generateKeyPairAndSeed MLKEM768
The seed is as secret as the decapsulation key: keyPairFromSeed turns
it back into the same pair.
keyPairFromSeed :: forall p proxy ba. (MLKEM p, ByteArrayAccess ba) => proxy p -> ba -> CryptoFailable (MLKEMEncapsulationKey p, DecapsulationKey p) Source #
Derive a key pair from a seed, which is d and z of FIPS 203 one
after the other and must be seedSize bytes.
This is the entry point to use when the seed comes from somewhere
particular -- a test vector, or a store that keeps seeds rather than
expanded keys. For an ordinary key, generateKeyPair draws the seed
itself.
Sizes
Size in bytes of the seed keyPairFromSeed takes, which is d and z
of FIPS 203 one after the other.
encapsulationCoinsSize :: Int Source #
Size in bytes of the randomness encapsulateWith takes, m in
FIPS 203.
sharedSecretSize :: Int Source #
Size in bytes of a SharedSecret.