From a90b1f609d8a559694ad31ea0b28ec6309a8b661 Mon Sep 17 00:00:00 2001 From: joe Date: Fri, 26 Aug 2016 02:40:02 -0400 Subject: Drop dependency on Thamas's crypto-api package. --- Crypto/Cipher/Cast5.hs | 50 ++++++++++++++++++++++---------------- Crypto/Cipher/ThomasToVincent.hs | 52 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 77 insertions(+), 25 deletions(-) (limited to 'Crypto') diff --git a/Crypto/Cipher/Cast5.hs b/Crypto/Cipher/Cast5.hs index fb5db20..dfd30c7 100644 --- a/Crypto/Cipher/Cast5.hs +++ b/Crypto/Cipher/Cast5.hs @@ -14,7 +14,7 @@ import qualified Data.Vector.Unboxed as Vector import Data.Vector.Unboxed (Vector, (//)) import Data.Word import Data.Tuple -import Crypto.Classes +-- import Crypto.Classes -- Thomas' crypto-api incompatible with Vincent's crypto-random. import Data.Serialize import qualified Data.ByteString as S import Data.Tagged (Tagged(..)) @@ -81,25 +81,32 @@ instance Cast5Bits size => Serialize (Cast5 size) where let Just key = buildKey bs return key -instance Cast5Bits size => BlockCipher (Cast5 size) where - blockSize = Tagged 64 - encryptBlock (Cast5 subkeys fs _ _ key) = - fromW32Pair . coreCrypto nrounds subkeys fs . toW32Pair - where - nrounds = numberOfRounds (cast5bits (undefined::size)) - decryptBlock (Cast5 _ _ subkeys fs key) = - fromW32Pair . coreCrypto nrounds subkeys fs . toW32Pair - where - nrounds = numberOfRounds (cast5bits (undefined::size)) - buildKey bs = Just (Cast5 subs fs subs' fs' key) - where - nrounds = numberOfRounds (cast5bits (undefined::size)) - key = initKey bs - fs = cycle [f1,f2,f3] - subs = subkeys key - fs' = drop (3 - (nrounds `rem` 3)) $ cycle [f3,f2,f1] - subs' = (reverse . take nrounds $ subs) - keyLength = Tagged (cast5bits (undefined::size)) +-- instance Cast5Bits size => BlockCipher (Cast5 size) where +blockSize :: forall size. Cast5Bits size => Tagged (Cast5 size) Int +blockSize = Tagged 64 + +encryptBlock :: forall size. Cast5Bits size => Cast5 size -> S.ByteString -> S.ByteString +encryptBlock (Cast5 subkeys fs _ _ key) = + fromW32Pair . coreCrypto nrounds subkeys fs . toW32Pair + where + nrounds = numberOfRounds (cast5bits (undefined::size)) +decryptBlock :: forall size. Cast5Bits size => Cast5 size -> S.ByteString -> S.ByteString +decryptBlock (Cast5 _ _ subkeys fs key) = + fromW32Pair . coreCrypto nrounds subkeys fs . toW32Pair + where + nrounds = numberOfRounds (cast5bits (undefined::size)) +buildKey :: forall size. Cast5Bits size => S.ByteString -> Maybe (Cast5 size) +buildKey bs = Just (Cast5 subs fs subs' fs' key) + where + nrounds = numberOfRounds (cast5bits (undefined::size)) + key = initKey bs + fs = cycle [f1,f2,f3] + subs = subkeys key + fs' = drop (3 - (nrounds `rem` 3)) $ cycle [f3,f2,f1] + subs' = (reverse . take nrounds $ subs) + +keyLength :: forall size. Cast5Bits size => Tagged (Cast5 size) Int +keyLength = Tagged (cast5bits (undefined::size)) {-# INLINE (^) #-} @@ -544,6 +551,8 @@ hasSize :: Cast5 size -> size -> a hasSize _ _ = undefined +{- + data StaticTest size = StaticTest { keysize :: size, keybytes :: S.ByteString, @@ -673,3 +682,4 @@ main = do , "expected b = " ++ show (S.unpack expected_b) , "computed b = " ++ show (S.unpack result_b) ] return () +-} diff --git a/Crypto/Cipher/ThomasToVincent.hs b/Crypto/Cipher/ThomasToVincent.hs index 11cede3..5a68cf3 100644 --- a/Crypto/Cipher/ThomasToVincent.hs +++ b/Crypto/Cipher/ThomasToVincent.hs @@ -2,16 +2,57 @@ {-# LANGUAGE ScopedTypeVariables #-} module Crypto.Cipher.ThomasToVincent where +import qualified Data.ByteString as S import Crypto.Cipher.Types +import Crypto.Cipher.Cast5 import Data.Byteable import Data.Tagged +{- import qualified Crypto.Classes as Thomas -#if ! MIN_VERSION_crypto_api(0,11,0) +if ! MIN_VERSION_crypto_api(0,11,0) import qualified Crypto.Modes as Thomas -#endif +endif +-} +type ThomasToVincent b = b + +instance Cast5Bits size => Cipher (Cast5 size) where + cipherName _ = "CAST-5" + cipherInit k = b + where Just b = buildKey (toBytes k) + cipherKeySize _ = KeySizeFixed (bitlen `div` 8) + where Tagged bitlen = keyLength :: Tagged (Cast5 size) Int + + +-- Break a bytestring into block size chunks. +chunkFor' :: (Cast5Bits size) => Cast5 size -> S.ByteString -> [S.ByteString] +chunkFor' k = go + where + blkSz = (Crypto.Cipher.Cast5.blockSize `for` k) `div` 8 + go bs | S.length bs < blkSz = [] + | otherwise = let (blk,rest) = S.splitAt blkSz bs in blk : go rest + +-- |Obtain a tagged value for a particular instantiated type. +for :: Tagged a b -> a -> b +for t _ = unTagged t + +instance Cast5Bits size => BlockCipher (Cast5 size) where + blockSize _ = bitlen `div` 8 + where Tagged bitlen = Crypto.Cipher.Cast5.blockSize :: Tagged (Cast5 size) Int + + -- modeEcb' :: BlockCipher k => k -> B.ByteString -> B.ByteString + ecbEncrypt k msg = + let chunks = chunkFor' k msg + in S.concat $ map (encryptBlock k) chunks + + ecbDecrypt k ct = + let chunks = chunkFor' k ct + in S.concat $ map (decryptBlock k) chunks + + +{- newtype ThomasToVincent b = ThomasToVincent b instance Thomas.BlockCipher b => Cipher (ThomasToVincent b) where @@ -24,12 +65,13 @@ instance Thomas.BlockCipher b => Cipher (ThomasToVincent b) where instance Thomas.BlockCipher b => BlockCipher (ThomasToVincent b) where blockSize _ = bitlen `div` 8 where Tagged bitlen = Thomas.blockSize :: Tagged b Int -#if ! MIN_VERSION_crypto_api(0,11,0) +if ! MIN_VERSION_crypto_api(0,11,0) ecbEncrypt (ThomasToVincent k) = Thomas.ecb' k ecbDecrypt (ThomasToVincent k) = Thomas.unEcb' k -#else +else ecbEncrypt (ThomasToVincent k) = Thomas.ecb k ecbDecrypt (ThomasToVincent k) = Thomas.unEcb k -#endif +endif +-} -- cgit v1.2.3