start cleaning up Camellia

This commit is contained in:
Vincent Hanquez 2015-04-09 07:41:15 +01:00
parent cf47754776
commit d96d89e4ba
5 changed files with 50 additions and 43 deletions

View File

@ -24,5 +24,5 @@ instance Cipher Camellia128 where
instance BlockCipher Camellia128 where
blockSize _ = 16
ecbEncrypt (Camellia128 key) = ecbEncryptLegacy encrypt key
ecbDecrypt (Camellia128 key) = ecbDecryptLegacy decrypt key
ecbEncrypt (Camellia128 key) = encrypt key
ecbDecrypt (Camellia128 key) = decrypt key

View File

@ -1,3 +1,4 @@
-- |
-- Module : Crypto.Cipher.Camellia.Primitive
-- License : BSD-style
@ -23,12 +24,10 @@ import qualified Data.ByteString.Unsafe as B
import Crypto.Error
import Crypto.Internal.ByteArray
import Crypto.Internal.Words
data Mode = Decrypt | Encrypt
-- should probably use crypto large word ?
data Word128 = Word128 !Word64 !Word64 deriving (Show, Eq)
w128tow64 :: Word128 -> (Word64, Word64)
w128tow64 (Word128 w1 w2) = (w1, w2)
@ -66,23 +65,6 @@ w64tow32 w = (fromIntegral (w `shiftR` 32), fromIntegral (w .&. 0xffffffff))
w32tow64 :: (Word32, Word32) -> Word64
w32tow64 (x1, x2) = ((fromIntegral x1) `shiftL` 32) .|. (fromIntegral x2)
w128tow8 :: Word128 -> [Word8]
w128tow8 (Word128 x1 x2) = [t1,t2,t3,t4,t5,t6,t7,t8,u1,u2,u3,u4,u5,u6,u7,u8]
where
(t1, t2, t3, t4, t5, t6, t7, t8) = w64tow8 x1
(u1, u2, u3, u4, u5, u6, u7, u8) = w64tow8 x2
getWord64 :: B.ByteString -> Word64
getWord64 s = sh 0 56 .|. sh 1 48 .|. sh 2 40 .|. sh 3 32 .|. sh 4 24 .|. sh 5 16 .|. sh 6 8 .|. sh 7 0
where
sh i l = (fromIntegral (s `B.index` i) `shiftL` l)
getWord128 :: B.ByteString -> Word128
getWord128 s = Word128 (getWord64 s) (getWord64 (B.drop 8 s))
putWord128 :: Word128 -> B.ByteString
putWord128 = B.pack . w128tow8
sbox :: Vector Word8
sbox = fromList
[112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65
@ -299,27 +281,16 @@ encryptBlock = doBlock Encrypt
decryptBlock :: Camellia -> Word128 -> Word128
decryptBlock = doBlock Decrypt
encryptChunk :: Camellia -> B.ByteString -> B.ByteString
encryptChunk key b = putWord128 $ encryptBlock key $ getWord128 b
decryptChunk :: Camellia -> B.ByteString -> B.ByteString
decryptChunk key b = putWord128 $ decryptBlock key $ getWord128 b
doChunks :: (B.ByteString -> B.ByteString) -> B.ByteString -> [B.ByteString]
doChunks f b =
let (x, rest) = B.splitAt 16 b in
if B.length rest >= 16
then f x : doChunks f rest
else [ f x ]
-- | Encrypts the given ByteString using the given Key
encrypt :: Camellia -- ^ The key to use
-> B.ByteString -- ^ The data to encrypt
-> B.ByteString
encrypt key b = B.concat $ doChunks (encryptChunk key) b
encrypt :: ByteArray ba
=> Camellia -- ^ The key to use
-> ba -- ^ The data to encrypt
-> ba
encrypt key = byteArrayMapAsWord128 (encryptBlock key)
-- | Decrypts the given ByteString using the given Key
decrypt :: Camellia -- ^ The key to use
-> B.ByteString -- ^ The data to decrypt
-> B.ByteString
decrypt key b = B.concat $ doChunks (decryptChunk key) b
decrypt :: ByteArray ba
=> Camellia -- ^ The key to use
-> ba -- ^ The data to decrypt
-> ba
decrypt key = byteArrayMapAsWord128 (decryptBlock key)

View File

@ -25,6 +25,7 @@ module Crypto.Internal.ByteArray
, byteArrayFromBS
, byteArrayToW64BE
, byteArrayToW64LE
, byteArrayMapAsWord128
) where
import Control.Applicative ((<$>), (<*>))
@ -34,6 +35,7 @@ import Crypto.Internal.Memory
import Crypto.Internal.Compat
import Crypto.Internal.Endian
import Crypto.Internal.Bytes (bufXor, bufCopy)
import Crypto.Internal.Words
import Foreign.Ptr
import Foreign.Storable
import Foreign.ForeignPtr
@ -180,3 +182,19 @@ byteArrayToW64BE bs ofs = unsafeDoIO $ withByteArray bs $ \p -> fromBE64 <$> pee
byteArrayToW64LE :: ByteArrayAccess bs => bs -> Int -> Word64
byteArrayToW64LE bs ofs = unsafeDoIO $ withByteArray bs $ \p -> fromLE64 <$> peek (p `plusPtr` ofs)
byteArrayMapAsWord128 :: ByteArray bs => (Word128 -> Word128) -> bs -> bs
byteArrayMapAsWord128 f bs =
byteArrayAllocAndFreeze len $ \dst ->
withByteArray bs $ \src ->
loop (len `div` 16) dst src
where
len = byteArrayLength bs
loop 0 _ _ = return ()
loop i d s = do
w1 <- peek s
w2 <- peek (s `plusPtr` 8)
let (Word128 r1 r2) = f (Word128 (fromBE64 w1) (fromBE64 w2))
poke d (toBE64 r1)
poke (d `plusPtr` 8) (toBE64 r2)
loop (i-1) (d `plusPtr` 16) (s `plusPtr` 16)

17
Crypto/Internal/Words.hs Normal file
View File

@ -0,0 +1,17 @@
-- |
-- Module : Crypto.Internal.Words
-- License : BSD-style
-- Maintainer : Vincent Hanquez <vincent@snarc.org>
-- Stability : experimental
-- Portability : unknown
--
-- Extra Word size
--
module Crypto.Internal.Words
( Word128(..)
) where
import Data.Word
-- should probably use crypto large word ?
data Word128 = Word128 !Word64 !Word64 deriving (Show, Eq)

View File

@ -130,6 +130,7 @@ Library
Crypto.Internal.Endian
Crypto.Internal.Imports
Crypto.Internal.Memory
Crypto.Internal.Words
Build-depends: base >= 4.3 && < 5
, bytestring
, securemem >= 0.1.7