Copyright | (c) Leo D 2023 |
---|---|
License | BSD-3-Clause |
Maintainer | leo@apotheca.io |
Stability | experimental |
Portability | POSIX |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
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 #
MkKEMEncrypt | |
|
withKEMEncrypt :: KEMEncrypt -> (BotanPKOpKEMEncrypt -> IO a) -> IO a Source #
kemEncryptDestroy :: KEMEncrypt -> IO () Source #
:: PubKey | key |
-> KDFName | kdf |
-> IO KEMEncrypt | op |
kemEncryptSharedKeyLength Source #
:: KEMEncrypt | op |
-> Int | desired_shared_key_length |
-> IO Int | output_shared_key_length |
kemEncryptEncapsulatedKeyLength Source #
:: KEMEncrypt | op |
-> IO Int | output_encapsulated_key_length |
kemEncryptCreateSharedKey Source #
:: KEMEncrypt | op |
-> RNG | rng |
-> ByteString | salt[] |
-> Int | desired_shared_key_len |
-> IO (KEMSharedKey, KEMEncapsulatedKey) | (shared_key,encapsulated_key) |
KEM Decryption
newtype KEMDecrypt Source #
MkKEMDecrypt | |
|
withKEMDecrypt :: KEMDecrypt -> (BotanPKOpKEMDecrypt -> IO a) -> IO a Source #
kemDecryptDestroy :: KEMDecrypt -> IO () Source #
:: PrivKey | key |
-> KDFName | kdf |
-> IO KEMDecrypt | op |
kemDecryptSharedKeyLength Source #
:: KEMDecrypt | op |
-> Int | desired_shared_key_length |
-> IO Int | output_shared_key_length |
:: KEMDecrypt | op |
-> ByteString | salt[] |
-> KEMEncapsulatedKey | encapsulated_key[] |
-> Int | desired_shared_key_len |
-> IO KEMSharedKey | shared_key[] |