blob: 8d4a3506e7a7b2a62be46b45f8643e6a738f4983 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
module Crypto where
import Val
import Hash
import Types
import qualified Crypto.PubKey.Ed25519 as Ed25519
import Crypto.Error
import Crypto.Random.Entropy
import Data.ByteArray (convert)
import Data.ByteString
dummySignature :: Signature
dummySignature = OtherSignature (Val undefined)
-- | Sign any Hashable value.
sign :: Hashable v => MySessionKey -> v -> Signature
sign (MySessionKey sk pk) v = Ed25519Signature $ Val $ convert $
Ed25519.sign sk pk $ val $ hashValue $ hash v
-- | Verifiy a signature of any Hashable value.
--
-- To avoid overhead of converting the PublicKey to the Ed25519.PublicKey
-- each time, partially evaluate this function.
verify :: Hashable v => PublicKey -> v -> Signature -> Bool
verify (PublicKey (Val pk) _) v (Ed25519Signature (Val s)) =
case Ed25519.publicKey pk of
CryptoPassed pk' -> case Ed25519.signature s of
CryptoPassed sig ->
Ed25519.verify pk' (val $ hashValue $ hash v) sig
CryptoFailed _ -> False
CryptoFailed _ -> False
verify _ _ (OtherSignature _) = False
data MySessionKey = MySessionKey Ed25519.SecretKey Ed25519.PublicKey
genMySessionKey :: IO MySessionKey
genMySessionKey = do
-- Crypto.Random.Entropy may use rdrand, or /dev/random.
-- Even if you don't trust rdrand to be free of backdoors,
-- it seems safe enough to use it for a session key that
-- is only used for signing, not encryption.
rand32 <- getEntropy 32 :: IO ByteString
sk <- throwCryptoErrorIO $ Ed25519.secretKey rand32
return $ MySessionKey sk (Ed25519.toPublic sk)
|