module Crypto.Store.Cipher.RC2
( RC2
, rc2WithEffectiveKeyLength
) where
import Data.ByteArray (ByteArrayAccess)
import qualified Data.ByteArray as B
import Data.Maybe (fromMaybe)
import Crypto.Error
import Crypto.Cipher.Types
import Crypto.Store.Cipher.RC2.Primitive
import Crypto.Store.Util
newtype RC2 = RC2 Key
instance Cipher RC2 where
cipherName :: RC2 -> String
cipherName RC2
_ = String
"RC2"
cipherKeySize :: RC2 -> KeySizeSpecifier
cipherKeySize RC2
_ = Int -> Int -> KeySizeSpecifier
KeySizeRange Int
1 Int
128
cipherInit :: forall key. ByteArray key => key -> CryptoFailable RC2
cipherInit = (Key -> RC2) -> CryptoFailable Key -> CryptoFailable RC2
forall a b. (a -> b) -> CryptoFailable a -> CryptoFailable b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Key -> RC2
RC2 (CryptoFailable Key -> CryptoFailable RC2)
-> (key -> CryptoFailable Key) -> key -> CryptoFailable RC2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Int -> key -> CryptoFailable Key
forall key.
ByteArrayAccess key =>
Maybe Int -> key -> CryptoFailable Key
initRC2 Maybe Int
forall a. Maybe a
Nothing
instance BlockCipher RC2 where
blockSize :: RC2 -> Int
blockSize RC2
_ = Int
8
ecbEncrypt :: forall ba. ByteArray ba => RC2 -> ba -> ba
ecbEncrypt (RC2 Key
k) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
mapAsWord64LE (Key -> Word64 -> Word64
encrypt Key
k)
ecbDecrypt :: forall ba. ByteArray ba => RC2 -> ba -> ba
ecbDecrypt (RC2 Key
k) = (Word64 -> Word64) -> ba -> ba
forall bs. ByteArray bs => (Word64 -> Word64) -> bs -> bs
mapAsWord64LE (Key -> Word64 -> Word64
decrypt Key
k)
rc2WithEffectiveKeyLength :: ByteArrayAccess key
=> Int -> key -> CryptoFailable RC2
rc2WithEffectiveKeyLength :: forall key. ByteArrayAccess key => Int -> key -> CryptoFailable RC2
rc2WithEffectiveKeyLength Int
bits key
key
| Int
bits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1 = CryptoError -> CryptoFailable RC2
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
| Int
bits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1024 = CryptoError -> CryptoFailable RC2
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
| Bool
otherwise = Key -> RC2
RC2 (Key -> RC2) -> CryptoFailable Key -> CryptoFailable RC2
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int -> key -> CryptoFailable Key
forall key.
ByteArrayAccess key =>
Maybe Int -> key -> CryptoFailable Key
initRC2 (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
bits) key
key
initRC2 :: ByteArrayAccess key => Maybe Int -> key -> CryptoFailable Key
initRC2 :: forall key.
ByteArrayAccess key =>
Maybe Int -> key -> CryptoFailable Key
initRC2 Maybe Int
mbits key
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
1 = CryptoError -> CryptoFailable Key
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
128 = Key -> CryptoFailable Key
forall a. a -> CryptoFailable a
CryptoPassed (Int -> key -> Key
forall key. ByteArrayAccess key => Int -> key -> Key
buildKey Int
t1 key
bs)
| Bool
otherwise = CryptoError -> CryptoFailable Key
forall a. CryptoError -> CryptoFailable a
CryptoFailed CryptoError
CryptoError_KeySizeInvalid
where len :: Int
len = key -> Int
forall ba. ByteArrayAccess ba => ba -> Int
B.length key
bs
t1 :: Int
t1 = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (Int
8 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
len) Maybe Int
mbits