cryptocipher 0.2.12 → 0.2.13
raw patch · 9 files changed
+1218/−1046 lines, 9 filesdep +ghc-primdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: ghc-prim
Dependency ranges changed: base
API changes (from Hackage documentation)
Files
- Crypto/Cipher/AES.hs +1014/−1006
- Number/Basic.hs +7/−0
- Number/Generate.hs +8/−6
- Number/ModArithmetic.hs +7/−0
- Number/Polynomial.hs +122/−0
- Number/Prime.hs +20/−33
- Number/Serialize.hs +7/−0
- System/Endian.hs +17/−0
- cryptocipher.cabal +16/−1
Crypto/Cipher/AES.hs view
@@ -1,1006 +1,1014 @@--- |--- Module : Crypto.Cipher.AES--- License : BSD-style--- Maintainer : Vincent Hanquez <vincent@snarc.org>--- Stability : experimental--- Portability : Good--module Crypto.Cipher.AES- ( Key- , IV- -- * Basic encryption and decryption- , encrypt- , decrypt- -- * CBC encryption and decryption- , encryptCBC- , decryptCBC- -- * key building mechanism- , initKey128- , initKey192- , initKey256- -- * Wrappers for "crypto-api" instances- , AES128- , AES192- , AES256- ) where--import Data.Word-import Data.Vector.Unboxed (Vector)-import qualified Data.Vector.Unboxed as V-import Data.Bits-import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import qualified Data.ByteString.Unsafe as B-import qualified Data.ByteString.Internal as B--import Foreign.Ptr-import Foreign.Storable--import Data.Tagged (Tagged(..))-import Crypto.Classes (BlockCipher(..))-import Data.Serialize (Serialize(..), getByteString, putByteString)--import Control.Monad (forM_)-import Control.Monad.Primitive--import Data.Primitive.ByteArray--newtype AES128 = A128 { unA128 :: Key }-newtype AES192 = A192 { unA192 :: Key }-newtype AES256 = A256 { unA256 :: Key }--instance BlockCipher AES128 where- blockSize = Tagged 128- encryptBlock = encrypt . unA128- decryptBlock = decrypt . unA128- buildKey b = either (const Nothing) (Just . A128) $ initKey128 b- keyLength = Tagged 128--instance BlockCipher AES192 where- blockSize = Tagged 128- encryptBlock = encrypt . unA192- decryptBlock = decrypt . unA192- buildKey b = either (const Nothing) (Just . A192) $ initKey192 b- keyLength = Tagged 192--instance BlockCipher AES256 where- blockSize = Tagged 128- encryptBlock = encrypt . unA256- decryptBlock = decrypt . unA256- buildKey b = either (const Nothing) (Just . A256) $ initKey256 b- keyLength = Tagged 256--serializeKey :: Key -> ByteString-serializeKey (Key v)- | V.length v == 176 = B.pack $ map (V.unsafeIndex v) [0..15]- | V.length v == 208 = B.pack $ map (V.unsafeIndex v) [0..23]- | otherwise = B.pack $ map (V.unsafeIndex v) [0..31]--instance Serialize AES128 where- put = putByteString . serializeKey . unA128- get = do- raw <- getByteString (128 `div` 8)- case buildKey raw of- Nothing -> fail "Invalid raw key material."- Just k -> return k--instance Serialize AES192 where- put = putByteString . serializeKey . unA192- get = do- raw <- getByteString (192 `div` 8)- case buildKey raw of- Nothing -> fail "Invalid raw key material."- Just k -> return k--instance Serialize AES256 where- put = putByteString . serializeKey . unA256- get = do- raw <- getByteString (256 `div` 8)- case buildKey raw of- Nothing -> fail "Invalid raw key material."- Just k -> return k--data Key = Key (Vector Word8)- deriving (Show,Eq)--type IV = B.ByteString--type AESState = MutableByteArray RealWorld--{- | encrypt using CBC mode- - IV need to be 16 bytes and the data to encrypt a multiple of 16 bytes -}-encryptCBC :: Key -> IV -> B.ByteString -> B.ByteString-encryptCBC key iv b- | B.length iv /= 16 = error "invalid IV length"- | B.length b `mod` 16 /= 0 = error "invalid data length"- | otherwise = B.concat $ encryptIter iv (makeChunks b)- where- encryptIter _ [] = []- encryptIter iv' (x:xs) =- let r = coreEncrypt key $ B.pack $ B.zipWith xor iv' x in- r : encryptIter r xs--{- | encrypt using simple EBC mode -}-encrypt :: Key -> B.ByteString -> B.ByteString-encrypt key b- | B.length b `mod` 16 /= 0 = error "invalid data length"- | otherwise = B.concat $ doChunks (coreEncrypt key) b--{- | decrypt using CBC mode- - IV need to be 16 bytes and the data to decrypt a multiple of 16 bytes -}-decryptCBC :: Key -> IV -> B.ByteString -> B.ByteString-decryptCBC key iv b- | B.length iv /= 16 = error "invalid IV length"- | B.length b `mod` 16 /= 0 = error "invalid data length"- | otherwise = B.concat $ decryptIter iv (makeChunks b)- where- decryptIter _ [] = []- decryptIter iv' (x:xs) =- let r = B.pack $ B.zipWith xor iv' $ coreDecrypt key x in- r : decryptIter x xs--{- | decrypt using simple EBC mode -}-decrypt :: Key -> B.ByteString -> B.ByteString-decrypt key b- | B.length b `mod` 16 /= 0 = error "invalid data length"- | otherwise = B.concat $ doChunks (coreDecrypt key) 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 ]--makeChunks :: B.ByteString -> [B.ByteString]-makeChunks = doChunks id--newAESState :: IO AESState-newAESState = newAlignedPinnedByteArray 16 16--coreEncrypt :: Key -> ByteString -> ByteString-coreEncrypt key input = B.unsafeCreate (B.length input) $ \ptr -> do- st <- newAESState- swapBlock input st- aesMain (getNbr key) key st- swapBlockInv st ptr--coreDecrypt :: Key -> ByteString -> ByteString-coreDecrypt key input = B.unsafeCreate (B.length input) $ \ptr -> do- st <- newAESState- swapBlock input st- aesMainInv (getNbr key) key st- swapBlockInv st ptr--getNbr :: Key -> Int-getNbr (Key v)- | V.length v == 176 = 10- | V.length v == 208 = 12- | otherwise = 14--initKey128, initKey192, initKey256 :: ByteString -> Either String Key--initKey128 = initKey 16-initKey192 = initKey 24-initKey256 = initKey 32--initKey :: Int -> ByteString -> Either String Key-initKey sz b- | B.length b == sz = Right $ coreExpandKey (V.generate sz $ B.unsafeIndex b)- | otherwise = Left "wrong key size"--aesMain :: Int -> Key -> AESState -> IO ()-aesMain nbr key blk = do- addRoundKey key 0 blk- forM_ [1..nbr-1] $ \i -> do- shiftRows blk >> mixColumns blk >> addRoundKey key i blk- shiftRows blk >> addRoundKey key nbr blk--aesMainInv :: Int -> Key -> AESState -> IO ()-aesMainInv nbr key blk = do- addRoundKey key nbr blk- forM_ (reverse [1..nbr-1]) $ \i -> do- shiftRowsInv blk >> addRoundKey key i blk >> mixColumnsInv blk- shiftRowsInv blk >> addRoundKey key 0 blk--{-# INLINE swapIndex #-}-swapIndex :: Int -> Int-swapIndex 0 = 0-swapIndex 1 = 4-swapIndex 2 = 8-swapIndex 3 = 12-swapIndex 4 = 1-swapIndex 5 = 5-swapIndex 6 = 9-swapIndex 7 = 13-swapIndex 8 = 2-swapIndex 9 = 6-swapIndex 10 = 10-swapIndex 11 = 14-swapIndex 12 = 3-swapIndex 13 = 7-swapIndex 14 = 11-swapIndex 15 = 15-swapIndex _ = 0--coreExpandKey :: Vector Word8 -> Key-coreExpandKey vkey- | V.length vkey == 16 = Key (V.concat (ek0 : ekN16))- | V.length vkey == 24 = Key (V.concat (ek0 : ekN24))- | V.length vkey == 32 = Key (V.concat (ek0 : ekN32))- | otherwise = Key (V.empty)- where- ek0 = vkey- ekN16 = reverse $ snd $ foldl (generateFold generate16) (ek0, []) [1..10]-- ekN24 =- let (lk, acc) = foldl (generateFold generate24) (ek0, []) [1..7] in- let nk = generate16 lk 8 in- reverse (nk : acc)-- ekN32 =- let (lk, acc) = foldl (generateFold generate32) (ek0, []) [1..6] in- let nk = generate16 lk 7 in- reverse (nk : acc)-- generateFold gen (prevk, accK) it = let nk = gen prevk it in (nk, nk : accK)-- generate16 prevk it =- let len = V.length prevk in- let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)- (V.unsafeIndex prevk $ len - 3)- (V.unsafeIndex prevk $ len - 2)- (V.unsafeIndex prevk $ len - 1) in- let eg0@(e0,e1,e2,e3) = xorVector prevk 0 v0 in- let eg1@(e4,e5,e6,e7) = xorVector prevk 4 eg0 in- let eg2@(e8,e9,e10,e11) = xorVector prevk 8 eg1 in- let (e12,e13,e14,e15) = xorVector prevk 12 eg2 in- V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15]-- generate24 prevk it =- let len = V.length prevk in- let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)- (V.unsafeIndex prevk $ len - 3)- (V.unsafeIndex prevk $ len - 2)- (V.unsafeIndex prevk $ len - 1) in- let eg0@(e0,e1,e2,e3) = xorVector prevk 0 v0 in- let eg1@(e4,e5,e6,e7) = xorVector prevk 4 eg0 in- let eg2@(e8,e9,e10,e11) = xorVector prevk 8 eg1 in- let eg3@(e12,e13,e14,e15) = xorVector prevk 12 eg2 in- let eg4@(e16,e17,e18,e19) = xorVector prevk 16 eg3 in- let (e20,e21,e22,e23) = xorVector prevk 20 eg4 in- V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23]-- generate32 prevk it =- let len = V.length prevk in- let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)- (V.unsafeIndex prevk $ len - 3)- (V.unsafeIndex prevk $ len - 2)- (V.unsafeIndex prevk $ len - 1) in- let eg0@(e0,e1,e2,e3) = xorVector prevk 0 v0 in- let eg1@(e4,e5,e6,e7) = xorVector prevk 4 eg0 in- let eg2@(e8,e9,e10,e11) = xorVector prevk 8 eg1 in- let eg3@(e12,e13,e14,e15) = xorVector prevk 12 eg2 in- let eg4@(e16,e17,e18,e19) = xorSboxVector prevk 16 eg3 in- let eg5@(e20,e21,e22,e23) = xorVector prevk 20 eg4 in- let eg6@(e24,e25,e26,e27) = xorVector prevk 24 eg5 in- let (e28,e29,e30,e31) = xorVector prevk 28 eg6 in- V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16- ,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31]-- xorVector k i (t0,t1,t2,t3) =- ( V.unsafeIndex k (i+0) `xor` t0- , V.unsafeIndex k (i+1) `xor` t1- , V.unsafeIndex k (i+2) `xor` t2- , V.unsafeIndex k (i+3) `xor` t3- )-- xorSboxVector k i (t0,t1,t2,t3) =- ( V.unsafeIndex k (i+0) `xor` sbox t0- , V.unsafeIndex k (i+1) `xor` sbox t1- , V.unsafeIndex k (i+2) `xor` sbox t2- , V.unsafeIndex k (i+3) `xor` sbox t3- )-- cR0 it r0 r1 r2 r3 =- (sbox r1 `xor` mRcon it, sbox r2, sbox r3, sbox r0)--{-# INLINE shiftRows #-}-shiftRows :: AESState -> IO ()-shiftRows blk = do- r32 blk 0 >>= w32 blk 0 . msbox32- r32 blk 1 >>= \t1 -> w32 blk 1 $ rotateR (msbox32 t1) 8- r32 blk 2 >>= \t2 -> w32 blk 2 $ rotateR (msbox32 t2) 16- r32 blk 3 >>= \t3 -> w32 blk 3 $ rotateR (msbox32 t3) 24--{-# INLINE addRoundKey #-}-addRoundKey :: Key -> Int -> AESState -> IO ()-addRoundKey (Key key) i blk = forM_ [0..15] $ \n -> do- r8 blk n >>= \v1 -> w8 blk n $ v1 `xor` V.unsafeIndex key (16 * i + swapIndex n)--{-# INLINE mixColumns #-}-mixColumns :: AESState -> IO ()-mixColumns state = pr 0 >> pr 1 >> pr 2 >> pr 3- where- {-# INLINE pr #-}- pr i = do- cpy0 <- r8 state (0 * 4 + i)- cpy1 <- r8 state (1 * 4 + i)- cpy2 <- r8 state (2 * 4 + i)- cpy3 <- r8 state (3 * 4 + i)-- let state0 = gm2 cpy0 `xor` gm1 cpy3 `xor` gm1 cpy2 `xor` gm3 cpy1- let state4 = gm2 cpy1 `xor` gm1 cpy0 `xor` gm1 cpy3 `xor` gm3 cpy2- let state8 = gm2 cpy2 `xor` gm1 cpy1 `xor` gm1 cpy0 `xor` gm3 cpy3- let state12 = gm2 cpy3 `xor` gm1 cpy2 `xor` gm1 cpy1 `xor` gm3 cpy0-- w8 state (0 * 4 + i) state0- w8 state (1 * 4 + i) state4- w8 state (2 * 4 + i) state8- w8 state (3 * 4 + i) state12- {-# INLINE gm1 #-}- gm1 a = a- {-# INLINE gm2 #-}- gm2 a = V.unsafeIndex gmtab2 $ fromIntegral a- {-# INLINE gm3 #-}- gm3 a = V.unsafeIndex gmtab3 $ fromIntegral a--{-# INLINE shiftRowsInv #-}-shiftRowsInv :: AESState -> IO ()-shiftRowsInv blk = do- r32 blk 0 >>= w32 blk 0 . mrsbox32- r32 blk 1 >>= \t1 -> w32 blk 1 $ mrsbox32 $ rotateL t1 8- r32 blk 2 >>= \t2 -> w32 blk 2 $ mrsbox32 $ rotateL t2 16- r32 blk 3 >>= \t3 -> w32 blk 3 $ mrsbox32 $ rotateL t3 24--{-# INLINE mixColumnsInv #-}-mixColumnsInv :: AESState -> IO ()-mixColumnsInv state = pr 0 >> pr 1 >> pr 2 >> pr 3- where- {-# INLINE pr #-}- pr i = do- cpy0 <- r8 state (0 * 4 + i)- cpy1 <- r8 state (1 * 4 + i)- cpy2 <- r8 state (2 * 4 + i)- cpy3 <- r8 state (3 * 4 + i)-- let state0 = gm14 cpy0 `xor` gm9 cpy3 `xor` gm13 cpy2 `xor` gm11 cpy1- let state4 = gm14 cpy1 `xor` gm9 cpy0 `xor` gm13 cpy3 `xor` gm11 cpy2- let state8 = gm14 cpy2 `xor` gm9 cpy1 `xor` gm13 cpy0 `xor` gm11 cpy3- let state12 = gm14 cpy3 `xor` gm9 cpy2 `xor` gm13 cpy1 `xor` gm11 cpy0-- w8 state (0 * 4 + i) state0- w8 state (1 * 4 + i) state4- w8 state (2 * 4 + i) state8- w8 state (3 * 4 + i) state12-- {-# INLINE gm14 #-}- {-# INLINE gm13 #-}- {-# INLINE gm11 #-}- {-# INLINE gm9 #-}- gm14 a = V.unsafeIndex gmtab14 $ fromIntegral a- gm13 a = V.unsafeIndex gmtab13 $ fromIntegral a- gm11 a = V.unsafeIndex gmtab11 $ fromIntegral a- gm9 a = V.unsafeIndex gmtab9 $ fromIntegral a--{-# INLINE r8 #-}-r8 :: AESState -> Int -> IO Word8-r8 = readByteArray--{-# INLINE w8 #-}-w8 :: AESState -> Int -> Word8 -> IO ()-w8 = writeByteArray--{-# INLINE r32 #-}-r32 :: AESState -> Int -> IO Word32-r32 = readByteArray--{-# INLINE w32 #-}-w32 :: AESState -> Int -> Word32 -> IO ()-w32 = writeByteArray--msbox32 :: Word32 -> Word32-msbox32 w = sbox4 a .|. sbox3 b .|. sbox2 c .|. sbox1 d- where- a = fromIntegral (w `shiftR` 24)- b = fromIntegral (w `shiftR` 16)- c = fromIntegral (w `shiftR` 8)- d = fromIntegral w--mrsbox32 :: Word32 -> Word32-mrsbox32 w = fromIntegral (rsbox a) `shiftL` 24 .|.- fromIntegral (rsbox b) `shiftL` 16 .|.- fromIntegral (rsbox c) `shiftL` 8 .|.- fromIntegral (rsbox d)- where- a = fromIntegral (w `shiftR` 24)- b = fromIntegral (w `shiftR` 16)- c = fromIntegral (w `shiftR` 8)- d = fromIntegral w---{-# INLINE swapBlock #-}-swapBlock :: ByteString -> AESState -> IO ()-swapBlock b blk = do -- V.generate 16 (\i -> B.unsafeIndex b $ swapIndex i)- forM_ [0..15] $ \i -> w8 blk i $ B.unsafeIndex b $ swapIndex i--{-# INLINE swapBlockInv #-}-swapBlockInv :: AESState -> Ptr Word8 -> IO ()-swapBlockInv blk ptr = forM_ [0..15] $ \i -> r8 blk (swapIndex i) >>= pokeByteOff ptr i--{-# INLINE mRcon #-}-mRcon :: Int -> Word8-mRcon i = V.unsafeIndex rcon (i `mod` len)- where len = V.length rcon--{-# INLINE sbox #-}-sbox :: Word8 -> Word8-sbox = V.unsafeIndex tab . fromIntegral- where tab = V.fromList- [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5- , 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76- , 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0- , 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0- , 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc- , 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15- , 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a- , 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75- , 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0- , 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84- , 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b- , 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf- , 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85- , 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8- , 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5- , 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2- , 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17- , 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73- , 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88- , 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb- , 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c- , 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79- , 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9- , 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08- , 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6- , 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a- , 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e- , 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e- , 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94- , 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf- , 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68- , 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16- ]--sbox1, sbox2, sbox3, sbox4 :: Word8 -> Word32--sbox1 = V.unsafeIndex tab . fromIntegral- where tab = V.fromList- [ 0x00000063, 0x0000007c, 0x00000077, 0x0000007b- , 0x000000f2, 0x0000006b, 0x0000006f, 0x000000c5- , 0x00000030, 0x00000001, 0x00000067, 0x0000002b- , 0x000000fe, 0x000000d7, 0x000000ab, 0x00000076- , 0x000000ca, 0x00000082, 0x000000c9, 0x0000007d- , 0x000000fa, 0x00000059, 0x00000047, 0x000000f0- , 0x000000ad, 0x000000d4, 0x000000a2, 0x000000af- , 0x0000009c, 0x000000a4, 0x00000072, 0x000000c0- , 0x000000b7, 0x000000fd, 0x00000093, 0x00000026- , 0x00000036, 0x0000003f, 0x000000f7, 0x000000cc- , 0x00000034, 0x000000a5, 0x000000e5, 0x000000f1- , 0x00000071, 0x000000d8, 0x00000031, 0x00000015- , 0x00000004, 0x000000c7, 0x00000023, 0x000000c3- , 0x00000018, 0x00000096, 0x00000005, 0x0000009a- , 0x00000007, 0x00000012, 0x00000080, 0x000000e2- , 0x000000eb, 0x00000027, 0x000000b2, 0x00000075- , 0x00000009, 0x00000083, 0x0000002c, 0x0000001a- , 0x0000001b, 0x0000006e, 0x0000005a, 0x000000a0- , 0x00000052, 0x0000003b, 0x000000d6, 0x000000b3- , 0x00000029, 0x000000e3, 0x0000002f, 0x00000084- , 0x00000053, 0x000000d1, 0x00000000, 0x000000ed- , 0x00000020, 0x000000fc, 0x000000b1, 0x0000005b- , 0x0000006a, 0x000000cb, 0x000000be, 0x00000039- , 0x0000004a, 0x0000004c, 0x00000058, 0x000000cf- , 0x000000d0, 0x000000ef, 0x000000aa, 0x000000fb- , 0x00000043, 0x0000004d, 0x00000033, 0x00000085- , 0x00000045, 0x000000f9, 0x00000002, 0x0000007f- , 0x00000050, 0x0000003c, 0x0000009f, 0x000000a8- , 0x00000051, 0x000000a3, 0x00000040, 0x0000008f- , 0x00000092, 0x0000009d, 0x00000038, 0x000000f5- , 0x000000bc, 0x000000b6, 0x000000da, 0x00000021- , 0x00000010, 0x000000ff, 0x000000f3, 0x000000d2- , 0x000000cd, 0x0000000c, 0x00000013, 0x000000ec- , 0x0000005f, 0x00000097, 0x00000044, 0x00000017- , 0x000000c4, 0x000000a7, 0x0000007e, 0x0000003d- , 0x00000064, 0x0000005d, 0x00000019, 0x00000073- , 0x00000060, 0x00000081, 0x0000004f, 0x000000dc- , 0x00000022, 0x0000002a, 0x00000090, 0x00000088- , 0x00000046, 0x000000ee, 0x000000b8, 0x00000014- , 0x000000de, 0x0000005e, 0x0000000b, 0x000000db- , 0x000000e0, 0x00000032, 0x0000003a, 0x0000000a- , 0x00000049, 0x00000006, 0x00000024, 0x0000005c- , 0x000000c2, 0x000000d3, 0x000000ac, 0x00000062- , 0x00000091, 0x00000095, 0x000000e4, 0x00000079- , 0x000000e7, 0x000000c8, 0x00000037, 0x0000006d- , 0x0000008d, 0x000000d5, 0x0000004e, 0x000000a9- , 0x0000006c, 0x00000056, 0x000000f4, 0x000000ea- , 0x00000065, 0x0000007a, 0x000000ae, 0x00000008- , 0x000000ba, 0x00000078, 0x00000025, 0x0000002e- , 0x0000001c, 0x000000a6, 0x000000b4, 0x000000c6- , 0x000000e8, 0x000000dd, 0x00000074, 0x0000001f- , 0x0000004b, 0x000000bd, 0x0000008b, 0x0000008a- , 0x00000070, 0x0000003e, 0x000000b5, 0x00000066- , 0x00000048, 0x00000003, 0x000000f6, 0x0000000e- , 0x00000061, 0x00000035, 0x00000057, 0x000000b9- , 0x00000086, 0x000000c1, 0x0000001d, 0x0000009e- , 0x000000e1, 0x000000f8, 0x00000098, 0x00000011- , 0x00000069, 0x000000d9, 0x0000008e, 0x00000094- , 0x0000009b, 0x0000001e, 0x00000087, 0x000000e9- , 0x000000ce, 0x00000055, 0x00000028, 0x000000df- , 0x0000008c, 0x000000a1, 0x00000089, 0x0000000d- , 0x000000bf, 0x000000e6, 0x00000042, 0x00000068- , 0x00000041, 0x00000099, 0x0000002d, 0x0000000f- , 0x000000b0, 0x00000054, 0x000000bb, 0x00000016- ]--sbox2 = V.unsafeIndex tab . fromIntegral- where tab = V.fromList- [ 0x00006300, 0x00007c00, 0x00007700, 0x00007b00- , 0x0000f200, 0x00006b00, 0x00006f00, 0x0000c500- , 0x00003000, 0x00000100, 0x00006700, 0x00002b00- , 0x0000fe00, 0x0000d700, 0x0000ab00, 0x00007600- , 0x0000ca00, 0x00008200, 0x0000c900, 0x00007d00- , 0x0000fa00, 0x00005900, 0x00004700, 0x0000f000- , 0x0000ad00, 0x0000d400, 0x0000a200, 0x0000af00- , 0x00009c00, 0x0000a400, 0x00007200, 0x0000c000- , 0x0000b700, 0x0000fd00, 0x00009300, 0x00002600- , 0x00003600, 0x00003f00, 0x0000f700, 0x0000cc00- , 0x00003400, 0x0000a500, 0x0000e500, 0x0000f100- , 0x00007100, 0x0000d800, 0x00003100, 0x00001500- , 0x00000400, 0x0000c700, 0x00002300, 0x0000c300- , 0x00001800, 0x00009600, 0x00000500, 0x00009a00- , 0x00000700, 0x00001200, 0x00008000, 0x0000e200- , 0x0000eb00, 0x00002700, 0x0000b200, 0x00007500- , 0x00000900, 0x00008300, 0x00002c00, 0x00001a00- , 0x00001b00, 0x00006e00, 0x00005a00, 0x0000a000- , 0x00005200, 0x00003b00, 0x0000d600, 0x0000b300- , 0x00002900, 0x0000e300, 0x00002f00, 0x00008400- , 0x00005300, 0x0000d100, 0x00000000, 0x0000ed00- , 0x00002000, 0x0000fc00, 0x0000b100, 0x00005b00- , 0x00006a00, 0x0000cb00, 0x0000be00, 0x00003900- , 0x00004a00, 0x00004c00, 0x00005800, 0x0000cf00- , 0x0000d000, 0x0000ef00, 0x0000aa00, 0x0000fb00- , 0x00004300, 0x00004d00, 0x00003300, 0x00008500- , 0x00004500, 0x0000f900, 0x00000200, 0x00007f00- , 0x00005000, 0x00003c00, 0x00009f00, 0x0000a800- , 0x00005100, 0x0000a300, 0x00004000, 0x00008f00- , 0x00009200, 0x00009d00, 0x00003800, 0x0000f500- , 0x0000bc00, 0x0000b600, 0x0000da00, 0x00002100- , 0x00001000, 0x0000ff00, 0x0000f300, 0x0000d200- , 0x0000cd00, 0x00000c00, 0x00001300, 0x0000ec00- , 0x00005f00, 0x00009700, 0x00004400, 0x00001700- , 0x0000c400, 0x0000a700, 0x00007e00, 0x00003d00- , 0x00006400, 0x00005d00, 0x00001900, 0x00007300- , 0x00006000, 0x00008100, 0x00004f00, 0x0000dc00- , 0x00002200, 0x00002a00, 0x00009000, 0x00008800- , 0x00004600, 0x0000ee00, 0x0000b800, 0x00001400- , 0x0000de00, 0x00005e00, 0x00000b00, 0x0000db00- , 0x0000e000, 0x00003200, 0x00003a00, 0x00000a00- , 0x00004900, 0x00000600, 0x00002400, 0x00005c00- , 0x0000c200, 0x0000d300, 0x0000ac00, 0x00006200- , 0x00009100, 0x00009500, 0x0000e400, 0x00007900- , 0x0000e700, 0x0000c800, 0x00003700, 0x00006d00- , 0x00008d00, 0x0000d500, 0x00004e00, 0x0000a900- , 0x00006c00, 0x00005600, 0x0000f400, 0x0000ea00- , 0x00006500, 0x00007a00, 0x0000ae00, 0x00000800- , 0x0000ba00, 0x00007800, 0x00002500, 0x00002e00- , 0x00001c00, 0x0000a600, 0x0000b400, 0x0000c600- , 0x0000e800, 0x0000dd00, 0x00007400, 0x00001f00- , 0x00004b00, 0x0000bd00, 0x00008b00, 0x00008a00- , 0x00007000, 0x00003e00, 0x0000b500, 0x00006600- , 0x00004800, 0x00000300, 0x0000f600, 0x00000e00- , 0x00006100, 0x00003500, 0x00005700, 0x0000b900- , 0x00008600, 0x0000c100, 0x00001d00, 0x00009e00- , 0x0000e100, 0x0000f800, 0x00009800, 0x00001100- , 0x00006900, 0x0000d900, 0x00008e00, 0x00009400- , 0x00009b00, 0x00001e00, 0x00008700, 0x0000e900- , 0x0000ce00, 0x00005500, 0x00002800, 0x0000df00- , 0x00008c00, 0x0000a100, 0x00008900, 0x00000d00- , 0x0000bf00, 0x0000e600, 0x00004200, 0x00006800- , 0x00004100, 0x00009900, 0x00002d00, 0x00000f00- , 0x0000b000, 0x00005400, 0x0000bb00, 0x00001600- ]--sbox3 = V.unsafeIndex tab . fromIntegral- where tab = V.fromList- [ 0x00630000, 0x007c0000, 0x00770000, 0x007b0000- , 0x00f20000, 0x006b0000, 0x006f0000, 0x00c50000- , 0x00300000, 0x00010000, 0x00670000, 0x002b0000- , 0x00fe0000, 0x00d70000, 0x00ab0000, 0x00760000- , 0x00ca0000, 0x00820000, 0x00c90000, 0x007d0000- , 0x00fa0000, 0x00590000, 0x00470000, 0x00f00000- , 0x00ad0000, 0x00d40000, 0x00a20000, 0x00af0000- , 0x009c0000, 0x00a40000, 0x00720000, 0x00c00000- , 0x00b70000, 0x00fd0000, 0x00930000, 0x00260000- , 0x00360000, 0x003f0000, 0x00f70000, 0x00cc0000- , 0x00340000, 0x00a50000, 0x00e50000, 0x00f10000- , 0x00710000, 0x00d80000, 0x00310000, 0x00150000- , 0x00040000, 0x00c70000, 0x00230000, 0x00c30000- , 0x00180000, 0x00960000, 0x00050000, 0x009a0000- , 0x00070000, 0x00120000, 0x00800000, 0x00e20000- , 0x00eb0000, 0x00270000, 0x00b20000, 0x00750000- , 0x00090000, 0x00830000, 0x002c0000, 0x001a0000- , 0x001b0000, 0x006e0000, 0x005a0000, 0x00a00000- , 0x00520000, 0x003b0000, 0x00d60000, 0x00b30000- , 0x00290000, 0x00e30000, 0x002f0000, 0x00840000- , 0x00530000, 0x00d10000, 0x00000000, 0x00ed0000- , 0x00200000, 0x00fc0000, 0x00b10000, 0x005b0000- , 0x006a0000, 0x00cb0000, 0x00be0000, 0x00390000- , 0x004a0000, 0x004c0000, 0x00580000, 0x00cf0000- , 0x00d00000, 0x00ef0000, 0x00aa0000, 0x00fb0000- , 0x00430000, 0x004d0000, 0x00330000, 0x00850000- , 0x00450000, 0x00f90000, 0x00020000, 0x007f0000- , 0x00500000, 0x003c0000, 0x009f0000, 0x00a80000- , 0x00510000, 0x00a30000, 0x00400000, 0x008f0000- , 0x00920000, 0x009d0000, 0x00380000, 0x00f50000- , 0x00bc0000, 0x00b60000, 0x00da0000, 0x00210000- , 0x00100000, 0x00ff0000, 0x00f30000, 0x00d20000- , 0x00cd0000, 0x000c0000, 0x00130000, 0x00ec0000- , 0x005f0000, 0x00970000, 0x00440000, 0x00170000- , 0x00c40000, 0x00a70000, 0x007e0000, 0x003d0000- , 0x00640000, 0x005d0000, 0x00190000, 0x00730000- , 0x00600000, 0x00810000, 0x004f0000, 0x00dc0000- , 0x00220000, 0x002a0000, 0x00900000, 0x00880000- , 0x00460000, 0x00ee0000, 0x00b80000, 0x00140000- , 0x00de0000, 0x005e0000, 0x000b0000, 0x00db0000- , 0x00e00000, 0x00320000, 0x003a0000, 0x000a0000- , 0x00490000, 0x00060000, 0x00240000, 0x005c0000- , 0x00c20000, 0x00d30000, 0x00ac0000, 0x00620000- , 0x00910000, 0x00950000, 0x00e40000, 0x00790000- , 0x00e70000, 0x00c80000, 0x00370000, 0x006d0000- , 0x008d0000, 0x00d50000, 0x004e0000, 0x00a90000- , 0x006c0000, 0x00560000, 0x00f40000, 0x00ea0000- , 0x00650000, 0x007a0000, 0x00ae0000, 0x00080000- , 0x00ba0000, 0x00780000, 0x00250000, 0x002e0000- , 0x001c0000, 0x00a60000, 0x00b40000, 0x00c60000- , 0x00e80000, 0x00dd0000, 0x00740000, 0x001f0000- , 0x004b0000, 0x00bd0000, 0x008b0000, 0x008a0000- , 0x00700000, 0x003e0000, 0x00b50000, 0x00660000- , 0x00480000, 0x00030000, 0x00f60000, 0x000e0000- , 0x00610000, 0x00350000, 0x00570000, 0x00b90000- , 0x00860000, 0x00c10000, 0x001d0000, 0x009e0000- , 0x00e10000, 0x00f80000, 0x00980000, 0x00110000- , 0x00690000, 0x00d90000, 0x008e0000, 0x00940000- , 0x009b0000, 0x001e0000, 0x00870000, 0x00e90000- , 0x00ce0000, 0x00550000, 0x00280000, 0x00df0000- , 0x008c0000, 0x00a10000, 0x00890000, 0x000d0000- , 0x00bf0000, 0x00e60000, 0x00420000, 0x00680000- , 0x00410000, 0x00990000, 0x002d0000, 0x000f0000- , 0x00b00000, 0x00540000, 0x00bb0000, 0x00160000- ]--sbox4 = V.unsafeIndex tab . fromIntegral- where tab = V.fromList- [ 0x63000000, 0x7c000000, 0x77000000, 0x7b000000- , 0xf2000000, 0x6b000000, 0x6f000000, 0xc5000000- , 0x30000000, 0x01000000, 0x67000000, 0x2b000000- , 0xfe000000, 0xd7000000, 0xab000000, 0x76000000- , 0xca000000, 0x82000000, 0xc9000000, 0x7d000000- , 0xfa000000, 0x59000000, 0x47000000, 0xf0000000- , 0xad000000, 0xd4000000, 0xa2000000, 0xaf000000- , 0x9c000000, 0xa4000000, 0x72000000, 0xc0000000- , 0xb7000000, 0xfd000000, 0x93000000, 0x26000000- , 0x36000000, 0x3f000000, 0xf7000000, 0xcc000000- , 0x34000000, 0xa5000000, 0xe5000000, 0xf1000000- , 0x71000000, 0xd8000000, 0x31000000, 0x15000000- , 0x04000000, 0xc7000000, 0x23000000, 0xc3000000- , 0x18000000, 0x96000000, 0x05000000, 0x9a000000- , 0x07000000, 0x12000000, 0x80000000, 0xe2000000- , 0xeb000000, 0x27000000, 0xb2000000, 0x75000000- , 0x09000000, 0x83000000, 0x2c000000, 0x1a000000- , 0x1b000000, 0x6e000000, 0x5a000000, 0xa0000000- , 0x52000000, 0x3b000000, 0xd6000000, 0xb3000000- , 0x29000000, 0xe3000000, 0x2f000000, 0x84000000- , 0x53000000, 0xd1000000, 0x00000000, 0xed000000- , 0x20000000, 0xfc000000, 0xb1000000, 0x5b000000- , 0x6a000000, 0xcb000000, 0xbe000000, 0x39000000- , 0x4a000000, 0x4c000000, 0x58000000, 0xcf000000- , 0xd0000000, 0xef000000, 0xaa000000, 0xfb000000- , 0x43000000, 0x4d000000, 0x33000000, 0x85000000- , 0x45000000, 0xf9000000, 0x02000000, 0x7f000000- , 0x50000000, 0x3c000000, 0x9f000000, 0xa8000000- , 0x51000000, 0xa3000000, 0x40000000, 0x8f000000- , 0x92000000, 0x9d000000, 0x38000000, 0xf5000000- , 0xbc000000, 0xb6000000, 0xda000000, 0x21000000- , 0x10000000, 0xff000000, 0xf3000000, 0xd2000000- , 0xcd000000, 0x0c000000, 0x13000000, 0xec000000- , 0x5f000000, 0x97000000, 0x44000000, 0x17000000- , 0xc4000000, 0xa7000000, 0x7e000000, 0x3d000000- , 0x64000000, 0x5d000000, 0x19000000, 0x73000000- , 0x60000000, 0x81000000, 0x4f000000, 0xdc000000- , 0x22000000, 0x2a000000, 0x90000000, 0x88000000- , 0x46000000, 0xee000000, 0xb8000000, 0x14000000- , 0xde000000, 0x5e000000, 0x0b000000, 0xdb000000- , 0xe0000000, 0x32000000, 0x3a000000, 0x0a000000- , 0x49000000, 0x06000000, 0x24000000, 0x5c000000- , 0xc2000000, 0xd3000000, 0xac000000, 0x62000000- , 0x91000000, 0x95000000, 0xe4000000, 0x79000000- , 0xe7000000, 0xc8000000, 0x37000000, 0x6d000000- , 0x8d000000, 0xd5000000, 0x4e000000, 0xa9000000- , 0x6c000000, 0x56000000, 0xf4000000, 0xea000000- , 0x65000000, 0x7a000000, 0xae000000, 0x08000000- , 0xba000000, 0x78000000, 0x25000000, 0x2e000000- , 0x1c000000, 0xa6000000, 0xb4000000, 0xc6000000- , 0xe8000000, 0xdd000000, 0x74000000, 0x1f000000- , 0x4b000000, 0xbd000000, 0x8b000000, 0x8a000000- , 0x70000000, 0x3e000000, 0xb5000000, 0x66000000- , 0x48000000, 0x03000000, 0xf6000000, 0x0e000000- , 0x61000000, 0x35000000, 0x57000000, 0xb9000000- , 0x86000000, 0xc1000000, 0x1d000000, 0x9e000000- , 0xe1000000, 0xf8000000, 0x98000000, 0x11000000- , 0x69000000, 0xd9000000, 0x8e000000, 0x94000000- , 0x9b000000, 0x1e000000, 0x87000000, 0xe9000000- , 0xce000000, 0x55000000, 0x28000000, 0xdf000000- , 0x8c000000, 0xa1000000, 0x89000000, 0x0d000000- , 0xbf000000, 0xe6000000, 0x42000000, 0x68000000- , 0x41000000, 0x99000000, 0x2d000000, 0x0f000000- , 0xb0000000, 0x54000000, 0xbb000000, 0x16000000- ]--{-# INLINE rsbox #-}-rsbox :: Word8 -> Word8-rsbox = V.unsafeIndex tab . fromIntegral- where tab = V.fromList- [ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38- , 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb- , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87- , 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb- , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d- , 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e- , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2- , 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25- , 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16- , 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92- , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda- , 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84- , 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a- , 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06- , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02- , 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b- , 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea- , 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73- , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85- , 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e- , 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89- , 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b- , 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20- , 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4- , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31- , 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f- , 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d- , 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef- , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0- , 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61- , 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26- , 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d- ]--rcon :: Vector Word8-rcon = V.fromList- [ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40- , 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a- , 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a- , 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39- , 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25- , 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a- , 0x74, 0xe8, 0xcb- ]--gmtab2, gmtab3, gmtab9, gmtab11, gmtab13, gmtab14 :: Vector Word8-gmtab2 = V.fromList- [ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e- , 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e- , 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e- , 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e- , 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e- , 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e- , 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e- , 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e- , 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e- , 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e- , 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae- , 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe- , 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce- , 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde- , 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee- , 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe- , 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15- , 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05- , 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35- , 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25- , 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55- , 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45- , 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75- , 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65- , 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95- , 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85- , 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5- , 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5- , 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5- , 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5- , 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5- , 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5- ]--gmtab3 = V.fromList- [ 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09- , 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11- , 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39- , 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21- , 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69- , 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71- , 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59- , 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41- , 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9- , 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1- , 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9- , 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1- , 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9- , 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1- , 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99- , 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81- , 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92- , 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a- , 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2- , 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba- , 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2- , 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea- , 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2- , 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda- , 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52- , 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a- , 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62- , 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a- , 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32- , 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a- , 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02- , 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a- ]--gmtab9 = V.fromList- [ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f- , 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77- , 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf- , 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7- , 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04- , 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c- , 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94- , 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc- , 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49- , 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01- , 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9- , 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91- , 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72- , 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a- , 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2- , 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa- , 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3- , 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b- , 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43- , 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b- , 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8- , 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0- , 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78- , 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30- , 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5- , 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed- , 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35- , 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d- , 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e- , 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6- , 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e- , 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46- ]--gmtab11 = V.fromList- [ 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31- , 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69- , 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81- , 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9- , 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a- , 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12- , 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa- , 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2- , 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7- , 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f- , 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77- , 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f- , 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc- , 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4- , 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c- , 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54- , 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6- , 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e- , 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76- , 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e- , 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd- , 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5- , 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d- , 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55- , 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30- , 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68- , 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80- , 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8- , 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b- , 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13- , 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb- , 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3- ]--gmtab13 = V.fromList- [ 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23- , 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b- , 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3- , 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b- , 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98- , 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0- , 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48- , 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20- , 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e- , 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26- , 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e- , 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6- , 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5- , 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d- , 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25- , 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d- , 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9- , 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91- , 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29- , 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41- , 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42- , 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a- , 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92- , 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa- , 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94- , 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc- , 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44- , 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c- , 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f- , 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47- , 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff- , 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97- ]--gmtab14 = V.fromList- [ 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a- , 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a- , 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca- , 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba- , 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1- , 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81- , 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11- , 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61- , 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87- , 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7- , 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67- , 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17- , 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c- , 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c- , 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc- , 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc- , 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b- , 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b- , 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b- , 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb- , 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0- , 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0- , 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50- , 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20- , 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6- , 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6- , 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26- , 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56- , 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d- , 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d- , 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd- , 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d- ]+{-# LANGUAGE MagicHash #-}+-- |+-- Module : Crypto.Cipher.AES+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : Good++module Crypto.Cipher.AES+ ( Key+ , IV+ -- * Basic encryption and decryption+ , encrypt+ , decrypt+ -- * CBC encryption and decryption+ , encryptCBC+ , decryptCBC+ -- * key building mechanism+ , initKey128+ , initKey192+ , initKey256+ -- * Wrappers for "crypto-api" instances+ , AES128+ , AES192+ , AES256+ ) where++import Data.Word+import Data.Vector.Unboxed (Vector)+import qualified Data.Vector.Unboxed as V+import Data.Bits+import Data.ByteString (ByteString)+import qualified Data.ByteString as B+import qualified Data.ByteString.Unsafe as B+import qualified Data.ByteString.Internal as B++import GHC.Prim (indexWord8OffAddr#, indexWord32OffAddr#, word2Int#, Addr#, remInt#)+import GHC.Word+import GHC.Types++import Foreign.Ptr+import Foreign.Storable++import Data.Tagged (Tagged(..))+import Crypto.Classes (BlockCipher(..))+import Data.Serialize (Serialize(..), getByteString, putByteString)++import Control.Monad (forM_)+import Control.Monad.Primitive++import Data.Primitive.ByteArray++import System.Endian (littleEndian)++newtype AES128 = A128 { unA128 :: Key }+newtype AES192 = A192 { unA192 :: Key }+newtype AES256 = A256 { unA256 :: Key }++instance BlockCipher AES128 where+ blockSize = Tagged 128+ encryptBlock = encrypt . unA128+ decryptBlock = decrypt . unA128+ buildKey b = either (const Nothing) (Just . A128) $ initKey128 b+ keyLength = Tagged 128++instance BlockCipher AES192 where+ blockSize = Tagged 128+ encryptBlock = encrypt . unA192+ decryptBlock = decrypt . unA192+ buildKey b = either (const Nothing) (Just . A192) $ initKey192 b+ keyLength = Tagged 192++instance BlockCipher AES256 where+ blockSize = Tagged 128+ encryptBlock = encrypt . unA256+ decryptBlock = decrypt . unA256+ buildKey b = either (const Nothing) (Just . A256) $ initKey256 b+ keyLength = Tagged 256++serializeKey :: Key -> ByteString+serializeKey (Key v)+ | V.length v == 176 = B.pack $ map (V.unsafeIndex v) [0..15]+ | V.length v == 208 = B.pack $ map (V.unsafeIndex v) [0..23]+ | otherwise = B.pack $ map (V.unsafeIndex v) [0..31]++instance Serialize AES128 where+ put = putByteString . serializeKey . unA128+ get = do+ raw <- getByteString (128 `div` 8)+ case buildKey raw of+ Nothing -> fail "Invalid raw key material."+ Just k -> return k++instance Serialize AES192 where+ put = putByteString . serializeKey . unA192+ get = do+ raw <- getByteString (192 `div` 8)+ case buildKey raw of+ Nothing -> fail "Invalid raw key material."+ Just k -> return k++instance Serialize AES256 where+ put = putByteString . serializeKey . unA256+ get = do+ raw <- getByteString (256 `div` 8)+ case buildKey raw of+ Nothing -> fail "Invalid raw key material."+ Just k -> return k++data Key = Key (Vector Word8)+ deriving (Show,Eq)++type IV = B.ByteString++type AESState = MutableByteArray RealWorld++{- | encrypt using CBC mode+ - IV need to be 16 bytes and the data to encrypt a multiple of 16 bytes -}+encryptCBC :: Key -> IV -> B.ByteString -> B.ByteString+encryptCBC key iv b+ | B.length iv /= 16 = error "invalid IV length"+ | B.length b `mod` 16 /= 0 = error "invalid data length"+ | otherwise = B.concat $ encryptIter iv (makeChunks b)+ where+ encryptIter _ [] = []+ encryptIter iv' (x:xs) =+ let r = coreEncrypt key $ B.pack $ B.zipWith xor iv' x in+ r : encryptIter r xs++{- | encrypt using simple EBC mode -}+encrypt :: Key -> B.ByteString -> B.ByteString+encrypt key b+ | B.length b `mod` 16 /= 0 = error "invalid data length"+ | otherwise = B.concat $ doChunks (coreEncrypt key) b++{- | decrypt using CBC mode+ - IV need to be 16 bytes and the data to decrypt a multiple of 16 bytes -}+decryptCBC :: Key -> IV -> B.ByteString -> B.ByteString+decryptCBC key iv b+ | B.length iv /= 16 = error "invalid IV length"+ | B.length b `mod` 16 /= 0 = error "invalid data length"+ | otherwise = B.concat $ decryptIter iv (makeChunks b)+ where+ decryptIter _ [] = []+ decryptIter iv' (x:xs) =+ let r = B.pack $ B.zipWith xor iv' $ coreDecrypt key x in+ r : decryptIter x xs++{- | decrypt using simple EBC mode -}+decrypt :: Key -> B.ByteString -> B.ByteString+decrypt key b+ | B.length b `mod` 16 /= 0 = error "invalid data length"+ | otherwise = B.concat $ doChunks (coreDecrypt key) 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 ]++makeChunks :: B.ByteString -> [B.ByteString]+makeChunks = doChunks id++newAESState :: IO AESState+newAESState = newAlignedPinnedByteArray 16 16++coreEncrypt :: Key -> ByteString -> ByteString+coreEncrypt key input = B.unsafeCreate (B.length input) $ \ptr -> do+ st <- newAESState+ swapBlock input st+ aesMain (getNbr key) key st+ swapBlockInv st ptr++coreDecrypt :: Key -> ByteString -> ByteString+coreDecrypt key input = B.unsafeCreate (B.length input) $ \ptr -> do+ st <- newAESState+ swapBlock input st+ aesMainInv (getNbr key) key st+ swapBlockInv st ptr++getNbr :: Key -> Int+getNbr (Key v)+ | V.length v == 176 = 10+ | V.length v == 208 = 12+ | otherwise = 14++initKey128, initKey192, initKey256 :: ByteString -> Either String Key++initKey128 = initKey 16+initKey192 = initKey 24+initKey256 = initKey 32++initKey :: Int -> ByteString -> Either String Key+initKey sz b+ | B.length b == sz = Right $ coreExpandKey (V.generate sz $ B.unsafeIndex b)+ | otherwise = Left "wrong key size"++aesMain :: Int -> Key -> AESState -> IO ()+aesMain nbr key blk = do+ addRoundKey key 0 blk+ forM_ [1..nbr-1] $ \i -> do+ shiftRows blk >> mixColumns blk >> addRoundKey key i blk+ shiftRows blk >> addRoundKey key nbr blk++aesMainInv :: Int -> Key -> AESState -> IO ()+aesMainInv nbr key blk = do+ addRoundKey key nbr blk+ forM_ (reverse [1..nbr-1]) $ \i -> do+ shiftRowsInv blk >> addRoundKey key i blk >> mixColumnsInv blk+ shiftRowsInv blk >> addRoundKey key 0 blk++{-# INLINE swapIndex #-}+swapIndex :: Int -> Int+swapIndex 0 = 0+swapIndex 1 = 4+swapIndex 2 = 8+swapIndex 3 = 12+swapIndex 4 = 1+swapIndex 5 = 5+swapIndex 6 = 9+swapIndex 7 = 13+swapIndex 8 = 2+swapIndex 9 = 6+swapIndex 10 = 10+swapIndex 11 = 14+swapIndex 12 = 3+swapIndex 13 = 7+swapIndex 14 = 11+swapIndex 15 = 15+swapIndex _ = 0++coreExpandKey :: Vector Word8 -> Key+coreExpandKey vkey+ | V.length vkey == 16 = Key (V.concat (ek0 : ekN16))+ | V.length vkey == 24 = Key (V.concat (ek0 : ekN24))+ | V.length vkey == 32 = Key (V.concat (ek0 : ekN32))+ | otherwise = Key (V.empty)+ where+ ek0 = vkey+ ekN16 = reverse $ snd $ foldl (generateFold generate16) (ek0, []) [1..10]++ ekN24 =+ let (lk, acc) = foldl (generateFold generate24) (ek0, []) [1..7] in+ let nk = generate16 lk 8 in+ reverse (nk : acc)++ ekN32 =+ let (lk, acc) = foldl (generateFold generate32) (ek0, []) [1..6] in+ let nk = generate16 lk 7 in+ reverse (nk : acc)++ generateFold gen (prevk, accK) it = let nk = gen prevk it in (nk, nk : accK)++ generate16 prevk it =+ let len = V.length prevk in+ let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)+ (V.unsafeIndex prevk $ len - 3)+ (V.unsafeIndex prevk $ len - 2)+ (V.unsafeIndex prevk $ len - 1) in+ let eg0@(e0,e1,e2,e3) = xorVector prevk 0 v0 in+ let eg1@(e4,e5,e6,e7) = xorVector prevk 4 eg0 in+ let eg2@(e8,e9,e10,e11) = xorVector prevk 8 eg1 in+ let (e12,e13,e14,e15) = xorVector prevk 12 eg2 in+ V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15]++ generate24 prevk it =+ let len = V.length prevk in+ let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)+ (V.unsafeIndex prevk $ len - 3)+ (V.unsafeIndex prevk $ len - 2)+ (V.unsafeIndex prevk $ len - 1) in+ let eg0@(e0,e1,e2,e3) = xorVector prevk 0 v0 in+ let eg1@(e4,e5,e6,e7) = xorVector prevk 4 eg0 in+ let eg2@(e8,e9,e10,e11) = xorVector prevk 8 eg1 in+ let eg3@(e12,e13,e14,e15) = xorVector prevk 12 eg2 in+ let eg4@(e16,e17,e18,e19) = xorVector prevk 16 eg3 in+ let (e20,e21,e22,e23) = xorVector prevk 20 eg4 in+ V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16,e17,e18,e19,e20,e21,e22,e23]++ generate32 prevk it =+ let len = V.length prevk in+ let v0 = cR0 it (V.unsafeIndex prevk $ len - 4)+ (V.unsafeIndex prevk $ len - 3)+ (V.unsafeIndex prevk $ len - 2)+ (V.unsafeIndex prevk $ len - 1) in+ let eg0@(e0,e1,e2,e3) = xorVector prevk 0 v0 in+ let eg1@(e4,e5,e6,e7) = xorVector prevk 4 eg0 in+ let eg2@(e8,e9,e10,e11) = xorVector prevk 8 eg1 in+ let eg3@(e12,e13,e14,e15) = xorVector prevk 12 eg2 in+ let eg4@(e16,e17,e18,e19) = xorSboxVector prevk 16 eg3 in+ let eg5@(e20,e21,e22,e23) = xorVector prevk 20 eg4 in+ let eg6@(e24,e25,e26,e27) = xorVector prevk 24 eg5 in+ let (e28,e29,e30,e31) = xorVector prevk 28 eg6 in+ V.fromList [e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15,e16+ ,e17,e18,e19,e20,e21,e22,e23,e24,e25,e26,e27,e28,e29,e30,e31]++ xorVector k i (t0,t1,t2,t3) =+ ( V.unsafeIndex k (i+0) `xor` t0+ , V.unsafeIndex k (i+1) `xor` t1+ , V.unsafeIndex k (i+2) `xor` t2+ , V.unsafeIndex k (i+3) `xor` t3+ )++ xorSboxVector k i (t0,t1,t2,t3) =+ ( V.unsafeIndex k (i+0) `xor` sbox t0+ , V.unsafeIndex k (i+1) `xor` sbox t1+ , V.unsafeIndex k (i+2) `xor` sbox t2+ , V.unsafeIndex k (i+3) `xor` sbox t3+ )++ cR0 it r0 r1 r2 r3 =+ (sbox r1 `xor` rcon it, sbox r2, sbox r3, sbox r0)++{-# INLINE shiftRows #-}+shiftRows :: AESState -> IO ()+shiftRows blk = do+ r32 blk 0 >>= w32 blk 0 . msbox32+ r32 blk 1 >>= \t1 -> w32 blk 1 $ rotateR (msbox32 t1) 8+ r32 blk 2 >>= \t2 -> w32 blk 2 $ rotateR (msbox32 t2) 16+ r32 blk 3 >>= \t3 -> w32 blk 3 $ rotateR (msbox32 t3) 24++{-# INLINE addRoundKey #-}+addRoundKey :: Key -> Int -> AESState -> IO ()+addRoundKey (Key key) i blk = forM_ [0..15] $ \n -> do+ r8 blk n >>= \v1 -> w8 blk n $ v1 `xor` V.unsafeIndex key (16 * i + swapIndex n)++{-# INLINE mixColumns #-}+mixColumns :: AESState -> IO ()+mixColumns state = pr 0 >> pr 1 >> pr 2 >> pr 3+ where+ {-# INLINE pr #-}+ pr i = do+ cpy0 <- r8 state (0 * 4 + i)+ cpy1 <- r8 state (1 * 4 + i)+ cpy2 <- r8 state (2 * 4 + i)+ cpy3 <- r8 state (3 * 4 + i)++ let state0 = gm2 cpy0 `xor` gm1 cpy3 `xor` gm1 cpy2 `xor` gm3 cpy1+ let state4 = gm2 cpy1 `xor` gm1 cpy0 `xor` gm1 cpy3 `xor` gm3 cpy2+ let state8 = gm2 cpy2 `xor` gm1 cpy1 `xor` gm1 cpy0 `xor` gm3 cpy3+ let state12 = gm2 cpy3 `xor` gm1 cpy2 `xor` gm1 cpy1 `xor` gm3 cpy0++ w8 state (0 * 4 + i) state0+ w8 state (1 * 4 + i) state4+ w8 state (2 * 4 + i) state8+ w8 state (3 * 4 + i) state12+ {-# INLINE gm1 #-}+ gm1 a = a++{-# INLINE shiftRowsInv #-}+shiftRowsInv :: AESState -> IO ()+shiftRowsInv blk = do+ r32 blk 0 >>= w32 blk 0 . mrsbox32+ r32 blk 1 >>= \t1 -> w32 blk 1 $ mrsbox32 $ rotateL t1 8+ r32 blk 2 >>= \t2 -> w32 blk 2 $ mrsbox32 $ rotateL t2 16+ r32 blk 3 >>= \t3 -> w32 blk 3 $ mrsbox32 $ rotateL t3 24++{-# INLINE mixColumnsInv #-}+mixColumnsInv :: AESState -> IO ()+mixColumnsInv state = pr 0 >> pr 1 >> pr 2 >> pr 3+ where+ {-# INLINE pr #-}+ pr i = do+ cpy0 <- r8 state (0 * 4 + i)+ cpy1 <- r8 state (1 * 4 + i)+ cpy2 <- r8 state (2 * 4 + i)+ cpy3 <- r8 state (3 * 4 + i)++ let state0 = gm14 cpy0 `xor` gm9 cpy3 `xor` gm13 cpy2 `xor` gm11 cpy1+ let state4 = gm14 cpy1 `xor` gm9 cpy0 `xor` gm13 cpy3 `xor` gm11 cpy2+ let state8 = gm14 cpy2 `xor` gm9 cpy1 `xor` gm13 cpy0 `xor` gm11 cpy3+ let state12 = gm14 cpy3 `xor` gm9 cpy2 `xor` gm13 cpy1 `xor` gm11 cpy0++ w8 state (0 * 4 + i) state0+ w8 state (1 * 4 + i) state4+ w8 state (2 * 4 + i) state8+ w8 state (3 * 4 + i) state12++{-# INLINE r8 #-}+r8 :: AESState -> Int -> IO Word8+r8 = readByteArray++{-# INLINE w8 #-}+w8 :: AESState -> Int -> Word8 -> IO ()+w8 = writeByteArray++{-# INLINE r32 #-}+r32 :: AESState -> Int -> IO Word32+r32 = readByteArray++{-# INLINE w32 #-}+w32 :: AESState -> Int -> Word32 -> IO ()+w32 = writeByteArray++msbox32 :: Word32 -> Word32+msbox32 w = sbox4 a .|. sbox3 b .|. sbox2 c .|. sbox1 d+ where+ a = fromIntegral (w `shiftR` 24)+ b = fromIntegral (w `shiftR` 16)+ c = fromIntegral (w `shiftR` 8)+ d = fromIntegral w++mrsbox32 :: Word32 -> Word32+mrsbox32 w = fromIntegral (rsbox a) `shiftL` 24 .|.+ fromIntegral (rsbox b) `shiftL` 16 .|.+ fromIntegral (rsbox c) `shiftL` 8 .|.+ fromIntegral (rsbox d)+ where+ a = fromIntegral (w `shiftR` 24)+ b = fromIntegral (w `shiftR` 16)+ c = fromIntegral (w `shiftR` 8)+ d = fromIntegral w+++{-# INLINE swapBlock #-}+swapBlock :: ByteString -> AESState -> IO ()+swapBlock b blk = do -- V.generate 16 (\i -> B.unsafeIndex b $ swapIndex i)+ forM_ [0..15] $ \i -> w8 blk i $ B.unsafeIndex b $ swapIndex i++{-# INLINE swapBlockInv #-}+swapBlockInv :: AESState -> Ptr Word8 -> IO ()+swapBlockInv blk ptr = forM_ [0..15] $ \i -> r8 blk (swapIndex i) >>= pokeByteOff ptr i++{-# INLINE sbox #-}+sbox :: Word8 -> Word8+sbox (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x63\x7c\x77\x7b\xf2\x6b\x6f\xc5\+ \\x30\x01\x67\x2b\xfe\xd7\xab\x76\+ \\xca\x82\xc9\x7d\xfa\x59\x47\xf0\+ \\xad\xd4\xa2\xaf\x9c\xa4\x72\xc0\+ \\xb7\xfd\x93\x26\x36\x3f\xf7\xcc\+ \\x34\xa5\xe5\xf1\x71\xd8\x31\x15\+ \\x04\xc7\x23\xc3\x18\x96\x05\x9a\+ \\x07\x12\x80\xe2\xeb\x27\xb2\x75\+ \\x09\x83\x2c\x1a\x1b\x6e\x5a\xa0\+ \\x52\x3b\xd6\xb3\x29\xe3\x2f\x84\+ \\x53\xd1\x00\xed\x20\xfc\xb1\x5b\+ \\x6a\xcb\xbe\x39\x4a\x4c\x58\xcf\+ \\xd0\xef\xaa\xfb\x43\x4d\x33\x85\+ \\x45\xf9\x02\x7f\x50\x3c\x9f\xa8\+ \\x51\xa3\x40\x8f\x92\x9d\x38\xf5\+ \\xbc\xb6\xda\x21\x10\xff\xf3\xd2\+ \\xcd\x0c\x13\xec\x5f\x97\x44\x17\+ \\xc4\xa7\x7e\x3d\x64\x5d\x19\x73\+ \\x60\x81\x4f\xdc\x22\x2a\x90\x88\+ \\x46\xee\xb8\x14\xde\x5e\x0b\xdb\+ \\xe0\x32\x3a\x0a\x49\x06\x24\x5c\+ \\xc2\xd3\xac\x62\x91\x95\xe4\x79\+ \\xe7\xc8\x37\x6d\x8d\xd5\x4e\xa9\+ \\x6c\x56\xf4\xea\x65\x7a\xae\x08\+ \\xba\x78\x25\x2e\x1c\xa6\xb4\xc6\+ \\xe8\xdd\x74\x1f\x4b\xbd\x8b\x8a\+ \\x70\x3e\xb5\x66\x48\x03\xf6\x0e\+ \\x61\x35\x57\xb9\x86\xc1\x1d\x9e\+ \\xe1\xf8\x98\x11\x69\xd9\x8e\x94\+ \\x9b\x1e\x87\xe9\xce\x55\x28\xdf\+ \\x8c\xa1\x89\x0d\xbf\xe6\x42\x68\+ \\x41\x99\x2d\x0f\xb0\x54\xbb\x16"#++{-# INLINE sbox1 #-}+{-# INLINE sbox2 #-}+{-# INLINE sbox3 #-}+{-# INLINE sbox4 #-}+sbox1, sbox2, sbox3, sbox4 :: Word8 -> Word32+sbox1 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))+ where !(Table table) = sbox1Tab+sbox2 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))+ where !(Table table) = sbox2Tab+sbox3 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))+ where !(Table table) = sbox3Tab+sbox4 (W8# w) = W32# (indexWord32OffAddr# table (word2Int# w))+ where !(Table table) = sbox4Tab++sbox1Tab, sbox2Tab, sbox3Tab, sbox4Tab :: Table+sbox1Tab = if littleEndian then sbox_x000 else sbox_000x+sbox2Tab = if littleEndian then sbox_0x00 else sbox_00x0+sbox3Tab = if littleEndian then sbox_00x0 else sbox_0x00+sbox4Tab = if littleEndian then sbox_000x else sbox_x000++data Table = Table !Addr#++sbox_000x, sbox_00x0, sbox_0x00, sbox_x000 :: Table+sbox_000x = Table+ "\x00\x00\x00\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\+ \\x00\x00\x00\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\+ \\x00\x00\x00\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\+ \\x00\x00\x00\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\+ \\x00\x00\x00\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\+ \\x00\x00\x00\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\+ \\x00\x00\x00\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\+ \\x00\x00\x00\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\+ \\x00\x00\x00\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\+ \\x00\x00\x00\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\+ \\x00\x00\x00\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\+ \\x00\x00\x00\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\+ \\x00\x00\x00\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\+ \\x00\x00\x00\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\+ \\x00\x00\x00\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\+ \\x00\x00\x00\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\+ \\x00\x00\x00\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\+ \\x00\x00\x00\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\+ \\x00\x00\x00\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\+ \\x00\x00\x00\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\+ \\x00\x00\x00\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\+ \\x00\x00\x00\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\+ \\x00\x00\x00\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\+ \\x00\x00\x00\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\+ \\x00\x00\x00\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\+ \\x00\x00\x00\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\+ \\x00\x00\x00\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\+ \\x00\x00\x00\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\+ \\x00\x00\x00\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\+ \\x00\x00\x00\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\+ \\x00\x00\x00\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\+ \\x00\x00\x00\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\+ \\x00\x00\x00\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\+ \\x00\x00\x00\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\+ \\x00\x00\x00\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\+ \\x00\x00\x00\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\+ \\x00\x00\x00\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\+ \\x00\x00\x00\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\+ \\x00\x00\x00\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\+ \\x00\x00\x00\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\+ \\x00\x00\x00\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\+ \\x00\x00\x00\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\+ \\x00\x00\x00\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\+ \\x00\x00\x00\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\+ \\x00\x00\x00\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\+ \\x00\x00\x00\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\+ \\x00\x00\x00\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\+ \\x00\x00\x00\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\+ \\x00\x00\x00\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\+ \\x00\x00\x00\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\+ \\x00\x00\x00\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\+ \\x00\x00\x00\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\+ \\x00\x00\x00\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\+ \\x00\x00\x00\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\+ \\x00\x00\x00\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\+ \\x00\x00\x00\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\+ \\x00\x00\x00\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\+ \\x00\x00\x00\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\+ \\x00\x00\x00\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\+ \\x00\x00\x00\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\+ \\x00\x00\x00\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\+ \\x00\x00\x00\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\+ \\x00\x00\x00\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\+ \\x00\x00\x00\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16"#++sbox_00x0 = Table+ "\x00\x00\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\x00\+ \\x00\x00\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\x00\+ \\x00\x00\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\x00\+ \\x00\x00\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\x00\+ \\x00\x00\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\x00\+ \\x00\x00\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\x00\+ \\x00\x00\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\x00\+ \\x00\x00\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\x00\+ \\x00\x00\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\x00\+ \\x00\x00\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\x00\+ \\x00\x00\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\x00\+ \\x00\x00\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\x00\+ \\x00\x00\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\x00\+ \\x00\x00\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\x00\+ \\x00\x00\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\x00\+ \\x00\x00\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\x00\+ \\x00\x00\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\x00\+ \\x00\x00\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\x00\+ \\x00\x00\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\x00\+ \\x00\x00\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\x00\+ \\x00\x00\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\x00\+ \\x00\x00\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\x00\+ \\x00\x00\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\x00\+ \\x00\x00\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\x00\+ \\x00\x00\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\x00\+ \\x00\x00\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\x00\+ \\x00\x00\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\x00\+ \\x00\x00\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\x00\+ \\x00\x00\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\x00\+ \\x00\x00\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\x00\+ \\x00\x00\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\x00\+ \\x00\x00\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\x00\+ \\x00\x00\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\x00\+ \\x00\x00\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\x00\+ \\x00\x00\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\x00\+ \\x00\x00\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\x00\+ \\x00\x00\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\x00\+ \\x00\x00\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\x00\+ \\x00\x00\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\x00\+ \\x00\x00\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\x00\+ \\x00\x00\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\x00\+ \\x00\x00\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\x00\+ \\x00\x00\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\x00\+ \\x00\x00\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\x00\+ \\x00\x00\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\x00\+ \\x00\x00\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\x00\+ \\x00\x00\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\x00\+ \\x00\x00\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\x00\+ \\x00\x00\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\x00\+ \\x00\x00\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\x00\+ \\x00\x00\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\x00\+ \\x00\x00\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\x00\+ \\x00\x00\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\x00\+ \\x00\x00\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\+ \\x00\x00\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\x00\+ \\x00\x00\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\x00\+ \\x00\x00\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\x00\+ \\x00\x00\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\x00\+ \\x00\x00\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\x00\+ \\x00\x00\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\x00\+ \\x00\x00\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\x00\+ \\x00\x00\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\x00\+ \\x00\x00\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\x00\+ \\x00\x00\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16\x00"#++sbox_0x00 = Table+ "\x00\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\x00\x00\+ \\x00\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\x00\x00\+ \\x00\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\x00\x00\+ \\x00\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\x00\x00\+ \\x00\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\x00\x00\+ \\x00\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\x00\x00\+ \\x00\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\x00\x00\+ \\x00\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\x00\x00\+ \\x00\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\x00\x00\+ \\x00\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\x00\x00\+ \\x00\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\x00\x00\+ \\x00\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\x00\x00\+ \\x00\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\x00\x00\+ \\x00\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\x00\x00\+ \\x00\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\x00\x00\+ \\x00\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\x00\x00\+ \\x00\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\x00\x00\+ \\x00\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\x00\x00\+ \\x00\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\x00\x00\+ \\x00\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\x00\x00\+ \\x00\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\+ \\x00\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\x00\x00\+ \\x00\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\x00\x00\+ \\x00\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\x00\x00\+ \\x00\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\x00\x00\+ \\x00\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\x00\x00\+ \\x00\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\x00\x00\+ \\x00\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\x00\x00\+ \\x00\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\x00\x00\+ \\x00\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\x00\x00\+ \\x00\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\x00\x00\+ \\x00\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\x00\x00\+ \\x00\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\x00\x00\+ \\x00\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\x00\x00\+ \\x00\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\x00\x00\+ \\x00\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\x00\x00\+ \\x00\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\x00\x00\+ \\x00\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\x00\x00\+ \\x00\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\x00\x00\+ \\x00\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\x00\x00\+ \\x00\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\x00\x00\+ \\x00\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\x00\x00\+ \\x00\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\x00\x00\+ \\x00\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\x00\x00\+ \\x00\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\x00\x00\+ \\x00\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\x00\x00\+ \\x00\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\x00\x00\+ \\x00\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\x00\x00\+ \\x00\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\x00\x00\+ \\x00\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\x00\x00\+ \\x00\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\x00\x00\+ \\x00\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\x00\x00\+ \\x00\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\x00\x00\+ \\x00\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\x00\+ \\x00\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\x00\x00\+ \\x00\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\x00\x00\+ \\x00\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\+ \\x00\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\x00\x00\+ \\x00\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\x00\x00\+ \\x00\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\x00\x00\+ \\x00\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\x00\x00\+ \\x00\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\x00\x00\+ \\x00\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\x00\x00\+ \\x00\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16\x00\x00"#++sbox_x000 = Table+ "\x63\x00\x00\x00\x7c\x00\x00\x00\x77\x00\x00\x00\x7b\x00\x00\x00\+ \\xf2\x00\x00\x00\x6b\x00\x00\x00\x6f\x00\x00\x00\xc5\x00\x00\x00\+ \\x30\x00\x00\x00\x01\x00\x00\x00\x67\x00\x00\x00\x2b\x00\x00\x00\+ \\xfe\x00\x00\x00\xd7\x00\x00\x00\xab\x00\x00\x00\x76\x00\x00\x00\+ \\xca\x00\x00\x00\x82\x00\x00\x00\xc9\x00\x00\x00\x7d\x00\x00\x00\+ \\xfa\x00\x00\x00\x59\x00\x00\x00\x47\x00\x00\x00\xf0\x00\x00\x00\+ \\xad\x00\x00\x00\xd4\x00\x00\x00\xa2\x00\x00\x00\xaf\x00\x00\x00\+ \\x9c\x00\x00\x00\xa4\x00\x00\x00\x72\x00\x00\x00\xc0\x00\x00\x00\+ \\xb7\x00\x00\x00\xfd\x00\x00\x00\x93\x00\x00\x00\x26\x00\x00\x00\+ \\x36\x00\x00\x00\x3f\x00\x00\x00\xf7\x00\x00\x00\xcc\x00\x00\x00\+ \\x34\x00\x00\x00\xa5\x00\x00\x00\xe5\x00\x00\x00\xf1\x00\x00\x00\+ \\x71\x00\x00\x00\xd8\x00\x00\x00\x31\x00\x00\x00\x15\x00\x00\x00\+ \\x04\x00\x00\x00\xc7\x00\x00\x00\x23\x00\x00\x00\xc3\x00\x00\x00\+ \\x18\x00\x00\x00\x96\x00\x00\x00\x05\x00\x00\x00\x9a\x00\x00\x00\+ \\x07\x00\x00\x00\x12\x00\x00\x00\x80\x00\x00\x00\xe2\x00\x00\x00\+ \\xeb\x00\x00\x00\x27\x00\x00\x00\xb2\x00\x00\x00\x75\x00\x00\x00\+ \\x09\x00\x00\x00\x83\x00\x00\x00\x2c\x00\x00\x00\x1a\x00\x00\x00\+ \\x1b\x00\x00\x00\x6e\x00\x00\x00\x5a\x00\x00\x00\xa0\x00\x00\x00\+ \\x52\x00\x00\x00\x3b\x00\x00\x00\xd6\x00\x00\x00\xb3\x00\x00\x00\+ \\x29\x00\x00\x00\xe3\x00\x00\x00\x2f\x00\x00\x00\x84\x00\x00\x00\+ \\x53\x00\x00\x00\xd1\x00\x00\x00\x00\x00\x00\x00\xed\x00\x00\x00\+ \\x20\x00\x00\x00\xfc\x00\x00\x00\xb1\x00\x00\x00\x5b\x00\x00\x00\+ \\x6a\x00\x00\x00\xcb\x00\x00\x00\xbe\x00\x00\x00\x39\x00\x00\x00\+ \\x4a\x00\x00\x00\x4c\x00\x00\x00\x58\x00\x00\x00\xcf\x00\x00\x00\+ \\xd0\x00\x00\x00\xef\x00\x00\x00\xaa\x00\x00\x00\xfb\x00\x00\x00\+ \\x43\x00\x00\x00\x4d\x00\x00\x00\x33\x00\x00\x00\x85\x00\x00\x00\+ \\x45\x00\x00\x00\xf9\x00\x00\x00\x02\x00\x00\x00\x7f\x00\x00\x00\+ \\x50\x00\x00\x00\x3c\x00\x00\x00\x9f\x00\x00\x00\xa8\x00\x00\x00\+ \\x51\x00\x00\x00\xa3\x00\x00\x00\x40\x00\x00\x00\x8f\x00\x00\x00\+ \\x92\x00\x00\x00\x9d\x00\x00\x00\x38\x00\x00\x00\xf5\x00\x00\x00\+ \\xbc\x00\x00\x00\xb6\x00\x00\x00\xda\x00\x00\x00\x21\x00\x00\x00\+ \\x10\x00\x00\x00\xff\x00\x00\x00\xf3\x00\x00\x00\xd2\x00\x00\x00\+ \\xcd\x00\x00\x00\x0c\x00\x00\x00\x13\x00\x00\x00\xec\x00\x00\x00\+ \\x5f\x00\x00\x00\x97\x00\x00\x00\x44\x00\x00\x00\x17\x00\x00\x00\+ \\xc4\x00\x00\x00\xa7\x00\x00\x00\x7e\x00\x00\x00\x3d\x00\x00\x00\+ \\x64\x00\x00\x00\x5d\x00\x00\x00\x19\x00\x00\x00\x73\x00\x00\x00\+ \\x60\x00\x00\x00\x81\x00\x00\x00\x4f\x00\x00\x00\xdc\x00\x00\x00\+ \\x22\x00\x00\x00\x2a\x00\x00\x00\x90\x00\x00\x00\x88\x00\x00\x00\+ \\x46\x00\x00\x00\xee\x00\x00\x00\xb8\x00\x00\x00\x14\x00\x00\x00\+ \\xde\x00\x00\x00\x5e\x00\x00\x00\x0b\x00\x00\x00\xdb\x00\x00\x00\+ \\xe0\x00\x00\x00\x32\x00\x00\x00\x3a\x00\x00\x00\x0a\x00\x00\x00\+ \\x49\x00\x00\x00\x06\x00\x00\x00\x24\x00\x00\x00\x5c\x00\x00\x00\+ \\xc2\x00\x00\x00\xd3\x00\x00\x00\xac\x00\x00\x00\x62\x00\x00\x00\+ \\x91\x00\x00\x00\x95\x00\x00\x00\xe4\x00\x00\x00\x79\x00\x00\x00\+ \\xe7\x00\x00\x00\xc8\x00\x00\x00\x37\x00\x00\x00\x6d\x00\x00\x00\+ \\x8d\x00\x00\x00\xd5\x00\x00\x00\x4e\x00\x00\x00\xa9\x00\x00\x00\+ \\x6c\x00\x00\x00\x56\x00\x00\x00\xf4\x00\x00\x00\xea\x00\x00\x00\+ \\x65\x00\x00\x00\x7a\x00\x00\x00\xae\x00\x00\x00\x08\x00\x00\x00\+ \\xba\x00\x00\x00\x78\x00\x00\x00\x25\x00\x00\x00\x2e\x00\x00\x00\+ \\x1c\x00\x00\x00\xa6\x00\x00\x00\xb4\x00\x00\x00\xc6\x00\x00\x00\+ \\xe8\x00\x00\x00\xdd\x00\x00\x00\x74\x00\x00\x00\x1f\x00\x00\x00\+ \\x4b\x00\x00\x00\xbd\x00\x00\x00\x8b\x00\x00\x00\x8a\x00\x00\x00\+ \\x70\x00\x00\x00\x3e\x00\x00\x00\xb5\x00\x00\x00\x66\x00\x00\x00\+ \\x48\x00\x00\x00\x03\x00\x00\x00\xf6\x00\x00\x00\x0e\x00\x00\x00\+ \\x61\x00\x00\x00\x35\x00\x00\x00\x57\x00\x00\x00\xb9\x00\x00\x00\+ \\x86\x00\x00\x00\xc1\x00\x00\x00\x1d\x00\x00\x00\x9e\x00\x00\x00\+ \\xe1\x00\x00\x00\xf8\x00\x00\x00\x98\x00\x00\x00\x11\x00\x00\x00\+ \\x69\x00\x00\x00\xd9\x00\x00\x00\x8e\x00\x00\x00\x94\x00\x00\x00\+ \\x9b\x00\x00\x00\x1e\x00\x00\x00\x87\x00\x00\x00\xe9\x00\x00\x00\+ \\xce\x00\x00\x00\x55\x00\x00\x00\x28\x00\x00\x00\xdf\x00\x00\x00\+ \\x8c\x00\x00\x00\xa1\x00\x00\x00\x89\x00\x00\x00\x0d\x00\x00\x00\+ \\xbf\x00\x00\x00\xe6\x00\x00\x00\x42\x00\x00\x00\x68\x00\x00\x00\+ \\x41\x00\x00\x00\x99\x00\x00\x00\x2d\x00\x00\x00\x0f\x00\x00\x00\+ \\xb0\x00\x00\x00\x54\x00\x00\x00\xbb\x00\x00\x00\x16\x00\x00\x00"#+++{-# INLINE rsbox #-}+rsbox :: Word8 -> Word8+rsbox (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x52\x09\x6a\xd5\x30\x36\xa5\x38\+ \\xbf\x40\xa3\x9e\x81\xf3\xd7\xfb\+ \\x7c\xe3\x39\x82\x9b\x2f\xff\x87\+ \\x34\x8e\x43\x44\xc4\xde\xe9\xcb\+ \\x54\x7b\x94\x32\xa6\xc2\x23\x3d\+ \\xee\x4c\x95\x0b\x42\xfa\xc3\x4e\+ \\x08\x2e\xa1\x66\x28\xd9\x24\xb2\+ \\x76\x5b\xa2\x49\x6d\x8b\xd1\x25\+ \\x72\xf8\xf6\x64\x86\x68\x98\x16\+ \\xd4\xa4\x5c\xcc\x5d\x65\xb6\x92\+ \\x6c\x70\x48\x50\xfd\xed\xb9\xda\+ \\x5e\x15\x46\x57\xa7\x8d\x9d\x84\+ \\x90\xd8\xab\x00\x8c\xbc\xd3\x0a\+ \\xf7\xe4\x58\x05\xb8\xb3\x45\x06\+ \\xd0\x2c\x1e\x8f\xca\x3f\x0f\x02\+ \\xc1\xaf\xbd\x03\x01\x13\x8a\x6b\+ \\x3a\x91\x11\x41\x4f\x67\xdc\xea\+ \\x97\xf2\xcf\xce\xf0\xb4\xe6\x73\+ \\x96\xac\x74\x22\xe7\xad\x35\x85\+ \\xe2\xf9\x37\xe8\x1c\x75\xdf\x6e\+ \\x47\xf1\x1a\x71\x1d\x29\xc5\x89\+ \\x6f\xb7\x62\x0e\xaa\x18\xbe\x1b\+ \\xfc\x56\x3e\x4b\xc6\xd2\x79\x20\+ \\x9a\xdb\xc0\xfe\x78\xcd\x5a\xf4\+ \\x1f\xdd\xa8\x33\x88\x07\xc7\x31\+ \\xb1\x12\x10\x59\x27\x80\xec\x5f\+ \\x60\x51\x7f\xa9\x19\xb5\x4a\x0d\+ \\x2d\xe5\x7a\x9f\x93\xc9\x9c\xef\+ \\xa0\xe0\x3b\x4d\xae\x2a\xf5\xb0\+ \\xc8\xeb\xbb\x3c\x83\x53\x99\x61\+ \\x17\x2b\x04\x7e\xba\x77\xd6\x26\+ \\xe1\x69\x14\x63\x55\x21\x0c\x7d"#++{-# INLINE rcon #-}+rcon :: Int -> Word8+rcon (I# i) = W8# (indexWord8OffAddr# table (i `remInt#` 51#))+ where !table =+ "\x8d\x01\x02\x04\x08\x10\x20\x40\+ \\x80\x1b\x36\x6c\xd8\xab\x4d\x9a\+ \\x2f\x5e\xbc\x63\xc6\x97\x35\x6a\+ \\xd4\xb3\x7d\xfa\xef\xc5\x91\x39\+ \\x72\xe4\xd3\xbd\x61\xc2\x9f\x25\+ \\x4a\x94\x33\x66\xcc\x83\x1d\x3a\+ \\x74\xe8\xcb"#++{-# INLINE gm2 #-}+{-# INLINE gm3 #-}+{-# INLINE gm9 #-}+{-# INLINE gm11 #-}+{-# INLINE gm13 #-}+{-# INLINE gm14 #-}+gm2, gm3, gm9, gm11, gm13, gm14 :: Word8 -> Word8+gm2 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x00\x02\x04\x06\x08\x0a\x0c\x0e\+ \\x10\x12\x14\x16\x18\x1a\x1c\x1e\+ \\x20\x22\x24\x26\x28\x2a\x2c\x2e\+ \\x30\x32\x34\x36\x38\x3a\x3c\x3e\+ \\x40\x42\x44\x46\x48\x4a\x4c\x4e\+ \\x50\x52\x54\x56\x58\x5a\x5c\x5e\+ \\x60\x62\x64\x66\x68\x6a\x6c\x6e\+ \\x70\x72\x74\x76\x78\x7a\x7c\x7e\+ \\x80\x82\x84\x86\x88\x8a\x8c\x8e\+ \\x90\x92\x94\x96\x98\x9a\x9c\x9e\+ \\xa0\xa2\xa4\xa6\xa8\xaa\xac\xae\+ \\xb0\xb2\xb4\xb6\xb8\xba\xbc\xbe\+ \\xc0\xc2\xc4\xc6\xc8\xca\xcc\xce\+ \\xd0\xd2\xd4\xd6\xd8\xda\xdc\xde\+ \\xe0\xe2\xe4\xe6\xe8\xea\xec\xee\+ \\xf0\xf2\xf4\xf6\xf8\xfa\xfc\xfe\+ \\x1b\x19\x1f\x1d\x13\x11\x17\x15\+ \\x0b\x09\x0f\x0d\x03\x01\x07\x05\+ \\x3b\x39\x3f\x3d\x33\x31\x37\x35\+ \\x2b\x29\x2f\x2d\x23\x21\x27\x25\+ \\x5b\x59\x5f\x5d\x53\x51\x57\x55\+ \\x4b\x49\x4f\x4d\x43\x41\x47\x45\+ \\x7b\x79\x7f\x7d\x73\x71\x77\x75\+ \\x6b\x69\x6f\x6d\x63\x61\x67\x65\+ \\x9b\x99\x9f\x9d\x93\x91\x97\x95\+ \\x8b\x89\x8f\x8d\x83\x81\x87\x85\+ \\xbb\xb9\xbf\xbd\xb3\xb1\xb7\xb5\+ \\xab\xa9\xaf\xad\xa3\xa1\xa7\xa5\+ \\xdb\xd9\xdf\xdd\xd3\xd1\xd7\xd5\+ \\xcb\xc9\xcf\xcd\xc3\xc1\xc7\xc5\+ \\xfb\xf9\xff\xfd\xf3\xf1\xf7\xf5\+ \\xeb\xe9\xef\xed\xe3\xe1\xe7\xe5"#++gm3 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x00\x03\x06\x05\x0c\x0f\x0a\x09\+ \\x18\x1b\x1e\x1d\x14\x17\x12\x11\+ \\x30\x33\x36\x35\x3c\x3f\x3a\x39\+ \\x28\x2b\x2e\x2d\x24\x27\x22\x21\+ \\x60\x63\x66\x65\x6c\x6f\x6a\x69\+ \\x78\x7b\x7e\x7d\x74\x77\x72\x71\+ \\x50\x53\x56\x55\x5c\x5f\x5a\x59\+ \\x48\x4b\x4e\x4d\x44\x47\x42\x41\+ \\xc0\xc3\xc6\xc5\xcc\xcf\xca\xc9\+ \\xd8\xdb\xde\xdd\xd4\xd7\xd2\xd1\+ \\xf0\xf3\xf6\xf5\xfc\xff\xfa\xf9\+ \\xe8\xeb\xee\xed\xe4\xe7\xe2\xe1\+ \\xa0\xa3\xa6\xa5\xac\xaf\xaa\xa9\+ \\xb8\xbb\xbe\xbd\xb4\xb7\xb2\xb1\+ \\x90\x93\x96\x95\x9c\x9f\x9a\x99\+ \\x88\x8b\x8e\x8d\x84\x87\x82\x81\+ \\x9b\x98\x9d\x9e\x97\x94\x91\x92\+ \\x83\x80\x85\x86\x8f\x8c\x89\x8a\+ \\xab\xa8\xad\xae\xa7\xa4\xa1\xa2\+ \\xb3\xb0\xb5\xb6\xbf\xbc\xb9\xba\+ \\xfb\xf8\xfd\xfe\xf7\xf4\xf1\xf2\+ \\xe3\xe0\xe5\xe6\xef\xec\xe9\xea\+ \\xcb\xc8\xcd\xce\xc7\xc4\xc1\xc2\+ \\xd3\xd0\xd5\xd6\xdf\xdc\xd9\xda\+ \\x5b\x58\x5d\x5e\x57\x54\x51\x52\+ \\x43\x40\x45\x46\x4f\x4c\x49\x4a\+ \\x6b\x68\x6d\x6e\x67\x64\x61\x62\+ \\x73\x70\x75\x76\x7f\x7c\x79\x7a\+ \\x3b\x38\x3d\x3e\x37\x34\x31\x32\+ \\x23\x20\x25\x26\x2f\x2c\x29\x2a\+ \\x0b\x08\x0d\x0e\x07\x04\x01\x02\+ \\x13\x10\x15\x16\x1f\x1c\x19\x1a"#++gm9 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x00\x09\x12\x1b\x24\x2d\x36\x3f\+ \\x48\x41\x5a\x53\x6c\x65\x7e\x77\+ \\x90\x99\x82\x8b\xb4\xbd\xa6\xaf\+ \\xd8\xd1\xca\xc3\xfc\xf5\xee\xe7\+ \\x3b\x32\x29\x20\x1f\x16\x0d\x04\+ \\x73\x7a\x61\x68\x57\x5e\x45\x4c\+ \\xab\xa2\xb9\xb0\x8f\x86\x9d\x94\+ \\xe3\xea\xf1\xf8\xc7\xce\xd5\xdc\+ \\x76\x7f\x64\x6d\x52\x5b\x40\x49\+ \\x3e\x37\x2c\x25\x1a\x13\x08\x01\+ \\xe6\xef\xf4\xfd\xc2\xcb\xd0\xd9\+ \\xae\xa7\xbc\xb5\x8a\x83\x98\x91\+ \\x4d\x44\x5f\x56\x69\x60\x7b\x72\+ \\x05\x0c\x17\x1e\x21\x28\x33\x3a\+ \\xdd\xd4\xcf\xc6\xf9\xf0\xeb\xe2\+ \\x95\x9c\x87\x8e\xb1\xb8\xa3\xaa\+ \\xec\xe5\xfe\xf7\xc8\xc1\xda\xd3\+ \\xa4\xad\xb6\xbf\x80\x89\x92\x9b\+ \\x7c\x75\x6e\x67\x58\x51\x4a\x43\+ \\x34\x3d\x26\x2f\x10\x19\x02\x0b\+ \\xd7\xde\xc5\xcc\xf3\xfa\xe1\xe8\+ \\x9f\x96\x8d\x84\xbb\xb2\xa9\xa0\+ \\x47\x4e\x55\x5c\x63\x6a\x71\x78\+ \\x0f\x06\x1d\x14\x2b\x22\x39\x30\+ \\x9a\x93\x88\x81\xbe\xb7\xac\xa5\+ \\xd2\xdb\xc0\xc9\xf6\xff\xe4\xed\+ \\x0a\x03\x18\x11\x2e\x27\x3c\x35\+ \\x42\x4b\x50\x59\x66\x6f\x74\x7d\+ \\xa1\xa8\xb3\xba\x85\x8c\x97\x9e\+ \\xe9\xe0\xfb\xf2\xcd\xc4\xdf\xd6\+ \\x31\x38\x23\x2a\x15\x1c\x07\x0e\+ \\x79\x70\x6b\x62\x5d\x54\x4f\x46"#++gm11 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x00\x0b\x16\x1d\x2c\x27\x3a\x31\+ \\x58\x53\x4e\x45\x74\x7f\x62\x69\+ \\xb0\xbb\xa6\xad\x9c\x97\x8a\x81\+ \\xe8\xe3\xfe\xf5\xc4\xcf\xd2\xd9\+ \\x7b\x70\x6d\x66\x57\x5c\x41\x4a\+ \\x23\x28\x35\x3e\x0f\x04\x19\x12\+ \\xcb\xc0\xdd\xd6\xe7\xec\xf1\xfa\+ \\x93\x98\x85\x8e\xbf\xb4\xa9\xa2\+ \\xf6\xfd\xe0\xeb\xda\xd1\xcc\xc7\+ \\xae\xa5\xb8\xb3\x82\x89\x94\x9f\+ \\x46\x4d\x50\x5b\x6a\x61\x7c\x77\+ \\x1e\x15\x08\x03\x32\x39\x24\x2f\+ \\x8d\x86\x9b\x90\xa1\xaa\xb7\xbc\+ \\xd5\xde\xc3\xc8\xf9\xf2\xef\xe4\+ \\x3d\x36\x2b\x20\x11\x1a\x07\x0c\+ \\x65\x6e\x73\x78\x49\x42\x5f\x54\+ \\xf7\xfc\xe1\xea\xdb\xd0\xcd\xc6\+ \\xaf\xa4\xb9\xb2\x83\x88\x95\x9e\+ \\x47\x4c\x51\x5a\x6b\x60\x7d\x76\+ \\x1f\x14\x09\x02\x33\x38\x25\x2e\+ \\x8c\x87\x9a\x91\xa0\xab\xb6\xbd\+ \\xd4\xdf\xc2\xc9\xf8\xf3\xee\xe5\+ \\x3c\x37\x2a\x21\x10\x1b\x06\x0d\+ \\x64\x6f\x72\x79\x48\x43\x5e\x55\+ \\x01\x0a\x17\x1c\x2d\x26\x3b\x30\+ \\x59\x52\x4f\x44\x75\x7e\x63\x68\+ \\xb1\xba\xa7\xac\x9d\x96\x8b\x80\+ \\xe9\xe2\xff\xf4\xc5\xce\xd3\xd8\+ \\x7a\x71\x6c\x67\x56\x5d\x40\x4b\+ \\x22\x29\x34\x3f\x0e\x05\x18\x13\+ \\xca\xc1\xdc\xd7\xe6\xed\xf0\xfb\+ \\x92\x99\x84\x8f\xbe\xb5\xa8\xa3"#++gm13 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x00\x0d\x1a\x17\x34\x39\x2e\x23\+ \\x68\x65\x72\x7f\x5c\x51\x46\x4b\+ \\xd0\xdd\xca\xc7\xe4\xe9\xfe\xf3\+ \\xb8\xb5\xa2\xaf\x8c\x81\x96\x9b\+ \\xbb\xb6\xa1\xac\x8f\x82\x95\x98\+ \\xd3\xde\xc9\xc4\xe7\xea\xfd\xf0\+ \\x6b\x66\x71\x7c\x5f\x52\x45\x48\+ \\x03\x0e\x19\x14\x37\x3a\x2d\x20\+ \\x6d\x60\x77\x7a\x59\x54\x43\x4e\+ \\x05\x08\x1f\x12\x31\x3c\x2b\x26\+ \\xbd\xb0\xa7\xaa\x89\x84\x93\x9e\+ \\xd5\xd8\xcf\xc2\xe1\xec\xfb\xf6\+ \\xd6\xdb\xcc\xc1\xe2\xef\xf8\xf5\+ \\xbe\xb3\xa4\xa9\x8a\x87\x90\x9d\+ \\x06\x0b\x1c\x11\x32\x3f\x28\x25\+ \\x6e\x63\x74\x79\x5a\x57\x40\x4d\+ \\xda\xd7\xc0\xcd\xee\xe3\xf4\xf9\+ \\xb2\xbf\xa8\xa5\x86\x8b\x9c\x91\+ \\x0a\x07\x10\x1d\x3e\x33\x24\x29\+ \\x62\x6f\x78\x75\x56\x5b\x4c\x41\+ \\x61\x6c\x7b\x76\x55\x58\x4f\x42\+ \\x09\x04\x13\x1e\x3d\x30\x27\x2a\+ \\xb1\xbc\xab\xa6\x85\x88\x9f\x92\+ \\xd9\xd4\xc3\xce\xed\xe0\xf7\xfa\+ \\xb7\xba\xad\xa0\x83\x8e\x99\x94\+ \\xdf\xd2\xc5\xc8\xeb\xe6\xf1\xfc\+ \\x67\x6a\x7d\x70\x53\x5e\x49\x44\+ \\x0f\x02\x15\x18\x3b\x36\x21\x2c\+ \\x0c\x01\x16\x1b\x38\x35\x22\x2f\+ \\x64\x69\x7e\x73\x50\x5d\x4a\x47\+ \\xdc\xd1\xc6\xcb\xe8\xe5\xf2\xff\+ \\xb4\xb9\xae\xa3\x80\x8d\x9a\x97"#++gm14 (W8# w) = W8# (indexWord8OffAddr# table (word2Int# w))+ where !table =+ "\x00\x0e\x1c\x12\x38\x36\x24\x2a\+ \\x70\x7e\x6c\x62\x48\x46\x54\x5a\+ \\xe0\xee\xfc\xf2\xd8\xd6\xc4\xca\+ \\x90\x9e\x8c\x82\xa8\xa6\xb4\xba\+ \\xdb\xd5\xc7\xc9\xe3\xed\xff\xf1\+ \\xab\xa5\xb7\xb9\x93\x9d\x8f\x81\+ \\x3b\x35\x27\x29\x03\x0d\x1f\x11\+ \\x4b\x45\x57\x59\x73\x7d\x6f\x61\+ \\xad\xa3\xb1\xbf\x95\x9b\x89\x87\+ \\xdd\xd3\xc1\xcf\xe5\xeb\xf9\xf7\+ \\x4d\x43\x51\x5f\x75\x7b\x69\x67\+ \\x3d\x33\x21\x2f\x05\x0b\x19\x17\+ \\x76\x78\x6a\x64\x4e\x40\x52\x5c\+ \\x06\x08\x1a\x14\x3e\x30\x22\x2c\+ \\x96\x98\x8a\x84\xae\xa0\xb2\xbc\+ \\xe6\xe8\xfa\xf4\xde\xd0\xc2\xcc\+ \\x41\x4f\x5d\x53\x79\x77\x65\x6b\+ \\x31\x3f\x2d\x23\x09\x07\x15\x1b\+ \\xa1\xaf\xbd\xb3\x99\x97\x85\x8b\+ \\xd1\xdf\xcd\xc3\xe9\xe7\xf5\xfb\+ \\x9a\x94\x86\x88\xa2\xac\xbe\xb0\+ \\xea\xe4\xf6\xf8\xd2\xdc\xce\xc0\+ \\x7a\x74\x66\x68\x42\x4c\x5e\x50\+ \\x0a\x04\x16\x18\x32\x3c\x2e\x20\+ \\xec\xe2\xf0\xfe\xd4\xda\xc8\xc6\+ \\x9c\x92\x80\x8e\xa4\xaa\xb8\xb6\+ \\x0c\x02\x10\x1e\x34\x3a\x28\x26\+ \\x7c\x72\x60\x6e\x44\x4a\x58\x56\+ \\x37\x39\x2b\x25\x0f\x01\x13\x1d\+ \\x47\x49\x5b\x55\x7f\x71\x63\x6d\+ \\xd7\xd9\xcb\xc5\xef\xe1\xf3\xfd\+ \\xa7\xa9\xbb\xb5\x9f\x91\x83\x8d"#
Number/Basic.hs view
@@ -1,4 +1,11 @@ {-# LANGUAGE BangPatterns #-}+-- |+-- Module : Number.Basic+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : Good+ module Number.Basic ( sqrti , gcde
Number/Generate.hs view
@@ -1,3 +1,10 @@+-- |+-- Module : Number.Generate+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : Good+ module Number.Generate ( generateMax , generateBetween@@ -12,7 +19,7 @@ -- | generate a positive integer between 0 and m. -- using as many bytes as necessary to the same size as m, that are converted to integer. generateMax :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)-generateMax rng m = case genBytes (logiBytes m) rng of+generateMax rng m = case genBytes (lengthBytes m) rng of Left err -> Left err Right (bs, rng') -> Right (os2ip bs `mod` m, rng') @@ -29,8 +36,3 @@ generateOfSize rng bits = case genBytes (bits `div` 8) rng of Left err -> Left err Right (bs, rng') -> Right (os2ip $ snd $ B.mapAccumL (\acc w -> (0, w .|. acc)) 0xc0 bs, rng')--logiBytes :: Integer -> Int-logiBytes n- | n < 256 = 1- | otherwise = 1 + logiBytes (n `div` 256)
Number/ModArithmetic.hs view
@@ -1,4 +1,11 @@ {-# LANGUAGE BangPatterns #-}+-- |+-- Module : Number.ModArithmetic+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : Good+ module Number.ModArithmetic ( exponantiation_rtl_binary , inverse
+ Number/Polynomial.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE BangPatterns #-}+-- |+-- Module : Number.Polynomial+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : Good++module Number.Polynomial+ ( Monomial(..)+ -- * polynomial operations+ , Polynomial+ , toList+ , fromList+ , addPoly+ , subPoly+ , mulPoly+ , squarePoly+ , expPoly+ , divPoly+ , negPoly+ ) where++import Data.List (intercalate, sort)+import Data.Vector ((!), Vector)+import qualified Data.Vector as V+import Control.Arrow (first)++data Monomial = Monomial {-# UNPACK #-} !Int !Integer+ deriving (Eq)++data Polynomial = Polynomial (Vector Monomial)+ deriving (Eq)++instance Ord Monomial where+ compare (Monomial w1 v1) (Monomial w2 v2) =+ case compare w1 w2 of+ EQ -> compare v1 v2+ r -> r++instance Show Monomial where+ show (Monomial w v) = show v ++ "x^" ++ show w++instance Show Polynomial where+ show (Polynomial p) = intercalate "+" $ map show $ V.toList p++toList (Polynomial p) = V.toList p++fromList = Polynomial . V.fromList . reverse . sort . filterZero+ where+ filterZero = filter (\(Monomial _ v) -> v /= 0)++getWeight (Polynomial p) n = look 0+ where+ plen = V.length p+ look !i+ | i >= plen = Nothing+ | otherwise =+ let (Monomial w v) = p ! i in+ case compare w n of+ LT -> Nothing+ EQ -> Just v+ GT -> look (i+1)+ ++mergePoly f (Polynomial p1) (Polynomial p2) = fromList $ loop 0 0+ where+ l1 = V.length p1+ l2 = V.length p2+ loop !i1 !i2+ | i1 == l1 && i2 == l2 = []+ | i1 == l1 = (p2 ! i2) : loop i1 (i2+1)+ | i2 == l2 = (p1 ! i1) : loop (i1+1) i2+ | otherwise =+ let (coef, i1inc, i2inc) = addCoef (p1 ! i1) (p2 ! i2) in+ coef : loop (i1+i1inc) (i2+i2inc)+ addCoef m1@(Monomial w1 v1) m2@(Monomial w2 v2) =+ case compare w1 w2 of+ LT -> (Monomial w2 (f 0 v2), 0, 1)+ EQ -> (Monomial w1 (f v1 v2), 1, 1)+ GT -> (m1, 1, 0)++addPoly = mergePoly (+)+subPoly = mergePoly (-)++negPoly (Polynomial p) = Polynomial $ V.map negateMonomial p+ where negateMonomial (Monomial w v) = Monomial w (-v)++mulPoly p1@(Polynomial v1) p2@(Polynomial v2) =+ fromList $ filter (\(Monomial _ v) -> v /= 0) $ map (\i -> Monomial i (c i)) $ reverse [0..(m+n)]+ where+ (Monomial m _) = v1 ! 0+ (Monomial n _) = v2 ! 0+ c r = foldl (\acc i -> (b $ r-i) * (a $ i) + acc) 0 [0..r]+ where+ a = maybe 0 id . getWeight p1+ b = maybe 0 id . getWeight p2++squarePoly p = p `mulPoly` p++expPoly p e = loop e+ where+ loop t 0 = t+ loop t n = loop (squarePoly t) (n-1)++divPoly :: Polynomial -> Polynomial -> (Polynomial, Polynomial)+divPoly p1 p2@(Polynomial pp2) = first fromList $ divLoop p1+ where divLoop d1@(Polynomial pp1)+ | V.null pp1 = ([], d1)+ | otherwise =+ let (Monomial w1 v1) = pp1 ! 0 in+ let (Monomial w2 v2) = pp2 ! 0 in+ let w = w1 - w2 in+ let (v,r) = v1 `divMod` v2 in+ if w >= 0 && r == 0+ then+ let mono = (Monomial w v) in+ let remain = d1 `subPoly` (p2 `mulPoly` (fromList [mono])) in+ let (l, finalRem) = divLoop remain in+ (mono : l, finalRem)+ else+ ([], d1)
Number/Prime.hs view
@@ -1,3 +1,11 @@+{-# LANGUAGE BangPatterns #-}+-- |+-- Module : Number.Prime+-- License : BSD-style+-- Maintainer : Vincent Hanquez <vincent@snarc.org>+-- Stability : experimental+-- Portability : Good+ module Number.Prime ( generatePrime , generateSafePrime@@ -5,7 +13,6 @@ , findPrimeFrom , findPrimeFromWith , primalityTestNaive- -- , primalityTestAKS , primalityTestMillerRabin , isCoprime ) where@@ -20,7 +27,7 @@ -- first a list of small primes are implicitely tested for divisibility, -- then the Miller Rabin algorithm is used with an accuracy of 30 recursions isProbablyPrime :: CryptoRandomGen g => g -> Integer -> Either GenError (Bool, g)-isProbablyPrime rng n+isProbablyPrime rng !n | any (\p -> p `divides` n) (filter (< n) smallPrimes) = Right (False, rng) | otherwise = primalityTestMillerRabin rng 30 n @@ -31,7 +38,7 @@ Right (sp, rng') -> findPrimeFrom rng' sp -- | generate a prime number of the form 2p+1 where p is also prime.--- it is also know as a Sophie Germaine prime or safe prime.+-- it is also knowed as a Sophie Germaine prime or safe prime. -- -- The number of safe prime is significantly smaller to the number of prime, -- as such it shouldn't be used if this number is supposed to be kept safe.@@ -44,7 +51,7 @@ -- | find a prime from a starting point where the property hold. findPrimeFromWith :: CryptoRandomGen g => g -> (g -> Integer -> Either GenError (Bool,g)) -> Integer -> Either GenError (Integer, g)-findPrimeFromWith rng prop n+findPrimeFromWith rng prop !n | even n = findPrimeFromWith rng prop (n+1) | otherwise = case isProbablyPrime rng n of Left err -> Left err@@ -62,52 +69,32 @@ -- | Miller Rabin algorithm return if the number is probably prime or composite. -- the tries parameter is the number of recursion, that determines the accuracy of the test. primalityTestMillerRabin :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Bool, g)-primalityTestMillerRabin rng tries n+primalityTestMillerRabin rng tries !n | n <= 3 = error "Miller-Rabin requires tested value to be > 3" | even n = Right (False, rng) | tries <= 0 = error "Miller-Rabin tries need to be > 0" | otherwise = loop rng (factorise 0 (n-1)) tries where -- factorise n-1 into the form 2^s*d factorise :: Integer -> Integer -> (Integer, Integer)- factorise s v+ factorise !s !v | v `testBit` 0 = (s, v) | otherwise = factorise (s+1) (v `shiftR` 1) expmod = exponantiation_rtl_binary -- when iteration reach zero, we have a probable prime- loop g _ 0 = Right (True, g)- loop g (s,d) k = case generateBetween g 2 (n-2) of+ loop g _ 0 = Right (True, g)+ loop g t@(_,d) k = case generateBetween g 2 (n-2) of Left err -> Left err Right (a, g') -> let x = expmod a d n in if x == (1 :: Integer) || x == (n-1)- then loop g' (s,d) (k-1)- else loop' g' (s,d) (k-1) ((x*x) `mod` n) 1+ then loop g' t (k-1)+ else loop' g' t (k-1) ((x*x) `mod` n) 1 -- loop from 1 to s-1. if we reach the end then it's composite- loop' g o@(s,_) km1 x2 r+ loop' g t@(s,_) km1 !x2 !r | r == s = Right (False, g) | x2 == 1 = Right (False, g)- | x2 /= (n-1) = loop' g o km1 ((x2*x2) `mod` n) (r+1)- | otherwise = loop g o km1- --- | AKS primality test return if the number is prime or composite--- it uses the following algorithm:--- Input: integer n > 1.--- If n = ab for integers a > 0 and b > 1, output composite.--- Find the smallest r such that o_r(n) > log2(n).--- If 1 < gcd(a,n) < n for some a ≤ r, output composite.--- If n <= r, output prime.--- For a = 1 to lower-bound(sqrt(phi(n)) * log2(n)) do--- if (X+a)n ≠ Xn+a (mod Xr − 1,n), output composite;--- Output prime.-primalityTestAKS :: Integer -> Bool-primalityTestAKS n = undefined- where- -- for p prime, the euler totient (# of coprime to n) is clearly n -1- totient = n-1- ubound = (fst $ sqrti totient) * (logi n)- logi z- | z == 0 = 0- | otherwise = 1 + logi (z `shiftR` 1)+ | x2 /= (n-1) = loop' g t km1 ((x2*x2) `mod` n) (r+1)+ | otherwise = loop g t km1 -- | Test naively is integer is prime. -- while naive, we skip even number and stop iteration at i > sqrt(n)
Number/Serialize.hs view
@@ -1,6 +1,7 @@ module Number.Serialize ( i2osp , os2ip+ , lengthBytes ) where import Data.ByteString (ByteString)@@ -17,3 +18,9 @@ where divMod256 0 = Nothing divMod256 n = Just (fromIntegral a,b) where (b,a) = n `divMod` 256++-- | returns the number of bytes to store an integer with i2osp+lengthBytes :: Integer -> Int+lengthBytes n+ | n < 256 = 1+ | otherwise = 1 + lengthBytes (n `div` 256)
+ System/Endian.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE CPP #-}+module System.Endian (littleEndian) where+++#ifdef BIG_ENDIAN+littleEndian :: Bool+littleEndian = False+#elif defined(LITTLE_ENDIAN)+littleEndian :: Bool+littleEndian = True+#else++import System.Info (arch)++littleEndian :: Bool+littleEndian = arch /= "sparc" && arch /= "ppc"+#endif
cryptocipher.cabal view
@@ -1,5 +1,5 @@ Name: cryptocipher-Version: 0.2.12+Version: 0.2.13 Description: Symmetrical Block, Stream and PubKey Ciphers License: BSD3 License-file: LICENSE@@ -24,6 +24,7 @@ Build-Depends: base >= 4 && < 5 , bytestring , vector >= 0.7+ , ghc-prim , primitive , crypto-api >= 0.5 , tagged@@ -38,8 +39,14 @@ Number.Serialize Number.Generate Number.Basic+ Number.Polynomial Number.Prime+ System.Endian ghc-options: -Wall+ if arch(ppc) || arch(sparc)+ cpp-options: -DBIG_ENDIAN+ else+ cpp-options: -DLITTLE_ENDIAN Executable Tests Main-Is: Tests.hs@@ -52,6 +59,10 @@ , QuickCheck >= 2 else Buildable: False+ if arch(ppc) || arch(sparc)+ cpp-options: -DBIG_ENDIAN+ else+ cpp-options: -DLITTLE_ENDIAN Executable Benchmarks Main-Is: Benchmarks.hs@@ -62,6 +73,10 @@ , mtl else Buildable: False+ if arch(ppc) || arch(sparc)+ cpp-options: -DBIG_ENDIAN+ else+ cpp-options: -DLITTLE_ENDIAN source-repository head type: git