Update tutorial based on suggestions

This commit is contained in:
tdietert 2017-03-26 00:47:02 +00:00
parent fd75eac415
commit f639ac9f0d
No known key found for this signature in database
GPG Key ID: E6E9ABBDB2807681

View File

@ -1,12 +1,12 @@
{- How to use @cryptonite@ with symmetric block ciphers {- How to use @cryptonite@ with symmetric block ciphers
> {-# LANGUAGE OverloadedStrings #-} > {-# LANGUAGE OverloadedStrings #-}
> {-# LANGUAGE ScopedTypeVariables #-} > {-# LANGUAGE ScopedTypeVariables #-}
> {-# LANGUAGE GADTs #-} > {-# LANGUAGE GADTs #-}
> >
> import Crypto.Cipher.AES (AES256) > import Crypto.Cipher.AES (AES256)
> import Crypto.Cipher.Types (BlockCipher(..), Cipher(..), nullIV, KeySizeSpecifier(..)) > import Crypto.Cipher.Types (BlockCipher(..), Cipher(..), nullIV, KeySizeSpecifier(..), IV, makeIV)
> import Crypto.Error (CryptoFailable(..), CryptoError(..)) > import Crypto.Error (CryptoFailable(..), CryptoError(..))
> >
> import qualified Crypto.Random.Types as CRT > import qualified Crypto.Random.Types as CRT
@ -18,40 +18,47 @@
> data Key c a where > data Key c a where
> Key :: (BlockCipher c, ByteArray a) => a -> Key c a > Key :: (BlockCipher c, ByteArray a) => a -> Key c a
> >
> genPrivateKey :: forall m c a. (CRT.MonadRandom m, BlockCipher c, ByteArray a) > -- | Generates a string of bytes (key) of a specific length for a given block cipher
> => c -> m (Key c a) > genSecretKey :: forall m c a. (CRT.MonadRandom m, BlockCipher c, ByteArray a) => c -> Int -> m (Key c a)
> genPrivateKey _ = fmap Key $ CRT.getRandomBytes $ > genSecretKey _ = fmap Key . CRT.getRandomBytes
> case cipherKeySize (undefined :: c) of >
> KeySizeRange _ maxSize -> maxSize > -- | Generate a random initialization vector for a given block cipher
> KeySizeFixed ks -> ks > genRandomIV :: forall m c. (CRT.MonadRandom m, BlockCipher c) => c -> m (Maybe (IV c))
> KeySizeEnum [] -> error "No key size specified" > genRandomIV _ = do
> KeySizeEnum kss -> last kss -- largest key size > bytes :: ByteString <- CRT.getRandomBytes $ blockSize (undefined :: c)
> > return $ makeIV bytes
>
> -- | Initialize a block cipher
> initCipher :: (BlockCipher c, ByteArray a) => Key c a -> Either CryptoError c > initCipher :: (BlockCipher c, ByteArray a) => Key c a -> Either CryptoError c
> initCipher (Key k) = case cipherInit k of > initCipher (Key k) = case cipherInit k of
> CryptoFailed e -> Left e > CryptoFailed e -> Left e
> CryptoPassed a -> Right a > CryptoPassed a -> Right a
> >
> encrypt :: (BlockCipher c, ByteArray a) => Key c a -> a -> Either CryptoError a > encrypt :: (BlockCipher c, ByteArray a) => Key c a -> IV c -> a -> Either CryptoError a
> encrypt privKey msg = > encrypt secretKey initIV msg =
> case initCipher privKey of > case initCipher secretKey of
> Left e -> Left e > Left e -> Left e
> Right c -> Right $ ctrCombine c nullIV msg > Right c -> Right $ ctrCombine c initIV msg
> >
> decrypt :: (BlockCipher c, ByteArray a) => Key c a -> a -> Either CryptoError a > decrypt :: (BlockCipher c, ByteArray a) => Key c a -> IV c -> a -> Either CryptoError a
> decrypt = encrypt > decrypt = encrypt
> >
> exampleAES256 :: ByteString -> IO () > exampleAES256 :: ByteString -> IO ()
> exampleAES256 msg = do > exampleAES256 msg = do
> privKey <- genPrivateKey (undefined :: AES256) > -- secret key needs 256 bits (32 * 8)
> let eMsg = encrypt privKey msg >>= decrypt privKey > secretKey <- genSecretKey (undefined :: AES256) 32
> case eMsg of > mInitIV <- genRandomIV (undefined :: AES256)
> Left err -> error $ show err > case mInitIV of
> Right msg' -> do > Nothing -> error "Failed to generate and initialization vector."
> putStrLn $ "Original Message: " ++ show msg > Just initIV -> do
> putStrLn $ "Message after encryption & decryption: " ++ show msg' > let encryptedMsg = encrypt secretKey initIV msg
> > decryptedMsg = decrypt secretKey initIV =<< encryptedMsg
> -- | More Examples... ? > case (,) <$> encryptedMsg <*> decryptedMsg of
> Left err -> error $ show err
> Right (eMsg, dMsg) -> do
> putStrLn $ "Original Message: " ++ show msg
> putStrLn $ "Message after encryption: " ++ show eMsg
> putStrLn $ "Message after decryption: " ++ show dMsg
|-} |-}