From 7f4e3016d7bd1417e04e4b6fb6930bfa504bb1d3 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Wed, 19 Apr 2017 17:28:23 -0400 Subject: implement base Crypto --- Crypto.hs | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) (limited to 'Crypto.hs') diff --git a/Crypto.hs b/Crypto.hs index 3d0529d..8d4a350 100644 --- a/Crypto.hs +++ b/Crypto.hs @@ -5,20 +5,41 @@ import Hash import Types import qualified Crypto.PubKey.Ed25519 as Ed25519 -import Data.ByteArray (convert) import Crypto.Error +import Crypto.Random.Entropy +import Data.ByteArray (convert) +import Data.ByteString dummySignature :: Signature -dummySignature = Unsigned +dummySignature = OtherSignature (Val undefined) -- | Sign any Hashable value. -sign :: Hashable v => Ed25519.SecretKey -> Ed25519.PublicKey -> v -> Signature -sign sk pk v = Ed25519 $ Val $ convert $ +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. -verify :: Hashable v => Ed25519.PublicKey -> v -> Signature -> Bool -verify pk v (Ed25519 (Val s)) = case Ed25519.signature s of - CryptoPassed sig -> Ed25519.verify pk (val $ hashValue $ hash v) sig - CryptoFailed _ -> False -verify _ _ Unsigned = False +-- +-- 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) -- cgit v1.2.3