| Copyright | (c) Leo D 2023 |
|---|---|
| License | BSD-3-Clause |
| Maintainer | leo@apotheca.io |
| Stability | experimental |
| Portability | POSIX |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Botan.Low.PubKey.KeyEncapsulation
Description
Synopsis
- type KEMSharedKey = ByteString
- type KEMEncapsulatedKey = ByteString
- newtype KEMEncrypt = MkKEMEncrypt {
- getKEMEncryptForeignPtr :: ForeignPtr BotanPKOpKEMEncryptStruct
- withKEMEncrypt :: KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a
- kemEncryptDestroy :: KEMEncrypt -> IO ()
- kemEncryptCreate :: PubKey -> KDFName -> IO KEMEncrypt
- kemEncryptSharedKeyLength :: KEMEncrypt -> Int -> IO Int
- kemEncryptEncapsulatedKeyLength :: KEMEncrypt -> IO Int
- kemEncryptCreateSharedKey :: KEMEncrypt -> RNG -> ByteString -> Int -> IO (KEMSharedKey, KEMEncapsulatedKey)
- newtype KEMDecrypt = MkKEMDecrypt {
- getKEMDecryptForeignPtr :: ForeignPtr BotanPKOpKEMDecryptStruct
- withKEMDecrypt :: KEMDecrypt -> (BotanPKOpKEMDecrypt -> IO a) -> IO a
- kemDecryptDestroy :: KEMDecrypt -> IO ()
- kemDecryptCreate :: PrivKey -> KDFName -> IO KEMDecrypt
- kemDecryptSharedKeyLength :: KEMDecrypt -> Int -> IO Int
- kemDecryptSharedKey :: KEMDecrypt -> ByteString -> KEMEncapsulatedKey -> Int -> IO KEMSharedKey
PK Key Encapsulation
Key encapsulation (KEM) is a variation on public key encryption which is commonly used by post-quantum secure schemes. Instead of choosing a random secret and encrypting it, as in typical public key encryption, a KEM encryption takes no inputs and produces two values, the shared secret and the encapsulated key. The decryption operation takes in the encapsulated key and returns the shared secret.
NOTE: KEM only requires the public knowledge of one person's key pair, unlike Key Agreement.
First, Alice generates her private and public key pair:
import Botan.Low.PubKey import Botan.Low.PubKey.KeyEncapsulation import Botan.Low.Hash import Botan.Low.KDF import Botan.Low.RNG rng <- rngInit UserRNG -- Alice generates her private and public keys alicePrivKey <- privKeyCreate RSA "2048" rng alicePubKey <- privKeyExportPubKey alicePrivKey
Then, Alice shares her public key somewhere where others can see. When Bob wants to create a shared key with Alice, they choose a KDF algorithm, generate a salt, and choose a shared key length.
kdfAlg = hkdf SHA256 salt <- rngGet rng 4 sharedKeyLength = 256
Then, Bob generates the shared + encapsulated key, and sends the encapsulated key to Alice:
encryptCtx <- kemEncryptCreate alicePubKey kdfAlg (bobSharedKey, encapsulatedKey) <- kemEncryptCreateSharedKey encryptCtx rng salt sharedKeyLength -- sendToAlice encapsulatedKey
Upon receiving the encapsulated key, Alice can decrypt and extract the shared key using her private key:
decryptCtx <- kemDecryptCreate alicePrivKey kdfAlg aliceSharedKey <- kemDecryptSharedKey decryptCtx salt encapsulatedKey sharedKeyLength bobSharedKey == aliceSharedKey -- True
Then, this shared key may be used for any suitable purpose.
KEM Encryption
type KEMSharedKey = ByteString Source #
type KEMEncapsulatedKey = ByteString Source #
newtype KEMEncrypt Source #
Constructors
| MkKEMEncrypt | |
Fields
| |
withKEMEncrypt :: KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a Source #
kemEncryptDestroy :: KEMEncrypt -> IO () Source #
Arguments
| :: PubKey | key |
| -> KDFName | kdf |
| -> IO KEMEncrypt | op |
kemEncryptSharedKeyLength Source #
Arguments
| :: KEMEncrypt | op |
| -> Int | desired_shared_key_length |
| -> IO Int | output_shared_key_length |
kemEncryptEncapsulatedKeyLength Source #
Arguments
| :: KEMEncrypt | op |
| -> IO Int | output_encapsulated_key_length |
kemEncryptCreateSharedKey Source #
Arguments
| :: KEMEncrypt | op |
| -> RNG | rng |
| -> ByteString | salt[] |
| -> Int | desired_shared_key_len |
| -> IO (KEMSharedKey, KEMEncapsulatedKey) | (shared_key,encapsulated_key) |
KEM Decryption
newtype KEMDecrypt Source #
Constructors
| MkKEMDecrypt | |
Fields
| |
withKEMDecrypt :: KEMDecrypt -> (BotanPKOpKEMDecrypt -> IO a) -> IO a Source #
kemDecryptDestroy :: KEMDecrypt -> IO () Source #
Arguments
| :: PrivKey | key |
| -> KDFName | kdf |
| -> IO KEMDecrypt | op |
kemDecryptSharedKeyLength Source #
Arguments
| :: KEMDecrypt | op |
| -> Int | desired_shared_key_length |
| -> IO Int | output_shared_key_length |
Arguments
| :: KEMDecrypt | op |
| -> ByteString | salt[] |
| -> KEMEncapsulatedKey | encapsulated_key[] |
| -> Int | desired_shared_key_len |
| -> IO KEMSharedKey | shared_key[] |