mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-06-08 15:12:23 +00:00
40 lines
1.6 KiB
Haskell
40 lines
1.6 KiB
Haskell
{-# LANGUAGE DataKinds #-}
|
|
{-# LANGUAGE GADTs #-}
|
|
{-# LANGUAGE LambdaCase #-}
|
|
|
|
-- spec: spec/modules/Simplex/Messaging/Crypto/SNTRUP761.md
|
|
module Simplex.Messaging.Crypto.SNTRUP761
|
|
( KEMHybridSecret (..),
|
|
kcbDecrypt,
|
|
kcbEncrypt,
|
|
kemHybridSecret,
|
|
) where
|
|
|
|
import Crypto.Hash (Digest, SHA3_256, hash)
|
|
import Data.ByteArray (ScrubbedBytes)
|
|
import qualified Data.ByteArray as BA
|
|
import Data.ByteString (ByteString)
|
|
import Simplex.Messaging.Crypto
|
|
import qualified Simplex.Messaging.Crypto as C
|
|
import Simplex.Messaging.Crypto.SNTRUP761.Bindings
|
|
|
|
-- Hybrid shared secret for crypto_box is defined as SHA256(DHSecret || KEMSharedKey),
|
|
-- similar to https://datatracker.ietf.org/doc/draft-josefsson-ntruprime-hybrid/
|
|
|
|
newtype KEMHybridSecret = KEMHybridSecret ScrubbedBytes
|
|
|
|
-- spec: spec/modules/Simplex/Messaging/Crypto/SNTRUP761.md#kcbencrypt--kcbdecrypt
|
|
-- | NaCl @crypto_box@ decrypt with a shared hybrid DH + KEM secret and 192-bit nonce.
|
|
kcbDecrypt :: KEMHybridSecret -> CbNonce -> ByteString -> Either CryptoError ByteString
|
|
kcbDecrypt (KEMHybridSecret k) = sbDecrypt_ k
|
|
|
|
-- | NaCl @crypto_box@ encrypt with a shared hybrid DH + KEM secret and 192-bit nonce.
|
|
kcbEncrypt :: KEMHybridSecret -> CbNonce -> ByteString -> Int -> Either CryptoError ByteString
|
|
kcbEncrypt (KEMHybridSecret k) = sbEncrypt_ k
|
|
|
|
-- spec: spec/modules/Simplex/Messaging/Crypto/SNTRUP761.md#kemhybridsecret
|
|
kemHybridSecret :: PublicKeyX25519 -> PrivateKeyX25519 -> KEMSharedKey -> KEMHybridSecret
|
|
kemHybridSecret k pk (KEMSharedKey kem) =
|
|
let DhSecretX25519 dh = C.dh' k pk
|
|
in KEMHybridSecret $ BA.convert (hash $ BA.convert dh <> kem :: Digest SHA3_256)
|