cryptonite-0.23/Crypto/0000755000000000000000000000000013077673501013315 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/0000755000000000000000000000000013075454604014526 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/AES/0000755000000000000000000000000013016771343015133 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/Blowfish/0000755000000000000000000000000012746570656016315 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/Camellia/0000755000000000000000000000000012527651103016227 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/DES/0000755000000000000000000000000012526641047015140 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/Twofish/0000755000000000000000000000000013075454604016151 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/Types/0000755000000000000000000000000012750030004015611 5ustar0000000000000000cryptonite-0.23/Crypto/ConstructHash/0000755000000000000000000000000012727442704016105 5ustar0000000000000000cryptonite-0.23/Crypto/Data/0000755000000000000000000000000013045161274014160 5ustar0000000000000000cryptonite-0.23/Crypto/ECC/0000755000000000000000000000000013020740134013670 5ustar0000000000000000cryptonite-0.23/Crypto/ECC/Simple/0000755000000000000000000000000013020740134015121 5ustar0000000000000000cryptonite-0.23/Crypto/Error/0000755000000000000000000000000013054050744014377 5ustar0000000000000000cryptonite-0.23/Crypto/Hash/0000755000000000000000000000000013077673501014200 5ustar0000000000000000cryptonite-0.23/Crypto/Internal/0000755000000000000000000000000013063753164015070 5ustar0000000000000000cryptonite-0.23/Crypto/KDF/0000755000000000000000000000000013075454604013720 5ustar0000000000000000cryptonite-0.23/Crypto/MAC/0000755000000000000000000000000013075642757013724 5ustar0000000000000000cryptonite-0.23/Crypto/Number/0000755000000000000000000000000013077673501014545 5ustar0000000000000000cryptonite-0.23/Crypto/Number/Serialize/0000755000000000000000000000000013070472141016462 5ustar0000000000000000cryptonite-0.23/Crypto/PubKey/0000755000000000000000000000000013065761056014514 5ustar0000000000000000cryptonite-0.23/Crypto/PubKey/ECC/0000755000000000000000000000000013075454604015105 5ustar0000000000000000cryptonite-0.23/Crypto/PubKey/RSA/0000755000000000000000000000000012673727640015146 5ustar0000000000000000cryptonite-0.23/Crypto/Random/0000755000000000000000000000000012775635732014545 5ustar0000000000000000cryptonite-0.23/Crypto/Random/Entropy/0000755000000000000000000000000012737432335016175 5ustar0000000000000000cryptonite-0.23/benchs/0000755000000000000000000000000013075454604013276 5ustar0000000000000000cryptonite-0.23/benchs/Number/0000755000000000000000000000000013075454604014526 5ustar0000000000000000cryptonite-0.23/cbits/0000755000000000000000000000000013054074213013127 5ustar0000000000000000cryptonite-0.23/cbits/aes/0000755000000000000000000000000013054074213013677 5ustar0000000000000000cryptonite-0.23/cbits/argon2/0000755000000000000000000000000013054050744014322 5ustar0000000000000000cryptonite-0.23/cbits/blake2/0000755000000000000000000000000012673727640014306 5ustar0000000000000000cryptonite-0.23/cbits/blake2/ref/0000755000000000000000000000000013054050744015046 5ustar0000000000000000cryptonite-0.23/cbits/blake2/sse/0000755000000000000000000000000013054050744015064 5ustar0000000000000000cryptonite-0.23/cbits/curve25519/0000755000000000000000000000000013045064524014665 5ustar0000000000000000cryptonite-0.23/cbits/ed25519/0000755000000000000000000000000013047776516014146 5ustar0000000000000000cryptonite-0.23/cbits/ed448/0000755000000000000000000000000013054074213013757 5ustar0000000000000000cryptonite-0.23/cbits/p256/0000755000000000000000000000000013047564000013623 5ustar0000000000000000cryptonite-0.23/tests/0000755000000000000000000000000013075454604013176 5ustar0000000000000000cryptonite-0.23/tests/KAT_AES/0000755000000000000000000000000012570523322014276 5ustar0000000000000000cryptonite-0.23/tests/KAT_PubKey/0000755000000000000000000000000013020314275015061 5ustar0000000000000000cryptonite-0.23/tests/Number/0000755000000000000000000000000012746570656014440 5ustar0000000000000000cryptonite-0.23/Crypto/Cipher/AES.hs0000644000000000000000000000432513075454604015476 0ustar0000000000000000-- | -- Module : Crypto.Cipher.AES -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good {-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Cipher.AES ( AES128 , AES192 , AES256 ) where import Crypto.Error import Crypto.Cipher.Types import Crypto.Cipher.Utils import Crypto.Cipher.Types.Block import Crypto.Cipher.AES.Primitive import Crypto.Internal.Imports import Data.ByteArray as BA -- | AES with 128 bit key newtype AES128 = AES128 AES deriving (NFData) -- | AES with 192 bit key newtype AES192 = AES192 AES deriving (NFData) -- | AES with 256 bit key newtype AES256 = AES256 AES deriving (NFData) instance Cipher AES128 where cipherName _ = "AES128" cipherKeySize _ = KeySizeFixed 16 cipherInit k = AES128 <$> (initAES =<< validateKeySize (undefined :: AES128) k) instance Cipher AES192 where cipherName _ = "AES192" cipherKeySize _ = KeySizeFixed 24 cipherInit k = AES192 <$> (initAES =<< validateKeySize (undefined :: AES192) k) instance Cipher AES256 where cipherName _ = "AES256" cipherKeySize _ = KeySizeFixed 32 cipherInit k = AES256 <$> (initAES =<< validateKeySize (undefined :: AES256) k) #define INSTANCE_BLOCKCIPHER(CSTR) \ instance BlockCipher CSTR where \ { blockSize _ = 16 \ ; ecbEncrypt (CSTR aes) = encryptECB aes \ ; ecbDecrypt (CSTR aes) = decryptECB aes \ ; cbcEncrypt (CSTR aes) (IV iv) = encryptCBC aes (IV iv) \ ; cbcDecrypt (CSTR aes) (IV iv) = decryptCBC aes (IV iv) \ ; ctrCombine (CSTR aes) (IV iv) = encryptCTR aes (IV iv) \ ; aeadInit AEAD_GCM (CSTR aes) iv = CryptoPassed $ AEAD (gcmMode aes) (gcmInit aes iv) \ ; aeadInit AEAD_OCB (CSTR aes) iv = CryptoPassed $ AEAD (ocbMode aes) (ocbInit aes iv) \ ; aeadInit _ _ _ = CryptoFailed CryptoError_AEADModeNotSupported \ }; \ instance BlockCipher128 CSTR where \ { xtsEncrypt (CSTR aes1, CSTR aes2) (IV iv) = encryptXTS (aes1,aes2) (IV iv) \ ; xtsDecrypt (CSTR aes1, CSTR aes2) (IV iv) = decryptXTS (aes1,aes2) (IV iv) \ }; INSTANCE_BLOCKCIPHER(AES128) INSTANCE_BLOCKCIPHER(AES192) INSTANCE_BLOCKCIPHER(AES256) cryptonite-0.23/Crypto/Cipher/Blowfish.hs0000644000000000000000000000341212527650543016640 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Blowfish -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- {-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Cipher.Blowfish ( Blowfish , Blowfish64 , Blowfish128 , Blowfish256 , Blowfish448 ) where import Crypto.Internal.Imports import Crypto.Cipher.Types import Crypto.Cipher.Blowfish.Primitive -- | variable keyed blowfish state newtype Blowfish = Blowfish Context deriving (NFData) -- | 64 bit keyed blowfish state newtype Blowfish64 = Blowfish64 Context deriving (NFData) -- | 128 bit keyed blowfish state newtype Blowfish128 = Blowfish128 Context deriving (NFData) -- | 256 bit keyed blowfish state newtype Blowfish256 = Blowfish256 Context deriving (NFData) -- | 448 bit keyed blowfish state newtype Blowfish448 = Blowfish448 Context deriving (NFData) instance Cipher Blowfish where cipherName _ = "blowfish" cipherKeySize _ = KeySizeRange 6 56 cipherInit k = Blowfish `fmap` initBlowfish k instance BlockCipher Blowfish where blockSize _ = 8 ecbEncrypt (Blowfish bf) = encrypt bf ecbDecrypt (Blowfish bf) = decrypt bf #define INSTANCE_CIPHER(CSTR, NAME, KEYSIZE) \ instance Cipher CSTR where \ { cipherName _ = NAME \ ; cipherKeySize _ = KeySizeFixed KEYSIZE \ ; cipherInit k = CSTR `fmap` initBlowfish k \ }; \ instance BlockCipher CSTR where \ { blockSize _ = 8 \ ; ecbEncrypt (CSTR bf) = encrypt bf \ ; ecbDecrypt (CSTR bf) = decrypt bf \ }; INSTANCE_CIPHER(Blowfish64, "blowfish64", 8) INSTANCE_CIPHER(Blowfish128, "blowfish128", 16) INSTANCE_CIPHER(Blowfish256, "blowfish256", 32) INSTANCE_CIPHER(Blowfish448, "blowfish448", 56) cryptonite-0.23/Crypto/Cipher/Camellia.hs0000644000000000000000000000141212516347336016571 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Camellia -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- Camellia support. only 128 bit variant available for now. module Crypto.Cipher.Camellia ( Camellia128 ) where import Crypto.Cipher.Camellia.Primitive import Crypto.Cipher.Types -- | Camellia block cipher with 128 bit key newtype Camellia128 = Camellia128 Camellia instance Cipher Camellia128 where cipherName _ = "Camellia128" cipherKeySize _ = KeySizeFixed 16 cipherInit k = Camellia128 `fmap` initCamellia k instance BlockCipher Camellia128 where blockSize _ = 16 ecbEncrypt (Camellia128 key) = encrypt key ecbDecrypt (Camellia128 key) = decrypt key cryptonite-0.23/Crypto/Cipher/ChaCha.hs0000644000000000000000000001151212556112410016156 0ustar0000000000000000-- | -- Module : Crypto.Cipher.ChaCha -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Cipher.ChaCha ( initialize , combine , generate , State -- * simple interface for DRG purpose , initializeSimple , generateSimple , StateSimple ) where import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Foreign.Ptr import Foreign.C.Types -- | ChaCha context newtype State = State ScrubbedBytes deriving (NFData) -- | ChaCha context for DRG purpose (see Crypto.Random.ChaChaDRG) newtype StateSimple = StateSimple ScrubbedBytes -- just ChaCha's state deriving (NFData) -- | Initialize a new ChaCha context with the number of rounds, -- the key and the nonce associated. initialize :: (ByteArrayAccess key, ByteArrayAccess nonce) => Int -- ^ number of rounds (8,12,20) -> key -- ^ the key (128 or 256 bits) -> nonce -- ^ the nonce (64 or 96 bits) -> State -- ^ the initial ChaCha state initialize nbRounds key nonce | not (kLen `elem` [16,32]) = error "ChaCha: key length should be 128 or 256 bits" | not (nonceLen `elem` [8,12]) = error "ChaCha: nonce length should be 64 or 96 bits" | not (nbRounds `elem` [8,12,20]) = error "ChaCha: rounds should be 8, 12 or 20" | otherwise = unsafeDoIO $ do stPtr <- B.alloc 132 $ \stPtr -> B.withByteArray nonce $ \noncePtr -> B.withByteArray key $ \keyPtr -> ccryptonite_chacha_init stPtr (fromIntegral nbRounds) kLen keyPtr nonceLen noncePtr return $ State stPtr where kLen = B.length key nonceLen = B.length nonce -- | Initialize simple ChaCha State initializeSimple :: ByteArray seed => seed -- ^ a 40 bytes long seed -> StateSimple initializeSimple seed | sLen /= 40 = error "ChaCha Random: seed length should be 40 bytes" | otherwise = unsafeDoIO $ do stPtr <- B.alloc 64 $ \stPtr -> B.withByteArray seed $ \seedPtr -> ccryptonite_chacha_init_core stPtr 32 seedPtr 8 (seedPtr `plusPtr` 32) return $ StateSimple stPtr where sLen = B.length seed -- | Combine the chacha output and an arbitrary message with a xor, -- and return the combined output and the new state. combine :: ByteArray ba => State -- ^ the current ChaCha state -> ba -- ^ the source to xor with the generator -> (ba, State) combine prevSt@(State prevStMem) src | B.null src = (B.empty, prevSt) | otherwise = unsafeDoIO $ do (out, st) <- B.copyRet prevStMem $ \ctx -> B.alloc (B.length src) $ \dstPtr -> B.withByteArray src $ \srcPtr -> ccryptonite_chacha_combine dstPtr ctx srcPtr (fromIntegral $ B.length src) return (out, State st) -- | Generate a number of bytes from the ChaCha output directly generate :: ByteArray ba => State -- ^ the current ChaCha state -> Int -- ^ the length of data to generate -> (ba, State) generate prevSt@(State prevStMem) len | len <= 0 = (B.empty, prevSt) | otherwise = unsafeDoIO $ do (out, st) <- B.copyRet prevStMem $ \ctx -> B.alloc len $ \dstPtr -> ccryptonite_chacha_generate dstPtr ctx (fromIntegral len) return (out, State st) -- | similar to 'generate' but assume certains values generateSimple :: ByteArray ba => StateSimple -> Int -> (ba, StateSimple) generateSimple (StateSimple prevSt) nbBytes = unsafeDoIO $ do newSt <- B.copy prevSt (\_ -> return ()) output <- B.alloc nbBytes $ \dstPtr -> B.withByteArray newSt $ \stPtr -> ccryptonite_chacha_random 8 dstPtr stPtr (fromIntegral nbBytes) return (output, StateSimple newSt) foreign import ccall "cryptonite_chacha_init_core" ccryptonite_chacha_init_core :: Ptr StateSimple -> Int -> Ptr Word8 -> Int -> Ptr Word8 -> IO () foreign import ccall "cryptonite_chacha_init" ccryptonite_chacha_init :: Ptr State -> Int -> Int -> Ptr Word8 -> Int -> Ptr Word8 -> IO () foreign import ccall "cryptonite_chacha_combine" ccryptonite_chacha_combine :: Ptr Word8 -> Ptr State -> Ptr Word8 -> CUInt -> IO () foreign import ccall "cryptonite_chacha_generate" ccryptonite_chacha_generate :: Ptr Word8 -> Ptr State -> CUInt -> IO () foreign import ccall "cryptonite_chacha_random" ccryptonite_chacha_random :: Int -> Ptr Word8 -> Ptr StateSimple -> CUInt -> IO () cryptonite-0.23/Crypto/Cipher/ChaChaPoly1305.hs0000644000000000000000000001647712673727640017373 0ustar0000000000000000-- | -- Module : Crypto.Cipher.ChaChaPoly1305 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- -- A simple AEAD scheme using ChaCha20 and Poly1305. See -- . -- -- The State is not modified in place, so each function changing the State, -- returns a new State. -- -- Authenticated Data need to be added before any call to 'encrypt' or 'decrypt', -- and once all the data has been added, then 'finalizeAAD' need to be called. -- -- Once 'finalizeAAD' has been called, no further 'appendAAD' call should be make. -- -- >import Data.ByteString.Char8 as B -- >import Data.ByteArray -- >import Crypto.Error -- >import Crypto.Cipher.ChaChaPoly1305 as C -- > -- >encrypt -- > :: ByteString -- nonce (12 random bytes) -- > -> ByteString -- symmetric key -- > -> ByteString -- optional associated data (won't be encrypted) -- > -> ByteString -- input plaintext to be encrypted -- > -> CryptoFailable ByteString -- ciphertext with a 128-bit tag attached -- >encrypt nonce key header plaintext = do -- > st1 <- C.nonce12 nonce >>= C.initialize key -- > let -- > st2 = C.finalizeAAD $ C.appendAAD header st1 -- > (out, st3) = C.encrypt plaintext st2 -- > auth = C.finalize st3 -- > return $ out `B.append` Data.ByteArray.convert auth -- module Crypto.Cipher.ChaChaPoly1305 ( State , Nonce , nonce12 , nonce8 , incrementNonce , initialize , appendAAD , finalizeAAD , encrypt , decrypt , finalize ) where import Control.Monad (when) import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes, ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Imports import Crypto.Error import qualified Crypto.Cipher.ChaCha as ChaCha import qualified Crypto.MAC.Poly1305 as Poly1305 import Data.Memory.Endian import qualified Data.ByteArray.Pack as P import Foreign.Ptr import Foreign.Storable -- | A ChaChaPoly1305 State. -- -- The state is immutable, and only new state can be created data State = State !ChaCha.State !Poly1305.State !Word64 -- AAD length !Word64 -- ciphertext length -- | Valid Nonce for ChaChaPoly1305. -- -- It can be created with 'nonce8' or 'nonce12' data Nonce = Nonce8 Bytes | Nonce12 Bytes instance ByteArrayAccess Nonce where length (Nonce8 n) = B.length n length (Nonce12 n) = B.length n withByteArray (Nonce8 n) = B.withByteArray n withByteArray (Nonce12 n) = B.withByteArray n -- Based on the following pseudo code: -- -- chacha20_aead_encrypt(aad, key, iv, constant, plaintext): -- nonce = constant | iv -- otk = poly1305_key_gen(key, nonce) -- ciphertext = chacha20_encrypt(key, 1, nonce, plaintext) -- mac_data = aad | pad16(aad) -- mac_data |= ciphertext | pad16(ciphertext) -- mac_data |= num_to_4_le_bytes(aad.length) -- mac_data |= num_to_4_le_bytes(ciphertext.length) -- tag = poly1305_mac(mac_data, otk) -- return (ciphertext, tag) pad16 :: Word64 -> Bytes pad16 n | modLen == 0 = B.empty | otherwise = B.replicate (16 - modLen) 0 where modLen = fromIntegral (n `mod` 16) -- | Nonce smart constructor 12 bytes IV, nonce constructor nonce12 :: ByteArrayAccess iv => iv -> CryptoFailable Nonce nonce12 iv | B.length iv /= 12 = CryptoFailed CryptoError_IvSizeInvalid | otherwise = CryptoPassed . Nonce12 . B.convert $ iv -- | 8 bytes IV, nonce constructor nonce8 :: ByteArrayAccess ba => ba -- ^ 4 bytes constant -> ba -- ^ 8 bytes IV -> CryptoFailable Nonce nonce8 constant iv | B.length constant /= 4 = CryptoFailed CryptoError_IvSizeInvalid | B.length iv /= 8 = CryptoFailed CryptoError_IvSizeInvalid | otherwise = CryptoPassed . Nonce8 . B.concat $ [constant, iv] -- | Increment a nonce incrementNonce :: Nonce -> Nonce incrementNonce (Nonce8 n) = Nonce8 $ incrementNonce' n 4 incrementNonce (Nonce12 n) = Nonce12 $ incrementNonce' n 0 incrementNonce' :: Bytes -> Int -> Bytes incrementNonce' b offset = B.copyAndFreeze b $ \s -> loop s (s `plusPtr` offset) where loop :: Ptr Word8 -> Ptr Word8 -> IO () loop s p | s == (p `plusPtr` (B.length b - offset - 1)) = peek s >>= poke s . (+) 1 | otherwise = do r <- (+) 1 <$> peek p poke p r when (r == 0) $ loop s (p `plusPtr` 1) -- | Initialize a new ChaChaPoly1305 State -- -- The key length need to be 256 bits, and the nonce -- procured using either `nonce8` or `nonce12` initialize :: ByteArrayAccess key => key -> Nonce -> CryptoFailable State initialize key (Nonce8 nonce) = initialize' key nonce initialize key (Nonce12 nonce) = initialize' key nonce initialize' :: ByteArrayAccess key => key -> Bytes -> CryptoFailable State initialize' key nonce | B.length key /= 32 = CryptoFailed CryptoError_KeySizeInvalid | otherwise = CryptoPassed $ State encState polyState 0 0 where rootState = ChaCha.initialize 20 key nonce (polyKey, encState) = ChaCha.generate rootState 64 polyState = throwCryptoError $ Poly1305.initialize (B.take 32 polyKey :: ScrubbedBytes) -- | Append Authenticated Data to the State and return -- the new modified State. -- -- Once no further call to this function need to be make, -- the user should call 'finalizeAAD' appendAAD :: ByteArrayAccess ba => ba -> State -> State appendAAD ba (State encState macState aadLength plainLength) = State encState newMacState newLength plainLength where newMacState = Poly1305.update macState ba newLength = aadLength + fromIntegral (B.length ba) -- | Finalize the Authenticated Data and return the finalized State finalizeAAD :: State -> State finalizeAAD (State encState macState aadLength plainLength) = State encState newMacState aadLength plainLength where newMacState = Poly1305.update macState $ pad16 aadLength -- | Encrypt a piece of data and returns the encrypted Data and the -- updated State. encrypt :: ByteArray ba => ba -> State -> (ba, State) encrypt input (State encState macState aadLength plainLength) = (output, State newEncState newMacState aadLength newPlainLength) where (output, newEncState) = ChaCha.combine encState input newMacState = Poly1305.update macState output newPlainLength = plainLength + fromIntegral (B.length input) -- | Decrypt a piece of data and returns the decrypted Data and the -- updated State. decrypt :: ByteArray ba => ba -> State -> (ba, State) decrypt input (State encState macState aadLength plainLength) = (output, State newEncState newMacState aadLength newPlainLength) where (output, newEncState) = ChaCha.combine encState input newMacState = Poly1305.update macState input newPlainLength = plainLength + fromIntegral (B.length input) -- | Generate an authentication tag from the State. finalize :: State -> Poly1305.Auth finalize (State _ macState aadLength plainLength) = Poly1305.finalize $ Poly1305.updates macState [ pad16 plainLength , either (error "finalize: internal error") id $ P.fill 16 (P.putStorable (toLE aadLength) >> P.putStorable (toLE plainLength)) ] cryptonite-0.23/Crypto/Cipher/DES.hs0000644000000000000000000000213312523403315015462 0ustar0000000000000000-- | -- Module : Crypto.Cipher.DES -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- module Crypto.Cipher.DES ( DES ) where import Data.Word import Crypto.Error import Crypto.Cipher.Types import Crypto.Cipher.DES.Primitive import Crypto.Internal.ByteArray (ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Data.Memory.Endian -- | DES Context data DES = DES Word64 deriving (Eq) instance Cipher DES where cipherName _ = "DES" cipherKeySize _ = KeySizeFixed 8 cipherInit k = initDES k instance BlockCipher DES where blockSize _ = 8 ecbEncrypt (DES key) = B.mapAsWord64 (unBlock . encrypt key . Block) ecbDecrypt (DES key) = B.mapAsWord64 (unBlock . decrypt key . Block) initDES :: ByteArrayAccess key => key -> CryptoFailable DES initDES k | len == 8 = CryptoPassed $ DES key | otherwise = CryptoFailed $ CryptoError_KeySizeInvalid where len = B.length k key = fromBE $ B.toW64BE k 0 cryptonite-0.23/Crypto/Cipher/RC4.hs0000644000000000000000000000543612527651130015454 0ustar0000000000000000-- | -- Module : Crypto.Cipher.RC4 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- Simple implementation of the RC4 stream cipher. -- http://en.wikipedia.org/wiki/RC4 -- -- Initial FFI implementation by Peter White -- -- Reorganized and simplified to have an opaque context. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Cipher.RC4 ( initialize , combine , generate , State ) where import Data.Word import Foreign.Ptr import Crypto.Internal.ByteArray (ScrubbedBytes, ByteArray, ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports -- | The encryption state for RC4 newtype State = State ScrubbedBytes deriving (ByteArrayAccess,NFData) -- | C Call for initializing the encryptor foreign import ccall unsafe "cryptonite_rc4.h cryptonite_rc4_init" c_rc4_init :: Ptr Word8 -- ^ The rc4 key -> Word32 -- ^ The key length -> Ptr State -- ^ The context -> IO () foreign import ccall unsafe "cryptonite_rc4.h cryptonite_rc4_combine" c_rc4_combine :: Ptr State -- ^ Pointer to the permutation -> Ptr Word8 -- ^ Pointer to the clear text -> Word32 -- ^ Length of the clear text -> Ptr Word8 -- ^ Output buffer -> IO () -- | RC4 context initialization. -- -- seed the context with an initial key. the key size need to be -- adequate otherwise security takes a hit. initialize :: ByteArrayAccess key => key -- ^ The key -> State -- ^ The RC4 context with the key mixed in initialize key = unsafeDoIO $ do st <- B.alloc 264 $ \stPtr -> B.withByteArray key $ \keyPtr -> c_rc4_init keyPtr (fromIntegral $ B.length key) (castPtr stPtr) return $ State st -- | generate the next len bytes of the rc4 stream without combining -- it to anything. generate :: ByteArray ba => State -> Int -> (State, ba) generate ctx len = combine ctx (B.zero len) -- | RC4 xor combination of the rc4 stream with an input combine :: ByteArray ba => State -- ^ rc4 context -> ba -- ^ input -> (State, ba) -- ^ new rc4 context, and the output combine (State prevSt) clearText = unsafeDoIO $ B.allocRet len $ \outptr -> B.withByteArray clearText $ \clearPtr -> do st <- B.copy prevSt $ \stPtr -> c_rc4_combine (castPtr stPtr) clearPtr (fromIntegral len) outptr return $! State st --return $! (State st, B.PS outfptr 0 len) where len = B.length clearText cryptonite-0.23/Crypto/Cipher/Salsa.hs0000644000000000000000000000637612777073622016146 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Salsa -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Cipher.Salsa ( initialize , combine , generate , State(..) ) where import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Foreign.Ptr import Foreign.C.Types -- | Salsa context newtype State = State ScrubbedBytes deriving (NFData) -- | Initialize a new Salsa context with the number of rounds, -- the key and the nonce associated. initialize :: (ByteArrayAccess key, ByteArrayAccess nonce) => Int -- ^ number of rounds (8,12,20) -> key -- ^ the key (128 or 256 bits) -> nonce -- ^ the nonce (64 or 96 bits) -> State -- ^ the initial Salsa state initialize nbRounds key nonce | not (kLen `elem` [16,32]) = error "Salsa: key length should be 128 or 256 bits" | not (nonceLen `elem` [8,12]) = error "Salsa: nonce length should be 64 or 96 bits" | not (nbRounds `elem` [8,12,20]) = error "Salsa: rounds should be 8, 12 or 20" | otherwise = unsafeDoIO $ do stPtr <- B.alloc 132 $ \stPtr -> B.withByteArray nonce $ \noncePtr -> B.withByteArray key $ \keyPtr -> ccryptonite_salsa_init stPtr (fromIntegral nbRounds) kLen keyPtr nonceLen noncePtr return $ State stPtr where kLen = B.length key nonceLen = B.length nonce -- | Combine the salsa output and an arbitrary message with a xor, -- and return the combined output and the new state. combine :: ByteArray ba => State -- ^ the current Salsa state -> ba -- ^ the source to xor with the generator -> (ba, State) combine prevSt@(State prevStMem) src | B.null src = (B.empty, prevSt) | otherwise = unsafeDoIO $ do (out, st) <- B.copyRet prevStMem $ \ctx -> B.alloc (B.length src) $ \dstPtr -> B.withByteArray src $ \srcPtr -> do ccryptonite_salsa_combine dstPtr ctx srcPtr (fromIntegral $ B.length src) return (out, State st) -- | Generate a number of bytes from the Salsa output directly generate :: ByteArray ba => State -- ^ the current Salsa state -> Int -- ^ the length of data to generate -> (ba, State) generate prevSt@(State prevStMem) len | len <= 0 = (B.empty, prevSt) | otherwise = unsafeDoIO $ do (out, st) <- B.copyRet prevStMem $ \ctx -> B.alloc len $ \dstPtr -> ccryptonite_salsa_generate dstPtr ctx (fromIntegral len) return (out, State st) foreign import ccall "cryptonite_salsa_init" ccryptonite_salsa_init :: Ptr State -> Int -> Int -> Ptr Word8 -> Int -> Ptr Word8 -> IO () foreign import ccall "cryptonite_salsa_combine" ccryptonite_salsa_combine :: Ptr Word8 -> Ptr State -> Ptr Word8 -> CUInt -> IO () foreign import ccall "cryptonite_salsa_generate" ccryptonite_salsa_generate :: Ptr Word8 -> Ptr State -> CUInt -> IO () cryptonite-0.23/Crypto/Cipher/TripleDES.hs0000644000000000000000000000653612523403474016663 0ustar0000000000000000-- | -- Module : Crypto.Cipher.TripleDES -- License : BSD-style -- Stability : experimental -- Portability : ??? module Crypto.Cipher.TripleDES ( DES_EEE3 , DES_EDE3 , DES_EEE2 , DES_EDE2 ) where import Data.Word import Crypto.Error import Crypto.Cipher.Types import Crypto.Cipher.DES.Primitive import Crypto.Internal.ByteArray (ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Data.Memory.Endian -- | 3DES with 3 different keys used all in the same direction data DES_EEE3 = DES_EEE3 Word64 Word64 Word64 deriving (Eq) -- | 3DES with 3 different keys used in alternative direction data DES_EDE3 = DES_EDE3 Word64 Word64 Word64 deriving (Eq) -- | 3DES where the first and third keys are equal, used in the same direction data DES_EEE2 = DES_EEE2 Word64 Word64 -- key1 and key3 are equal deriving (Eq) -- | 3DES where the first and third keys are equal, used in alternative direction data DES_EDE2 = DES_EDE2 Word64 Word64 -- key1 and key3 are equal deriving (Eq) instance Cipher DES_EEE3 where cipherName _ = "3DES_EEE" cipherKeySize _ = KeySizeFixed 24 cipherInit k = init3DES DES_EEE3 k instance Cipher DES_EDE3 where cipherName _ = "3DES_EDE" cipherKeySize _ = KeySizeFixed 24 cipherInit k = init3DES DES_EDE3 k instance Cipher DES_EDE2 where cipherName _ = "2DES_EDE" cipherKeySize _ = KeySizeFixed 16 cipherInit k = init2DES DES_EDE2 k instance Cipher DES_EEE2 where cipherName _ = "2DES_EEE" cipherKeySize _ = KeySizeFixed 16 cipherInit k = init2DES DES_EEE2 k instance BlockCipher DES_EEE3 where blockSize _ = 8 ecbEncrypt (DES_EEE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (encrypt k3 . encrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EEE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k3) . Block) instance BlockCipher DES_EDE3 where blockSize _ = 8 ecbEncrypt (DES_EDE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (encrypt k3 . decrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EDE3 k1 k2 k3) = B.mapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k3) . Block) instance BlockCipher DES_EEE2 where blockSize _ = 8 ecbEncrypt (DES_EEE2 k1 k2) = B.mapAsWord64 (unBlock . (encrypt k1 . encrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EEE2 k1 k2) = B.mapAsWord64 (unBlock . (decrypt k1 . decrypt k2 . decrypt k1) . Block) instance BlockCipher DES_EDE2 where blockSize _ = 8 ecbEncrypt (DES_EDE2 k1 k2) = B.mapAsWord64 (unBlock . (encrypt k1 . decrypt k2 . encrypt k1) . Block) ecbDecrypt (DES_EDE2 k1 k2) = B.mapAsWord64 (unBlock . (decrypt k1 . encrypt k2 . decrypt k1) . Block) init3DES :: ByteArrayAccess key => (Word64 -> Word64 -> Word64 -> a) -> key -> CryptoFailable a init3DES constr k | len == 24 = CryptoPassed $ constr k1 k2 k3 | otherwise = CryptoFailed CryptoError_KeySizeInvalid where len = B.length k (k1, k2, k3) = (fromBE $ B.toW64BE k 0, fromBE $ B.toW64BE k 8, fromBE $ B.toW64BE k 16) init2DES :: ByteArrayAccess key => (Word64 -> Word64 -> a) -> key -> CryptoFailable a init2DES constr k | len == 16 = CryptoPassed $ constr k1 k2 | otherwise = CryptoFailed CryptoError_KeySizeInvalid where len = B.length k (k1, k2) = (fromBE $ B.toW64BE k 0, fromBE $ B.toW64BE k 8) cryptonite-0.23/Crypto/Cipher/Twofish.hs0000644000000000000000000000267413075454604016516 0ustar0000000000000000module Crypto.Cipher.Twofish ( Twofish128 , Twofish192 , Twofish256 ) where import Crypto.Cipher.Twofish.Primitive import Crypto.Cipher.Types import Crypto.Cipher.Utils import Crypto.Internal.Imports newtype Twofish128 = Twofish128 Twofish instance Cipher Twofish128 where cipherName _ = "Twofish128" cipherKeySize _ = KeySizeFixed 16 cipherInit key = Twofish128 <$> (initTwofish =<< validateKeySize (undefined :: Twofish128) key) instance BlockCipher Twofish128 where blockSize _ = 16 ecbEncrypt (Twofish128 key) = encrypt key ecbDecrypt (Twofish128 key) = decrypt key newtype Twofish192 = Twofish192 Twofish instance Cipher Twofish192 where cipherName _ = "Twofish192" cipherKeySize _ = KeySizeFixed 24 cipherInit key = Twofish192 <$> (initTwofish =<< validateKeySize (undefined :: Twofish192) key) instance BlockCipher Twofish192 where blockSize _ = 16 ecbEncrypt (Twofish192 key) = encrypt key ecbDecrypt (Twofish192 key) = decrypt key newtype Twofish256 = Twofish256 Twofish instance Cipher Twofish256 where cipherName _ = "Twofish256" cipherKeySize _ = KeySizeFixed 32 cipherInit key = Twofish256 <$> (initTwofish =<< validateKeySize (undefined :: Twofish256) key) instance BlockCipher Twofish256 where blockSize _ = 16 ecbEncrypt (Twofish256 key) = encrypt key ecbDecrypt (Twofish256 key) = decrypt key cryptonite-0.23/Crypto/Cipher/Types.hs0000644000000000000000000000151612516347336016173 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- -- symmetric cipher basic types -- {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Cipher.Types ( -- * Cipher classes Cipher(..) , BlockCipher(..) , BlockCipher128(..) , StreamCipher(..) , DataUnitOffset , KeySizeSpecifier(..) -- , cfb8Encrypt -- , cfb8Decrypt -- * AEAD functions , AEADMode(..) , module Crypto.Cipher.Types.AEAD -- * Initial Vector type and constructor , IV , makeIV , nullIV , ivAdd -- * Authentification Tag , AuthTag(..) ) where import Crypto.Cipher.Types.Base import Crypto.Cipher.Types.Block import Crypto.Cipher.Types.Stream import Crypto.Cipher.Types.AEAD cryptonite-0.23/Crypto/Cipher/Utils.hs0000644000000000000000000000123413075454604016162 0ustar0000000000000000module Crypto.Cipher.Utils ( validateKeySize ) where import Crypto.Error import Crypto.Cipher.Types import Crypto.Internal.Imports import Data.ByteArray as BA validateKeySize :: (ByteArrayAccess key, Cipher cipher) => cipher -> key -> CryptoFailable key validateKeySize c k = if validKeyLength then CryptoPassed k else CryptoFailed CryptoError_KeySizeInvalid where keyLength = BA.length k validKeyLength = case cipherKeySize c of KeySizeRange low high -> keyLength >= low && keyLength <= high KeySizeEnum lengths -> keyLength `elem` lengths KeySizeFixed s -> keyLength == scryptonite-0.23/Crypto/Cipher/XSalsa.hs0000644000000000000000000000374312777073622016271 0ustar0000000000000000-- | -- Module : Crypto.Cipher.XSalsa -- License : BSD-style -- Maintainer : Brandon Hamilton -- Stability : stable -- Portability : good -- -- Implementation of XSalsa20 algorithm -- -- Based on the Salsa20 algorithm with 256 bit key extended with 192 bit nonce {-# LANGUAGE ForeignFunctionInterface #-} module Crypto.Cipher.XSalsa ( initialize , combine , generate , State ) where import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Foreign.Ptr import Foreign.Storable import Foreign.C.Types import Crypto.Cipher.Salsa hiding (initialize) -- | Initialize a new XSalsa context with the number of rounds, -- the key and the nonce associated. initialize :: (ByteArrayAccess key, ByteArrayAccess nonce) => Int -- ^ number of rounds (8,12,20) -> key -- ^ the key (256 bits) -> nonce -- ^ the nonce (192 bits) -> State -- ^ the initial XSalsa state initialize nbRounds key nonce | kLen /= 32 = error "XSalsa: key length should be 256 bits" | nonceLen /= 24 = error "XSalsa: nonce length should be 192 bits" | not (nbRounds `elem` [8,12,20]) = error "XSalsa: rounds should be 8, 12 or 20" | otherwise = unsafeDoIO $ do stPtr <- B.alloc 132 $ \stPtr -> B.withByteArray nonce $ \noncePtr -> B.withByteArray key $ \keyPtr -> ccryptonite_xsalsa_init stPtr (fromIntegral nbRounds) kLen keyPtr nonceLen noncePtr return $ State stPtr where kLen = B.length key nonceLen = B.length nonce foreign import ccall "cryptonite_xsalsa_init" ccryptonite_xsalsa_init :: Ptr State -> Int -> Int -> Ptr Word8 -> Int -> Ptr Word8 -> IO () cryptonite-0.23/Crypto/ConstructHash/MiyaguchiPreneel.hs0000644000000000000000000000435512727442704021702 0ustar0000000000000000-- | -- Module : Crypto.ConstructHash.MiyaguchiPreneel -- License : BSD-style -- Maintainer : Kei Hibino -- Stability : experimental -- Portability : unknown -- -- provide the hash function construction method from block cipher -- -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.ConstructHash.MiyaguchiPreneel ( compute, compute' , MiyaguchiPreneel ) where import Data.List (foldl') import Crypto.Data.Padding (pad, Format (ZERO)) import Crypto.Cipher.Types import Crypto.Error (throwCryptoError) import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B newtype MiyaguchiPreneel a = MP Bytes deriving (ByteArrayAccess) instance Eq (MiyaguchiPreneel a) where MP b1 == MP b2 = B.constEq b1 b2 -- | Compute Miyaguchi-Preneel one way compress using the supplied block cipher. compute' :: (ByteArrayAccess bin, BlockCipher cipher) => (Bytes -> cipher) -- ^ key build function to compute Miyaguchi-Preneel. care about block-size and key-size -> bin -- ^ input message -> MiyaguchiPreneel cipher -- ^ output tag compute' g = MP . foldl' (step $ g) (B.replicate bsz 0) . chunks . pad (ZERO bsz) . B.convert where bsz = blockSize ( g B.empty {- dummy to get block size -} ) chunks msg | B.null msg = [] | otherwise = (hd :: Bytes) : chunks tl where (hd, tl) = B.splitAt bsz msg -- | Compute Miyaguchi-Preneel one way compress using the infered block cipher. -- Only safe when KEY-SIZE equals to BLOCK-SIZE. -- -- Simple usage /mp' msg :: MiyaguchiPreneel AES128/ compute :: (ByteArrayAccess bin, BlockCipher cipher) => bin -- ^ input message -> MiyaguchiPreneel cipher -- ^ output tag compute = compute' $ throwCryptoError . cipherInit -- | computation step of Miyaguchi-Preneel step :: (ByteArray ba, BlockCipher k) => (ba -> k) -> ba -> ba -> ba step g iv msg = ecbEncrypt k msg `bxor` iv `bxor` msg where k = g iv bxor :: ByteArray ba => ba -> ba -> ba bxor = B.xor cryptonite-0.23/Crypto/Data/AFIS.hs0000644000000000000000000001350612523402033015232 0ustar0000000000000000-- | -- Module : Crypto.Data.AFIS -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- haskell implementation of the Anti-forensic information splitter -- available in LUKS. -- -- The algorithm bloats an arbitrary secret with many bits that are necessary for -- the recovery of the key (merge), and allow greater way to permanently -- destroy a key stored on disk. -- {-# LANGUAGE ScopedTypeVariables #-} module Crypto.Data.AFIS ( split , merge ) where import Crypto.Hash import Crypto.Random.Types import Crypto.Internal.Compat import Control.Monad (forM_, foldM) import Data.Word import Data.Bits import Foreign.Storable import Foreign.Ptr import Crypto.Internal.ByteArray (ByteArray, Bytes, MemView(..)) import qualified Crypto.Internal.ByteArray as B import Data.Memory.PtrMethods (memSet, memCopy) -- | Split data to diffused data, using a random generator and -- an hash algorithm. -- -- the diffused data will consist of random data for (expandTimes-1) -- then the last block will be xor of the accumulated random data diffused by -- the hash algorithm. -- -- ---------- -- - orig - -- ---------- -- -- ---------- ---------- -------------- -- - rand1 - - rand2 - - orig ^ acc - -- ---------- ---------- -------------- -- -- where acc is : -- acc(n+1) = hash (n ++ rand(n)) ^ acc(n) -- split :: (ByteArray ba, HashAlgorithm hash, DRG rng) => hash -- ^ Hash algorithm to use as diffuser -> rng -- ^ Random generator to use -> Int -- ^ Number of times to diffuse the data. -> ba -- ^ original data to diffuse. -> (ba, rng) -- ^ The diffused data {-# NOINLINE split #-} split hashAlg rng expandTimes src | expandTimes <= 1 = error "invalid expandTimes value" | otherwise = unsafeDoIO $ do (rng', bs) <- B.allocRet diffusedLen runOp return (bs, rng') where diffusedLen = blockSize * expandTimes blockSize = B.length src runOp dstPtr = do let lastBlock = dstPtr `plusPtr` (blockSize * (expandTimes-1)) memSet lastBlock 0 blockSize let randomBlockPtrs = map (plusPtr dstPtr . (*) blockSize) [0..(expandTimes-2)] rng' <- foldM fillRandomBlock rng randomBlockPtrs mapM_ (addRandomBlock lastBlock) randomBlockPtrs B.withByteArray src $ \srcPtr -> xorMem srcPtr lastBlock blockSize return rng' addRandomBlock lastBlock blockPtr = do xorMem blockPtr lastBlock blockSize diffuse hashAlg lastBlock blockSize fillRandomBlock g blockPtr = do let (rand :: Bytes, g') = randomBytesGenerate blockSize g B.withByteArray rand $ \randPtr -> memCopy blockPtr randPtr (fromIntegral blockSize) return g' -- | Merge previously diffused data back to the original data. merge :: (ByteArray ba, HashAlgorithm hash) => hash -- ^ Hash algorithm used as diffuser -> Int -- ^ Number of times to un-diffuse the data -> ba -- ^ Diffused data -> ba -- ^ Original data {-# NOINLINE merge #-} merge hashAlg expandTimes bs | r /= 0 = error "diffused data not a multiple of expandTimes" | originalSize <= 0 = error "diffused data null" | otherwise = B.allocAndFreeze originalSize $ \dstPtr -> B.withByteArray bs $ \srcPtr -> do memSet dstPtr 0 originalSize forM_ [0..(expandTimes-2)] $ \i -> do xorMem (srcPtr `plusPtr` (i * originalSize)) dstPtr originalSize diffuse hashAlg dstPtr originalSize xorMem (srcPtr `plusPtr` ((expandTimes-1) * originalSize)) dstPtr originalSize return () where (originalSize,r) = len `quotRem` expandTimes len = B.length bs -- | inplace Xor with an input -- dst = src `xor` dst xorMem :: Ptr Word8 -> Ptr Word8 -> Int -> IO () xorMem src dst sz | sz `mod` 64 == 0 = loop 8 (castPtr src :: Ptr Word64) (castPtr dst) sz | sz `mod` 32 == 0 = loop 4 (castPtr src :: Ptr Word32) (castPtr dst) sz | otherwise = loop 1 (src :: Ptr Word8) dst sz where loop _ _ _ 0 = return () loop incr s d n = do a <- peek s b <- peek d poke d (a `xor` b) loop incr (s `plusPtr` incr) (d `plusPtr` incr) (n-incr) diffuse :: HashAlgorithm hash => hash -- ^ Hash function to use as diffuser -> Ptr Word8 -- ^ buffer to diffuse, modify in place -> Int -- ^ length of buffer to diffuse -> IO () diffuse hashAlg src sz = loop src 0 where (full,pad) = sz `quotRem` digestSize loop s i | i < full = do h <- hashBlock i s digestSize B.withByteArray h $ \hPtr -> memCopy s hPtr digestSize loop (s `plusPtr` digestSize) (i+1) | pad /= 0 = do h <- hashBlock i s pad B.withByteArray h $ \hPtr -> memCopy s hPtr pad return () | otherwise = return () digestSize = hashDigestSize hashAlg -- Hash [ BE32(n), (p .. p+hashSz) ] hashBlock n p hashSz = do let ctx = hashInitWith hashAlg return $! hashFinalize $ hashUpdate (hashUpdate ctx (be32 n)) (MemView p hashSz) be32 :: Int -> Bytes be32 n = B.allocAndFreeze 4 $ \ptr -> do poke ptr (f8 (n `shiftR` 24)) poke (ptr `plusPtr` 1) (f8 (n `shiftR` 16)) poke (ptr `plusPtr` 2) (f8 (n `shiftR` 8)) poke (ptr `plusPtr` 3) (f8 n) where f8 :: Int -> Word8 f8 = fromIntegral cryptonite-0.23/Crypto/Data/Padding.hs0000644000000000000000000000421312727442704016070 0ustar0000000000000000-- | -- Module : Crypto.Data.Padding -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Various cryptographic padding commonly used for block ciphers -- or assymetric systems. -- module Crypto.Data.Padding ( Format(..) , pad , unpad ) where import Data.ByteArray (ByteArray, Bytes) import qualified Data.ByteArray as B -- | Format of padding data Format = PKCS5 -- ^ PKCS5: PKCS7 with hardcoded size of 8 | PKCS7 Int -- ^ PKCS7 with padding size between 1 and 255 | ZERO Int -- ^ zero padding with block size deriving (Show, Eq) -- | Apply some pad to a bytearray pad :: ByteArray byteArray => Format -> byteArray -> byteArray pad PKCS5 bin = pad (PKCS7 8) bin pad (PKCS7 sz) bin = bin `B.append` paddingString where paddingString = B.replicate paddingByte (fromIntegral paddingByte) paddingByte = sz - (B.length bin `mod` sz) pad (ZERO sz) bin = bin `B.append` paddingString where paddingString = B.replicate paddingSz 0 paddingSz | len == 0 = sz | m == 0 = 0 | otherwise = sz - m m = len `mod` sz len = B.length bin -- | Try to remove some padding from a bytearray. unpad :: ByteArray byteArray => Format -> byteArray -> Maybe byteArray unpad PKCS5 bin = unpad (PKCS7 8) bin unpad (PKCS7 sz) bin | len == 0 = Nothing | (len `mod` sz) /= 0 = Nothing | paddingSz < 1 || paddingSz > len = Nothing | paddingWitness `B.constEq` padding = Just content | otherwise = Nothing where len = B.length bin paddingByte = B.index bin (len - 1) paddingSz = fromIntegral paddingByte (content, padding) = B.splitAt (len - paddingSz) bin paddingWitness = B.replicate paddingSz paddingByte :: Bytes unpad (ZERO sz) bin | len == 0 = Nothing | (len `mod` sz) /= 0 = Nothing | B.index bin (len - 1) /= 0 = Just bin | otherwise = Nothing where len = B.length bin cryptonite-0.23/Crypto/ECC.hs0000644000000000000000000001776413050556742014260 0ustar0000000000000000-- | -- Module : Crypto.ECC -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Elliptic Curve Cryptography -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ScopedTypeVariables #-} module Crypto.ECC ( Curve_P256R1(..) , Curve_P384R1(..) , Curve_P521R1(..) , Curve_X25519(..) , Curve_X448(..) , EllipticCurve(..) , EllipticCurveDH(..) , EllipticCurveArith(..) , KeyPair(..) , SharedSecret(..) ) where import qualified Crypto.PubKey.ECC.P256 as P256 import qualified Crypto.ECC.Simple.Types as Simple import qualified Crypto.ECC.Simple.Prim as Simple import Crypto.Random import Crypto.Error import Crypto.Internal.Proxy import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess, ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Number.Serialize (i2ospOf_, os2ip) import qualified Crypto.PubKey.Curve25519 as X25519 import qualified Crypto.PubKey.Curve448 as X448 import Data.Function (on) import Data.ByteArray (convert) -- | An elliptic curve key pair composed of the private part (a scalar), and -- the associated point. data KeyPair curve = KeyPair { keypairGetPublic :: !(Point curve) , keypairGetPrivate :: !(Scalar curve) } newtype SharedSecret = SharedSecret ScrubbedBytes deriving (Eq, ByteArrayAccess) class EllipticCurve curve where -- | Point on an Elliptic Curve type Point curve :: * -- | Scalar in the Elliptic Curve domain type Scalar curve :: * -- | Generate a new random scalar on the curve. -- The scalar will represent a number between 1 and the order of the curve non included curveGenerateScalar :: MonadRandom randomly => proxy curve -> randomly (Scalar curve) -- | Generate a new random keypair curveGenerateKeyPair :: MonadRandom randomly => proxy curve -> randomly (KeyPair curve) -- | Get the curve size in bits curveSizeBits :: proxy curve -> Int -- | Encode a elliptic curve point into binary form encodePoint :: ByteArray bs => proxy curve -> Point curve -> bs -- | Try to decode the binary form of an elliptic curve point decodePoint :: ByteArray bs => proxy curve -> bs -> CryptoFailable (Point curve) class EllipticCurve curve => EllipticCurveDH curve where -- | Generate a Diffie hellman secret value. -- -- This is generally just the .x coordinate of the resulting point, that -- is not hashed. -- -- use `pointSmul` to keep the result in Point format. ecdh :: proxy curve -> Scalar curve -> Point curve -> SharedSecret class EllipticCurve curve => EllipticCurveArith curve where -- | Add points on a curve pointAdd :: proxy curve -> Point curve -> Point curve -> Point curve -- | Scalar Multiplication on a curve pointSmul :: proxy curve -> Scalar curve -> Point curve -> Point curve -- -- | Scalar Inverse -- scalarInverse :: Scalar curve -> Scalar curve -- | P256 Curve -- -- also known as P256 data Curve_P256R1 = Curve_P256R1 instance EllipticCurve Curve_P256R1 where type Point Curve_P256R1 = P256.Point type Scalar Curve_P256R1 = P256.Scalar curveSizeBits _ = 256 curveGenerateScalar _ = P256.scalarGenerate curveGenerateKeyPair _ = toKeyPair <$> P256.scalarGenerate where toKeyPair scalar = KeyPair (P256.toPoint scalar) scalar encodePoint _ p = mxy where mxy :: forall bs. ByteArray bs => bs mxy = B.concat [uncompressed, xy] where uncompressed, xy :: bs uncompressed = B.singleton 4 xy = P256.pointToBinary p decodePoint _ mxy = case B.uncons mxy of Nothing -> CryptoFailed $ CryptoError_PointSizeInvalid Just (m,xy) -- uncompressed | m == 4 -> P256.pointFromBinary xy | otherwise -> CryptoFailed $ CryptoError_PointFormatInvalid instance EllipticCurveArith Curve_P256R1 where pointAdd _ a b = P256.pointAdd a b pointSmul _ s p = P256.pointMul s p instance EllipticCurveDH Curve_P256R1 where ecdh _ s p = SharedSecret $ P256.pointDh s p data Curve_P384R1 = Curve_P384R1 instance EllipticCurve Curve_P384R1 where type Point Curve_P384R1 = Simple.Point Simple.SEC_p384r1 type Scalar Curve_P384R1 = Simple.Scalar Simple.SEC_p384r1 curveSizeBits _ = 384 curveGenerateScalar _ = Simple.scalarGenerate curveGenerateKeyPair _ = toKeyPair <$> Simple.scalarGenerate where toKeyPair scalar = KeyPair (Simple.pointBaseMul scalar) scalar encodePoint _ point = encodeECPoint point decodePoint _ bs = decodeECPoint bs instance EllipticCurveArith Curve_P384R1 where pointAdd _ a b = Simple.pointAdd a b pointSmul _ s p = Simple.pointMul s p instance EllipticCurveDH Curve_P384R1 where ecdh _ s p = SharedSecret $ i2ospOf_ (curveSizeBytes prx) x where prx = Proxy :: Proxy Curve_P384R1 Simple.Point x _ = pointSmul prx s p data Curve_P521R1 = Curve_P521R1 instance EllipticCurve Curve_P521R1 where type Point Curve_P521R1 = Simple.Point Simple.SEC_p521r1 type Scalar Curve_P521R1 = Simple.Scalar Simple.SEC_p521r1 curveSizeBits _ = 521 curveGenerateScalar _ = Simple.scalarGenerate curveGenerateKeyPair _ = toKeyPair <$> Simple.scalarGenerate where toKeyPair scalar = KeyPair (Simple.pointBaseMul scalar) scalar encodePoint _ point = encodeECPoint point decodePoint _ bs = decodeECPoint bs instance EllipticCurveArith Curve_P521R1 where pointAdd _ a b = Simple.pointAdd a b pointSmul _ s p = Simple.pointMul s p instance EllipticCurveDH Curve_P521R1 where ecdh _ s p = SharedSecret $ i2ospOf_ (curveSizeBytes prx) x where prx = Proxy :: Proxy Curve_P521R1 Simple.Point x _ = pointSmul prx s p data Curve_X25519 = Curve_X25519 instance EllipticCurve Curve_X25519 where type Point Curve_X25519 = X25519.PublicKey type Scalar Curve_X25519 = X25519.SecretKey curveSizeBits _ = 255 curveGenerateScalar _ = X25519.generateSecretKey curveGenerateKeyPair _ = do s <- X25519.generateSecretKey return $ KeyPair (X25519.toPublic s) s encodePoint _ p = B.convert p decodePoint _ bs = X25519.publicKey bs instance EllipticCurveDH Curve_X25519 where ecdh _ s p = SharedSecret $ convert secret where secret = X25519.dh p s data Curve_X448 = Curve_X448 instance EllipticCurve Curve_X448 where type Point Curve_X448 = X448.PublicKey type Scalar Curve_X448 = X448.SecretKey curveSizeBits _ = 448 curveGenerateScalar _ = X448.generateSecretKey curveGenerateKeyPair _ = do s <- X448.generateSecretKey return $ KeyPair (X448.toPublic s) s encodePoint _ p = B.convert p decodePoint _ bs = X448.publicKey bs instance EllipticCurveDH Curve_X448 where ecdh _ s p = SharedSecret $ convert secret where secret = X448.dh p s encodeECPoint :: forall curve bs . (Simple.Curve curve, ByteArray bs) => Simple.Point curve -> bs encodeECPoint Simple.PointO = error "encodeECPoint: cannot serialize point at infinity" encodeECPoint (Simple.Point x y) = B.concat [uncompressed,xb,yb] where size = Simple.curveSizeBytes (Proxy :: Proxy curve) uncompressed, xb, yb :: bs uncompressed = B.singleton 4 xb = i2ospOf_ size x yb = i2ospOf_ size y decodeECPoint :: (Simple.Curve curve, ByteArray bs) => bs -> CryptoFailable (Simple.Point curve) decodeECPoint mxy = case B.uncons mxy of Nothing -> CryptoFailed $ CryptoError_PointSizeInvalid Just (m,xy) -- uncompressed | m == 4 -> let siz = B.length xy `div` 2 (xb,yb) = B.splitAt siz xy x = os2ip xb y = os2ip yb in Simple.pointFromIntegers (x,y) | otherwise -> CryptoFailed $ CryptoError_PointFormatInvalid curveSizeBytes :: EllipticCurve c => Proxy c -> Int curveSizeBytes proxy = (curveSizeBits proxy + 7) `div` 8 cryptonite-0.23/Crypto/Error.hs0000644000000000000000000000040412516347336014741 0ustar0000000000000000-- | -- Module : Crypto.Error -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- module Crypto.Error ( module Crypto.Error.Types ) where import Crypto.Error.Types cryptonite-0.23/Crypto/MAC/CMAC.hs0000644000000000000000000001017412702145223014744 0ustar0000000000000000-- | -- Module : Crypto.MAC.CMAC -- License : BSD-style -- Maintainer : Kei Hibino -- Stability : experimental -- Portability : unknown -- -- provide the CMAC (Cipher based Message Authentification Code) base algorithm. -- -- -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.MAC.CMAC ( cmac , CMAC , subKeys ) where import Data.Word import Data.Bits (setBit, testBit, shiftL) import Data.List (foldl') import Crypto.Cipher.Types import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B -- | Authentication code newtype CMAC a = CMAC Bytes deriving (ByteArrayAccess) instance Eq (CMAC a) where CMAC b1 == CMAC b2 = B.constEq b1 b2 -- | compute a MAC using the supplied cipher cmac :: (ByteArrayAccess bin, BlockCipher cipher) => cipher -- ^ key to compute CMAC with -> bin -- ^ input message -> CMAC cipher -- ^ output tag cmac k msg = CMAC $ foldl' (\c m -> ecbEncrypt k $ bxor c m) zeroV ms where bytes = blockSize k zeroV = B.replicate bytes 0 :: Bytes (k1, k2) = subKeys k ms = cmacChunks k k1 k2 $ B.convert msg cmacChunks :: (BlockCipher k, ByteArray ba) => k -> ba -> ba -> ba -> [ba] cmacChunks k k1 k2 = rec' where rec' msg | B.null tl = if lack == 0 then [bxor k1 hd] else [bxor k2 $ hd `B.append` B.pack (0x80 : replicate (lack - 1) 0)] | otherwise = hd : rec' tl where bytes = blockSize k (hd, tl) = B.splitAt bytes msg lack = bytes - B.length hd -- | make sub-keys used in CMAC subKeys :: (BlockCipher k, ByteArray ba) => k -- ^ key to compute CMAC with -> (ba, ba) -- ^ sub-keys to compute CMAC subKeys k = (k1, k2) where ipt = cipherIPT k k0 = ecbEncrypt k $ B.replicate (blockSize k) 0 k1 = subKey ipt k0 k2 = subKey ipt k1 -- polynomial multiply operation to culculate subkey subKey :: (ByteArray ba) => [Word8] -> ba -> ba subKey ipt ws = case B.unpack ws of [] -> B.empty w:_ | testBit w 7 -> B.pack ipt `bxor` shiftL1 ws | otherwise -> shiftL1 ws shiftL1 :: (ByteArray ba) => ba -> ba shiftL1 = B.pack . shiftL1W . B.unpack shiftL1W :: [Word8] -> [Word8] shiftL1W [] = [] shiftL1W ws@(_:ns) = rec' $ zip ws (ns ++ [0]) where rec' [] = [] rec' ((x,y):ps) = w : rec' ps where w | testBit y 7 = setBit sl1 0 | otherwise = sl1 where sl1 = shiftL x 1 bxor :: ByteArray ba => ba -> ba -> ba bxor = B.xor ----- cipherIPT :: BlockCipher k => k -> [Word8] cipherIPT = expandIPT . blockSize where -- Data type which represents the smallest irreducibule binary polynomial -- against specified degree. -- -- Maximum degree bit and degree 0 bit are omitted. -- For example, The value /Q 7 2 1/ corresponds to the degree /128/. -- It represents that the smallest irreducible binary polynomial of degree 128 -- is x^128 + x^7 + x^2 + x^1 + 1. data IPolynomial = Q Int Int Int --- | T Int iPolynomial :: Int -> Maybe IPolynomial iPolynomial = d where d 64 = Just $ Q 4 3 1 d 128 = Just $ Q 7 2 1 d _ = Nothing -- Expand a tail bit pattern of irreducible binary polynomial expandIPT :: Int -> [Word8] expandIPT bytes = expandIPT' bytes ipt where ipt = maybe (error $ "Irreducible binary polynomial not defined against " ++ show nb ++ " bit") id $ iPolynomial nb nb = bytes * 8 -- Expand a tail bit pattern of irreducible binary polynomial expandIPT' :: Int -- ^ width in byte -> IPolynomial -- ^ irreducible binary polynomial definition -> [Word8] -- ^ result bit pattern expandIPT' bytes (Q x y z) = reverse . setB x . setB y . setB z . setB 0 $ replicate bytes 0 where setB i ws = hd ++ setBit (head tl) r : tail tl where (q, r) = i `quotRem` 8 (hd, tl) = splitAt q ws cryptonite-0.23/Crypto/MAC/Poly1305.hs0000644000000000000000000000761112673727640015517 0ustar0000000000000000 -- | -- Module : Crypto.MAC.Poly1305 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Poly1305 implementation -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.MAC.Poly1305 ( Ctx , State , Auth(..) , authTag -- * Incremental MAC Functions , initialize -- :: State , update -- :: State -> ByteString -> State , updates -- :: State -> [ByteString] -> State , finalize -- :: State -> Auth -- * One-pass MAC function , auth ) where import Foreign.Ptr import Foreign.C.Types import Data.Word import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes, Bytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.DeepSeq import Crypto.Error -- | Poly1305 State newtype State = State ScrubbedBytes deriving (ByteArrayAccess) -- | Poly1305 State. use State instead of Ctx type Ctx = State {-# DEPRECATED Ctx "use Poly1305 State instead" #-} -- | Poly1305 Auth newtype Auth = Auth Bytes deriving (ByteArrayAccess,NFData) authTag :: ByteArrayAccess b => b -> CryptoFailable Auth authTag b | B.length b /= 16 = CryptoFailed $ CryptoError_AuthenticationTagSizeInvalid | otherwise = CryptoPassed $ Auth $ B.convert b instance Eq Auth where (Auth a1) == (Auth a2) = B.constEq a1 a2 foreign import ccall unsafe "cryptonite_poly1305.h cryptonite_poly1305_init" c_poly1305_init :: Ptr State -> Ptr Word8 -> IO () foreign import ccall "cryptonite_poly1305.h cryptonite_poly1305_update" c_poly1305_update :: Ptr State -> Ptr Word8 -> CUInt -> IO () foreign import ccall unsafe "cryptonite_poly1305.h cryptonite_poly1305_finalize" c_poly1305_finalize :: Ptr Word8 -> Ptr State -> IO () -- | initialize a Poly1305 context initialize :: ByteArrayAccess key => key -> CryptoFailable State initialize key | B.length key /= 32 = CryptoFailed $ CryptoError_MacKeyInvalid | otherwise = CryptoPassed $ State $ B.allocAndFreeze 84 $ \ctxPtr -> B.withByteArray key $ \keyPtr -> c_poly1305_init (castPtr ctxPtr) keyPtr {-# NOINLINE initialize #-} -- | update a context with a bytestring update :: ByteArrayAccess ba => State -> ba -> State update (State prevCtx) d = State $ B.copyAndFreeze prevCtx $ \ctxPtr -> B.withByteArray d $ \dataPtr -> c_poly1305_update (castPtr ctxPtr) dataPtr (fromIntegral $ B.length d) {-# NOINLINE update #-} -- | updates a context with multiples bytestring updates :: ByteArrayAccess ba => State -> [ba] -> State updates (State prevCtx) d = State $ B.copyAndFreeze prevCtx (loop d) where loop [] _ = return () loop (x:xs) ctxPtr = do B.withByteArray x $ \dataPtr -> c_poly1305_update ctxPtr dataPtr (fromIntegral $ B.length x) loop xs ctxPtr {-# NOINLINE updates #-} -- | finalize the context into a digest bytestring finalize :: State -> Auth finalize (State prevCtx) = Auth $ B.allocAndFreeze 16 $ \dst -> do _ <- B.copy prevCtx (\ctxPtr -> c_poly1305_finalize dst (castPtr ctxPtr)) :: IO ScrubbedBytes return () {-# NOINLINE finalize #-} -- | One-pass authorization creation auth :: (ByteArrayAccess key, ByteArrayAccess ba) => key -> ba -> Auth auth key d | B.length key /= 32 = error "Poly1305: key length expected 32 bytes" | otherwise = Auth $ B.allocAndFreeze 16 $ \dst -> do _ <- B.alloc 84 (onCtx dst) :: IO ScrubbedBytes return () where onCtx dst ctxPtr = B.withByteArray key $ \keyPtr -> do c_poly1305_init (castPtr ctxPtr) keyPtr B.withByteArray d $ \dataPtr -> c_poly1305_update (castPtr ctxPtr) dataPtr (fromIntegral $ B.length d) c_poly1305_finalize dst (castPtr ctxPtr) cryptonite-0.23/Crypto/MAC/HMAC.hs0000644000000000000000000001130612673727640014767 0ustar0000000000000000-- | -- Module : Crypto.MAC.HMAC -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- provide the HMAC (Hash based Message Authentification Code) base algorithm. -- -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.MAC.HMAC ( hmac , HMAC(..) -- * incremental , Context(..) , initialize , update , updates , finalize ) where import Crypto.Hash hiding (Context) import qualified Crypto.Hash as Hash (Context) import Crypto.Hash.IO import Crypto.Internal.ByteArray (ScrubbedBytes, ByteArray, ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Data.Memory.PtrMethods import Crypto.Internal.Compat import Crypto.Internal.Imports -- | Represent an HMAC that is a phantom type with the hash used to produce the mac. -- -- The Eq instance is constant time. newtype HMAC a = HMAC { hmacGetDigest :: Digest a } deriving (ByteArrayAccess) instance Eq (HMAC a) where (HMAC b1) == (HMAC b2) = B.constEq b1 b2 -- | compute a MAC using the supplied hashing function hmac :: (ByteArrayAccess key, ByteArrayAccess message, HashAlgorithm a) => key -- ^ Secret key -> message -- ^ Message to MAC -> HMAC a hmac secret msg = finalize $ updates (initialize secret) [msg] -- | Represent an ongoing HMAC state, that can be appended with 'update' -- and finalize to an HMAC with 'hmacFinalize' data Context hashalg = Context !(Hash.Context hashalg) !(Hash.Context hashalg) -- | Initialize a new incremental HMAC context initialize :: (ByteArrayAccess key, HashAlgorithm a) => key -- ^ Secret key -> Context a initialize secret = unsafeDoIO (doHashAlg undefined) where doHashAlg :: HashAlgorithm a => a -> IO (Context a) doHashAlg alg = do !withKey <- case B.length secret `compare` blockSize of EQ -> return $ B.withByteArray secret LT -> do key <- B.alloc blockSize $ \k -> do memSet k 0 blockSize B.withByteArray secret $ \s -> memCopy k s (B.length secret) return $ B.withByteArray (key :: ScrubbedBytes) GT -> do -- hash the secret key ctx <- hashMutableInitWith alg hashMutableUpdate ctx secret digest <- hashMutableFinalize ctx hashMutableReset ctx -- pad it if necessary if digestSize < blockSize then do key <- B.alloc blockSize $ \k -> do memSet k 0 blockSize B.withByteArray digest $ \s -> memCopy k s (B.length digest) return $ B.withByteArray (key :: ScrubbedBytes) else return $ B.withByteArray digest (inner, outer) <- withKey $ \keyPtr -> (,) <$> B.alloc blockSize (\p -> memXorWith p 0x36 keyPtr blockSize) <*> B.alloc blockSize (\p -> memXorWith p 0x5c keyPtr blockSize) return $ Context (hashUpdates initCtx [outer :: ScrubbedBytes]) (hashUpdates initCtx [inner :: ScrubbedBytes]) where blockSize = hashBlockSize alg digestSize = hashDigestSize alg initCtx = hashInitWith alg {-# NOINLINE initialize #-} -- | Incrementally update a HMAC context update :: (ByteArrayAccess message, HashAlgorithm a) => Context a -- ^ Current HMAC context -> message -- ^ Message to append to the MAC -> Context a -- ^ Updated HMAC context update (Context octx ictx) msg = Context octx (hashUpdate ictx msg) -- | Increamentally update a HMAC context with multiple inputs updates :: (ByteArrayAccess message, HashAlgorithm a) => Context a -- ^ Current HMAC context -> [message] -- ^ Messages to append to the MAC -> Context a -- ^ Updated HMAC context updates (Context octx ictx) msgs = Context octx (hashUpdates ictx msgs) -- | Finalize a HMAC context and return the HMAC. finalize :: HashAlgorithm a => Context a -> HMAC a finalize (Context octx ictx) = HMAC $ hashFinalize $ hashUpdates octx [hashFinalize ictx] cryptonite-0.23/Crypto/Number/Basic.hs0000644000000000000000000000671512530033346016121 0ustar0000000000000000-- | -- Module : Crypto.Number.Basic -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good {-# LANGUAGE BangPatterns #-} module Crypto.Number.Basic ( sqrti , gcde , areEven , log2 , numBits , numBytes ) where import Crypto.Number.Compat -- | sqrti returns two integer (l,b) so that l <= sqrt i <= b -- the implementation is quite naive, use an approximation for the first number -- and use a dichotomy algorithm to compute the bound relatively efficiently. sqrti :: Integer -> (Integer, Integer) sqrti i | i < 0 = error "cannot compute negative square root" | i == 0 = (0,0) | i == 1 = (1,1) | i == 2 = (1,2) | otherwise = loop x0 where nbdigits = length $ show i x0n = (if even nbdigits then nbdigits - 2 else nbdigits - 1) `div` 2 x0 = if even nbdigits then 2 * 10 ^ x0n else 6 * 10 ^ x0n loop x = case compare (sq x) i of LT -> iterUp x EQ -> (x, x) GT -> iterDown x iterUp lb = if sq ub >= i then iter lb ub else iterUp ub where ub = lb * 2 iterDown ub = if sq lb >= i then iterDown lb else iter lb ub where lb = ub `div` 2 iter lb ub | lb == ub = (lb, ub) | lb+1 == ub = (lb, ub) | otherwise = let d = (ub - lb) `div` 2 in if sq (lb + d) >= i then iter lb (ub-d) else iter (lb+d) ub sq a = a * a -- | get the extended GCD of two integer using integer divMod -- -- gcde 'a' 'b' find (x,y,gcd(a,b)) where ax + by = d -- gcde :: Integer -> Integer -> (Integer, Integer, Integer) gcde a b = onGmpUnsupported (gmpGcde a b) $ if d < 0 then (-x,-y,-d) else (x,y,d) where (d, x, y) = f (a,1,0) (b,0,1) f t (0, _, _) = t f (a', sa, ta) t@(b', sb, tb) = let (q, r) = a' `divMod` b' in f t (r, sa - (q * sb), ta - (q * tb)) -- | check if a list of integer are all even areEven :: [Integer] -> Bool areEven = and . map even -- | Compute the binary logarithm of a integer log2 :: Integer -> Int log2 n = onGmpUnsupported (gmpLog2 n) $ imLog 2 n where -- http://www.haskell.org/pipermail/haskell-cafe/2008-February/039465.html imLog b x = if x < b then 0 else (x `div` b^l) `doDiv` l where l = 2 * imLog (b * b) x doDiv x' l' = if x' < b then l' else (x' `div` b) `doDiv` (l' + 1) {-# INLINE log2 #-} -- | Compute the number of bits for an integer numBits :: Integer -> Int numBits n = gmpSizeInBits n `onGmpUnsupported` (if n == 0 then 1 else computeBits 0 n) where computeBits !acc i | q == 0 = if r >= 0x80 then acc+8 else if r >= 0x40 then acc+7 else if r >= 0x20 then acc+6 else if r >= 0x10 then acc+5 else if r >= 0x08 then acc+4 else if r >= 0x04 then acc+3 else if r >= 0x02 then acc+2 else if r >= 0x01 then acc+1 else acc -- should be catch by previous loop | otherwise = computeBits (acc+8) q where (q,r) = i `divMod` 256 -- | Compute the number of bytes for an integer numBytes :: Integer -> Int numBytes n = gmpSizeInBytes n `onGmpUnsupported` ((numBits n + 7) `div` 8) cryptonite-0.23/Crypto/Number/F2m.hs0000644000000000000000000001144512746570656015543 0ustar0000000000000000-- | -- Module : Crypto.Math.F2m -- License : BSD-style -- Maintainer : Danny Navarro -- Stability : experimental -- Portability : Good -- -- This module provides basic arithmetic operations over F₂m. Performance is -- not optimal and it doesn't provide protection against timing -- attacks. The 'm' parameter is implicitly derived from the irreducible -- polynomial where applicable. module Crypto.Number.F2m ( BinaryPolynomial , addF2m , mulF2m , squareF2m' , squareF2m , modF2m , invF2m , divF2m ) where import Data.Bits (xor, shift, testBit, setBit) import Data.List import Crypto.Internal.Imports import Crypto.Number.Basic -- | Binary Polynomial represented by an integer type BinaryPolynomial = Integer -- | Addition over F₂m. This is just a synonym of 'xor'. addF2m :: Integer -> Integer -> Integer addF2m = xor {-# INLINE addF2m #-} -- | Reduction by modulo over F₂m. -- -- This function is undefined for negative arguments, because their bit -- representation is platform-dependent. Zero modulus is also prohibited. modF2m :: BinaryPolynomial -- ^ Modulus -> Integer -> Integer modF2m fx i | fx < 0 || i < 0 = error "modF2m: negative number represent no binary polynomial" | fx == 0 = error "modF2m: cannot divide by zero polynomial" | fx == 1 = 0 | otherwise = go i where lfx = log2 fx go n | s == 0 = n `addF2m` fx | s < 0 = n | otherwise = go $ n `addF2m` shift fx s where s = log2 n - lfx {-# INLINE modF2m #-} -- | Multiplication over F₂m. -- -- This function is undefined for negative arguments, because their bit -- representation is platform-dependent. Zero modulus is also prohibited. mulF2m :: BinaryPolynomial -- ^ Modulus -> Integer -> Integer -> Integer mulF2m fx n1 n2 | fx < 0 || n1 < 0 || n2 < 0 = error "mulF2m: negative number represent no binary binary polynomial" | fx == 0 = error "modF2m: cannot multiply modulo zero polynomial" | otherwise = modF2m fx $ go (if n2 `mod` 2 == 1 then n1 else 0) (log2 n2) where go n s | s == 0 = n | otherwise = if testBit n2 s then go (n `addF2m` shift n1 s) (s - 1) else go n (s - 1) {-# INLINABLE mulF2m #-} -- | Squaring over F₂m. -- -- This function is undefined for negative arguments, because their bit -- representation is platform-dependent. Zero modulus is also prohibited. squareF2m :: BinaryPolynomial -- ^ Modulus -> Integer -> Integer squareF2m fx = modF2m fx . squareF2m' {-# INLINE squareF2m #-} -- | Squaring over F₂m without reduction by modulo. -- -- The implementation utilizes the fact that for binary polynomial S(x) we have -- S(x)^2 = S(x^2). In other words, insert a zero bit between every bits of argument: 1101 -> 1010001. -- -- This function is undefined for negative arguments, because their bit -- representation is platform-dependent. squareF2m' :: Integer -> Integer squareF2m' n | n < 0 = error "mulF2m: negative number represent no binary binary polynomial" | otherwise = foldl' (\acc s -> if testBit n s then setBit acc (2 * s) else acc) 0 [0 .. log2 n] {-# INLINE squareF2m' #-} -- | Extended GCD algorithm for polynomials. For @a@ and @b@ returns @(g, u, v)@ such that @a * u + b * v == g@. -- -- Reference: https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#B.C3.A9zout.27s_identity_and_extended_GCD_algorithm gcdF2m :: Integer -> Integer -> (Integer, Integer, Integer) gcdF2m a b = go (a, b, 1, 0, 0, 1) where go (g, 0, u, _, v, _) = (g, u, v) go (r0, r1, s0, s1, t0, t1) = go (r1, r0 `addF2m` shift r1 j, s1, s0 `addF2m` shift s1 j, t1, t0 `addF2m` shift t1 j) where j = max 0 (log2 r0 - log2 r1) -- | Modular inversion over F₂m. -- If @n@ doesn't have an inverse, 'Nothing' is returned. -- -- This function is undefined for negative arguments, because their bit -- representation is platform-dependent. Zero modulus is also prohibited. invF2m :: BinaryPolynomial -- ^ Modulus -> Integer -> Maybe Integer invF2m fx n = if g == 1 then Just (modF2m fx u) else Nothing where (g, u, _) = gcdF2m n fx {-# INLINABLE invF2m #-} -- | Division over F₂m. If the dividend doesn't have an inverse it returns -- 'Nothing'. -- -- This function is undefined for negative arguments, because their bit -- representation is platform-dependent. Zero modulus is also prohibited. divF2m :: BinaryPolynomial -- ^ Modulus -> Integer -- ^ Dividend -> Integer -- ^ Divisor -> Maybe Integer -- ^ Quotient divF2m fx n1 n2 = mulF2m fx n1 <$> invF2m fx n2 {-# INLINE divF2m #-} cryptonite-0.23/Crypto/Number/Generate.hs0000644000000000000000000001074213077673501016637 0ustar0000000000000000-- | -- Module : Crypto.Number.Generate -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good module Crypto.Number.Generate ( GenTopPolicy(..) , generateParams , generateMax , generateBetween ) where import Crypto.Internal.Imports import Crypto.Number.Basic import Crypto.Number.Serialize import Crypto.Random.Types import Control.Monad (when) import Foreign.Ptr import Foreign.Storable import Data.Bits ((.|.), (.&.), shiftL, complement, testBit) import Crypto.Internal.ByteArray (ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B -- | Top bits policy when generating a number data GenTopPolicy = SetHighest -- ^ set the highest bit | SetTwoHighest -- ^ set the two highest bit deriving (Show,Eq) -- | Generate a number for a specific size of bits, -- and optionaly set bottom and top bits -- -- If the top bit policy is 'Nothing', then nothing is -- done on the highest bit (it's whatever the random generator set). -- -- If @generateOdd is set to 'True', then the number generated -- is guaranteed to be odd. Otherwise it will be whatever is generated -- generateParams :: MonadRandom m => Int -- ^ number of bits -> Maybe GenTopPolicy -- ^ top bit policy -> Bool -- ^ force the number to be odd -> m Integer generateParams bits genTopPolicy generateOdd | bits <= 0 = return 0 | otherwise = os2ip . tweak <$> getRandomBytes bytes where tweak :: ScrubbedBytes -> ScrubbedBytes tweak orig = B.copyAndFreeze orig $ \p0 -> do let p1 = p0 `plusPtr` 1 pEnd = p0 `plusPtr` (bytes - 1) case genTopPolicy of Nothing -> return () Just SetHighest -> p0 |= (1 `shiftL` bit) Just SetTwoHighest | bit == 0 -> do p0 $= 0x1 p1 |= 0x80 | otherwise -> p0 |= (0x3 `shiftL` (bit - 1)) p0 &= (complement $ mask) when generateOdd (pEnd |= 0x1) ($=) :: Ptr Word8 -> Word8 -> IO () ($=) p w = poke p w (|=) :: Ptr Word8 -> Word8 -> IO () (|=) p w = peek p >>= \v -> poke p (v .|. w) (&=) :: Ptr Word8 -> Word8 -> IO () (&=) p w = peek p >>= \v -> poke p (v .&. w) bytes = (bits + 7) `div` 8; bit = (bits - 1) `mod` 8; mask = 0xff `shiftL` (bit + 1); -- | Generate a positive integer x, s.t. 0 <= x < range generateMax :: MonadRandom m => Integer -- ^ range -> m Integer generateMax range | range <= 1 = return 0 | range < 127 = generateSimple | canOverGenerate = loopGenerateOver tries | otherwise = loopGenerate tries where -- this "generator" is mostly for quickcheck benefits. it'll be biased if -- range is not a multiple of 2, but overall, no security should be -- assumed for a number between 0 and 127. generateSimple = flip mod range `fmap` generateParams bits Nothing False loopGenerate count | count == 0 = error $ "internal: generateMax(" ++ show range ++ " bits=" ++ show bits ++ ") (normal) doesn't seems to work properly" | otherwise = do r <- generateParams bits Nothing False if isValid r then return r else loopGenerate (count-1) loopGenerateOver count | count == 0 = error $ "internal: generateMax(" ++ show range ++ " bits=" ++ show bits ++ ") (over) doesn't seems to work properly" | otherwise = do r <- generateParams (bits+1) Nothing False let r2 = r - range r3 = r2 - range if isValid r then return r else if isValid r2 then return r2 else if isValid r3 then return r3 else loopGenerateOver (count-1) bits = numBits range canOverGenerate = bits > 3 && not (range `testBit` (bits-2)) && not (range `testBit` (bits-3)) isValid n = n < range tries :: Int tries = 100 -- | generate a number between the inclusive bound [low,high]. generateBetween :: MonadRandom m => Integer -> Integer -> m Integer generateBetween low high = (low +) <$> generateMax (high - low + 1) cryptonite-0.23/Crypto/Number/ModArithmetic.hs0000644000000000000000000000621312533034410017616 0ustar0000000000000000{-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} -- | -- Module : Crypto.Number.ModArithmetic -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good module Crypto.Number.ModArithmetic ( -- * exponentiation expSafe , expFast -- * inverse computing , inverse , inverseCoprimes ) where import Control.Exception (throw, Exception) import Data.Typeable import Crypto.Number.Basic import Crypto.Number.Compat -- | Raised when two numbers are supposed to be coprimes but are not. data CoprimesAssertionError = CoprimesAssertionError deriving (Show,Typeable) instance Exception CoprimesAssertionError -- | Compute the modular exponentiation of base^exponant using -- algorithms design to avoid side channels and timing measurement -- -- Modulo need to be odd otherwise the normal fast modular exponentiation -- is used. -- -- When used with integer-simple, this function is not different -- from expFast, and thus provide the same unstudied and dubious -- timing and side channels claims. -- -- with GHC 7.10, the powModSecInteger is missing from integer-gmp -- (which is now integer-gmp2), so is has the same security as old -- ghc version. expSafe :: Integer -- ^ base -> Integer -- ^ exponant -> Integer -- ^ modulo -> Integer -- ^ result expSafe b e m | odd m = gmpPowModSecInteger b e m `onGmpUnsupported` (gmpPowModInteger b e m `onGmpUnsupported` exponentiation b e m) | otherwise = gmpPowModInteger b e m `onGmpUnsupported` exponentiation b e m -- | Compute the modular exponentiation of base^exponant using -- the fastest algorithm without any consideration for -- hiding parameters. -- -- Use this function when all the parameters are public, -- otherwise 'expSafe' should be prefered. expFast :: Integer -- ^ base -> Integer -- ^ exponant -> Integer -- ^ modulo -> Integer -- ^ result expFast b e m = gmpPowModInteger b e m `onGmpUnsupported` exponentiation b e m -- | exponentiation computes modular exponentiation as b^e mod m -- using repetitive squaring. exponentiation :: Integer -> Integer -> Integer -> Integer exponentiation b e m | b == 1 = b | e == 0 = 1 | e == 1 = b `mod` m | even e = let p = (exponentiation b (e `div` 2) m) `mod` m in (p^(2::Integer)) `mod` m | otherwise = (b * exponentiation b (e-1) m) `mod` m -- | inverse computes the modular inverse as in g^(-1) mod m inverse :: Integer -> Integer -> Maybe Integer inverse g m = gmpInverse g m `onGmpUnsupported` v where v | d > 1 = Nothing | otherwise = Just (x `mod` m) (x,_,d) = gcde g m -- | Compute the modular inverse of 2 coprime numbers. -- This is equivalent to inverse except that the result -- is known to exists. -- -- if the numbers are not defined as coprime, this function -- will raise a CoprimesAssertionError. inverseCoprimes :: Integer -> Integer -> Integer inverseCoprimes g m = case inverse g m of Nothing -> throw CoprimesAssertionError Just i -> i cryptonite-0.23/Crypto/Number/Prime.hs0000644000000000000000000002344513050556742016163 0ustar0000000000000000-- | -- Module : Crypto.Number.Prime -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good {-# LANGUAGE BangPatterns #-} module Crypto.Number.Prime ( generatePrime , generateSafePrime , isProbablyPrime , findPrimeFrom , findPrimeFromWith , primalityTestMillerRabin , primalityTestNaive , primalityTestFermat , isCoprime ) where import Crypto.Internal.Imports import Crypto.Number.Compat import Crypto.Number.Generate import Crypto.Number.Basic (sqrti, gcde) import Crypto.Number.ModArithmetic (expSafe) import Crypto.Random.Types import Crypto.Random.Probabilistic import Crypto.Error import Data.Bits -- | returns if the number is probably prime. -- first a list of small primes are implicitely tested for divisibility, -- then a fermat primality test is used with arbitrary numbers and -- then the Miller Rabin algorithm is used with an accuracy of 30 recursions isProbablyPrime :: Integer -> Bool isProbablyPrime !n | any (\p -> p `divides` n) (filter (< n) firstPrimes) = False | n >= 2 && n <= 2903 = True | primalityTestFermat 50 (n `div` 2) n = primalityTestMillerRabin 30 n | otherwise = False -- | generate a prime number of the required bitsize (i.e. in the range -- [2^(b-1)+2^(b-2), 2^b)). -- -- May throw a CryptoError_PrimeSizeInvalid if the requested size is less -- than 5 bits, as the smallest prime meeting these conditions is 29. -- This function requires that the two highest bits are set, so that when -- multiplied with another prime to create a key, it is guaranteed to be of -- the proper size. generatePrime :: MonadRandom m => Int -> m Integer generatePrime bits = do if bits < 5 then throwCryptoError $ CryptoFailed $ CryptoError_PrimeSizeInvalid else do sp <- generateParams bits (Just SetTwoHighest) True let prime = findPrimeFrom sp if prime < 1 `shiftL` bits then return $ prime else generatePrime bits -- | generate a prime number of the form 2p+1 where p is also 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. -- -- May throw a CryptoError_PrimeSizeInvalid if the requested size is less than -- 6 bits, as the smallest safe prime with the two highest bits set is 59. generateSafePrime :: MonadRandom m => Int -> m Integer generateSafePrime bits = do if bits < 6 then throwCryptoError $ CryptoFailed $ CryptoError_PrimeSizeInvalid else do sp <- generateParams bits (Just SetTwoHighest) True let p = findPrimeFromWith (\i -> isProbablyPrime (2*i+1)) (sp `div` 2) let val = 2 * p + 1 if val < 1 `shiftL` bits then return $ val else generateSafePrime bits -- | find a prime from a starting point where the property hold. findPrimeFromWith :: (Integer -> Bool) -> Integer -> Integer findPrimeFromWith prop !n | even n = findPrimeFromWith prop (n+1) | otherwise = if not (isProbablyPrime n) then findPrimeFromWith prop (n+2) else if prop n then n else findPrimeFromWith prop (n+2) -- | find a prime from a starting point with no specific property. findPrimeFrom :: Integer -> Integer findPrimeFrom n = case gmpNextPrime n of GmpSupported p -> p GmpUnsupported -> findPrimeFromWith (\_ -> True) n -- | 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 :: Int -> Integer -> Bool primalityTestMillerRabin tries !n = case gmpTestPrimeMillerRabin tries n of GmpSupported b -> b GmpUnsupported -> probabilistic run where run | n <= 3 = error "Miller-Rabin requires tested value to be > 3" | even n = return False | tries <= 0 = error "Miller-Rabin tries need to be > 0" | otherwise = loop <$> generateTries tries !nm1 = n-1 !nm2 = n-2 (!s,!d) = (factorise 0 nm1) generateTries 0 = return [] generateTries t = do v <- generateBetween 2 nm2 vs <- generateTries (t-1) return (v:vs) -- factorise n-1 into the form 2^s*d factorise :: Integer -> Integer -> (Integer, Integer) factorise !si !vi | vi `testBit` 0 = (si, vi) | otherwise = factorise (si+1) (vi `shiftR` 1) -- probably faster to not shift v continously, but just once. expmod = expSafe -- when iteration reach zero, we have a probable prime loop [] = True loop (w:ws) = let x = expmod w d n in if x == (1 :: Integer) || x == nm1 then loop ws else loop' ws ((x*x) `mod` n) 1 -- loop from 1 to s-1. if we reach the end then it's composite loop' ws !x2 !r | r == s = False | x2 == 1 = False | x2 /= nm1 = loop' ws ((x2*x2) `mod` n) (r+1) | otherwise = loop ws {- n < z -> witness to test 1373653 [2,3] 9080191 [31,73] 4759123141 [2,7,61] 2152302898747 [2,3,5,7,11] 3474749660383 [2,3,5,7,11,13] 341550071728321 [2,3,5,7,11,13,17] -} -- | Probabilitic Test using Fermat primility test. -- Beware of Carmichael numbers that are Fermat liars, i.e. this test -- is useless for them. always combines with some other test. primalityTestFermat :: Int -- ^ number of iterations of the algorithm -> Integer -- ^ starting a -> Integer -- ^ number to test for primality -> Bool primalityTestFermat n a p = and $ map expTest [a..(a+fromIntegral n)] where !pm1 = p-1 expTest i = expSafe i pm1 p == 1 -- | Test naively is integer is prime. -- while naive, we skip even number and stop iteration at i > sqrt(n) primalityTestNaive :: Integer -> Bool primalityTestNaive n | n <= 1 = False | n == 2 = True | even n = False | otherwise = search 3 where !ubound = snd $ sqrti n search !i | i > ubound = True | i `divides` n = False | otherwise = search (i+2) -- | Test is two integer are coprime to each other isCoprime :: Integer -> Integer -> Bool isCoprime m n = case gcde m n of (_,_,d) -> d == 1 -- | list of the first primes till 2903.. firstPrimes :: [Integer] firstPrimes = [ 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 , 29 , 31 , 37 , 41 , 43 , 47 , 53 , 59 , 61 , 67 , 71 , 73 , 79 , 83 , 89 , 97 , 101 , 103 , 107 , 109 , 113 , 127 , 131 , 137 , 139 , 149 , 151 , 157 , 163 , 167 , 173 , 179 , 181 , 191 , 193 , 197 , 199 , 211 , 223 , 227 , 229 , 233 , 239 , 241 , 251 , 257 , 263 , 269 , 271 , 277 , 281 , 283 , 293 , 307 , 311 , 313 , 317 , 331 , 337 , 347 , 349 , 353 , 359 , 367 , 373 , 379 , 383 , 389 , 397 , 401 , 409 , 419 , 421 , 431 , 433 , 439 , 443 , 449 , 457 , 461 , 463 , 467 , 479 , 487 , 491 , 499 , 503 , 509 , 521 , 523 , 541 , 547 , 557 , 563 , 569 , 571 , 577 , 587 , 593 , 599 , 601 , 607 , 613 , 617 , 619 , 631 , 641 , 643 , 647 , 653 , 659 , 661 , 673 , 677 , 683 , 691 , 701 , 709 , 719 , 727 , 733 , 739 , 743 , 751 , 757 , 761 , 769 , 773 , 787 , 797 , 809 , 811 , 821 , 823 , 827 , 829 , 839 , 853 , 857 , 859 , 863 , 877 , 881 , 883 , 887 , 907 , 911 , 919 , 929 , 937 , 941 , 947 , 953 , 967 , 971 , 977 , 983 , 991 , 997 , 1009 , 1013 , 1019 , 1021 , 1031 , 1033 , 1039 , 1049 , 1051 , 1061 , 1063 , 1069 , 1087 , 1091 , 1093 , 1097 , 1103 , 1109 , 1117 , 1123 , 1129 , 1151 , 1153 , 1163 , 1171 , 1181 , 1187 , 1193 , 1201 , 1213 , 1217 , 1223 , 1229 , 1231 , 1237 , 1249 , 1259 , 1277 , 1279 , 1283 , 1289 , 1291 , 1297 , 1301 , 1303 , 1307 , 1319 , 1321 , 1327 , 1361 , 1367 , 1373 , 1381 , 1399 , 1409 , 1423 , 1427 , 1429 , 1433 , 1439 , 1447 , 1451 , 1453 , 1459 , 1471 , 1481 , 1483 , 1487 , 1489 , 1493 , 1499 , 1511 , 1523 , 1531 , 1543 , 1549 , 1553 , 1559 , 1567 , 1571 , 1579 , 1583 , 1597 , 1601 , 1607 , 1609 , 1613 , 1619 , 1621 , 1627 , 1637 , 1657 , 1663 , 1667 , 1669 , 1693 , 1697 , 1699 , 1709 , 1721 , 1723 , 1733 , 1741 , 1747 , 1753 , 1759 , 1777 , 1783 , 1787 , 1789 , 1801 , 1811 , 1823 , 1831 , 1847 , 1861 , 1867 , 1871 , 1873 , 1877 , 1879 , 1889 , 1901 , 1907 , 1913 , 1931 , 1933 , 1949 , 1951 , 1973 , 1979 , 1987 , 1993 , 1997 , 1999 , 2003 , 2011 , 2017 , 2027 , 2029 , 2039 , 2053 , 2063 , 2069 , 2081 , 2083 , 2087 , 2089 , 2099 , 2111 , 2113 , 2129 , 2131 , 2137 , 2141 , 2143 , 2153 , 2161 , 2179 , 2203 , 2207 , 2213 , 2221 , 2237 , 2239 , 2243 , 2251 , 2267 , 2269 , 2273 , 2281 , 2287 , 2293 , 2297 , 2309 , 2311 , 2333 , 2339 , 2341 , 2347 , 2351 , 2357 , 2371 , 2377 , 2381 , 2383 , 2389 , 2393 , 2399 , 2411 , 2417 , 2423 , 2437 , 2441 , 2447 , 2459 , 2467 , 2473 , 2477 , 2503 , 2521 , 2531 , 2539 , 2543 , 2549 , 2551 , 2557 , 2579 , 2591 , 2593 , 2609 , 2617 , 2621 , 2633 , 2647 , 2657 , 2659 , 2663 , 2671 , 2677 , 2683 , 2687 , 2689 , 2693 , 2699 , 2707 , 2711 , 2713 , 2719 , 2729 , 2731 , 2741 , 2749 , 2753 , 2767 , 2777 , 2789 , 2791 , 2797 , 2801 , 2803 , 2819 , 2833 , 2837 , 2843 , 2851 , 2857 , 2861 , 2879 , 2887 , 2897 , 2903 ] {-# INLINE divides #-} divides :: Integer -> Integer -> Bool divides i n = n `mod` i == 0 cryptonite-0.23/Crypto/Number/Serialize.hs0000644000000000000000000000366613045447125017037 0ustar0000000000000000-- | -- Module : Crypto.Number.Serialize -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- fast serialization primitives for integer {-# LANGUAGE BangPatterns #-} module Crypto.Number.Serialize ( i2osp , os2ip , i2ospOf , i2ospOf_ ) where import Crypto.Number.Basic import Crypto.Internal.Compat (unsafeDoIO) import qualified Crypto.Internal.ByteArray as B import qualified Crypto.Number.Serialize.Internal as Internal -- | os2ip converts a byte string into a positive integer os2ip :: B.ByteArrayAccess ba => ba -> Integer os2ip bs = unsafeDoIO $ B.withByteArray bs (\p -> Internal.os2ip p (B.length bs)) -- | i2osp converts a positive integer into a byte string -- -- first byte is MSB (most significant byte), last byte is the LSB (least significant byte) i2osp :: B.ByteArray ba => Integer -> ba i2osp 0 = B.allocAndFreeze 1 (\p -> Internal.i2osp 0 p 1 >> return ()) i2osp m = B.allocAndFreeze sz (\p -> Internal.i2osp m p sz >> return ()) where !sz = numBytes m -- | just like i2osp, but take an extra parameter for size. -- if the number is too big to fit in @len@ bytes, 'Nothing' is returned -- otherwise the number is padded with 0 to fit the @len@ required. i2ospOf :: B.ByteArray ba => Int -> Integer -> Maybe ba i2ospOf len m | len <= 0 = Nothing | m < 0 = Nothing | sz > len = Nothing | otherwise = Just $ B.unsafeCreate len (\p -> Internal.i2ospOf m p len >> return ()) where !sz = numBytes m -- | just like i2ospOf except that it doesn't expect a failure: i.e. -- an integer larger than the number of output bytes requested -- -- for example if you just took a modulo of the number that represent -- the size (example the RSA modulo n). i2ospOf_ :: B.ByteArray ba => Int -> Integer -> ba i2ospOf_ len = maybe (error "i2ospOf_: integer is larger than expected") id . i2ospOf len cryptonite-0.23/Crypto/Number/Serialize/Internal.hs0000644000000000000000000000462612673470266020620 0ustar0000000000000000-- | -- Module : Crypto.Number.Serialize.Internal -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- fast serialization primitives for integer using raw pointers {-# LANGUAGE BangPatterns #-} module Crypto.Number.Serialize.Internal ( i2osp , i2ospOf , os2ip ) where import Crypto.Number.Compat import Crypto.Number.Basic import Data.Bits import Data.Memory.PtrMethods import Data.Word (Word8) import Foreign.Ptr import Foreign.Storable -- | fill a pointer with the big endian binary representation of an integer -- -- if the room available @ptrSz is less than the number of bytes needed, -- 0 is returned. Likewise if a parameter is invalid, 0 is returned. -- -- returns the number of bytes written i2osp :: Integer -> Ptr Word8 -> Int -> IO Int i2osp m ptr ptrSz | ptrSz <= 0 = return 0 | m < 0 = return 0 | m == 0 = pokeByteOff ptr 0 (0 :: Word8) >> return 1 | ptrSz < sz = return 0 | otherwise = fillPtr ptr sz m >> return sz where !sz = numBytes m -- | Similar to 'i2osp', except it will pad any remaining space with zero. i2ospOf :: Integer -> Ptr Word8 -> Int -> IO Int i2ospOf m ptr ptrSz | ptrSz <= 0 = return 0 | m < 0 = return 0 | ptrSz < sz = return 0 | otherwise = do memSet ptr 0 ptrSz fillPtr (ptr `plusPtr` padSz) sz m return ptrSz where !sz = numBytes m !padSz = ptrSz - sz fillPtr :: Ptr Word8 -> Int -> Integer -> IO () fillPtr p sz m = gmpExportInteger m p `onGmpUnsupported` export (sz-1) m where export ofs i | ofs == 0 = pokeByteOff p ofs (fromIntegral i :: Word8) | otherwise = do let (i', b) = i `divMod` 256 pokeByteOff p ofs (fromIntegral b :: Word8) export (ofs-1) i' -- | transform a big endian binary integer representation pointed by a pointer and a size -- into an integer os2ip :: Ptr Word8 -> Int -> IO Integer os2ip ptr ptrSz | ptrSz <= 0 = return 0 | otherwise = gmpImportInteger ptrSz ptr `onGmpUnsupported` loop 0 0 ptr where loop :: Integer -> Int -> Ptr Word8 -> IO Integer loop !acc i p | i == ptrSz = return acc | otherwise = do w <- peekByteOff p i :: IO Word8 loop ((acc `shiftL` 8) .|. fromIntegral w) (i+1) p cryptonite-0.23/Crypto/KDF/Argon2.hs0000644000000000000000000001275113075454604015412 0ustar0000000000000000-- | -- Module : Crypto.KDF.Argon2 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Argon2 hashing function (P-H-C winner) -- -- Recommended to use this module qualified -- -- File started from Argon2.hs, from Oliver Charles -- at https://github.com/ocharles/argon2 -- module Crypto.KDF.Argon2 ( Options(..) , TimeCost , MemoryCost , Parallelism , Variant(..) , Version(..) , defaultOptions -- * Hashing function , hash ) where import Crypto.Internal.ByteArray (ScrubbedBytes, ByteArray, ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Crypto.Error import Control.Monad (when) import Data.Word import Foreign.C import Foreign.Ptr -- | Which variant of Argon2 to use. You should choose the variant that is most -- applicable to your intention to hash inputs. data Variant = Argon2d -- ^ Argon2i uses data-independent memory access, which is preferred -- for password hashing and password-based key derivation. Argon2i -- is slower as it makes more passes over the memory to protect from -- tradeoff attacks. | Argon2i -- ^ Argon2d is faster and uses data-depending memory access, which -- makes it suitable for cryptocurrencies and applications with no -- threats from side-channel timing attacks. | Argon2id -- ^ Argon2id is a hybrid of Argon2i and Argon2d, using a combination -- of data-depending and data-independent memory accesses, which gives -- some of Argon2i's resistance to side-channel cache timing attacks -- and much of Argon2d's resistance to GPU cracking attacks deriving (Eq,Ord,Read,Show,Enum,Bounded) -- | Which version of Argon2 to use data Version = Version10 | Version13 deriving (Eq,Ord,Read,Show,Enum,Bounded) -- | The time cost, which defines the amount of computation realized and therefore the execution time, given in number of iterations. -- -- 'FFI.ARGON2_MIN_TIME' <= 'hashIterations' <= 'FFI.ARGON2_MAX_TIME' type TimeCost = Word32 -- | The memory cost, which defines the memory usage, given in kibibytes. -- -- max 'FFI.ARGON2_MIN_MEMORY' (8 * 'hashParallelism') <= 'hashMemory' <= 'FFI.ARGON2_MAX_MEMORY' type MemoryCost = Word32 -- \ A parallelism degree, which defines the number of parallel threads. -- -- 'FFI.ARGON2_MIN_LANES' <= 'hashParallelism' <= 'FFI.ARGON2_MAX_LANES' && 'FFI.ARGON_MIN_THREADS' <= 'hashParallelism' <= 'FFI.ARGON2_MAX_THREADS' type Parallelism = Word32 -- | Parameters that can be adjusted to change the runtime performance of the -- hashing. data Options = Options { iterations :: !TimeCost , memory :: !MemoryCost , parallelism :: !Parallelism , variant :: !Variant -- ^ Which variant of Argon2 to use. , version :: !Version -- ^ Which version of Argon2 to use. } deriving (Eq,Ord,Read,Show) saltMinLength :: Int saltMinLength = 8 outputMinLength :: Int outputMinLength = 4 -- specification allows up to 2^32-1 but this is too big for a signed Int -- on a 32-bit architecture, so we limit tag length to 2^31-1 bytes outputMaxLength :: Int outputMaxLength = 0x7fffffff defaultOptions :: Options defaultOptions = Options { iterations = 1 , memory = 2 ^ (17 :: Int) , parallelism = 4 , variant = Argon2i , version = Version13 } hash :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray out) => Options -> password -> salt -> Int -> CryptoFailable out hash options password salt outLen | saltLen < saltMinLength = CryptoFailed CryptoError_SaltTooSmall | outLen < outputMinLength = CryptoFailed CryptoError_OutputLengthTooSmall | outLen > outputMaxLength = CryptoFailed CryptoError_OutputLengthTooBig | otherwise = CryptoPassed $ B.allocAndFreeze outLen $ \out -> do res <- B.withByteArray password $ \pPass -> B.withByteArray salt $ \pSalt -> argon2_hash (iterations options) (memory options) (parallelism options) pPass (csizeOfInt passwordLen) pSalt (csizeOfInt saltLen) out (csizeOfInt outLen) (cOfVariant $ variant options) (cOfVersion $ version options) when (res /= 0) $ error "argon2: hash: internal error" where saltLen = B.length salt passwordLen = B.length password data Pass data Salt data HashOut type CVariant = CInt -- valid value is 0 (Argon2d), 1 (Argon2i) and 2 (Argon2id) type CVersion = CInt -- valid value is 0x10, 0x13 cOfVersion :: Version -> CVersion cOfVersion Version10 = 0x10 cOfVersion Version13 = 0x13 cOfVariant :: Variant -> CVariant cOfVariant Argon2d = 0 cOfVariant Argon2i = 1 cOfVariant Argon2id = 2 csizeOfInt :: Int -> CSize csizeOfInt = fromIntegral foreign import ccall unsafe "cryptonite_argon2_hash" argon2_hash :: Word32 -> Word32 -> Word32 -> Ptr Pass -> CSize -> Ptr Salt -> CSize -> Ptr HashOut -> CSize -> CVariant -> CVersion -> IO CInt cryptonite-0.23/Crypto/KDF/PBKDF2.hs0000644000000000000000000001515313050556742015170 0ustar0000000000000000-- | -- Module : Crypto.KDF.PBKDF2 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Password Based Key Derivation Function 2 -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE ForeignFunctionInterface #-} module Crypto.KDF.PBKDF2 ( PRF , prfHMAC , Parameters(..) , generate , fastPBKDF2_SHA1 , fastPBKDF2_SHA256 , fastPBKDF2_SHA512 ) where import Data.Word import Data.Bits import Foreign.Marshal.Alloc import Foreign.Ptr (plusPtr, Ptr) import Foreign.C.Types (CUInt(..), CInt(..), CSize(..)) import Crypto.Hash (HashAlgorithm) import qualified Crypto.MAC.HMAC as HMAC import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess, Bytes) import qualified Crypto.Internal.ByteArray as B import Data.Memory.PtrMethods -- | The PRF used for PBKDF2 type PRF password = password -- ^ the password parameters -> Bytes -- ^ the content -> Bytes -- ^ prf(password,content) -- | PRF for PBKDF2 using HMAC with the hash algorithm as parameter prfHMAC :: (HashAlgorithm a, ByteArrayAccess password) => a -> PRF password prfHMAC alg k = hmacIncr alg (HMAC.initialize k) where hmacIncr :: HashAlgorithm a => a -> HMAC.Context a -> (Bytes -> Bytes) hmacIncr _ !ctx = \b -> B.convert $ HMAC.finalize $ HMAC.update ctx b -- | Parameters for PBKDF2 data Parameters = Parameters { iterCounts :: Int -- ^ the number of user-defined iterations for the algorithms. e.g. WPA2 uses 4000. , outputLength :: Int -- ^ the number of bytes to generate out of PBKDF2 } -- | generate the pbkdf2 key derivation function from the output generate :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray ba) => PRF password -> Parameters -> password -> salt -> ba generate prf params password salt = B.allocAndFreeze (outputLength params) $ \p -> do memSet p 0 (outputLength params) loop 1 (outputLength params) p where !runPRF = prf password !hLen = B.length $ runPRF B.empty -- run the following f function on each complete chunk. -- when having an incomplete chunk, we call partial. -- partial need to be the last call. -- -- f(pass,salt,c,i) = U1 xor U2 xor .. xor Uc -- U1 = PRF(pass,salt || BE32(i)) -- Uc = PRF(pass,Uc-1) loop iterNb len p | len == 0 = return () | len < hLen = partial iterNb len p | otherwise = do let applyMany 0 _ = return () applyMany i uprev = do let uData = runPRF uprev B.withByteArray uData $ \u -> memXor p p u hLen applyMany (i-1) uData applyMany (iterCounts params) (B.convert salt `B.append` toBS iterNb) loop (iterNb+1) (len - hLen) (p `plusPtr` hLen) partial iterNb len p = allocaBytesAligned hLen 8 $ \tmp -> do let applyMany :: Int -> Bytes -> IO () applyMany 0 _ = return () applyMany i uprev = do let uData = runPRF uprev B.withByteArray uData $ \u -> memXor tmp tmp u hLen applyMany (i-1) uData memSet tmp 0 hLen applyMany (iterCounts params) (B.convert salt `B.append` toBS iterNb) memCopy p tmp len -- big endian encoding of Word32 toBS :: ByteArray ba => Word32 -> ba toBS w = B.pack [a,b,c,d] where a = fromIntegral (w `shiftR` 24) b = fromIntegral ((w `shiftR` 16) .&. 0xff) c = fromIntegral ((w `shiftR` 8) .&. 0xff) d = fromIntegral (w .&. 0xff) {-# NOINLINE generate #-} fastPBKDF2_SHA1 :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray out) => Parameters -> password -> salt -> out fastPBKDF2_SHA1 params password salt = B.allocAndFreeze (outputLength params) $ \outPtr -> B.withByteArray password $ \passPtr -> B.withByteArray salt $ \saltPtr -> c_cryptonite_fastpbkdf2_hmac_sha1 passPtr (fromIntegral $ B.length password) saltPtr (fromIntegral $ B.length salt) (fromIntegral $ iterCounts params) outPtr (fromIntegral $ outputLength params) fastPBKDF2_SHA256 :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray out) => Parameters -> password -> salt -> out fastPBKDF2_SHA256 params password salt = B.allocAndFreeze (outputLength params) $ \outPtr -> B.withByteArray password $ \passPtr -> B.withByteArray salt $ \saltPtr -> c_cryptonite_fastpbkdf2_hmac_sha256 passPtr (fromIntegral $ B.length password) saltPtr (fromIntegral $ B.length salt) (fromIntegral $ iterCounts params) outPtr (fromIntegral $ outputLength params) fastPBKDF2_SHA512 :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray out) => Parameters -> password -> salt -> out fastPBKDF2_SHA512 params password salt = B.allocAndFreeze (outputLength params) $ \outPtr -> B.withByteArray password $ \passPtr -> B.withByteArray salt $ \saltPtr -> c_cryptonite_fastpbkdf2_hmac_sha512 passPtr (fromIntegral $ B.length password) saltPtr (fromIntegral $ B.length salt) (fromIntegral $ iterCounts params) outPtr (fromIntegral $ outputLength params) foreign import ccall unsafe "cryptonite_pbkdf2.h cryptonite_fastpbkdf2_hmac_sha1" c_cryptonite_fastpbkdf2_hmac_sha1 :: Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> CUInt -> Ptr Word8 -> CSize -> IO () foreign import ccall unsafe "cryptonite_pbkdf2.h cryptonite_fastpbkdf2_hmac_sha256" c_cryptonite_fastpbkdf2_hmac_sha256 :: Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> CUInt -> Ptr Word8 -> CSize -> IO () foreign import ccall unsafe "cryptonite_pbkdf2.h cryptonite_fastpbkdf2_hmac_sha512" c_cryptonite_fastpbkdf2_hmac_sha512 :: Ptr Word8 -> CSize -> Ptr Word8 -> CSize -> CUInt -> Ptr Word8 -> CSize -> IO () cryptonite-0.23/Crypto/KDF/Scrypt.hs0000644000000000000000000000511212727713654015545 0ustar0000000000000000-- | -- Module : Crypto.KDF.Scrypt -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Scrypt key derivation function as defined in Colin Percival's paper -- "Stronger Key Derivation via Sequential Memory-Hard Functions" -- . -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE ForeignFunctionInterface #-} module Crypto.KDF.Scrypt ( Parameters(..) , generate ) where import Data.Word import Foreign.Marshal.Alloc import Foreign.Ptr (Ptr, plusPtr) import Control.Monad (forM_) import Crypto.Hash (SHA256(..)) import qualified Crypto.KDF.PBKDF2 as PBKDF2 import Crypto.Internal.Compat (popCount, unsafeDoIO) import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B -- | Parameters for Scrypt data Parameters = Parameters { n :: Word64 -- ^ Cpu/Memory cost ratio. must be a power of 2 greater than 1. also known as N. , r :: Int -- ^ Must satisfy r * p < 2^30 , p :: Int -- ^ Must satisfy r * p < 2^30 , outputLength :: Int -- ^ the number of bytes to generate out of Scrypt } foreign import ccall "cryptonite_scrypt_smix" ccryptonite_scrypt_smix :: Ptr Word8 -> Word32 -> Word64 -> Ptr Word8 -> Ptr Word8 -> IO () -- | Generate the scrypt key derivation data generate :: (ByteArrayAccess password, ByteArrayAccess salt, ByteArray output) => Parameters -> password -> salt -> output generate params password salt | r params * p params >= 0x40000000 = error "Scrypt: invalid parameters: r and p constraint" | popCount (n params) /= 1 = error "Scrypt: invalid parameters: n not a power of 2" | otherwise = unsafeDoIO $ do let b = PBKDF2.generate prf (PBKDF2.Parameters 1 intLen) password salt :: B.Bytes newSalt <- B.copy b $ \bPtr -> allocaBytesAligned (128*(fromIntegral $ n params)*(r params)) 8 $ \v -> allocaBytesAligned (256*r params + 64) 8 $ \xy -> do forM_ [0..(p params-1)] $ \i -> ccryptonite_scrypt_smix (bPtr `plusPtr` (i * 128 * (r params))) (fromIntegral $ r params) (n params) v xy return $ PBKDF2.generate prf (PBKDF2.Parameters 1 (outputLength params)) password (newSalt :: B.Bytes) where prf = PBKDF2.prfHMAC SHA256 intLen = p params * 128 * r params {-# NOINLINE generate #-} cryptonite-0.23/Crypto/KDF/BCrypt.hs0000644000000000000000000001642212673727640015472 0ustar0000000000000000 -- | Password encoding and validation using bcrypt. -- -- Example usage: -- -- >>> import Crypto.KDF.BCrypt (hashPassword, validatePassword) -- >>> import qualified Data.ByteString.Char8 as B -- >>> -- >>> let bcryptHash = B.pack "$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW" -- >>> let password = B.pack "password" -- >>> validatePassword password bcryptHash -- >>> True -- >>> let otherPassword = B.pack "otherpassword" -- >>> otherHash <- hashPassword 12 otherPasssword :: IO B.ByteString -- >>> validatePassword otherPassword otherHash -- >>> True -- -- See -- for details of the original algorithm. -- -- The functions @hashPassword@ and @validatePassword@ should be all that -- most users need. -- -- Hashes are strings of the form -- @$2a$10$MJJifxfaqQmbx1Mhsq3oq.YmMmfNhkyW4s/MS3K5rIMVfB7w0Q/OW@ which -- encode a version number, an integer cost parameter and the concatenated -- salt and hash bytes (each separately Base64 encoded. Incrementing the -- cost parameter approximately doubles the time taken to calculate the hash. -- -- The different version numbers have evolved because of bugs in the standard -- C implementations. The most up to date version is @2b@ and this -- implementation the @2b@ version prefix, but will also attempt to validate -- against hashes with versions @2a@ and @2y@. Version @2@ or @2x@ will be -- rejected. No attempt is made to differentiate between the different versions -- when validating a password, but in practice this shouldn't cause any problems -- if passwords are UTF-8 encoded (which they should be). -- -- The cost parameter can be between 4 and 31 inclusive, but anything less than -- 10 is probably not strong enough. High values may be prohibitively slow -- depending on your hardware. Choose the highest value you can without having -- an unacceptable impact on your users. The cost parameter can also be varied -- depending on the account, since it is unique to an individual hash. module Crypto.KDF.BCrypt ( hashPassword , validatePassword , validatePasswordEither , bcrypt ) where import Control.Monad (unless, when) import Crypto.Cipher.Blowfish.Primitive (eksBlowfish, encrypt) import Crypto.Random (MonadRandom, getRandomBytes) import Data.ByteArray (ByteArrayAccess, ByteArray, Bytes) import qualified Data.ByteArray as B import Data.ByteArray.Encoding import Data.Char data BCryptHash = BCH Char Int Bytes Bytes -- | Create a bcrypt hash for a password with a provided cost value. -- Typically used to create a hash when a new user account is registered -- or when a user changes their password. -- -- Each increment of the cost approximately doubles the time taken. -- The 16 bytes of random salt will be generated internally. hashPassword :: (MonadRandom m, ByteArray password, ByteArray hash) => Int -- ^ The cost parameter. Should be between 4 and 31 (inclusive). -- Values which lie outside this range will be adjusted accordingly. -> password -- ^ The password. Should be the UTF-8 encoded bytes of the password text. -> m hash -- ^ The bcrypt hash in standard format. hashPassword cost password = do salt <- getRandomBytes 16 return $ bcrypt cost (salt :: Bytes) password -- | Create a bcrypt hash for a password with a provided cost value and salt. -- -- Cost value under 4 will be automatically adjusted back to 10 for safety reason. bcrypt :: (ByteArray salt, ByteArray password, ByteArray output) => Int -- ^ The cost parameter. Should be between 4 and 31 (inclusive). -- Values which lie outside this range will be adjusted accordingly. -> salt -- ^ The salt. Must be 16 bytes in length or an error will be raised. -> password -- ^ The password. Should be the UTF-8 encoded bytes of the password text. -> output -- ^ The bcrypt hash in standard format. bcrypt cost salt password = B.concat [header, B.snoc costBytes dollar, b64 salt, b64 hash] where hash = rawHash 'b' realCost salt password header = B.pack [dollar, fromIntegral (ord '2'), fromIntegral (ord 'a'), dollar] dollar = fromIntegral (ord '$') zero = fromIntegral (ord '0') costBytes = B.pack [zero + fromIntegral (realCost `div` 10), zero + fromIntegral (realCost `mod` 10)] realCost | cost < 4 = 10 -- 4 is virtually pointless so go for 10 | cost > 31 = 31 | otherwise = cost b64 :: (ByteArray ba) => ba -> ba b64 = convertToBase Base64OpenBSD -- | Check a password against a stored bcrypt hash when authenticating a user. -- -- Returns @False@ if the password doesn't match the hash, or if the hash is -- invalid or an unsupported version. validatePassword :: (ByteArray password, ByteArray hash) => password -> hash -> Bool validatePassword password bcHash = either (const False) id (validatePasswordEither password bcHash) -- | Check a password against a bcrypt hash -- -- As for @validatePassword@ but will provide error information if the hash is invalid or -- an unsupported version. validatePasswordEither :: (ByteArray password, ByteArray hash) => password -> hash -> Either String Bool validatePasswordEither password bcHash = do BCH version cost salt hash <- parseBCryptHash bcHash return $ (rawHash version cost salt password :: Bytes) `B.constEq` hash rawHash :: (ByteArrayAccess salt, ByteArray password, ByteArray output) => Char -> Int -> salt -> password -> output rawHash _ cost salt password = B.take 23 hash -- Another compatibility bug. Ignore last byte of hash where hash = loop (0 :: Int) orpheanBeholder loop i input | i < 64 = loop (i+1) (encrypt ctx input) | otherwise = input -- Truncate the password if necessary and append a null byte for C compatibility key = B.snoc (B.take 72 password) 0 ctx = eksBlowfish cost salt key -- The BCrypt plaintext: "OrpheanBeholderScryDoubt" orpheanBeholder = B.pack [79,114,112,104,101,97,110,66,101,104,111,108,100,101,114,83,99,114,121,68,111,117,98,116] -- "$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga" parseBCryptHash :: (ByteArray ba) => ba -> Either String BCryptHash parseBCryptHash bc = do unless (B.length bc == 60 && B.index bc 0 == dollar && B.index bc 1 == fromIntegral (ord '2') && B.index bc 3 == dollar && B.index bc 6 == dollar) (Left "Invalid hash format") unless (version == 'b' || version == 'a' || version == 'y') (Left ("Unsupported minor version: " ++ [version])) when (costTens > 3 || cost > 31 || cost < 4) (Left "Invalid bcrypt cost") (salt, hash) <- decodeSaltHash (B.drop 7 bc) return (BCH version cost salt hash) where dollar = fromIntegral (ord '$') zero = ord '0' costTens = fromIntegral (B.index bc 4) - zero costUnits = fromIntegral (B.index bc 5) - zero version = chr (fromIntegral (B.index bc 2)) cost = costUnits + (if costTens == 0 then 0 else 10^costTens) :: Int decodeSaltHash saltHash = do let (s, h) = B.splitAt 22 saltHash salt <- convertFromBase Base64OpenBSD s hash <- convertFromBase Base64OpenBSD h return (salt, hash) cryptonite-0.23/Crypto/KDF/HKDF.hs0000644000000000000000000000534613020740134014762 0ustar0000000000000000-- | -- Module : Crypto.KDF.HKDF -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Key Derivation Function based on HMAC -- -- See RFC5869 -- {-# LANGUAGE BangPatterns #-} module Crypto.KDF.HKDF ( PRK , extract , extractSkip , expand ) where import Data.Word import Crypto.Hash import Crypto.MAC.HMAC import Crypto.Internal.ByteArray (ScrubbedBytes, ByteArray, ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B -- | Pseudo Random Key data PRK a = PRK (HMAC a) | PRK_NoExpand ScrubbedBytes deriving (Eq) instance ByteArrayAccess (PRK a) where length (PRK hm) = B.length hm length (PRK_NoExpand sb) = B.length sb withByteArray (PRK hm) = B.withByteArray hm withByteArray (PRK_NoExpand sb) = B.withByteArray sb -- | Extract a Pseudo Random Key using the parameter and the underlaying hash mechanism extract :: (HashAlgorithm a, ByteArrayAccess salt, ByteArrayAccess ikm) => salt -- ^ Salt -> ikm -- ^ Input Keying Material -> PRK a -- ^ Pseudo random key extract salt ikm = PRK $ hmac salt ikm -- | Create a PRK directly from the input key material. -- -- Only use when guaranteed to have a good quality and random data to use directly as key. -- This effectively skip a HMAC with key=salt and data=key. extractSkip :: ByteArrayAccess ikm => ikm -> PRK a extractSkip ikm = PRK_NoExpand $ B.convert ikm -- | Expand key material of specific length out of the parameters expand :: (HashAlgorithm a, ByteArrayAccess info, ByteArray out) => PRK a -- ^ Pseudo Random Key -> info -- ^ Optional context and application specific information -> Int -- ^ Output length in bytes -> out -- ^ Output data expand prkAt infoAt outputLength = let hF = hFGet prkAt in B.concat $ loop hF B.empty outputLength 1 where hFGet :: (HashAlgorithm a, ByteArrayAccess b) => PRK a -> (b -> HMAC a) hFGet prk = case prk of PRK hmacKey -> hmac hmacKey PRK_NoExpand ikm -> hmac ikm info :: ScrubbedBytes info = B.convert infoAt loop :: HashAlgorithm a => (ScrubbedBytes -> HMAC a) -> ScrubbedBytes -> Int -> Word8 -> [ScrubbedBytes] loop hF tim1 n i | n <= 0 = [] | otherwise = let input = B.concat [tim1,info,B.singleton i] :: ScrubbedBytes ti = B.convert $ hF input hashLen = B.length ti r = n - hashLen in (if n >= hashLen then ti else B.take n ti) : loop hF ti r (i+1) cryptonite-0.23/Crypto/Hash.hs0000644000000000000000000000742013077673501014537 0ustar0000000000000000-- | -- Module : Crypto.Hash -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Generalized cryptographic hash interface, that you can use with cryptographic hash -- algorithm that belong to the HashAlgorithm type class. -- -- > import Crypto.Hash -- > -- > sha1 :: ByteString -> Digest SHA1 -- > sha1 = hash -- > -- > hexSha3_512 :: ByteString -> String -- > hexSha3_512 bs = show (hash bs :: Digest SHA3_512) -- {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE BangPatterns #-} module Crypto.Hash ( -- * Types Context , Digest -- * Functions , digestFromByteString -- * hash methods parametrized by algorithm , hashInitWith , hashWith -- * hash methods , hashInit , hashUpdates , hashUpdate , hashFinalize , hashBlockSize , hashDigestSize , hash , hashlazy -- * Hash algorithms , module Crypto.Hash.Algorithms ) where import Control.Monad import Crypto.Hash.Types import Crypto.Hash.Algorithms import Foreign.Ptr (Ptr) import Crypto.Internal.ByteArray (ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import qualified Data.ByteString.Lazy as L -- | Hash a strict bytestring into a digest. hash :: (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a hash bs = hashFinalize $ hashUpdate hashInit bs -- | Hash a lazy bytestring into a digest. hashlazy :: HashAlgorithm a => L.ByteString -> Digest a hashlazy lbs = hashFinalize $ hashUpdates hashInit (L.toChunks lbs) -- | Initialize a new context for this hash algorithm hashInit :: forall a . HashAlgorithm a => Context a hashInit = Context $ B.allocAndFreeze (hashInternalContextSize (undefined :: a)) $ \(ptr :: Ptr (Context a)) -> hashInternalInit ptr -- | run hashUpdates on one single bytestring and return the updated context. hashUpdate :: (ByteArrayAccess ba, HashAlgorithm a) => Context a -> ba -> Context a hashUpdate ctx b | B.null b = ctx | otherwise = hashUpdates ctx [b] -- | Update the context with a list of strict bytestring, -- and return a new context with the updates. hashUpdates :: forall a ba . (HashAlgorithm a, ByteArrayAccess ba) => Context a -> [ba] -> Context a hashUpdates c l | null ls = c | otherwise = Context $ B.copyAndFreeze c $ \(ctx :: Ptr (Context a)) -> mapM_ (\b -> B.withByteArray b $ \d -> hashInternalUpdate ctx d (fromIntegral $ B.length b)) ls where ls = filter (not . B.null) l -- | Finalize a context and return a digest. hashFinalize :: forall a . HashAlgorithm a => Context a -> Digest a hashFinalize !c = Digest $ B.allocAndFreeze (hashDigestSize (undefined :: a)) $ \(dig :: Ptr (Digest a)) -> do ((!_) :: B.Bytes) <- B.copy c $ \(ctx :: Ptr (Context a)) -> hashInternalFinalize ctx dig return () -- | Initialize a new context for a specified hash algorithm hashInitWith :: HashAlgorithm alg => alg -> Context alg hashInitWith _ = hashInit -- | Run the 'hash' function but takes an explicit hash algorithm parameter hashWith :: (ByteArrayAccess ba, HashAlgorithm alg) => alg -> ba -> Digest alg hashWith _ = hash -- | Try to transform a bytearray into a Digest of specific algorithm. -- -- If the digest is not the right size for the algorithm specified, then -- Nothing is returned. digestFromByteString :: (HashAlgorithm a, ByteArrayAccess ba) => ba -> Maybe (Digest a) digestFromByteString = from undefined where from :: (HashAlgorithm a, ByteArrayAccess ba) => a -> ba -> Maybe (Digest a) from alg bs | B.length bs == (hashDigestSize alg) = (Just $ Digest $ B.convert bs) | otherwise = Nothing cryptonite-0.23/Crypto/Hash/IO.hs0000644000000000000000000000502213077673501015042 0ustar0000000000000000-- | -- Module : Crypto.Hash.IO -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Generalized impure cryptographic hash interface -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} module Crypto.Hash.IO ( HashAlgorithm(..) , MutableContext , hashMutableInit , hashMutableInitWith , hashMutableUpdate , hashMutableFinalize , hashMutableReset ) where import Crypto.Hash.Types import qualified Crypto.Internal.ByteArray as B import Foreign.Ptr -- | A Mutable hash context newtype MutableContext a = MutableContext B.Bytes deriving (B.ByteArrayAccess) -- | Create a new mutable hash context. -- -- the algorithm used is automatically determined from the return constraint. hashMutableInit :: HashAlgorithm alg => IO (MutableContext alg) hashMutableInit = doInit undefined B.alloc where doInit :: HashAlgorithm a => a -> (Int -> (Ptr (Context a) -> IO ()) -> IO B.Bytes) -> IO (MutableContext a) doInit alg alloc = MutableContext `fmap` alloc (hashInternalContextSize alg) hashInternalInit -- | Create a new mutable hash context. -- -- The algorithm is explicitely passed as parameter hashMutableInitWith :: HashAlgorithm alg => alg -> IO (MutableContext alg) hashMutableInitWith _ = hashMutableInit -- | Update a mutable hash context in place hashMutableUpdate :: (B.ByteArrayAccess ba, HashAlgorithm a) => MutableContext a -> ba -> IO () hashMutableUpdate mc dat = doUpdate mc (B.withByteArray mc) where doUpdate :: HashAlgorithm a => MutableContext a -> ((Ptr (Context a) -> IO ()) -> IO ()) -> IO () doUpdate _ withCtx = withCtx $ \ctx -> B.withByteArray dat $ \d -> hashInternalUpdate ctx d (fromIntegral $ B.length dat) -- | Finalize a mutable hash context and compute a digest hashMutableFinalize :: forall a . HashAlgorithm a => MutableContext a -> IO (Digest a) hashMutableFinalize mc = do b <- B.alloc (hashDigestSize (undefined :: a)) $ \dig -> B.withByteArray mc $ \(ctx :: Ptr (Context a)) -> hashInternalFinalize ctx dig return $ Digest b -- | Reset the mutable context to the initial state of the hash hashMutableReset :: HashAlgorithm a => MutableContext a -> IO () hashMutableReset mc = doReset mc (B.withByteArray mc) where doReset :: HashAlgorithm a => MutableContext a -> ((Ptr (Context a) -> IO ()) -> IO ()) -> IO () doReset _ withCtx = withCtx hashInternalInit cryptonite-0.23/Crypto/Hash/Algorithms.hs0000644000000000000000000000411013063753164016640 0ustar0000000000000000{-# LANGUAGE CPP #-} -- | -- Module : Crypto.Hash.Algorithms -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Definitions of known hash algorithms -- module Crypto.Hash.Algorithms ( HashAlgorithm -- * hash algorithms , Blake2s_160(..) , Blake2s_224(..) , Blake2s_256(..) , Blake2sp_224(..) , Blake2sp_256(..) , Blake2b_160(..) , Blake2b_224(..) , Blake2b_256(..) , Blake2b_384(..) , Blake2b_512(..) , Blake2bp_512(..) , MD2(..) , MD4(..) , MD5(..) , SHA1(..) , SHA224(..) , SHA256(..) , SHA384(..) , SHA512(..) , SHA512t_224(..) , SHA512t_256(..) , RIPEMD160(..) , Tiger(..) , Keccak_224(..) , Keccak_256(..) , Keccak_384(..) , Keccak_512(..) , SHA3_224(..) , SHA3_256(..) , SHA3_384(..) , SHA3_512(..) #if MIN_VERSION_base(4,7,0) , SHAKE128(..) , SHAKE256(..) , Blake2b(..), Blake2bp(..) , Blake2s(..), Blake2sp(..) #endif , Skein256_224(..) , Skein256_256(..) , Skein512_224(..) , Skein512_256(..) , Skein512_384(..) , Skein512_512(..) , Whirlpool(..) ) where import Crypto.Hash.Types (HashAlgorithm) import Crypto.Hash.Blake2s import Crypto.Hash.Blake2sp import Crypto.Hash.Blake2b import Crypto.Hash.Blake2bp import Crypto.Hash.MD2 import Crypto.Hash.MD4 import Crypto.Hash.MD5 import Crypto.Hash.SHA1 import Crypto.Hash.SHA224 import Crypto.Hash.SHA256 import Crypto.Hash.SHA384 import Crypto.Hash.SHA512 import Crypto.Hash.SHA512t import Crypto.Hash.SHA3 import Crypto.Hash.Keccak import Crypto.Hash.RIPEMD160 import Crypto.Hash.Tiger import Crypto.Hash.Skein256 import Crypto.Hash.Skein512 import Crypto.Hash.Whirlpool #if MIN_VERSION_base(4,7,0) import Crypto.Hash.SHAKE import Crypto.Hash.Blake2 #endif cryptonite-0.23/Crypto/OTP.hs0000644000000000000000000001467613050556742014327 0ustar0000000000000000{-# LANGUAGE ScopedTypeVariables #-} -- | One-time password implementation as defined by the -- and -- specifications. -- -- Both implementations use a shared key between the client and the server. HOTP passwords -- are based on a synchronized counter. TOTP passwords use the same approach but calculate -- the counter as a number of time steps from the Unix epoch to the current time, thus -- requiring that both client and server have synchronized clocks. -- -- Probably the best-known use of TOTP is in Google's 2-factor authentication. -- -- The TOTP API doesn't depend on any particular time package, so the user needs to supply -- the current @OTPTime@ value, based on the system time. For example, using the @hourglass@ -- package, you could create a @getOTPTime@ function: -- -- >>> import Time.System -- >>> import Time.Types -- >>> -- >>> let getOTPTime = timeCurrent >>= \(Elapsed t) -> return (fromIntegral t :: OTPTime) -- -- Or if you prefer, the @time@ package could be used: -- -- >>> import Data.Time.Clock.POSIX -- >>> -- >>> let getOTPTime = getPOSIXTime >>= \t -> return (floor t :: OTPTime) -- module Crypto.OTP ( OTP , OTPDigits (..) , OTPTime , hotp , resynchronize , totp , totpVerify , TOTPParams , ClockSkew (..) , defaultTOTPParams , mkTOTPParams ) where import Data.Bits (shiftL, shiftR, (.&.), (.|.)) import Data.ByteArray.Mapping (fromW64BE) import Data.List (elemIndex) import Data.Word import Foreign.Storable (poke) import Control.Monad (unless) import Crypto.Hash (HashAlgorithm, SHA1(..)) import Crypto.MAC.HMAC import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B -- | A one-time password which is a sequence of 4 to 9 digits. type OTP = Word32 -- | The strength of the calculated HOTP value, namely -- the number of digits (between 4 and 9) in the extracted value. data OTPDigits = OTP4 | OTP5 | OTP6 | OTP7 | OTP8 | OTP9 deriving (Show) -- | An integral time value in seconds. type OTPTime = Word64 hotp :: forall hash key. (HashAlgorithm hash, ByteArrayAccess key) => hash -> OTPDigits -- ^ Number of digits in the HOTP value extracted from the calculated HMAC -> key -- ^ Shared secret between the client and server -> Word64 -- ^ Counter value synchronized between the client and server -> OTP -- ^ The HOTP value hotp _ d k c = dt `mod` digitsPower d where mac = hmac k (fromW64BE c :: Bytes) :: HMAC hash offset = fromIntegral (B.index mac (B.length mac - 1) .&. 0xf) dt = (fromIntegral (B.index mac offset .&. 0x7f) `shiftL` 24) .|. (fromIntegral (B.index mac (offset + 1) .&. 0xff) `shiftL` 16) .|. (fromIntegral (B.index mac (offset + 2) .&. 0xff) `shiftL` 8) .|. fromIntegral (B.index mac (offset + 3) .&. 0xff) -- | Attempt to resynchronize the server's counter value -- with the client, given a sequence of HOTP values. resynchronize :: (HashAlgorithm hash, ByteArrayAccess key) => hash -> OTPDigits -> Word16 -- ^ The look-ahead window parameter. Up to this many values will -- be calculated and checked against the value(s) submitted by the client -> key -- ^ The shared secret -> Word64 -- ^ The current server counter value -> (OTP, [OTP]) -- ^ The first OTP submitted by the client and a list of additional -- sequential OTPs (which may be empty) -> Maybe Word64 -- ^ The new counter value, synchronized with the client's current counter -- or Nothing if the submitted OTP values didn't match anywhere within the window resynchronize h d s k c (p1, extras) = do offBy <- fmap fromIntegral (elemIndex p1 range) checkExtraOtps (c + offBy + 1) extras where checkExtraOtps ctr [] = Just ctr checkExtraOtps ctr (p:ps) | hotp h d k ctr /= p = Nothing | otherwise = checkExtraOtps (ctr + 1) ps range = map (hotp h d k)[c..c + fromIntegral s] digitsPower :: OTPDigits -> Word32 digitsPower OTP4 = 10000 digitsPower OTP5 = 100000 digitsPower OTP6 = 1000000 digitsPower OTP7 = 10000000 digitsPower OTP8 = 100000000 digitsPower OTP9 = 1000000000 data TOTPParams h = TP !h !OTPTime !Word16 !OTPDigits !ClockSkew deriving (Show) data ClockSkew = NoSkew | OneStep | TwoSteps | ThreeSteps | FourSteps deriving (Enum, Show) -- | The default TOTP configuration. defaultTOTPParams :: TOTPParams SHA1 defaultTOTPParams = TP SHA1 0 30 OTP6 TwoSteps -- | Create a TOTP configuration with customized parameters. mkTOTPParams :: (HashAlgorithm hash) => hash -> OTPTime -- ^ The T0 parameter in seconds. This is the Unix time from which to start -- counting steps (default 0). Must be before the current time. -> Word16 -- ^ The time step parameter X in seconds (default 30, maximum allowed 300) -> OTPDigits -- ^ Number of required digits in the OTP (default 6) -> ClockSkew -- ^ The number of time steps to check either side of the current value -- to allow for clock skew between client and server and or delay in -- submitting the value. The default is two time steps. -> Either String (TOTPParams hash) mkTOTPParams h t0 x d skew = do unless (x > 0) (Left "Time step must be greater than zero") unless (x <= 300) (Left "Time step cannot be greater than 300 seconds") return (TP h t0 x d skew) -- | Calculate a totp value for the given time. totp :: (HashAlgorithm hash, ByteArrayAccess key) => TOTPParams hash -> key -- ^ The shared secret -> OTPTime -- ^ The time for which the OTP should be calculated. -- This is usually the current time as returned by @Data.Time.Clock.POSIX.getPOSIXTime@ -> OTP totp (TP h t0 x d _) k now = hotp h d k (timeToCounter now t0 x) -- | Check a supplied TOTP value is valid for the given time, -- within the window defined by the skew parameter. totpVerify :: (HashAlgorithm hash, ByteArrayAccess key) => TOTPParams hash -> key -> OTPTime -> OTP -> Bool totpVerify (TP h t0 x d skew) k now otp = otp `elem` map (hotp h d k) (range window []) where t = timeToCounter now t0 x window = fromIntegral (fromEnum skew) range 0 acc = t : acc range n acc = range (n-1) ((t-n) : (t+n) : acc) timeToCounter :: Word64 -> Word64 -> Word16 -> Word64 timeToCounter now t0 x = (now - t0) `div` fromIntegral x cryptonite-0.23/Crypto/PubKey/Curve25519.hs0000644000000000000000000001104313020740134016522 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Curve25519 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Curve25519 support -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE ScopedTypeVariables #-} module Crypto.PubKey.Curve25519 ( SecretKey , PublicKey , DhSecret -- * Smart constructors , dhSecret , publicKey , secretKey -- * methods , dh , toPublic , generateSecretKey ) where import Data.Bits import Data.Word import Foreign.Ptr import Foreign.Storable import GHC.Ptr import Crypto.Error import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, ScrubbedBytes, Bytes, withByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Error (CryptoFailable(..)) import Crypto.Random -- | A Curve25519 Secret key newtype SecretKey = SecretKey ScrubbedBytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | A Curve25519 public key newtype PublicKey = PublicKey Bytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | A Curve25519 Diffie Hellman secret related to a -- public key and a secret key. newtype DhSecret = DhSecret ScrubbedBytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | Try to build a public key from a bytearray publicKey :: ByteArrayAccess bs => bs -> CryptoFailable PublicKey publicKey bs | B.length bs == 32 = CryptoPassed $ PublicKey $ B.copyAndFreeze bs (\_ -> return ()) | otherwise = CryptoFailed CryptoError_PublicKeySizeInvalid -- | Try to build a secret key from a bytearray secretKey :: ByteArrayAccess bs => bs -> CryptoFailable SecretKey secretKey bs | B.length bs == 32 = unsafeDoIO $ do withByteArray bs $ \inp -> do valid <- isValidPtr inp if valid then (CryptoPassed . SecretKey) <$> B.copy bs (\_ -> return ()) else return $ CryptoFailed CryptoError_SecretKeyStructureInvalid | otherwise = CryptoFailed CryptoError_SecretKeySizeInvalid where -- e[0] &= 0xf8; -- e[31] &= 0x7f; -- e[31] |= 40; isValidPtr :: Ptr Word8 -> IO Bool isValidPtr _ = do --b0 <- peekElemOff inp 0 --b31 <- peekElemOff inp 31 return True {- return $ and [ testBit b0 0 == False , testBit b0 1 == False , testBit b0 2 == False , testBit b31 7 == False , testBit b31 6 == True ] -} {-# NOINLINE secretKey #-} -- | Create a DhSecret from a bytearray object dhSecret :: ByteArrayAccess b => b -> CryptoFailable DhSecret dhSecret bs | B.length bs == 32 = CryptoPassed $ DhSecret $ B.copyAndFreeze bs (\_ -> return ()) | otherwise = CryptoFailed CryptoError_SharedSecretSizeInvalid -- | Compute the Diffie Hellman secret from a public key and a secret key dh :: PublicKey -> SecretKey -> DhSecret dh (PublicKey pub) (SecretKey sec) = DhSecret <$> B.allocAndFreeze 32 $ \result -> withByteArray sec $ \psec -> withByteArray pub $ \ppub -> ccryptonite_curve25519 result psec ppub {-# NOINLINE dh #-} -- | Create a public key from a secret key toPublic :: SecretKey -> PublicKey toPublic (SecretKey sec) = PublicKey <$> B.allocAndFreeze 32 $ \result -> withByteArray sec $ \psec -> ccryptonite_curve25519 result psec basePoint where basePoint = Ptr "\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# {-# NOINLINE toPublic #-} -- | Generate a secret key. generateSecretKey :: MonadRandom m => m SecretKey generateSecretKey = tweakToSecretKey <$> getRandomBytes 32 where tweakToSecretKey :: ScrubbedBytes -> SecretKey tweakToSecretKey bin = SecretKey $ B.copyAndFreeze bin $ \inp -> do modifyByte inp 0 (\e0 -> e0 .&. 0xf8) modifyByte inp 31 (\e31 -> (e31 .&. 0x7f) .|. 0x40) modifyByte :: Ptr Word8 -> Int -> (Word8 -> Word8) -> IO () modifyByte p n f = peekByteOff p n >>= pokeByteOff p n . f foreign import ccall "cryptonite_curve25519_donna" ccryptonite_curve25519 :: Ptr Word8 -- ^ public -> Ptr Word8 -- ^ secret -> Ptr Word8 -- ^ basepoint -> IO () cryptonite-0.23/Crypto/PubKey/Curve448.hs0000644000000000000000000000735113050556742016400 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Curve448 -- License : BSD-style -- Maintainer : John Galt -- Stability : experimental -- Portability : unknown -- -- Curve448 support -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MagicHash #-} module Crypto.PubKey.Curve448 ( SecretKey , PublicKey , DhSecret -- * Smart constructors , dhSecret , publicKey , secretKey -- * methods , dh , toPublic , generateSecretKey ) where import Data.Word import Foreign.Ptr import GHC.Ptr import Crypto.Error import Crypto.Random import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess, ScrubbedBytes, Bytes, withByteArray) import qualified Crypto.Internal.ByteArray as B -- | A Curve448 Secret key newtype SecretKey = SecretKey ScrubbedBytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | A Curve448 public key newtype PublicKey = PublicKey Bytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | A Curve448 Diffie Hellman secret related to a -- public key and a secret key. newtype DhSecret = DhSecret ScrubbedBytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | Try to build a public key from a bytearray publicKey :: ByteArrayAccess bs => bs -> CryptoFailable PublicKey publicKey bs | B.length bs == x448_bytes = CryptoPassed $ PublicKey $ B.copyAndFreeze bs (\_ -> return ()) | otherwise = CryptoFailed CryptoError_PublicKeySizeInvalid -- | Try to build a secret key from a bytearray secretKey :: ByteArrayAccess bs => bs -> CryptoFailable SecretKey secretKey bs | B.length bs == x448_bytes = unsafeDoIO $ withByteArray bs $ \inp -> do valid <- isValidPtr inp if valid then (CryptoPassed . SecretKey) <$> B.copy bs (\_ -> return ()) else return $ CryptoFailed CryptoError_SecretKeyStructureInvalid | otherwise = CryptoFailed CryptoError_SecretKeySizeInvalid where isValidPtr :: Ptr Word8 -> IO Bool isValidPtr _ = return True {-# NOINLINE secretKey #-} -- | Create a DhSecret from a bytearray object dhSecret :: ByteArrayAccess b => b -> CryptoFailable DhSecret dhSecret bs | B.length bs == x448_bytes = CryptoPassed $ DhSecret $ B.copyAndFreeze bs (\_ -> return ()) | otherwise = CryptoFailed CryptoError_SharedSecretSizeInvalid -- | Compute the Diffie Hellman secret from a public key and a secret key dh :: PublicKey -> SecretKey -> DhSecret dh (PublicKey pub) (SecretKey sec) = DhSecret <$> B.allocAndFreeze x448_bytes $ \result -> withByteArray sec $ \psec -> withByteArray pub $ \ppub -> ccryptonite_ed448 result psec ppub {-# NOINLINE dh #-} -- | Create a public key from a secret key toPublic :: SecretKey -> PublicKey toPublic (SecretKey sec) = PublicKey <$> B.allocAndFreeze x448_bytes $ \result -> withByteArray sec $ \psec -> ccryptonite_ed448 result psec basePoint where basePoint = Ptr "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"# {-# NOINLINE toPublic #-} -- | Generate a secret key. generateSecretKey :: MonadRandom m => m SecretKey generateSecretKey = SecretKey <$> getRandomBytes x448_bytes x448_bytes :: Int x448_bytes = 448 `quot` 8 foreign import ccall "cryptonite_x448" ccryptonite_ed448 :: Ptr Word8 -- ^ public -> Ptr Word8 -- ^ secret -> Ptr Word8 -- ^ basepoint -> IO () cryptonite-0.23/Crypto/PubKey/MaskGenFunction.hs0000644000000000000000000000245312527327224020104 0ustar0000000000000000-- | -- Module : Crypto.PubKey.MaskGenFunction -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- {-# LANGUAGE BangPatterns #-} module Crypto.PubKey.MaskGenFunction ( MaskGenAlgorithm , mgf1 ) where import Crypto.Number.Serialize (i2ospOf_) import Crypto.Hash import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B -- | Represent a mask generation algorithm type MaskGenAlgorithm seed output = seed -- ^ seed -> Int -- ^ length to generate -> output -- | Mask generation algorithm MGF1 mgf1 :: (ByteArrayAccess seed, ByteArray output, HashAlgorithm hashAlg) => hashAlg -> seed -> Int -> output mgf1 hashAlg seed len = let !seededCtx = hashUpdate (hashInitWith hashAlg) seed in B.take len $ B.concat $ map (hashCounter seededCtx) [0..fromIntegral (maxCounter-1)] where digestLen = hashDigestSize hashAlg (chunks,left) = len `divMod` digestLen maxCounter = if left > 0 then chunks + 1 else chunks hashCounter :: HashAlgorithm a => Context a -> Integer -> Digest a hashCounter ctx counter = hashFinalize $ hashUpdate ctx (i2ospOf_ 4 counter :: Bytes) cryptonite-0.23/Crypto/PubKey/DH.hs0000644000000000000000000000557512702223243015343 0ustar0000000000000000-- | -- Module : Crypto.PubKey.DH -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.PubKey.DH ( Params(..) , PublicNumber(..) , PrivateNumber(..) , SharedKey(..) , generateParams , generatePrivate , calculatePublic , generatePublic , getShared ) where import Crypto.Internal.Imports import Crypto.Number.ModArithmetic (expSafe) import Crypto.Number.Prime (generateSafePrime) import Crypto.Number.Generate (generateMax) import Crypto.Number.Serialize (i2ospOf_) import Crypto.Random.Types import Data.ByteArray (ByteArrayAccess, ScrubbedBytes) import Data.Data -- | Represent Diffie Hellman parameters namely P (prime), and G (generator). data Params = Params { params_p :: Integer , params_g :: Integer , params_bits :: Int } deriving (Show,Read,Eq,Data,Typeable) -- | Represent Diffie Hellman public number Y. newtype PublicNumber = PublicNumber Integer deriving (Show,Read,Eq,Enum,Real,Num,Ord) -- | Represent Diffie Hellman private number X. newtype PrivateNumber = PrivateNumber Integer deriving (Show,Read,Eq,Enum,Real,Num,Ord) -- | Represent Diffie Hellman shared secret. newtype SharedKey = SharedKey ScrubbedBytes deriving (Show,Eq,ByteArrayAccess) -- | generate params from a specific generator (2 or 5 are common values) -- we generate a safe prime (a prime number of the form 2p+1 where p is also prime) generateParams :: MonadRandom m => Int -- ^ number of bits -> Integer -- ^ generator -> m Params generateParams bits generator = (\p -> Params p generator bits) <$> generateSafePrime bits -- | generate a private number with no specific property -- this number is usually called X in DH text. generatePrivate :: MonadRandom m => Params -> m PrivateNumber generatePrivate (Params p _ _) = PrivateNumber <$> generateMax p -- | calculate the public number from the parameters and the private key -- this number is usually called Y in DH text. calculatePublic :: Params -> PrivateNumber -> PublicNumber calculatePublic (Params p g _) (PrivateNumber x) = PublicNumber $ expSafe g x p -- | calculate the public number from the parameters and the private key -- this number is usually called Y in DH text. -- -- DEPRECATED use calculatePublic generatePublic :: Params -> PrivateNumber -> PublicNumber generatePublic = calculatePublic -- commented until 0.3 {-# DEPRECATED generatePublic "use calculatePublic" #-} -- | generate a shared key using our private number and the other party public number getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey getShared (Params p _ bits) (PrivateNumber x) (PublicNumber y) = SharedKey $ i2ospOf_ ((bits + 7) `div` 8) $ expSafe y x p cryptonite-0.23/Crypto/PubKey/DSA.hs0000644000000000000000000001277612673727640015501 0ustar0000000000000000-- | -- Module : Crypto.PubKey.DSA -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- An implementation of the Digital Signature Algorithm (DSA) {-# LANGUAGE DeriveDataTypeable #-} module Crypto.PubKey.DSA ( Params(..) , Signature(..) , PublicKey(..) , PrivateKey(..) , PublicNumber , PrivateNumber -- * generation , generatePrivate , calculatePublic -- * signature primitive , sign , signWith -- * verification primitive , verify -- * Key pair , KeyPair(..) , toPublicKey , toPrivateKey ) where import Crypto.Random.Types import Data.Bits (testBit) import Data.Data import Data.Maybe import Crypto.Number.Basic (numBits) import Crypto.Number.ModArithmetic (expFast, expSafe, inverse) import Crypto.Number.Serialize import Crypto.Number.Generate import Crypto.Internal.ByteArray (ByteArrayAccess(length), convert, index, dropView, takeView) import Crypto.Internal.Imports import Crypto.Hash import Prelude hiding (length) -- | DSA Public Number, usually embedded in DSA Public Key type PublicNumber = Integer -- | DSA Private Number, usually embedded in DSA Private Key type PrivateNumber = Integer -- | Represent DSA parameters namely P, G, and Q. data Params = Params { params_p :: Integer -- ^ DSA p , params_g :: Integer -- ^ DSA g , params_q :: Integer -- ^ DSA q } deriving (Show,Read,Eq,Data,Typeable) instance NFData Params where rnf (Params p g q) = p `seq` g `seq` q `seq` () -- | Represent a DSA signature namely R and S. data Signature = Signature { sign_r :: Integer -- ^ DSA r , sign_s :: Integer -- ^ DSA s } deriving (Show,Read,Eq,Data,Typeable) instance NFData Signature where rnf (Signature r s) = r `seq` s `seq` () -- | Represent a DSA public key. data PublicKey = PublicKey { public_params :: Params -- ^ DSA parameters , public_y :: PublicNumber -- ^ DSA public Y } deriving (Show,Read,Eq,Data,Typeable) instance NFData PublicKey where rnf (PublicKey params y) = y `seq` params `seq` () -- | Represent a DSA private key. -- -- Only x need to be secret. -- the DSA parameters are publicly shared with the other side. data PrivateKey = PrivateKey { private_params :: Params -- ^ DSA parameters , private_x :: PrivateNumber -- ^ DSA private X } deriving (Show,Read,Eq,Data,Typeable) instance NFData PrivateKey where rnf (PrivateKey params x) = x `seq` params `seq` () -- | Represent a DSA key pair data KeyPair = KeyPair Params PublicNumber PrivateNumber deriving (Show,Read,Eq,Data,Typeable) instance NFData KeyPair where rnf (KeyPair params y x) = x `seq` y `seq` params `seq` () -- | Public key of a DSA Key pair toPublicKey :: KeyPair -> PublicKey toPublicKey (KeyPair params pub _) = PublicKey params pub -- | Private key of a DSA Key pair toPrivateKey :: KeyPair -> PrivateKey toPrivateKey (KeyPair params _ priv) = PrivateKey params priv -- | generate a private number with no specific property -- this number is usually called X in DSA text. generatePrivate :: MonadRandom m => Params -> m PrivateNumber generatePrivate (Params _ _ q) = generateMax q -- | Calculate the public number from the parameters and the private key calculatePublic :: Params -> PrivateNumber -> PublicNumber calculatePublic (Params p g _) x = expSafe g x p -- | sign message using the private key and an explicit k number. signWith :: (ByteArrayAccess msg, HashAlgorithm hash) => Integer -- ^ k random number -> PrivateKey -- ^ private key -> hash -- ^ hash function -> msg -- ^ message to sign -> Maybe Signature signWith k pk hashAlg msg | r == 0 || s == 0 = Nothing | otherwise = Just $ Signature r s where -- parameters (Params p g q) = private_params pk x = private_x pk -- compute r,s kInv = fromJust $ inverse k q hm = os2ip $ hashWith hashAlg msg r = expSafe g k p `mod` q s = (kInv * (hm + x * r)) `mod` q -- | sign message using the private key. sign :: (ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) => PrivateKey -> hash -> msg -> m Signature sign pk hashAlg msg = do k <- generateMax q case signWith k pk hashAlg msg of Nothing -> sign pk hashAlg msg Just sig -> return sig where (Params _ _ q) = private_params pk -- | verify a bytestring using the public key. verify :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> PublicKey -> Signature -> msg -> Bool verify hashAlg pk (Signature r s) m -- Reject the signature if either 0 < r < q or 0 < s < q is not satisfied. | r <= 0 || r >= q || s <= 0 || s >= q = False | otherwise = v == r where (Params p g q) = public_params pk y = public_y pk hm = os2ip . truncateHash $ hashWith hashAlg m w = fromJust $ inverse s q u1 = (hm*w) `mod` q u2 = (r*w) `mod` q v = ((expFast g u1 p) * (expFast y u2 p)) `mod` p `mod` q -- if the hash is larger than the size of q, truncate it; FIXME: deal with the case of a q not evenly divisible by 8 truncateHash h = if numBits (os2ip h) > numBits q then takeView h (numBits q `div` 8) else dropView h 0 cryptonite-0.23/Crypto/PubKey/ECC/Generate.hs0000644000000000000000000000144712516347336017203 0ustar0000000000000000-- | Signature generation. module Crypto.PubKey.ECC.Generate where import Crypto.Random.Types import Crypto.PubKey.ECC.Types import Crypto.PubKey.ECC.ECDSA import Crypto.Number.Generate import Crypto.PubKey.ECC.Prim -- | Generate Q given d. -- -- /WARNING:/ Vulnerable to timing attacks. generateQ :: Curve -> Integer -> Point generateQ curve d = pointMul curve d g where g = ecc_g $ common_curve curve -- | Generate a pair of (private, public) key. -- -- /WARNING:/ Vulnerable to timing attacks. generate :: MonadRandom m => Curve -- ^ Elliptic Curve -> m (PublicKey, PrivateKey) generate curve = do d <- generateBetween 1 (n - 1) let q = generateQ curve d return (PublicKey curve q, PrivateKey curve d) where n = ecc_n $ common_curve curve cryptonite-0.23/Crypto/PubKey/ECC/Prim.hs0000644000000000000000000001336613016300400016334 0ustar0000000000000000-- | Elliptic Curve Arithmetic. -- -- /WARNING:/ These functions are vulnerable to timing attacks. module Crypto.PubKey.ECC.Prim ( scalarGenerate , pointAdd , pointDouble , pointBaseMul , pointMul , pointAddTwoMuls , isPointAtInfinity , isPointValid ) where import Data.Maybe import Crypto.Number.ModArithmetic import Crypto.Number.F2m import Crypto.Number.Generate (generateBetween) import Crypto.PubKey.ECC.Types import Crypto.Random -- | Generate a valid scalar for a specific Curve scalarGenerate :: MonadRandom randomly => Curve -> randomly PrivateNumber scalarGenerate curve = generateBetween 1 (n - 1) where n = ecc_n $ common_curve curve --TODO: Extract helper function for `fromMaybe PointO...` -- | Elliptic Curve point negation: -- @pointNegate c p@ returns point @q@ such that @pointAdd c p q == PointO@. pointNegate :: Curve -> Point -> Point pointNegate _ PointO = PointO pointNegate CurveFP{} (Point x y) = Point x (-y) pointNegate CurveF2m{} (Point x y) = Point x (x `addF2m` y) -- | Elliptic Curve point addition. -- -- /WARNING:/ Vulnerable to timing attacks. pointAdd :: Curve -> Point -> Point -> Point pointAdd _ PointO PointO = PointO pointAdd _ PointO q = q pointAdd _ p PointO = p pointAdd c p q | p == q = pointDouble c p | p == pointNegate c q = PointO pointAdd (CurveFP (CurvePrime pr _)) (Point xp yp) (Point xq yq) = fromMaybe PointO $ do s <- divmod (yp - yq) (xp - xq) pr let xr = (s ^ (2::Int) - xp - xq) `mod` pr yr = (s * (xp - xr) - yp) `mod` pr return $ Point xr yr pointAdd (CurveF2m (CurveBinary fx cc)) (Point xp yp) (Point xq yq) = fromMaybe PointO $ do s <- divF2m fx (yp `addF2m` yq) (xp `addF2m` xq) let xr = mulF2m fx s s `addF2m` s `addF2m` xp `addF2m` xq `addF2m` a yr = mulF2m fx s (xp `addF2m` xr) `addF2m` xr `addF2m` yp return $ Point xr yr where a = ecc_a cc -- | Elliptic Curve point doubling. -- -- /WARNING:/ Vulnerable to timing attacks. -- -- This perform the following calculation: -- > lambda = (3 * xp ^ 2 + a) / 2 yp -- > xr = lambda ^ 2 - 2 xp -- > yr = lambda (xp - xr) - yp -- -- With binary curve: -- > xp == 0 => P = O -- > otherwise => -- > s = xp + (yp / xp) -- > xr = s ^ 2 + s + a -- > yr = xp ^ 2 + (s+1) * xr -- pointDouble :: Curve -> Point -> Point pointDouble _ PointO = PointO pointDouble (CurveFP (CurvePrime pr cc)) (Point xp yp) = fromMaybe PointO $ do lambda <- divmod (3 * xp ^ (2::Int) + a) (2 * yp) pr let xr = (lambda ^ (2::Int) - 2 * xp) `mod` pr yr = (lambda * (xp - xr) - yp) `mod` pr return $ Point xr yr where a = ecc_a cc pointDouble (CurveF2m (CurveBinary fx cc)) (Point xp yp) | xp == 0 = PointO | otherwise = fromMaybe PointO $ do s <- return . addF2m xp =<< divF2m fx yp xp let xr = mulF2m fx s s `addF2m` s `addF2m` a yr = mulF2m fx xp xp `addF2m` mulF2m fx xr (s `addF2m` 1) return $ Point xr yr where a = ecc_a cc -- | Elliptic curve point multiplication using the base -- -- /WARNING:/ Vulnerable to timing attacks. pointBaseMul :: Curve -> Integer -> Point pointBaseMul c n = pointMul c n (ecc_g $ common_curve c) -- | Elliptic curve point multiplication (double and add algorithm). -- -- /WARNING:/ Vulnerable to timing attacks. pointMul :: Curve -> Integer -> Point -> Point pointMul _ _ PointO = PointO pointMul c n p | n < 0 = pointMul c (-n) (pointNegate c p) | n == 0 = PointO | n == 1 = p | odd n = pointAdd c p (pointMul c (n - 1) p) | otherwise = pointMul c (n `div` 2) (pointDouble c p) -- | Elliptic curve double-scalar multiplication (uses Shamir's trick). -- -- > pointAddTwoMuls c n1 p1 n2 p2 == pointAdd c (pointMul c n1 p1) -- > (pointMul c n2 p2) -- -- /WARNING:/ Vulnerable to timing attacks. pointAddTwoMuls :: Curve -> Integer -> Point -> Integer -> Point -> Point pointAddTwoMuls _ _ PointO _ PointO = PointO pointAddTwoMuls c _ PointO n2 p2 = pointMul c n2 p2 pointAddTwoMuls c n1 p1 _ PointO = pointMul c n1 p1 pointAddTwoMuls c n1 p1 n2 p2 | n1 < 0 = pointAddTwoMuls c (-n1) (pointNegate c p1) n2 p2 | n2 < 0 = pointAddTwoMuls c n1 p1 (-n2) (pointNegate c p2) | otherwise = go (n1, n2) where p0 = pointAdd c p1 p2 go (0, 0 ) = PointO go (k1, k2) = let q = pointDouble c $ go (k1 `div` 2, k2 `div` 2) in case (odd k1, odd k2) of (True , True ) -> pointAdd c p0 q (True , False ) -> pointAdd c p1 q (False , True ) -> pointAdd c p2 q (False , False ) -> q -- | Check if a point is the point at infinity. isPointAtInfinity :: Point -> Bool isPointAtInfinity PointO = True isPointAtInfinity _ = False -- | check if a point is on specific curve -- -- This perform three checks: -- -- * x is not out of range -- * y is not out of range -- * the equation @y^2 = x^3 + a*x + b (mod p)@ holds isPointValid :: Curve -> Point -> Bool isPointValid _ PointO = True isPointValid (CurveFP (CurvePrime p cc)) (Point x y) = isValid x && isValid y && (y ^ (2 :: Int)) `eqModP` (x ^ (3 :: Int) + a * x + b) where a = ecc_a cc b = ecc_b cc eqModP z1 z2 = (z1 `mod` p) == (z2 `mod` p) isValid e = e >= 0 && e < p isPointValid (CurveF2m (CurveBinary fx cc)) (Point x y) = and [ isValid x , isValid y , ((((x `add` a) `mul` x `add` y) `mul` x) `add` b `add` (squareF2m fx y)) == 0 ] where a = ecc_a cc b = ecc_b cc add = addF2m mul = mulF2m fx isValid e = modF2m fx e == e -- | div and mod divmod :: Integer -> Integer -> Integer -> Maybe Integer divmod y x m = do i <- inverse (x `mod` m) m return $ y * i `mod` m cryptonite-0.23/Crypto/PubKey/ECC/DH.hs0000644000000000000000000000261312702223260015722 0ustar0000000000000000-- | -- Module : Crypto.PubKey.ECC.DH -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Elliptic curve Diffie Hellman -- module Crypto.PubKey.ECC.DH ( Curve , PublicPoint , PrivateNumber , SharedKey(..) , generatePrivate , calculatePublic , getShared ) where import Crypto.Number.Generate (generateMax) import Crypto.Number.Serialize (i2ospOf_) import Crypto.PubKey.ECC.Prim (pointMul) import Crypto.Random.Types import Crypto.PubKey.DH (SharedKey(..)) import Crypto.PubKey.ECC.Types (PublicPoint, PrivateNumber, Curve, Point(..), curveSizeBits) import Crypto.PubKey.ECC.Types (ecc_n, ecc_g, common_curve) -- | Generating a private number d. generatePrivate :: MonadRandom m => Curve -> m PrivateNumber generatePrivate curve = generateMax n where n = ecc_n $ common_curve curve -- | Generating a public point Q. calculatePublic :: Curve -> PrivateNumber -> PublicPoint calculatePublic curve d = q where g = ecc_g $ common_curve curve q = pointMul curve d g -- | Generating a shared key using our private number and -- the other party public point. getShared :: Curve -> PrivateNumber -> PublicPoint -> SharedKey getShared curve db qa = SharedKey $ i2ospOf_ ((nbBits + 7) `div` 8) x where Point x _ = pointMul curve db qa nbBits = curveSizeBits curve cryptonite-0.23/Crypto/PubKey/ECC/ECDSA.hs0000644000000000000000000000740713030510145016250 0ustar0000000000000000-- | /WARNING:/ Signature operations may leak the private key. Signature verification -- should be safe. {-# LANGUAGE DeriveDataTypeable #-} module Crypto.PubKey.ECC.ECDSA ( Signature(..) , PublicPoint , PublicKey(..) , PrivateNumber , PrivateKey(..) , KeyPair(..) , toPublicKey , toPrivateKey , signWith , sign , verify ) where import Control.Monad import Crypto.Random.Types import Data.Bits (shiftR) import Crypto.Internal.ByteArray (ByteArrayAccess) import Data.Data import Crypto.Number.Basic (numBits) import Crypto.Number.ModArithmetic (inverse) import Crypto.Number.Serialize import Crypto.Number.Generate import Crypto.PubKey.ECC.Types import Crypto.PubKey.ECC.Prim import Crypto.Hash import Crypto.Hash.Types (hashDigestSize) -- | Represent a ECDSA signature namely R and S. data Signature = Signature { sign_r :: Integer -- ^ ECDSA r , sign_s :: Integer -- ^ ECDSA s } deriving (Show,Read,Eq,Data,Typeable) -- | ECDSA Private Key. data PrivateKey = PrivateKey { private_curve :: Curve , private_d :: PrivateNumber } deriving (Show,Read,Eq,Data,Typeable) -- | ECDSA Public Key. data PublicKey = PublicKey { public_curve :: Curve , public_q :: PublicPoint } deriving (Show,Read,Eq,Data,Typeable) -- | ECDSA Key Pair. data KeyPair = KeyPair Curve PublicPoint PrivateNumber deriving (Show,Read,Eq,Data,Typeable) -- | Public key of a ECDSA Key pair. toPublicKey :: KeyPair -> PublicKey toPublicKey (KeyPair curve pub _) = PublicKey curve pub -- | Private key of a ECDSA Key pair. toPrivateKey :: KeyPair -> PrivateKey toPrivateKey (KeyPair curve _ priv) = PrivateKey curve priv -- | Sign message using the private key and an explicit k number. -- -- /WARNING:/ Vulnerable to timing attacks. signWith :: (ByteArrayAccess msg, HashAlgorithm hash) => Integer -- ^ k random number -> PrivateKey -- ^ private key -> hash -- ^ hash function -> msg -- ^ message to sign -> Maybe Signature signWith k (PrivateKey curve d) hashAlg msg = do let z = tHash hashAlg msg n CurveCommon _ _ g n _ = common_curve curve let point = pointMul curve k g r <- case point of PointO -> Nothing Point x _ -> return $ x `mod` n kInv <- inverse k n let s = kInv * (z + r * d) `mod` n when (r == 0 || s == 0) Nothing return $ Signature r s -- | Sign message using the private key. -- -- /WARNING:/ Vulnerable to timing attacks. sign :: (ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) => PrivateKey -> hash -> msg -> m Signature sign pk hashAlg msg = do k <- generateBetween 1 (n - 1) case signWith k pk hashAlg msg of Nothing -> sign pk hashAlg msg Just sig -> return sig where n = ecc_n . common_curve $ private_curve pk -- | Verify a bytestring using the public key. verify :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> PublicKey -> Signature -> msg -> Bool verify _ (PublicKey _ PointO) _ _ = False verify hashAlg pk@(PublicKey curve q) (Signature r s) msg | r < 1 || r >= n || s < 1 || s >= n = False | otherwise = maybe False (r ==) $ do w <- inverse s n let z = tHash hashAlg msg n u1 = z * w `mod` n u2 = r * w `mod` n x = pointAddTwoMuls curve u1 g u2 q case x of PointO -> Nothing Point x1 _ -> return $ x1 `mod` n where n = ecc_n cc g = ecc_g cc cc = common_curve $ public_curve pk -- | Truncate and hash. tHash :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> msg -> Integer -> Integer tHash hashAlg m n | d > 0 = shiftR e d | otherwise = e where e = os2ip $ hashWith hashAlg m d = hashDigestSize hashAlg * 8 - numBits n cryptonite-0.23/Crypto/PubKey/ECC/P256.hs0000644000000000000000000003304113075454604016076 0ustar0000000000000000-- | -- Module : Crypto.PubKey.ECC.P256 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- P256 support -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE EmptyDataDecls #-} {-# OPTIONS_GHC -fno-warn-unused-binds #-} module Crypto.PubKey.ECC.P256 ( Scalar , Point -- * point arithmetic , pointBase , pointAdd , pointMul , pointDh , pointsMulVarTime , pointIsValid , toPoint , pointToIntegers , pointFromIntegers , pointToBinary , pointFromBinary -- * scalar arithmetic , scalarGenerate , scalarZero , scalarIsZero , scalarAdd , scalarSub , scalarInv , scalarCmp , scalarFromBinary , scalarToBinary , scalarFromInteger , scalarToInteger ) where import Data.Word import Foreign.Ptr import Foreign.C.Types import Control.Monad import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray import qualified Crypto.Internal.ByteArray as B import Data.Memory.PtrMethods (memSet) import Crypto.Error import Crypto.Random import Crypto.Number.Serialize.Internal (os2ip, i2ospOf) import qualified Crypto.Number.Serialize as S (os2ip, i2ospOf) -- | A P256 scalar newtype Scalar = Scalar ScrubbedBytes deriving (Show,Eq,ByteArrayAccess) -- | A P256 point newtype Point = Point Bytes deriving (Show,Eq) scalarSize :: Int scalarSize = 32 pointSize :: Int pointSize = 64 type P256Digit = Word32 data P256Scalar data P256Y data P256X ------------------------------------------------------------------------ -- Point methods ------------------------------------------------------------------------ -- | Get the base point for the P256 Curve pointBase :: Point pointBase = case scalarFromInteger 1 of CryptoPassed s -> toPoint s CryptoFailed _ -> error "pointBase: assumption failed" -- | Lift to curve a scalar -- -- Using the curve generator as base point compute: -- -- > scalar * G -- toPoint :: Scalar -> Point toPoint s | scalarIsZero s = error "cannot create point from zero" | otherwise = withNewPoint $ \px py -> withScalar s $ \p -> ccryptonite_p256_basepoint_mul p px py -- | Add a point to another point pointAdd :: Point -> Point -> Point pointAdd a b = withNewPoint $ \dx dy -> withPoint a $ \ax ay -> withPoint b $ \bx by -> ccryptonite_p256e_point_add ax ay bx by dx dy -- | Multiply a point by a scalar -- -- warning: variable time pointMul :: Scalar -> Point -> Point pointMul scalar p = withNewPoint $ \dx dy -> withScalar scalar $ \n -> withPoint p $ \px py -> withScalarZero $ \nzero -> ccryptonite_p256_points_mul_vartime nzero n px py dx dy -- | Similar to 'pointMul', serializing the x coordinate as binary pointDh :: ByteArray binary => Scalar -> Point -> binary pointDh scalar p = B.unsafeCreate scalarSize $ \dst -> withTempPoint $ \dx dy -> do withScalar scalar $ \n -> withPoint p $ \px py -> withScalarZero $ \nzero -> ccryptonite_p256_points_mul_vartime nzero n px py dx dy ccryptonite_p256_to_bin (castPtr dx) dst -- | multiply the point @p with @n2 and add a lifted to curve value @n1 -- -- > n1 * G + n2 * p -- -- warning: variable time pointsMulVarTime :: Scalar -> Scalar -> Point -> Point pointsMulVarTime n1 n2 p = withNewPoint $ \dx dy -> withScalar n1 $ \pn1 -> withScalar n2 $ \pn2 -> withPoint p $ \px py -> ccryptonite_p256_points_mul_vartime pn1 pn2 px py dx dy -- | Check if a 'Point' is valid pointIsValid :: Point -> Bool pointIsValid p = unsafeDoIO $ withPoint p $ \px py -> do r <- ccryptonite_p256_is_valid_point px py return (r /= 0) -- | Convert a point to (x,y) Integers pointToIntegers :: Point -> (Integer, Integer) pointToIntegers p = unsafeDoIO $ withPoint p $ \px py -> allocTemp 32 (serialize (castPtr px) (castPtr py)) where serialize px py temp = do ccryptonite_p256_to_bin px temp x <- os2ip temp scalarSize ccryptonite_p256_to_bin py temp y <- os2ip temp scalarSize return (x,y) -- | Convert from (x,y) Integers to a point pointFromIntegers :: (Integer, Integer) -> Point pointFromIntegers (x,y) = withNewPoint $ \dx dy -> allocTemp scalarSize (\temp -> fill temp (castPtr dx) x >> fill temp (castPtr dy) y) where -- put @n to @temp in big endian format, then from @temp to @dest in p256 scalar format fill :: Ptr Word8 -> Ptr P256Scalar -> Integer -> IO () fill temp dest n = do -- write the integer in big endian format to temp memSet temp 0 scalarSize e <- i2ospOf n temp scalarSize if e == 0 then error "pointFromIntegers: filling failed" else return () -- then fill dest with the P256 scalar from temp ccryptonite_p256_from_bin temp dest -- | Convert a point to a binary representation pointToBinary :: ByteArray ba => Point -> ba pointToBinary p = B.unsafeCreate pointSize $ \dst -> withPoint p $ \px py -> do ccryptonite_p256_to_bin (castPtr px) dst ccryptonite_p256_to_bin (castPtr py) (dst `plusPtr` 32) -- | Convert from binary to a point pointFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Point pointFromBinary ba | B.length ba /= pointSize = CryptoFailed $ CryptoError_PublicKeySizeInvalid | otherwise = CryptoPassed $ withNewPoint $ \px py -> B.withByteArray ba $ \src -> do ccryptonite_p256_from_bin src (castPtr px) ccryptonite_p256_from_bin (src `plusPtr` scalarSize) (castPtr py) ------------------------------------------------------------------------ -- Scalar methods ------------------------------------------------------------------------ -- | Generate a randomly generated new scalar scalarGenerate :: MonadRandom randomly => randomly Scalar scalarGenerate = unwrap . scalarFromBinary . witness <$> getRandomBytes 32 where unwrap (CryptoFailed _) = error "scalarGenerate: assumption failed" unwrap (CryptoPassed s) = s witness :: ScrubbedBytes -> ScrubbedBytes witness = id -- | The scalar representing 0 scalarZero :: Scalar scalarZero = withNewScalarFreeze $ \d -> ccryptonite_p256_init d -- | Check if the scalar is 0 scalarIsZero :: Scalar -> Bool scalarIsZero s = unsafeDoIO $ withScalar s $ \d -> do result <- ccryptonite_p256_is_zero d return $ result /= 0 scalarNeedReducing :: Ptr P256Scalar -> IO Bool scalarNeedReducing d = do c <- ccryptonite_p256_cmp d ccryptonite_SECP256r1_n return (c >= 0) -- | Perform addition between two scalars -- -- > a + b scalarAdd :: Scalar -> Scalar -> Scalar scalarAdd a b = withNewScalarFreeze $ \d -> withScalar a $ \pa -> withScalar b $ \pb -> do carry <- ccryptonite_p256_add pa pb d when (carry /= 0) $ void $ ccryptonite_p256_sub d ccryptonite_SECP256r1_n d needReducing <- scalarNeedReducing d when needReducing $ do ccryptonite_p256_mod ccryptonite_SECP256r1_n d d -- | Perform subtraction between two scalars -- -- > a - b scalarSub :: Scalar -> Scalar -> Scalar scalarSub a b = withNewScalarFreeze $ \d -> withScalar a $ \pa -> withScalar b $ \pb -> do borrow <- ccryptonite_p256_sub pa pb d when (borrow /= 0) $ void $ ccryptonite_p256_add d ccryptonite_SECP256r1_n d --needReducing <- scalarNeedReducing d --when needReducing $ do -- ccryptonite_p256_mod ccryptonite_SECP256r1_n d d -- | Give the inverse of the scalar -- -- > 1 / a -- -- warning: variable time scalarInv :: Scalar -> Scalar scalarInv a = withNewScalarFreeze $ \b -> withScalar a $ \pa -> ccryptonite_p256_modinv_vartime ccryptonite_SECP256r1_n pa b -- | Compare 2 Scalar scalarCmp :: Scalar -> Scalar -> Ordering scalarCmp a b = unsafeDoIO $ withScalar a $ \pa -> withScalar b $ \pb -> do v <- ccryptonite_p256_cmp pa pb return $ compare v 0 -- | convert a scalar from binary scalarFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Scalar scalarFromBinary ba | B.length ba /= scalarSize = CryptoFailed $ CryptoError_SecretKeySizeInvalid | otherwise = CryptoPassed $ withNewScalarFreeze $ \p -> B.withByteArray ba $ \b -> ccryptonite_p256_from_bin b p {-# NOINLINE scalarFromBinary #-} -- | convert a scalar to binary scalarToBinary :: ByteArray ba => Scalar -> ba scalarToBinary s = B.unsafeCreate scalarSize $ \b -> withScalar s $ \p -> ccryptonite_p256_to_bin p b {-# NOINLINE scalarToBinary #-} -- | Convert from an Integer to a P256 Scalar scalarFromInteger :: Integer -> CryptoFailable Scalar scalarFromInteger i = maybe (CryptoFailed CryptoError_SecretKeySizeInvalid) scalarFromBinary (S.i2ospOf 32 i :: Maybe Bytes) -- | Convert from a P256 Scalar to an Integer scalarToInteger :: Scalar -> Integer scalarToInteger s = S.os2ip (scalarToBinary s :: Bytes) ------------------------------------------------------------------------ -- Memory Helpers ------------------------------------------------------------------------ withNewPoint :: (Ptr P256X -> Ptr P256Y -> IO ()) -> Point withNewPoint f = Point $ B.unsafeCreate pointSize $ \px -> f px (pxToPy px) {-# NOINLINE withNewPoint #-} withPoint :: Point -> (Ptr P256X -> Ptr P256Y -> IO a) -> IO a withPoint (Point d) f = B.withByteArray d $ \px -> f px (pxToPy px) pxToPy :: Ptr P256X -> Ptr P256Y pxToPy px = castPtr (px `plusPtr` scalarSize) withNewScalarFreeze :: (Ptr P256Scalar -> IO ()) -> Scalar withNewScalarFreeze f = Scalar $ B.allocAndFreeze scalarSize f {-# NOINLINE withNewScalarFreeze #-} withTempPoint :: (Ptr P256X -> Ptr P256Y -> IO a) -> IO a withTempPoint f = allocTempScrubbed pointSize (\p -> let px = castPtr p in f px (pxToPy px)) withTempScalar :: (Ptr P256Scalar -> IO a) -> IO a withTempScalar f = allocTempScrubbed scalarSize (f . castPtr) withScalar :: Scalar -> (Ptr P256Scalar -> IO a) -> IO a withScalar (Scalar d) f = B.withByteArray d f withScalarZero :: (Ptr P256Scalar -> IO a) -> IO a withScalarZero f = withTempScalar $ \d -> do ccryptonite_p256_init d f d allocTemp :: Int -> (Ptr Word8 -> IO a) -> IO a allocTemp n f = ignoreSnd <$> B.allocRet n f where ignoreSnd :: (a, Bytes) -> a ignoreSnd = fst allocTempScrubbed :: Int -> (Ptr Word8 -> IO a) -> IO a allocTempScrubbed n f = ignoreSnd <$> B.allocRet n f where ignoreSnd :: (a, ScrubbedBytes) -> a ignoreSnd = fst ------------------------------------------------------------------------ -- Foreign bindings ------------------------------------------------------------------------ foreign import ccall "&cryptonite_SECP256r1_n" ccryptonite_SECP256r1_n :: Ptr P256Scalar foreign import ccall "&cryptonite_SECP256r1_p" ccryptonite_SECP256r1_p :: Ptr P256Scalar foreign import ccall "&cryptonite_SECP256r1_b" ccryptonite_SECP256r1_b :: Ptr P256Scalar foreign import ccall "cryptonite_p256_init" ccryptonite_p256_init :: Ptr P256Scalar -> IO () foreign import ccall "cryptonite_p256_is_zero" ccryptonite_p256_is_zero :: Ptr P256Scalar -> IO CInt foreign import ccall "cryptonite_p256_clear" ccryptonite_p256_clear :: Ptr P256Scalar -> IO () foreign import ccall "cryptonite_p256_add" ccryptonite_p256_add :: Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> IO CInt foreign import ccall "cryptonite_p256_add_d" ccryptonite_p256_add_d :: Ptr P256Scalar -> P256Digit -> Ptr P256Scalar -> IO CInt foreign import ccall "cryptonite_p256_sub" ccryptonite_p256_sub :: Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> IO CInt foreign import ccall "cryptonite_p256_cmp" ccryptonite_p256_cmp :: Ptr P256Scalar -> Ptr P256Scalar -> IO CInt foreign import ccall "cryptonite_p256_mod" ccryptonite_p256_mod :: Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> IO () foreign import ccall "cryptonite_p256_modmul" ccryptonite_p256_modmul :: Ptr P256Scalar -> Ptr P256Scalar -> P256Digit -> Ptr P256Scalar -> Ptr P256Scalar -> IO () --foreign import ccall "cryptonite_p256_modinv" -- ccryptonite_p256_modinv :: Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> IO () foreign import ccall "cryptonite_p256_modinv_vartime" ccryptonite_p256_modinv_vartime :: Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> IO () foreign import ccall "cryptonite_p256_base_point_mul" ccryptonite_p256_basepoint_mul :: Ptr P256Scalar -> Ptr P256X -> Ptr P256Y -> IO () foreign import ccall "cryptonite_p256e_point_add" ccryptonite_p256e_point_add :: Ptr P256X -> Ptr P256Y -> Ptr P256X -> Ptr P256Y -> Ptr P256X -> Ptr P256Y -> IO () -- compute (out_x,out,y) = n1 * G + n2 * (in_x,in_y) foreign import ccall "cryptonite_p256_points_mul_vartime" ccryptonite_p256_points_mul_vartime :: Ptr P256Scalar -- n1 -> Ptr P256Scalar -- n2 -> Ptr P256X -> Ptr P256Y -- in_{x,y} -> Ptr P256X -> Ptr P256Y -- out_{x,y} -> IO () foreign import ccall "cryptonite_p256_is_valid_point" ccryptonite_p256_is_valid_point :: Ptr P256X -> Ptr P256Y -> IO CInt foreign import ccall "cryptonite_p256_to_bin" ccryptonite_p256_to_bin :: Ptr P256Scalar -> Ptr Word8 -> IO () foreign import ccall "cryptonite_p256_from_bin" ccryptonite_p256_from_bin :: Ptr Word8 -> Ptr P256Scalar -> IO () cryptonite-0.23/Crypto/PubKey/ECC/Types.hs0000644000000000000000000005704613020740134016543 0ustar0000000000000000{-# LANGUAGE DeriveDataTypeable #-} -- | -- Module : Crypto.PubKey.ECC.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Experimental -- Portability : Excellent -- -- references: -- -- module Crypto.PubKey.ECC.Types ( Curve(..) , Point(..) , PublicPoint , PrivateNumber , CurveBinary(..) , CurvePrime(..) , common_curve , curveSizeBits , ecc_fx , ecc_p , CurveCommon(..) -- * recommended curves definition , CurveName(..) , getCurveByName ) where import Data.Data import Crypto.Internal.Imports import Crypto.Number.Basic (numBits) -- | Define either a binary curve or a prime curve. data Curve = CurveF2m CurveBinary -- ^ 𝔽(2^m) | CurveFP CurvePrime -- ^ 𝔽p deriving (Show,Read,Eq,Data,Typeable) -- | ECC Public Point type PublicPoint = Point -- | ECC Private Number type PrivateNumber = Integer -- | Define a point on a curve. data Point = Point Integer Integer | PointO -- ^ Point at Infinity deriving (Show,Read,Eq,Data,Typeable) instance NFData Point where rnf (Point x y) = x `seq` y `seq` () rnf PointO = () -- | Define an elliptic curve in 𝔽(2^m). -- The firt parameter is the Integer representatioin of the irreducible polynomial f(x). data CurveBinary = CurveBinary Integer CurveCommon deriving (Show,Read,Eq,Data,Typeable) instance NFData CurveBinary where rnf (CurveBinary i cc) = i `seq` cc `seq` () -- | Define an elliptic curve in 𝔽p. -- The first parameter is the Prime Number. data CurvePrime = CurvePrime Integer CurveCommon deriving (Show,Read,Eq,Data,Typeable) -- | Parameters in common between binary and prime curves. common_curve :: Curve -> CurveCommon common_curve (CurveF2m (CurveBinary _ cc)) = cc common_curve (CurveFP (CurvePrime _ cc)) = cc -- | Irreducible polynomial representing the characteristic of a CurveBinary. ecc_fx :: CurveBinary -> Integer ecc_fx (CurveBinary fx _) = fx -- | Prime number representing the characteristic of a CurvePrime. ecc_p :: CurvePrime -> Integer ecc_p (CurvePrime p _) = p -- | Define common parameters in a curve definition -- of the form: y^2 = x^3 + ax + b. data CurveCommon = CurveCommon { ecc_a :: Integer -- ^ curve parameter a , ecc_b :: Integer -- ^ curve parameter b , ecc_g :: Point -- ^ base point , ecc_n :: Integer -- ^ order of G , ecc_h :: Integer -- ^ cofactor } deriving (Show,Read,Eq,Data,Typeable) -- | Define names for known recommended curves. data CurveName = SEC_p112r1 | SEC_p112r2 | SEC_p128r1 | SEC_p128r2 | SEC_p160k1 | SEC_p160r1 | SEC_p160r2 | SEC_p192k1 | SEC_p192r1 -- aka prime192v1 | SEC_p224k1 | SEC_p224r1 | SEC_p256k1 | SEC_p256r1 -- aka prime256v1 | SEC_p384r1 | SEC_p521r1 | SEC_t113r1 | SEC_t113r2 | SEC_t131r1 | SEC_t131r2 | SEC_t163k1 | SEC_t163r1 | SEC_t163r2 | SEC_t193r1 | SEC_t193r2 | SEC_t233k1 -- aka NIST K-233 | SEC_t233r1 | SEC_t239k1 | SEC_t283k1 | SEC_t283r1 | SEC_t409k1 | SEC_t409r1 | SEC_t571k1 | SEC_t571r1 deriving (Show,Read,Eq,Ord,Enum,Bounded,Data,Typeable) {- curvesOIDs :: [ (CurveName, [Integer]) ] curvesOIDs = [ (SEC_p112r1, [1,3,132,0,6]) , (SEC_p112r2, [1,3,132,0,7]) , (SEC_p128r1, [1,3,132,0,28]) , (SEC_p128r2, [1,3,132,0,29]) , (SEC_p160k1, [1,3,132,0,9]) , (SEC_p160r1, [1,3,132,0,8]) , (SEC_p160r2, [1,3,132,0,30]) , (SEC_p192k1, [1,3,132,0,31]) , (SEC_p192r1, [1,2,840,10045,3,1,1]) , (SEC_p224k1, [1,3,132,0,32]) , (SEC_p224r1, [1,3,132,0,33]) , (SEC_p256k1, [1,3,132,0,10]) , (SEC_p256r1, [1,2,840,10045,3,1,7]) , (SEC_p384r1, [1,3,132,0,34]) , (SEC_p521r1, [1,3,132,0,35]) , (SEC_t113r1, [1,3,132,0,4]) , (SEC_t113r2, [1,3,132,0,5]) , (SEC_t131r1, [1,3,132,0,22]) , (SEC_t131r2, [1,3,132,0,23]) , (SEC_t163k1, [1,3,132,0,1]) , (SEC_t163r1, [1,3,132,0,2]) , (SEC_t163r2, [1,3,132,0,15]) , (SEC_t193r1, [1,3,132,0,24]) , (SEC_t193r2, [1,3,132,0,25]) , (SEC_t233k1, [1,3,132,0,26]) , (SEC_t233r1, [1,3,132,0,27]) , (SEC_t239k1, [1,3,132,0,3]) , (SEC_t283k1, [1,3,132,0,16]) , (SEC_t283r1, [1,3,132,0,17]) , (SEC_t409k1, [1,3,132,0,36]) , (SEC_t409r1, [1,3,132,0,37]) , (SEC_t571k1, [1,3,132,0,38]) , (SEC_t571r1, [1,3,132,0,39]) ] -} -- | get the size of the curve in bits curveSizeBits :: Curve -> Int curveSizeBits (CurveFP c) = numBits (ecc_p c) curveSizeBits (CurveF2m c) = numBits (ecc_fx c) - 1 -- | Get the curve definition associated with a recommended known curve name. getCurveByName :: CurveName -> Curve getCurveByName SEC_p112r1 = CurveFP $ CurvePrime 0xdb7c2abf62e35e668076bead208b (CurveCommon { ecc_a = 0xdb7c2abf62e35e668076bead2088 , ecc_b = 0x659ef8ba043916eede8911702b22 , ecc_g = Point 0x09487239995a5ee76b55f9c2f098 0xa89ce5af8724c0a23e0e0ff77500 , ecc_n = 0xdb7c2abf62e35e7628dfac6561c5 , ecc_h = 1 }) getCurveByName SEC_p112r2 = CurveFP $ CurvePrime 0xdb7c2abf62e35e668076bead208b (CurveCommon { ecc_a = 0x6127c24c05f38a0aaaf65c0ef02c , ecc_b = 0x51def1815db5ed74fcc34c85d709 , ecc_g = Point 0x4ba30ab5e892b4e1649dd0928643 0xadcd46f5882e3747def36e956e97 , ecc_n = 0x36df0aafd8b8d7597ca10520d04b , ecc_h = 4 }) getCurveByName SEC_p128r1 = CurveFP $ CurvePrime 0xfffffffdffffffffffffffffffffffff (CurveCommon { ecc_a = 0xfffffffdfffffffffffffffffffffffc , ecc_b = 0xe87579c11079f43dd824993c2cee5ed3 , ecc_g = Point 0x161ff7528b899b2d0c28607ca52c5b86 0xcf5ac8395bafeb13c02da292dded7a83 , ecc_n = 0xfffffffe0000000075a30d1b9038a115 , ecc_h = 1 }) getCurveByName SEC_p128r2 = CurveFP $ CurvePrime 0xfffffffdffffffffffffffffffffffff (CurveCommon { ecc_a = 0xd6031998d1b3bbfebf59cc9bbff9aee1 , ecc_b = 0x5eeefca380d02919dc2c6558bb6d8a5d , ecc_g = Point 0x7b6aa5d85e572983e6fb32a7cdebc140 0x27b6916a894d3aee7106fe805fc34b44 , ecc_n = 0x3fffffff7fffffffbe0024720613b5a3 , ecc_h = 4 }) getCurveByName SEC_p160k1 = CurveFP $ CurvePrime 0x00fffffffffffffffffffffffffffffffeffffac73 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000 , ecc_b = 0x000000000000000000000000000000000000000007 , ecc_g = Point 0x003b4c382ce37aa192a4019e763036f4f5dd4d7ebb 0x00938cf935318fdced6bc28286531733c3f03c4fee , ecc_n = 0x0100000000000000000001b8fa16dfab9aca16b6b3 , ecc_h = 1 }) getCurveByName SEC_p160r1 = CurveFP $ CurvePrime 0x00ffffffffffffffffffffffffffffffff7fffffff (CurveCommon { ecc_a = 0x00ffffffffffffffffffffffffffffffff7ffffffc , ecc_b = 0x001c97befc54bd7a8b65acf89f81d4d4adc565fa45 , ecc_g = Point 0x004a96b5688ef573284664698968c38bb913cbfc82 0x0023a628553168947d59dcc912042351377ac5fb32 , ecc_n = 0x0100000000000000000001f4c8f927aed3ca752257 , ecc_h = 1 }) getCurveByName SEC_p160r2 = CurveFP $ CurvePrime 0x00fffffffffffffffffffffffffffffffeffffac73 (CurveCommon { ecc_a = 0x00fffffffffffffffffffffffffffffffeffffac70 , ecc_b = 0x00b4e134d3fb59eb8bab57274904664d5af50388ba , ecc_g = Point 0x0052dcb034293a117e1f4ff11b30f7199d3144ce6d 0x00feaffef2e331f296e071fa0df9982cfea7d43f2e , ecc_n = 0x0100000000000000000000351ee786a818f3a1a16b , ecc_h = 1 }) getCurveByName SEC_p192k1 = CurveFP $ CurvePrime 0xfffffffffffffffffffffffffffffffffffffffeffffee37 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000 , ecc_b = 0x000000000000000000000000000000000000000000000003 , ecc_g = Point 0xdb4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d 0x9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d , ecc_n = 0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d , ecc_h = 1 }) getCurveByName SEC_p192r1 = CurveFP $ CurvePrime 0xfffffffffffffffffffffffffffffffeffffffffffffffff (CurveCommon { ecc_a = 0xfffffffffffffffffffffffffffffffefffffffffffffffc , ecc_b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 , ecc_g = Point 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811 , ecc_n = 0xffffffffffffffffffffffff99def836146bc9b1b4d22831 , ecc_h = 1 }) getCurveByName SEC_p224k1 = CurveFP $ CurvePrime 0x00fffffffffffffffffffffffffffffffffffffffffffffffeffffe56d (CurveCommon { ecc_a = 0x0000000000000000000000000000000000000000000000000000000000 , ecc_b = 0x0000000000000000000000000000000000000000000000000000000005 , ecc_g = Point 0x00a1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45c 0x007e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5 , ecc_n = 0x010000000000000000000000000001dce8d2ec6184caf0a971769fb1f7 , ecc_h = 1 }) getCurveByName SEC_p224r1 = CurveFP $ CurvePrime 0xffffffffffffffffffffffffffffffff000000000000000000000001 (CurveCommon { ecc_a = 0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe , ecc_b = 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 , ecc_g = Point 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 , ecc_n = 0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d , ecc_h = 1 }) getCurveByName SEC_p256k1 = CurveFP $ CurvePrime 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f (CurveCommon { ecc_a = 0x0000000000000000000000000000000000000000000000000000000000000000 , ecc_b = 0x0000000000000000000000000000000000000000000000000000000000000007 , ecc_g = Point 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 , ecc_n = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 , ecc_h = 1 }) getCurveByName SEC_p256r1 = CurveFP $ CurvePrime 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff (CurveCommon { ecc_a = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc , ecc_b = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b , ecc_g = Point 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 , ecc_n = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 , ecc_h = 1 }) getCurveByName SEC_p384r1 = CurveFP $ CurvePrime 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff (CurveCommon { ecc_a = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc , ecc_b = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef , ecc_g = Point 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f , ecc_n = 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 , ecc_h = 1 }) getCurveByName SEC_p521r1 = CurveFP $ CurvePrime 0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (CurveCommon { ecc_a = 0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc , ecc_b = 0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 , ecc_g = Point 0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66 0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650 , ecc_n = 0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409 , ecc_h = 1 }) getCurveByName SEC_t113r1 = CurveF2m $ CurveBinary 0x020000000000000000000000000201 (CurveCommon { ecc_a = 0x003088250ca6e7c7fe649ce85820f7 , ecc_b = 0x00e8bee4d3e2260744188be0e9c723 , ecc_g = Point 0x009d73616f35f4ab1407d73562c10f 0x00a52830277958ee84d1315ed31886 , ecc_n = 0x0100000000000000d9ccec8a39e56f , ecc_h = 2 }) getCurveByName SEC_t113r2 = CurveF2m $ CurveBinary 0x020000000000000000000000000201 (CurveCommon { ecc_a = 0x00689918dbec7e5a0dd6dfc0aa55c7 , ecc_b = 0x0095e9a9ec9b297bd4bf36e059184f , ecc_g = Point 0x01a57a6a7b26ca5ef52fcdb8164797 0x00b3adc94ed1fe674c06e695baba1d , ecc_n = 0x010000000000000108789b2496af93 , ecc_h = 2 }) getCurveByName SEC_t131r1 = CurveF2m $ CurveBinary 0x080000000000000000000000000000010d (CurveCommon { ecc_a = 0x07a11b09a76b562144418ff3ff8c2570b8 , ecc_b = 0x0217c05610884b63b9c6c7291678f9d341 , ecc_g = Point 0x0081baf91fdf9833c40f9c181343638399 0x078c6e7ea38c001f73c8134b1b4ef9e150 , ecc_n = 0x0400000000000000023123953a9464b54d , ecc_h = 2 }) getCurveByName SEC_t131r2 = CurveF2m $ CurveBinary 0x080000000000000000000000000000010d (CurveCommon { ecc_a = 0x03e5a88919d7cafcbf415f07c2176573b2 , ecc_b = 0x04b8266a46c55657ac734ce38f018f2192 , ecc_g = Point 0x0356dcd8f2f95031ad652d23951bb366a8 0x0648f06d867940a5366d9e265de9eb240f , ecc_n = 0x0400000000000000016954a233049ba98f , ecc_h = 2 }) getCurveByName SEC_t163k1 = CurveF2m $ CurveBinary 0x0800000000000000000000000000000000000000c9 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000001 , ecc_b = 0x000000000000000000000000000000000000000001 , ecc_g = Point 0x02fe13c0537bbc11acaa07d793de4e6d5e5c94eee8 0x0289070fb05d38ff58321f2e800536d538ccdaa3d9 , ecc_n = 0x04000000000000000000020108a2e0cc0d99f8a5ef , ecc_h = 2 }) getCurveByName SEC_t163r1 = CurveF2m $ CurveBinary 0x0800000000000000000000000000000000000000c9 (CurveCommon { ecc_a = 0x07b6882caaefa84f9554ff8428bd88e246d2782ae2 , ecc_b = 0x0713612dcddcb40aab946bda29ca91f73af958afd9 , ecc_g = Point 0x0369979697ab43897789566789567f787a7876a654 0x00435edb42efafb2989d51fefce3c80988f41ff883 , ecc_n = 0x03ffffffffffffffffffff48aab689c29ca710279b , ecc_h = 2 }) getCurveByName SEC_t163r2 = CurveF2m $ CurveBinary 0x0800000000000000000000000000000000000000c9 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000001 , ecc_b = 0x020a601907b8c953ca1481eb10512f78744a3205fd , ecc_g = Point 0x03f0eba16286a2d57ea0991168d4994637e8343e36 0x00d51fbc6c71a0094fa2cdd545b11c5c0c797324f1 , ecc_n = 0x040000000000000000000292fe77e70c12a4234c33 , ecc_h = 2 }) getCurveByName SEC_t193r1 = CurveF2m $ CurveBinary 0x02000000000000000000000000000000000000000000008001 (CurveCommon { ecc_a = 0x0017858feb7a98975169e171f77b4087de098ac8a911df7b01 , ecc_b = 0x00fdfb49bfe6c3a89facadaa7a1e5bbc7cc1c2e5d831478814 , ecc_g = Point 0x01f481bc5f0ff84a74ad6cdf6fdef4bf6179625372d8c0c5e1 0x0025e399f2903712ccf3ea9e3a1ad17fb0b3201b6af7ce1b05 , ecc_n = 0x01000000000000000000000000c7f34a778f443acc920eba49 , ecc_h = 2 }) getCurveByName SEC_t193r2 = CurveF2m $ CurveBinary 0x02000000000000000000000000000000000000000000008001 (CurveCommon { ecc_a = 0x0163f35a5137c2ce3ea6ed8667190b0bc43ecd69977702709b , ecc_b = 0x00c9bb9e8927d4d64c377e2ab2856a5b16e3efb7f61d4316ae , ecc_g = Point 0x00d9b67d192e0367c803f39e1a7e82ca14a651350aae617e8f 0x01ce94335607c304ac29e7defbd9ca01f596f927224cdecf6c , ecc_n = 0x010000000000000000000000015aab561b005413ccd4ee99d5 , ecc_h = 2 }) getCurveByName SEC_t233k1 = CurveF2m $ CurveBinary 0x020000000000000000000000000000000000000004000000000000000001 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000000000000000 , ecc_b = 0x000000000000000000000000000000000000000000000000000000000001 , ecc_g = Point 0x017232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126 0x01db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3 , ecc_n = 0x008000000000000000000000000000069d5bb915bcd46efb1ad5f173abdf , ecc_h = 4 }) getCurveByName SEC_t233r1 = CurveF2m $ CurveBinary 0x020000000000000000000000000000000000000004000000000000000001 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000000000000001 , ecc_b = 0x0066647ede6c332c7f8c0923bb58213b333b20e9ce4281fe115f7d8f90ad , ecc_g = Point 0x00fac9dfcbac8313bb2139f1bb755fef65bc391f8b36f8f8eb7371fd558b 0x01006a08a41903350678e58528bebf8a0beff867a7ca36716f7e01f81052 , ecc_n = 0x01000000000000000000000000000013e974e72f8a6922031d2603cfe0d7 , ecc_h = 2 }) getCurveByName SEC_t239k1 = CurveF2m $ CurveBinary 0x800000000000000000004000000000000000000000000000000000000001 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000000000000000 , ecc_b = 0x000000000000000000000000000000000000000000000000000000000001 , ecc_g = Point 0x29a0b6a887a983e9730988a68727a8b2d126c44cc2cc7b2a6555193035dc 0x76310804f12e549bdb011c103089e73510acb275fc312a5dc6b76553f0ca , ecc_n = 0x2000000000000000000000000000005a79fec67cb6e91f1c1da800e478a5 , ecc_h = 4 }) getCurveByName SEC_t283k1 = CurveF2m $ CurveBinary 0x0800000000000000000000000000000000000000000000000000000000000000000010a1 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000000000000000000000000000 , ecc_b = 0x000000000000000000000000000000000000000000000000000000000000000000000001 , ecc_g = Point 0x0503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836 0x01ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259 , ecc_n = 0x01ffffffffffffffffffffffffffffffffffe9ae2ed07577265dff7f94451e061e163c61 , ecc_h = 4 }) getCurveByName SEC_t283r1 = CurveF2m $ CurveBinary 0x0800000000000000000000000000000000000000000000000000000000000000000010a1 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000000000000000000000000001 , ecc_b = 0x027b680ac8b8596da5a4af8a19a0303fca97fd7645309fa2a581485af6263e313b79a2f5 , ecc_g = Point 0x05f939258db7dd90e1934f8c70b0dfec2eed25b8557eac9c80e2e198f8cdbecd86b12053 0x03676854fe24141cb98fe6d4b20d02b4516ff702350eddb0826779c813f0df45be8112f4 , ecc_n = 0x03ffffffffffffffffffffffffffffffffffef90399660fc938a90165b042a7cefadb307 , ecc_h = 2 }) getCurveByName SEC_t409k1 = CurveF2m $ CurveBinary 0x02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001 (CurveCommon { ecc_a = 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 , ecc_b = 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , ecc_g = Point 0x0060f05f658f49c1ad3ab1890f7184210efd0987e307c84c27accfb8f9f67cc2c460189eb5aaaa62ee222eb1b35540cfe9023746 0x01e369050b7c4e42acba1dacbf04299c3460782f918ea427e6325165e9ea10e3da5f6c42e9c55215aa9ca27a5863ec48d8e0286b , ecc_n = 0x007ffffffffffffffffffffffffffffffffffffffffffffffffffe5f83b2d4ea20400ec4557d5ed3e3e7ca5b4b5c83b8e01e5fcf , ecc_h = 4 }) getCurveByName SEC_t409r1 = CurveF2m $ CurveBinary 0x02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001 (CurveCommon { ecc_a = 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , ecc_b = 0x0021a5c2c8ee9feb5c4b9a753b7b476b7fd6422ef1f3dd674761fa99d6ac27c8a9a197b272822f6cd57a55aa4f50ae317b13545f , ecc_g = Point 0x015d4860d088ddb3496b0c6064756260441cde4af1771d4db01ffe5b34e59703dc255a868a1180515603aeab60794e54bb7996a7 0x0061b1cfab6be5f32bbfa78324ed106a7636b9c5a7bd198d0158aa4f5488d08f38514f1fdf4b4f40d2181b3681c364ba0273c706 , ecc_n = 0x010000000000000000000000000000000000000000000000000001e2aad6a612f33307be5fa47c3c9e052f838164cd37d9a21173 , ecc_h = 2 }) getCurveByName SEC_t571k1 = CurveF2m $ CurveBinary 0x080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 , ecc_b = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , ecc_g = Point 0x026eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972 0x0349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3 , ecc_n = 0x020000000000000000000000000000000000000000000000000000000000000000000000131850e1f19a63e4b391a8db917f4138b630d84be5d639381e91deb45cfe778f637c1001 , ecc_h = 4 }) getCurveByName SEC_t571r1 = CurveF2m $ CurveBinary 0x080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425 (CurveCommon { ecc_a = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , ecc_b = 0x02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a , ecc_g = Point 0x0303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19 0x037bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b , ecc_n = 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47 , ecc_h = 2 }) cryptonite-0.23/Crypto/PubKey/ECIES.hs0000644000000000000000000000405413020740134015664 0ustar0000000000000000-- | -- Module : Crypto.PubKey.ECIES -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- IES with Elliptic curve -- -- This is a simple cryptographic system between 2 parties using Elliptic Curve. -- -- The sending party create a shared secret using the receiver public key, and use the shared secret -- to generate cryptographic material for an symmetric encryption scheme (preferably authenticated encryption). -- -- The receiving party receive the temporary ephemeral public key which is combined to its secret key -- to create the shared secret which just like on the sending is used to generate cryptographic material. -- -- This module doesn't provide any symmetric data encryption capability or any mean to derive -- cryptographic key material for a symmetric key from the shared secret. -- this is left to the user for now. -- module Crypto.PubKey.ECIES ( deriveEncrypt , deriveDecrypt ) where import Crypto.ECC import Crypto.Random import Crypto.Internal.Proxy -- | Generate random a new Shared secret and the associated point -- to do a ECIES style encryption deriveEncrypt :: (MonadRandom randomly, EllipticCurveDH curve) => proxy curve -- ^ representation of the curve -> Point curve -- ^ the public key of the receiver -> randomly (Point curve, SharedSecret) deriveEncrypt proxy pub = do (KeyPair rPoint rScalar) <- curveGenerateKeyPair proxy return (rPoint, ecdh proxy rScalar pub) -- | Derive the shared secret with the receiver key -- and the R point of the scheme. deriveDecrypt :: EllipticCurveDH curve => proxy curve -- ^ representation of the curve -> Point curve -- ^ The received R (supposedly, randomly generated on the encrypt side) -> Scalar curve -- ^ The secret key of the receiver -> SharedSecret deriveDecrypt proxy point secret = ecdh proxy secret point cryptonite-0.23/Crypto/PubKey/Ed25519.hs0000644000000000000000000001102512617137377016012 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Ed25519 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Ed25519 support -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE BangPatterns #-} module Crypto.PubKey.Ed25519 ( SecretKey , PublicKey , Signature -- * Smart constructors , signature , publicKey , secretKey -- * methods , toPublic , sign , verify ) where import Data.Word import Foreign.Ptr import Foreign.C.Types import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess, withByteArray, ScrubbedBytes, Bytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Error -- | An Ed25519 Secret key newtype SecretKey = SecretKey ScrubbedBytes deriving (Eq,ByteArrayAccess,NFData) -- | An Ed25519 public key newtype PublicKey = PublicKey Bytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | An Ed25519 signature newtype Signature = Signature Bytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | Try to build a public key from a bytearray publicKey :: ByteArrayAccess ba => ba -> CryptoFailable PublicKey publicKey bs | B.length bs == publicKeySize = CryptoPassed $ PublicKey $ B.copyAndFreeze bs (\_ -> return ()) | otherwise = CryptoFailed $ CryptoError_PublicKeySizeInvalid -- | Try to build a secret key from a bytearray secretKey :: ByteArrayAccess ba => ba -> CryptoFailable SecretKey secretKey bs | B.length bs == secretKeySize = unsafeDoIO $ withByteArray bs initialize | otherwise = CryptoFailed CryptoError_SecretKeyStructureInvalid where initialize inp = do valid <- isValidPtr inp if valid then (CryptoPassed . SecretKey) <$> B.copy bs (\_ -> return ()) else return $ CryptoFailed CryptoError_SecretKeyStructureInvalid isValidPtr _ = return True {-# NOINLINE secretKey #-} -- | Try to build a signature from a bytearray signature :: ByteArrayAccess ba => ba -> CryptoFailable Signature signature bs | B.length bs == signatureSize = CryptoPassed $ Signature $ B.copyAndFreeze bs (\_ -> return ()) | otherwise = CryptoFailed CryptoError_SecretKeyStructureInvalid -- | Create a public key from a secret key toPublic :: SecretKey -> PublicKey toPublic (SecretKey sec) = PublicKey <$> B.allocAndFreeze publicKeySize $ \result -> withByteArray sec $ \psec -> ccryptonite_ed25519_publickey psec result {-# NOINLINE toPublic #-} -- | Sign a message using the key pair sign :: ByteArrayAccess ba => SecretKey -> PublicKey -> ba -> Signature sign secret public message = Signature $ B.allocAndFreeze signatureSize $ \sig -> withByteArray secret $ \sec -> withByteArray public $ \pub -> withByteArray message $ \msg -> ccryptonite_ed25519_sign msg (fromIntegral msgLen) sec pub sig where !msgLen = B.length message -- | Verify a message verify :: ByteArrayAccess ba => PublicKey -> ba -> Signature -> Bool verify public message signatureVal = unsafeDoIO $ withByteArray signatureVal $ \sig -> withByteArray public $ \pub -> withByteArray message $ \msg -> do r <- ccryptonite_ed25519_sign_open msg (fromIntegral msgLen) pub sig return (r == 0) where !msgLen = B.length message publicKeySize :: Int publicKeySize = 32 secretKeySize :: Int secretKeySize = 32 signatureSize :: Int signatureSize = 64 foreign import ccall "cryptonite_ed25519_publickey" ccryptonite_ed25519_publickey :: Ptr SecretKey -- secret key -> Ptr PublicKey -- public key -> IO () foreign import ccall "cryptonite_ed25519_sign_open" ccryptonite_ed25519_sign_open :: Ptr Word8 -- message -> CSize -- message len -> Ptr PublicKey -- public -> Ptr Signature -- signature -> IO CInt foreign import ccall "cryptonite_ed25519_sign" ccryptonite_ed25519_sign :: Ptr Word8 -- message -> CSize -- message len -> Ptr SecretKey -- secret -> Ptr PublicKey -- public -> Ptr Signature -- signature -> IO () cryptonite-0.23/Crypto/PubKey/Ed448.hs0000644000000000000000000000104313050556742015634 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Ed448 -- License : BSD-style -- Maintainer : John Galt -- Stability : experimental -- Portability : unknown -- -- Ed448 support -- -- /Functions and types exported here will be DEPRECATED in a future version./ -- For Diffie-Hellman over curve448 please use module "Crypto.PubKey.Curve448" -- instead. -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MagicHash #-} module Crypto.PubKey.Ed448 ( module Crypto.PubKey.Curve448 ) where import Crypto.PubKey.Curve448 cryptonite-0.23/Crypto/PubKey/RSA.hs0000644000000000000000000000752712530073117015476 0ustar0000000000000000-- | -- Module : Crypto.PubKey.RSA -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.PubKey.RSA ( Error(..) , PublicKey(..) , PrivateKey(..) , Blinder(..) -- * generation function , generateWith , generate , generateBlinder ) where import Crypto.Internal.Imports import Crypto.Random.Types import Crypto.Number.ModArithmetic (inverse, inverseCoprimes) import Crypto.Number.Generate (generateMax) import Crypto.Number.Prime (generatePrime) import Crypto.PubKey.RSA.Types {- -- some bad implementation will not serialize ASN.1 integer properly, leading -- to negative modulus. -- TODO : Find a better place for this toPositive :: Integer -> Integer toPositive int | int < 0 = uintOfBytes $ bytesOfInt int | otherwise = int where uintOfBytes = foldl (\acc n -> (acc `shiftL` 8) + fromIntegral n) 0 bytesOfInt :: Integer -> [Word8] bytesOfInt n = if testBit (head nints) 7 then nints else 0xff : nints where nints = reverse $ plusOne $ reverse $ map complement $ bytesOfUInt (abs n) plusOne [] = [1] plusOne (x:xs) = if x == 0xff then 0 : plusOne xs else (x+1) : xs bytesOfUInt x = reverse (list x) where list i = if i <= 0xff then [fromIntegral i] else (fromIntegral i .&. 0xff) : list (i `shiftR` 8) -} -- | Generate a key pair given p and q. -- -- p and q need to be distinct prime numbers. -- -- e need to be coprime to phi=(p-1)*(q-1). If that's not the -- case, the function will not return a key pair. -- A small hamming weight results in better performance. -- -- * e=0x10001 is a popular choice -- -- * e=3 is popular as well, but proven to not be as secure for some cases. -- generateWith :: (Integer, Integer) -- ^ chosen distinct primes p and q -> Int -- ^ size in bytes -> Integer -- ^ RSA public exponant 'e' -> Maybe (PublicKey, PrivateKey) generateWith (p,q) size e = case inverse e phi of Nothing -> Nothing Just d -> Just (pub,priv d) where n = p*q phi = (p-1)*(q-1) -- q and p should be *distinct* *prime* numbers, hence always coprime qinv = inverseCoprimes q p pub = PublicKey { public_size = size , public_n = n , public_e = e } priv d = PrivateKey { private_pub = pub , private_d = d , private_p = p , private_q = q , private_dP = d `mod` (p-1) , private_dQ = d `mod` (q-1) , private_qinv = qinv } -- | generate a pair of (private, public) key of size in bytes. generate :: MonadRandom m => Int -- ^ size in bytes -> Integer -- ^ RSA public exponant 'e' -> m (PublicKey, PrivateKey) generate size e = loop where loop = do -- loop until we find a valid key pair given e pq <- generatePQ case generateWith pq size e of Nothing -> loop Just pp -> return pp generatePQ = do p <- generatePrime (8 * (size `div` 2)) q <- generateQ p return (p,q) generateQ p = do q <- generatePrime (8 * (size - (size `div` 2))) if p == q then generateQ p else return q -- | Generate a blinder to use with decryption and signing operation -- -- the unique parameter apart from the random number generator is the -- public key value N. generateBlinder :: MonadRandom m => Integer -- ^ RSA public N parameter. -> m Blinder generateBlinder n = (\r -> Blinder r (inverseCoprimes r n)) <$> generateMax n cryptonite-0.23/Crypto/PubKey/RSA/PKCS15.hs0000644000000000000000000002061412673727640016413 0ustar0000000000000000-- | -- Module : Crypto.PubKey.RSA.PKCS15 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.PubKey.RSA.PKCS15 ( -- * padding and unpadding pad , padSignature , unpad -- * private key operations , decrypt , decryptSafer , sign , signSafer -- * public key operations , encrypt , verify -- * hash ASN1 description , HashAlgorithmASN1 ) where import Crypto.Random.Types import Crypto.PubKey.Internal (and') import Crypto.PubKey.RSA.Types import Crypto.PubKey.RSA.Prim import Crypto.PubKey.RSA (generateBlinder) import Crypto.Hash import Data.ByteString (ByteString) import Data.Word import Crypto.Internal.ByteArray (ByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B -- | A specialized class for hash algorithm that can product -- a ASN1 wrapped description the algorithm plus the content -- of the digest. class HashAlgorithm hashAlg => HashAlgorithmASN1 hashAlg where -- | Convert a Digest into an ASN1 wrapped descriptive ByteArray hashDigestASN1 :: ByteArray out => Digest hashAlg -> out -- http://uk.emc.com/emc-plus/rsa-labs/pkcs/files/h11300-wp-pkcs-1v2-2-rsa-cryptography-standard.pdf -- EMSA-PKCS1-v1_5 instance HashAlgorithmASN1 MD2 where hashDigestASN1 = addDigestPrefix [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10] instance HashAlgorithmASN1 MD5 where hashDigestASN1 = addDigestPrefix [0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10] instance HashAlgorithmASN1 SHA1 where hashDigestASN1 = addDigestPrefix [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14] instance HashAlgorithmASN1 SHA224 where hashDigestASN1 = addDigestPrefix [0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c] instance HashAlgorithmASN1 SHA256 where hashDigestASN1 = addDigestPrefix [0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20] instance HashAlgorithmASN1 SHA384 where hashDigestASN1 = addDigestPrefix [0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30] instance HashAlgorithmASN1 SHA512 where hashDigestASN1 = addDigestPrefix [0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40] instance HashAlgorithmASN1 SHA512t_224 where hashDigestASN1 = addDigestPrefix [0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x05,0x05,0x00,0x04,0x1c] instance HashAlgorithmASN1 SHA512t_256 where hashDigestASN1 = addDigestPrefix [0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x06,0x05,0x00,0x04,0x20] instance HashAlgorithmASN1 RIPEMD160 where hashDigestASN1 = addDigestPrefix [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14] -- -- ** Hack ** -- -- this happens to not need a real ASN1 encoder, because -- thanks to the digest being a specific size AND -- that the digest data is the last bytes in the encoding, -- this allows to just prepend the right prefix to the -- computed digest, to make it in the expected and valid shape. -- -- Otherwise the expected structure is in the following form: -- -- Start Sequence -- ,Start Sequence -- ,OID oid -- ,Null -- ,End Sequence -- ,OctetString digest -- ,End Sequence addDigestPrefix :: ByteArray out => [Word8] -> Digest hashAlg -> out addDigestPrefix prefix digest = B.pack prefix `B.append` B.convert digest -- | This produce a standard PKCS1.5 padding for encryption pad :: (MonadRandom m, ByteArray message) => Int -> message -> m (Either Error message) pad len m | B.length m > len - 11 = return (Left MessageTooLong) | otherwise = do padding <- getNonNullRandom (len - B.length m - 3) return $ Right $ B.concat [ B.pack [0,2], padding, B.pack [0], m ] where -- get random non-null bytes getNonNullRandom :: (ByteArray bytearray, MonadRandom m) => Int -> m bytearray getNonNullRandom n = do bs0 <- getRandomBytes n let bytes = B.pack $ filter (/= 0) $ B.unpack (bs0 :: Bytes) left = n - B.length bytes if left == 0 then return bytes else do bend <- getNonNullRandom left return (bytes `B.append` bend) -- | Produce a standard PKCS1.5 padding for signature padSignature :: ByteArray signature => Int -> signature -> Either Error signature padSignature klen signature | klen < siglen+1 = Left SignatureTooLong | otherwise = Right (B.pack padding `B.append` signature) where siglen = B.length signature padding = 0 : 1 : (replicate (klen - siglen - 3) 0xff ++ [0]) -- | Try to remove a standard PKCS1.5 encryption padding. unpad :: ByteArray bytearray => bytearray -> Either Error bytearray unpad packed | paddingSuccess = Right m | otherwise = Left MessageNotRecognized where (zt, ps0m) = B.splitAt 2 packed (ps, zm) = B.span (/= 0) ps0m (z, m) = B.splitAt 1 zm paddingSuccess = and' [ zt `B.constEq` (B.pack [0,2] :: Bytes) , z == B.zero 1 , B.length ps >= 8 ] -- | decrypt message using the private key. -- -- When the decryption is not in a context where an attacker could gain -- information from the timing of the operation, the blinder can be set to None. -- -- If unsure always set a blinder or use decryptSafer decrypt :: Maybe Blinder -- ^ optional blinder -> PrivateKey -- ^ RSA private key -> ByteString -- ^ cipher text -> Either Error ByteString decrypt blinder pk c | B.length c /= (private_size pk) = Left MessageSizeIncorrect | otherwise = unpad $ dp blinder pk c -- | decrypt message using the private key and by automatically generating a blinder. decryptSafer :: MonadRandom m => PrivateKey -- ^ RSA private key -> ByteString -- ^ cipher text -> m (Either Error ByteString) decryptSafer pk b = do blinder <- generateBlinder (private_n pk) return (decrypt (Just blinder) pk b) -- | encrypt a bytestring using the public key. -- -- the message needs to be smaller than the key size - 11 encrypt :: MonadRandom m => PublicKey -> ByteString -> m (Either Error ByteString) encrypt pk m = do r <- pad (public_size pk) m case r of Left err -> return $ Left err Right em -> return $ Right (ep pk em) -- | sign message using private key, a hash and its ASN1 description -- -- When the signature is not in a context where an attacker could gain -- information from the timing of the operation, the blinder can be set to None. -- -- If unsure always set a blinder or use signSafer sign :: HashAlgorithmASN1 hashAlg => Maybe Blinder -- ^ optional blinder -> Maybe hashAlg -- ^ hash algorithm -> PrivateKey -- ^ private key -> ByteString -- ^ message to sign -> Either Error ByteString sign blinder hashDescr pk m = dp blinder pk `fmap` makeSignature hashDescr (private_size pk) m -- | sign message using the private key and by automatically generating a blinder. signSafer :: (HashAlgorithmASN1 hashAlg, MonadRandom m) => Maybe hashAlg -- ^ Hash algorithm -> PrivateKey -- ^ private key -> ByteString -- ^ message to sign -> m (Either Error ByteString) signSafer hashAlg pk m = do blinder <- generateBlinder (private_n pk) return (sign (Just blinder) hashAlg pk m) -- | verify message with the signed message verify :: HashAlgorithmASN1 hashAlg => Maybe hashAlg -> PublicKey -> ByteString -> ByteString -> Bool verify hashAlg pk m sm = case makeSignature hashAlg (public_size pk) m of Left _ -> False Right s -> s == (ep pk sm) -- | make signature digest, used in 'sign' and 'verify' makeSignature :: HashAlgorithmASN1 hashAlg => Maybe hashAlg -- ^ optional hashing algorithm -> Int -> ByteString -> Either Error ByteString makeSignature Nothing klen m = padSignature klen m makeSignature (Just hashAlg) klen m = padSignature klen (hashDigestASN1 $ hashWith hashAlg m) cryptonite-0.23/Crypto/PubKey/RSA/Prim.hs0000644000000000000000000000471312533034317016401 0ustar0000000000000000-- | -- Module : Crypto.PubKey.RSA.Prim -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.PubKey.RSA.Prim ( -- * decrypt primitive dp -- * encrypt primitive , ep ) where import Crypto.PubKey.RSA.Types import Crypto.Number.ModArithmetic (expFast, expSafe) import Crypto.Number.Serialize (os2ip, i2ospOf_) import Crypto.Internal.ByteArray (ByteArray) {- dpSlow computes the decrypted message not using any precomputed cache value. only n and d need to valid. -} dpSlow :: ByteArray ba => PrivateKey -> ba -> ba dpSlow pk c = i2ospOf_ (private_size pk) $ expSafe (os2ip c) (private_d pk) (private_n pk) {- dpFast computes the decrypted message more efficiently if the precomputed private values are available. mod p and mod q are faster to compute than mod pq -} dpFast :: ByteArray ba => Blinder -> PrivateKey -> ba -> ba dpFast (Blinder r rm1) pk c = i2ospOf_ (private_size pk) (multiplication rm1 (m2 + h * (private_q pk)) (private_n pk)) where re = expFast r (public_e $ private_pub pk) (private_n pk) iC = multiplication re (os2ip c) (private_n pk) m1 = expSafe iC (private_dP pk) (private_p pk) m2 = expSafe iC (private_dQ pk) (private_q pk) h = ((private_qinv pk) * (m1 - m2)) `mod` (private_p pk) dpFastNoBlinder :: ByteArray ba => PrivateKey -> ba -> ba dpFastNoBlinder pk c = i2ospOf_ (private_size pk) (m2 + h * (private_q pk)) where iC = os2ip c m1 = expSafe iC (private_dP pk) (private_p pk) m2 = expSafe iC (private_dQ pk) (private_q pk) h = ((private_qinv pk) * (m1 - m2)) `mod` (private_p pk) -- | Compute the RSA decrypt primitive. -- if the p and q numbers are available, then dpFast is used -- otherwise, we use dpSlow which only need d and n. dp :: ByteArray ba => Maybe Blinder -> PrivateKey -> ba -> ba dp blinder pk | private_p pk /= 0 && private_q pk /= 0 = maybe dpFastNoBlinder dpFast blinder $ pk | otherwise = dpSlow pk -- | Compute the RSA encrypt primitive ep :: ByteArray ba => PublicKey -> ba -> ba ep pk m = i2ospOf_ (public_size pk) $ expFast (os2ip m) (public_e pk) (public_n pk) -- | multiply 2 integers in Zm only performing the modulo operation if necessary multiplication :: Integer -> Integer -> Integer -> Integer multiplication a b m = (a * b) `mod` m cryptonite-0.23/Crypto/PubKey/RSA/PSS.hs0000644000000000000000000001361112527357171016145 0ustar0000000000000000-- | -- Module : Crypto.PubKey.RSA.PSS -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.PubKey.RSA.PSS ( PSSParams(..) , defaultPSSParams , defaultPSSParamsSHA1 -- * Sign and verify functions , signWithSalt , sign , signSafer , verify ) where import Crypto.Random.Types import Crypto.PubKey.RSA.Types import Crypto.PubKey.RSA.Prim import Crypto.PubKey.RSA (generateBlinder) import Crypto.PubKey.MaskGenFunction import Crypto.Hash import Data.Bits (xor, shiftR, (.&.)) import Data.Word import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B (convert) import Data.ByteString (ByteString) import qualified Data.ByteString as B -- | Parameters for PSS signature/verification. data PSSParams hash seed output = PSSParams { pssHash :: hash -- ^ Hash function to use , pssMaskGenAlg :: MaskGenAlgorithm seed output -- ^ Mask Gen algorithm to use , pssSaltLength :: Int -- ^ Length of salt. need to be <= to hLen. , pssTrailerField :: Word8 -- ^ Trailer field, usually 0xbc } -- | Default Params with a specified hash function defaultPSSParams :: (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) => hash -> PSSParams hash seed output defaultPSSParams hashAlg = PSSParams { pssHash = hashAlg , pssMaskGenAlg = mgf1 hashAlg , pssSaltLength = hashDigestSize hashAlg , pssTrailerField = 0xbc } -- | Default Params using SHA1 algorithm. defaultPSSParamsSHA1 :: PSSParams SHA1 ByteString ByteString defaultPSSParamsSHA1 = defaultPSSParams SHA1 -- | Sign using the PSS parameters and the salt explicitely passed as parameters. -- -- the function ignore SaltLength from the PSS Parameters signWithSalt :: HashAlgorithm hash => ByteString -- ^ Salt to use -> Maybe Blinder -- ^ optional blinder to use -> PSSParams hash ByteString ByteString -- ^ PSS Parameters to use -> PrivateKey -- ^ RSA Private Key -> ByteString -- ^ Message to sign -> Either Error ByteString signWithSalt salt blinder params pk m | k < hashLen + saltLen + 2 = Left InvalidParameters | otherwise = Right $ dp blinder pk em where mHash = B.convert $ hashWith (pssHash params) m k = private_size pk dbLen = k - hashLen - 1 saltLen = B.length salt hashLen = hashDigestSize (pssHash params) pubBits = private_size pk * 8 -- to change if public_size is converted in bytes m' = B.concat [B.replicate 8 0,mHash,salt] h = B.convert $ hashWith (pssHash params) m' db = B.concat [B.replicate (dbLen - saltLen - 1) 0,B.singleton 1,salt] dbmask = (pssMaskGenAlg params) h dbLen maskedDB = B.pack $ normalizeToKeySize pubBits $ B.zipWith xor db dbmask em = B.concat [maskedDB, h, B.singleton (pssTrailerField params)] -- | Sign using the PSS Parameters sign :: (HashAlgorithm hash, MonadRandom m) => Maybe Blinder -- ^ optional blinder to use -> PSSParams hash ByteString ByteString -- ^ PSS Parameters to use -> PrivateKey -- ^ RSA Private Key -> ByteString -- ^ Message to sign -> m (Either Error ByteString) sign blinder params pk m = do salt <- getRandomBytes (pssSaltLength params) return (signWithSalt salt blinder params pk m) -- | Sign using the PSS Parameters and an automatically generated blinder. signSafer :: (HashAlgorithm hash, MonadRandom m) => PSSParams hash ByteString ByteString -- ^ PSS Parameters to use -> PrivateKey -- ^ private key -> ByteString -- ^ message to sign -> m (Either Error ByteString) signSafer params pk m = do blinder <- generateBlinder (private_n pk) sign (Just blinder) params pk m -- | Verify a signature using the PSS Parameters verify :: HashAlgorithm hash => PSSParams hash ByteString ByteString -- ^ PSS Parameters to use to verify, -- this need to be identical to the parameters when signing -> PublicKey -- ^ RSA Public Key -> ByteString -- ^ Message to verify -> ByteString -- ^ Signature -> Bool verify params pk m s | public_size pk /= B.length s = False | B.last em /= pssTrailerField params = False | not (B.all (== 0) ps0) = False | b1 /= B.singleton 1 = False | otherwise = h == B.convert h' where -- parameters hashLen = hashDigestSize (pssHash params) dbLen = public_size pk - hashLen - 1 pubBits = public_size pk * 8 -- to change if public_size is converted in bytes -- unmarshall fields em = ep pk s maskedDB = B.take (B.length em - hashLen - 1) em h = B.take hashLen $ B.drop (B.length maskedDB) em dbmask = (pssMaskGenAlg params) h dbLen db = B.pack $ normalizeToKeySize pubBits $ B.zipWith xor maskedDB dbmask (ps0,z) = B.break (== 1) db (b1,salt) = B.splitAt 1 z mHash = B.convert $ hashWith (pssHash params) m m' = B.concat [B.replicate 8 0,mHash,salt] h' = hashWith (pssHash params) m' normalizeToKeySize :: Int -> [Word8] -> [Word8] normalizeToKeySize _ [] = [] -- very unlikely normalizeToKeySize bits (x:xs) = x .&. mask : xs where mask = if sh > 0 then 0xff `shiftR` (8-sh) else 0xff sh = ((bits-1) .&. 0x7) cryptonite-0.23/Crypto/PubKey/RSA/OAEP.hs0000644000000000000000000001437312527326466016235 0ustar0000000000000000-- | -- Module : Crypto.PubKey.RSA.OAEP -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- RSA OAEP mode -- -- module Crypto.PubKey.RSA.OAEP ( OAEPParams(..) , defaultOAEPParams -- * OAEP encryption , encryptWithSeed , encrypt -- * OAEP decryption , decrypt , decryptSafer ) where import Crypto.Hash import Crypto.Random.Types import Crypto.PubKey.RSA.Types import Crypto.PubKey.MaskGenFunction import Crypto.PubKey.RSA.Prim import Crypto.PubKey.RSA (generateBlinder) import Crypto.PubKey.Internal (and') import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.Bits (xor) import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B (convert) -- | Parameters for OAEP encryption/decryption data OAEPParams hash seed output = OAEPParams { oaepHash :: hash -- ^ Hash function to use. , oaepMaskGenAlg :: MaskGenAlgorithm seed output -- ^ Mask Gen algorithm to use. , oaepLabel :: Maybe ByteString -- ^ Optional label prepended to message. } -- | Default Params with a specified hash function defaultOAEPParams :: (ByteArrayAccess seed, ByteArray output, HashAlgorithm hash) => hash -> OAEPParams hash seed output defaultOAEPParams hashAlg = OAEPParams { oaepHash = hashAlg , oaepMaskGenAlg = mgf1 hashAlg , oaepLabel = Nothing } -- | Encrypt a message using OAEP with a predefined seed. encryptWithSeed :: HashAlgorithm hash => ByteString -- ^ Seed -> OAEPParams hash ByteString ByteString -- ^ OAEP params to use for encryption -> PublicKey -- ^ Public key. -> ByteString -- ^ Message to encrypt -> Either Error ByteString encryptWithSeed seed oaep pk msg | k < 2*hashLen+2 = Left InvalidParameters | B.length seed /= hashLen = Left InvalidParameters | mLen > k - 2*hashLen-2 = Left MessageTooLong | otherwise = Right $ ep pk em where -- parameters k = public_size pk mLen = B.length msg mgf = oaepMaskGenAlg oaep labelHash = hashWith (oaepHash oaep) (maybe B.empty id $ oaepLabel oaep) hashLen = hashDigestSize (oaepHash oaep) -- put fields ps = B.replicate (k - mLen - 2*hashLen - 2) 0 db = B.concat [B.convert labelHash, ps, B.singleton 0x1, msg] dbmask = mgf seed (k - hashLen - 1) maskedDB = B.pack $ B.zipWith xor db dbmask seedMask = mgf maskedDB hashLen maskedSeed = B.pack $ B.zipWith xor seed seedMask em = B.concat [B.singleton 0x0,maskedSeed,maskedDB] -- | Encrypt a message using OAEP encrypt :: (HashAlgorithm hash, MonadRandom m) => OAEPParams hash ByteString ByteString -- ^ OAEP params to use for encryption. -> PublicKey -- ^ Public key. -> ByteString -- ^ Message to encrypt -> m (Either Error ByteString) encrypt oaep pk msg = do seed <- getRandomBytes hashLen return (encryptWithSeed seed oaep pk msg) where hashLen = hashDigestSize (oaepHash oaep) -- | un-pad a OAEP encoded message. -- -- It doesn't apply the RSA decryption primitive unpad :: HashAlgorithm hash => OAEPParams hash ByteString ByteString -- ^ OAEP params to use -> Int -- ^ size of the key in bytes -> ByteString -- ^ encoded message (not encrypted) -> Either Error ByteString unpad oaep k em | paddingSuccess = Right msg | otherwise = Left MessageNotRecognized where -- parameters mgf = oaepMaskGenAlg oaep labelHash = B.convert $ hashWith (oaepHash oaep) (maybe B.empty id $ oaepLabel oaep) hashLen = hashDigestSize (oaepHash oaep) -- getting em's fields (pb, em0) = B.splitAt 1 em (maskedSeed,maskedDB) = B.splitAt hashLen em0 seedMask = mgf maskedDB hashLen seed = B.pack $ B.zipWith xor maskedSeed seedMask dbmask = mgf seed (k - hashLen - 1) db = B.pack $ B.zipWith xor maskedDB dbmask -- getting db's fields (labelHash',db1) = B.splitAt hashLen db (_,db2) = B.break (/= 0) db1 (ps1,msg) = B.splitAt 1 db2 paddingSuccess = and' [ labelHash' == labelHash -- no need for constant eq , ps1 == B.replicate 1 0x1 , pb == B.replicate 1 0x0 ] -- | Decrypt a ciphertext using OAEP -- -- When the signature is not in a context where an attacker could gain -- information from the timing of the operation, the blinder can be set to None. -- -- If unsure always set a blinder or use decryptSafer decrypt :: HashAlgorithm hash => Maybe Blinder -- ^ Optional blinder -> OAEPParams hash ByteString ByteString -- ^ OAEP params to use for decryption -> PrivateKey -- ^ Private key -> ByteString -- ^ Cipher text -> Either Error ByteString decrypt blinder oaep pk cipher | B.length cipher /= k = Left MessageSizeIncorrect | k < 2*hashLen+2 = Left InvalidParameters | otherwise = unpad oaep (private_size pk) $ dp blinder pk cipher where -- parameters k = private_size pk hashLen = hashDigestSize (oaepHash oaep) -- | Decrypt a ciphertext using OAEP and by automatically generating a blinder. decryptSafer :: (HashAlgorithm hash, MonadRandom m) => OAEPParams hash ByteString ByteString -- ^ OAEP params to use for decryption -> PrivateKey -- ^ Private key -> ByteString -- ^ Cipher text -> m (Either Error ByteString) decryptSafer oaep pk cipher = do blinder <- generateBlinder (private_n pk) return (decrypt (Just blinder) oaep pk cipher) cryptonite-0.23/Crypto/PubKey/RSA/Types.hs0000644000000000000000000000635612527650331016606 0ustar0000000000000000-- | -- Module : Crypto.PubKey.RSA.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.PubKey.RSA.Types ( Error(..) , Blinder(..) , PublicKey(..) , PrivateKey(..) , KeyPair(..) , toPublicKey , toPrivateKey , private_size , private_n , private_e ) where import Data.Data import Crypto.Internal.Imports -- | Blinder which is used to obfuscate the timing -- of the decryption primitive (used by decryption and signing). data Blinder = Blinder !Integer !Integer deriving (Show,Eq) -- | error possible during encryption, decryption or signing. data Error = MessageSizeIncorrect -- ^ the message to decrypt is not of the correct size (need to be == private_size) | MessageTooLong -- ^ the message to encrypt is too long | MessageNotRecognized -- ^ the message decrypted doesn't have a PKCS15 structure (0 2 .. 0 msg) | SignatureTooLong -- ^ the message's digest is too long | InvalidParameters -- ^ some parameters lead to breaking assumptions. deriving (Show,Eq) -- | Represent a RSA public key data PublicKey = PublicKey { public_size :: Int -- ^ size of key in bytes , public_n :: Integer -- ^ public p*q , public_e :: Integer -- ^ public exponant e } deriving (Show,Read,Eq,Data,Typeable) instance NFData PublicKey where rnf (PublicKey sz n e) = rnf n `seq` rnf e `seq` sz `seq` () -- | Represent a RSA private key. -- -- Only the pub, d fields are mandatory to fill. -- -- p, q, dP, dQ, qinv are by-product during RSA generation, -- but are useful to record here to speed up massively -- the decrypt and sign operation. -- -- implementations can leave optional fields to 0. -- data PrivateKey = PrivateKey { private_pub :: PublicKey -- ^ public part of a private key (size, n and e) , private_d :: Integer -- ^ private exponant d , private_p :: Integer -- ^ p prime number , private_q :: Integer -- ^ q prime number , private_dP :: Integer -- ^ d mod (p-1) , private_dQ :: Integer -- ^ d mod (q-1) , private_qinv :: Integer -- ^ q^(-1) mod p } deriving (Show,Read,Eq,Data,Typeable) instance NFData PrivateKey where rnf (PrivateKey pub d p q dp dq qinv) = rnf pub `seq` rnf d `seq` rnf p `seq` rnf q `seq` rnf dp `seq` rnf dq `seq` qinv `seq` () -- | get the size in bytes from a private key private_size :: PrivateKey -> Int private_size = public_size . private_pub -- | get n from a private key private_n :: PrivateKey -> Integer private_n = public_n . private_pub -- | get e from a private key private_e :: PrivateKey -> Integer private_e = public_e . private_pub -- | Represent RSA KeyPair -- -- note the RSA private key contains already an instance of public key for efficiency newtype KeyPair = KeyPair PrivateKey deriving (Show,Read,Eq,Data,Typeable,NFData) -- | Public key of a RSA KeyPair toPublicKey :: KeyPair -> PublicKey toPublicKey (KeyPair priv) = private_pub priv -- | Private key of a RSA KeyPair toPrivateKey :: KeyPair -> PrivateKey toPrivateKey (KeyPair priv) = priv cryptonite-0.23/Crypto/Random.hs0000644000000000000000000000440012702176335015064 0ustar0000000000000000-- | -- Module : Crypto.Random -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Random ( -- * Deterministic instances ChaChaDRG , SystemDRG , Seed -- * Seed , seedNew , seedFromInteger , seedToInteger -- * Deterministic Random class , getSystemDRG , drgNew , drgNewSeed , drgNewTest , withDRG , withRandomBytes , DRG(..) -- * Random abstraction , MonadRandom(..) , MonadPseudoRandom ) where import Crypto.Random.Types import Crypto.Random.ChaChaDRG import Crypto.Random.SystemDRG import Data.ByteArray (ByteArray, ByteArrayAccess, ScrubbedBytes) import Crypto.Internal.Imports import qualified Crypto.Number.Serialize as Serialize newtype Seed = Seed ScrubbedBytes deriving (ByteArrayAccess) -- Length for ChaCha DRG seed seedLength :: Int seedLength = 40 -- | Create a new Seed from system entropy seedNew :: MonadRandom randomly => randomly Seed seedNew = Seed `fmap` getRandomBytes seedLength -- | Convert a Seed to an integer seedToInteger :: Seed -> Integer seedToInteger (Seed b) = Serialize.os2ip b -- | Convert an integer to a Seed seedFromInteger :: Integer -> Seed seedFromInteger i = Seed $ Serialize.i2ospOf_ seedLength (i `mod` 2^(seedLength * 8)) -- | Create a new DRG from system entropy drgNew :: MonadRandom randomly => randomly ChaChaDRG drgNew = drgNewSeed `fmap` seedNew -- | Create a new DRG from a seed drgNewSeed :: Seed -> ChaChaDRG drgNewSeed (Seed seed) = initialize seed -- | Create a new DRG from 5 Word64. -- -- This is a convenient interface to create deterministic interface -- for quickcheck style testing. -- -- It can also be used in other contexts provided the input -- has been properly randomly generated. drgNewTest :: (Word64, Word64, Word64, Word64, Word64) -> ChaChaDRG drgNewTest = initializeWords -- | Generate @len random bytes and mapped the bytes to the function @f. -- -- This is equivalent to use Control.Arrow 'first' with 'randomBytesGenerate' withRandomBytes :: (ByteArray ba, DRG g) => g -> Int -> (ba -> a) -> (a, g) withRandomBytes rng len f = (f bs, rng') where (bs, rng') = randomBytesGenerate len rng cryptonite-0.23/Crypto/Random/Types.hs0000644000000000000000000000372512623123513016171 0ustar0000000000000000-- | -- Module : Crypto.Random.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.Random.Types ( MonadRandom(..) , MonadPseudoRandom , DRG(..) , withDRG ) where import Crypto.Random.Entropy import Crypto.Internal.ByteArray import Crypto.Internal.Imports -- | A monad constraint that allows to generate random bytes class (Functor m, Monad m) => MonadRandom m where getRandomBytes :: ByteArray byteArray => Int -> m byteArray -- | A Deterministic Random Generator (DRG) class class DRG gen where -- | Generate N bytes of randomness from a DRG randomBytesGenerate :: ByteArray byteArray => Int -> gen -> (byteArray, gen) instance MonadRandom IO where getRandomBytes = getEntropy -- | A simple Monad class very similar to a State Monad -- with the state being a DRG. newtype MonadPseudoRandom gen a = MonadPseudoRandom { runPseudoRandom :: gen -> (a, gen) } instance DRG gen => Functor (MonadPseudoRandom gen) where fmap f m = MonadPseudoRandom $ \g1 -> let (a, g2) = runPseudoRandom m g1 in (f a, g2) instance DRG gen => Applicative (MonadPseudoRandom gen) where pure a = MonadPseudoRandom $ \g -> (a, g) (<*>) fm m = MonadPseudoRandom $ \g1 -> let (f, g2) = runPseudoRandom fm g1 (a, g3) = runPseudoRandom m g2 in (f a, g3) instance DRG gen => Monad (MonadPseudoRandom gen) where return a = MonadPseudoRandom $ \g -> (a, g) (>>=) m1 m2 = MonadPseudoRandom $ \g1 -> let (a, g2) = runPseudoRandom m1 g1 in runPseudoRandom (m2 a) g2 instance DRG gen => MonadRandom (MonadPseudoRandom gen) where getRandomBytes n = MonadPseudoRandom (randomBytesGenerate n) -- | Run a pure computation with a Deterministic Random Generator -- in the 'MonadPseudoRandom' withDRG :: DRG gen => gen -> MonadPseudoRandom gen a -> (a, gen) withDRG gen m = runPseudoRandom m gen cryptonite-0.23/Crypto/Random/Entropy.hs0000644000000000000000000000122112541276547016531 0ustar0000000000000000-- | -- Module : Crypto.Random.Entropy -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.Random.Entropy ( getEntropy ) where import Data.Maybe (catMaybes) import Crypto.Internal.ByteArray (ByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Random.Entropy.Unsafe -- | Get some entropy from the system source of entropy getEntropy :: ByteArray byteArray => Int -> IO byteArray getEntropy n = do backends <- catMaybes `fmap` sequence supportedBackends B.alloc n (replenish n backends) cryptonite-0.23/Crypto/Random/EntropyPool.hs0000644000000000000000000000514112723504474017363 0ustar0000000000000000-- | -- Module : Crypto.Random.EntropyPool -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.Random.EntropyPool ( EntropyPool , createEntropyPool , createEntropyPoolWith , getEntropyFrom ) where import Control.Concurrent.MVar import Crypto.Random.Entropy.Unsafe import Crypto.Internal.ByteArray (ByteArray, ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B import Data.Word (Word8) import Data.Maybe (catMaybes) import Foreign.Marshal.Utils (copyBytes) import Foreign.Ptr (plusPtr, Ptr) -- | Pool of Entropy. Contains a self-mutating pool of entropy, -- that is always guaranteed to contain data. data EntropyPool = EntropyPool [EntropyBackend] (MVar Int) ScrubbedBytes -- size of entropy pool by default defaultPoolSize :: Int defaultPoolSize = 4096 -- | Create a new entropy pool of a specific size -- -- While you can create as many entropy pools as you want, -- the pool can be shared between multiples RNGs. createEntropyPoolWith :: Int -> [EntropyBackend] -> IO EntropyPool createEntropyPoolWith poolSize backends = do m <- newMVar 0 sm <- B.alloc poolSize (replenish poolSize backends) return $ EntropyPool backends m sm -- | Create a new entropy pool with a default size. -- -- While you can create as many entropy pools as you want, -- the pool can be shared between multiples RNGs. createEntropyPool :: IO EntropyPool createEntropyPool = do backends <- catMaybes `fmap` sequence supportedBackends createEntropyPoolWith defaultPoolSize backends -- | Put a chunk of the entropy pool into a buffer getEntropyPtr :: EntropyPool -> Int -> Ptr Word8 -> IO () getEntropyPtr (EntropyPool backends posM sm) n outPtr = B.withByteArray sm $ \entropyPoolPtr -> modifyMVar_ posM $ \pos -> copyLoop outPtr entropyPoolPtr pos n where poolSize = B.length sm copyLoop d s pos left | left == 0 = return pos | otherwise = do wrappedPos <- if pos == poolSize then replenish poolSize backends s >> return 0 else return pos let m = min (poolSize - wrappedPos) left copyBytes d (s `plusPtr` wrappedPos) m copyLoop (d `plusPtr` m) s (wrappedPos + m) (left - m) -- | Grab a chunk of entropy from the entropy pool. getEntropyFrom :: ByteArray byteArray => EntropyPool -> Int -> IO byteArray getEntropyFrom pool n = B.alloc n (getEntropyPtr pool n) cryptonite-0.23/Crypto/Random/Entropy/Unsafe.hs0000644000000000000000000000240112531124535017737 0ustar0000000000000000-- | -- Module : Crypto.Random.Entropy.Unsafe -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.Random.Entropy.Unsafe ( replenish , module Crypto.Random.Entropy.Backend ) where import Data.Word (Word8) import Foreign.Ptr (Ptr, plusPtr) import Crypto.Random.Entropy.Backend -- | Refill the entropy in a buffer -- -- call each entropy backend in turn until the buffer has -- been replenish. -- -- If the buffer cannot be refill after 3 loopings, this will raise -- an User Error exception replenish :: Int -> [EntropyBackend] -> Ptr Word8 -> IO () replenish _ [] _ = fail "cryptonite: random: cannot get any source of entropy on this system" replenish poolSize backends ptr = loop 0 backends ptr poolSize where loop :: Int -> [EntropyBackend] -> Ptr Word8 -> Int -> IO () loop retry [] p n | n == 0 = return () | retry == 3 = error "cryptonite: random: cannot fully replenish" | otherwise = loop (retry+1) backends p n loop _ (_:_) _ 0 = return () loop retry (b:bs) p n = do r <- gatherBackend b p n loop retry bs (p `plusPtr` r) (n - r) cryptonite-0.23/Crypto/Tutorial.hs0000644000000000000000000000503013075454604015451 0ustar0000000000000000 {- How to use @cryptonite@ with symmetric block ciphers > {-# LANGUAGE OverloadedStrings #-} > {-# LANGUAGE ScopedTypeVariables #-} > {-# LANGUAGE GADTs #-} > > import Crypto.Cipher.AES (AES256) > import Crypto.Cipher.Types (BlockCipher(..), Cipher(..), nullIV, KeySizeSpecifier(..), IV, makeIV) > import Crypto.Error (CryptoFailable(..), CryptoError(..)) > > import qualified Crypto.Random.Types as CRT > > import Data.ByteArray (ByteArray) > import Data.ByteString (ByteString) > > -- | Not required, but most general implementation > data Key c a where > Key :: (BlockCipher c, ByteArray a) => a -> Key c a > > -- | Generates a string of bytes (key) of a specific length for a given block cipher > genSecretKey :: forall m c a. (CRT.MonadRandom m, BlockCipher c, ByteArray a) => c -> Int -> m (Key c a) > genSecretKey _ = fmap Key . CRT.getRandomBytes > > -- | Generate a random initialization vector for a given block cipher > genRandomIV :: forall m c. (CRT.MonadRandom m, BlockCipher c) => c -> m (Maybe (IV c)) > genRandomIV _ = do > bytes :: ByteString <- CRT.getRandomBytes $ blockSize (undefined :: c) > return $ makeIV bytes > > -- | Initialize a block cipher > initCipher :: (BlockCipher c, ByteArray a) => Key c a -> Either CryptoError c > initCipher (Key k) = case cipherInit k of > CryptoFailed e -> Left e > CryptoPassed a -> Right a > > encrypt :: (BlockCipher c, ByteArray a) => Key c a -> IV c -> a -> Either CryptoError a > encrypt secretKey initIV msg = > case initCipher secretKey of > Left e -> Left e > Right c -> Right $ ctrCombine c initIV msg > > decrypt :: (BlockCipher c, ByteArray a) => Key c a -> IV c -> a -> Either CryptoError a > decrypt = encrypt > > exampleAES256 :: ByteString -> IO () > exampleAES256 msg = do > -- secret key needs 256 bits (32 * 8) > secretKey <- genSecretKey (undefined :: AES256) 32 > mInitIV <- genRandomIV (undefined :: AES256) > case mInitIV of > Nothing -> error "Failed to generate and initialization vector." > Just initIV -> do > let encryptedMsg = encrypt secretKey initIV msg > decryptedMsg = decrypt secretKey initIV =<< encryptedMsg > case (,) <$> encryptedMsg <*> decryptedMsg of > Left err -> error $ show err > Right (eMsg, dMsg) -> do > putStrLn $ "Original Message: " ++ show msg > putStrLn $ "Message after encryption: " ++ show eMsg > putStrLn $ "Message after decryption: " ++ show dMsg |-} module Crypto.Tutorial where cryptonite-0.23/Crypto/Cipher/AES/Primitive.hs0000644000000000000000000004742512535575651017464 0ustar0000000000000000{-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | -- Module : Crypto.Cipher.AES.Primitive -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- module Crypto.Cipher.AES.Primitive ( -- * block cipher data types AES -- * Authenticated encryption block cipher types , AESGCM , AESOCB -- * creation , initAES -- * misc , genCTR , genCounter -- * encryption , encryptECB , encryptCBC , encryptCTR , encryptXTS -- * decryption , decryptECB , decryptCBC , decryptCTR , decryptXTS -- * incremental GCM , gcmMode , gcmInit -- * incremental OCB , ocbMode , ocbInit ) where import Data.Word import Foreign.Ptr import Foreign.C.Types import Foreign.C.String import Crypto.Error import Crypto.Cipher.Types import Crypto.Cipher.Types.Block (IV(..)) import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess, ScrubbedBytes, withByteArray) import qualified Crypto.Internal.ByteArray as B instance Cipher AES where cipherName _ = "AES" cipherKeySize _ = KeySizeEnum [16,24,32] cipherInit k = initAES k instance BlockCipher AES where blockSize _ = 16 ecbEncrypt = encryptECB ecbDecrypt = decryptECB cbcEncrypt = encryptCBC cbcDecrypt = decryptCBC ctrCombine = encryptCTR aeadInit AEAD_GCM aes iv = CryptoPassed $ AEAD (gcmMode aes) (gcmInit aes iv) aeadInit AEAD_OCB aes iv = CryptoPassed $ AEAD (ocbMode aes) (ocbInit aes iv) aeadInit _ _ _ = CryptoFailed CryptoError_AEADModeNotSupported instance BlockCipher128 AES where xtsEncrypt = encryptXTS xtsDecrypt = decryptXTS -- | Create an AES AEAD implementation for GCM gcmMode :: AES -> AEADModeImpl AESGCM gcmMode aes = AEADModeImpl { aeadImplAppendHeader = gcmAppendAAD , aeadImplEncrypt = gcmAppendEncrypt aes , aeadImplDecrypt = gcmAppendDecrypt aes , aeadImplFinalize = gcmFinish aes } -- | Create an AES AEAD implementation for OCB ocbMode :: AES -> AEADModeImpl AESOCB ocbMode aes = AEADModeImpl { aeadImplAppendHeader = ocbAppendAAD aes , aeadImplEncrypt = ocbAppendEncrypt aes , aeadImplDecrypt = ocbAppendDecrypt aes , aeadImplFinalize = ocbFinish aes } -- | AES Context (pre-processed key) newtype AES = AES ScrubbedBytes deriving (NFData) -- | AESGCM State newtype AESGCM = AESGCM ScrubbedBytes deriving (NFData) -- | AESOCB State newtype AESOCB = AESOCB ScrubbedBytes deriving (NFData) sizeGCM :: Int sizeGCM = 80 sizeOCB :: Int sizeOCB = 160 keyToPtr :: AES -> (Ptr AES -> IO a) -> IO a keyToPtr (AES b) f = withByteArray b (f . castPtr) ivToPtr :: ByteArrayAccess iv => iv -> (Ptr Word8 -> IO a) -> IO a ivToPtr iv f = withByteArray iv (f . castPtr) ivCopyPtr :: IV AES -> (Ptr Word8 -> IO a) -> IO (a, IV AES) ivCopyPtr (IV iv) f = (\(x,y) -> (x, IV y)) `fmap` copyAndModify iv f where copyAndModify :: ByteArray ba => ba -> (Ptr Word8 -> IO a) -> IO (a, ba) copyAndModify ba f' = B.copyRet ba f' withKeyAndIV :: ByteArrayAccess iv => AES -> iv -> (Ptr AES -> Ptr Word8 -> IO a) -> IO a withKeyAndIV ctx iv f = keyToPtr ctx $ \kptr -> ivToPtr iv $ \ivp -> f kptr ivp withKey2AndIV :: ByteArrayAccess iv => AES -> AES -> iv -> (Ptr AES -> Ptr AES -> Ptr Word8 -> IO a) -> IO a withKey2AndIV key1 key2 iv f = keyToPtr key1 $ \kptr1 -> keyToPtr key2 $ \kptr2 -> ivToPtr iv $ \ivp -> f kptr1 kptr2 ivp withGCMKeyAndCopySt :: AES -> AESGCM -> (Ptr AESGCM -> Ptr AES -> IO a) -> IO (a, AESGCM) withGCMKeyAndCopySt aes (AESGCM gcmSt) f = keyToPtr aes $ \aesPtr -> do newSt <- B.copy gcmSt (\_ -> return ()) a <- withByteArray newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr return (a, AESGCM newSt) withNewGCMSt :: AESGCM -> (Ptr AESGCM -> IO ()) -> IO AESGCM withNewGCMSt (AESGCM gcmSt) f = B.copy gcmSt (f . castPtr) >>= \sm2 -> return (AESGCM sm2) withOCBKeyAndCopySt :: AES -> AESOCB -> (Ptr AESOCB -> Ptr AES -> IO a) -> IO (a, AESOCB) withOCBKeyAndCopySt aes (AESOCB gcmSt) f = keyToPtr aes $ \aesPtr -> do newSt <- B.copy gcmSt (\_ -> return ()) a <- withByteArray newSt $ \gcmStPtr -> f (castPtr gcmStPtr) aesPtr return (a, AESOCB newSt) -- | Initialize a new context with a key -- -- Key needs to be of length 16, 24 or 32 bytes. Any other values will return failure initAES :: ByteArrayAccess key => key -> CryptoFailable AES initAES k | len == 16 = CryptoPassed $ initWithRounds 10 | len == 24 = CryptoPassed $ initWithRounds 12 | len == 32 = CryptoPassed $ initWithRounds 14 | otherwise = CryptoFailed CryptoError_KeySizeInvalid where len = B.length k initWithRounds nbR = AES $ B.allocAndFreeze (16+2*2*16*nbR) aesInit aesInit ptr = withByteArray k $ \ikey -> c_aes_init (castPtr ptr) (castPtr ikey) (fromIntegral len) -- | encrypt using Electronic Code Book (ECB) {-# NOINLINE encryptECB #-} encryptECB :: ByteArray ba => AES -> ba -> ba encryptECB = doECB c_aes_encrypt_ecb -- | encrypt using Cipher Block Chaining (CBC) {-# NOINLINE encryptCBC #-} encryptCBC :: ByteArray ba => AES -- ^ AES Context -> IV AES -- ^ Initial vector of AES block size -> ba -- ^ plaintext -> ba -- ^ ciphertext encryptCBC = doCBC c_aes_encrypt_cbc -- | generate a counter mode pad. this is generally xor-ed to an input -- to make the standard counter mode block operations. -- -- if the length requested is not a multiple of the block cipher size, -- more data will be returned, so that the returned bytearray is -- a multiple of the block cipher size. {-# NOINLINE genCTR #-} genCTR :: ByteArray ba => AES -- ^ Cipher Key. -> IV AES -- ^ usually a 128 bit integer. -> Int -- ^ length of bytes required. -> ba genCTR ctx (IV iv) len | len <= 0 = B.empty | otherwise = B.allocAndFreeze (nbBlocks * 16) generate where generate o = withKeyAndIV ctx iv $ \k i -> c_aes_gen_ctr (castPtr o) k i (fromIntegral nbBlocks) (nbBlocks',r) = len `quotRem` 16 nbBlocks = if r == 0 then nbBlocks' else nbBlocks' + 1 -- | generate a counter mode pad. this is generally xor-ed to an input -- to make the standard counter mode block operations. -- -- if the length requested is not a multiple of the block cipher size, -- more data will be returned, so that the returned bytearray is -- a multiple of the block cipher size. -- -- Similiar to 'genCTR' but also return the next IV for continuation {-# NOINLINE genCounter #-} genCounter :: ByteArray ba => AES -> IV AES -> Int -> (ba, IV AES) genCounter ctx iv len | len <= 0 = (B.empty, iv) | otherwise = unsafeDoIO $ keyToPtr ctx $ \k -> ivCopyPtr iv $ \i -> B.alloc outputLength $ \o -> do c_aes_gen_ctr_cont (castPtr o) k i (fromIntegral nbBlocks) where (nbBlocks',r) = len `quotRem` 16 nbBlocks = if r == 0 then nbBlocks' else nbBlocks' + 1 outputLength = nbBlocks * 16 {- TODO: when genCTR has same AESIV requirements for IV, add the following rules: - RULES "snd . genCounter" forall ctx iv len . snd (genCounter ctx iv len) = genCTR ctx iv len -} -- | encrypt using Counter mode (CTR) -- -- in CTR mode encryption and decryption is the same operation. {-# NOINLINE encryptCTR #-} encryptCTR :: ByteArray ba => AES -- ^ AES Context -> IV AES -- ^ initial vector of AES block size (usually representing a 128 bit integer) -> ba -- ^ plaintext input -> ba -- ^ ciphertext output encryptCTR ctx iv input | len <= 0 = B.empty | B.length iv /= 16 = error $ "AES error: IV length must be block size (16). Its length is: " ++ (show $ B.length iv) | otherwise = B.allocAndFreeze len doEncrypt where doEncrypt o = withKeyAndIV ctx iv $ \k v -> withByteArray input $ \i -> c_aes_encrypt_ctr (castPtr o) k v i (fromIntegral len) len = B.length input -- | encrypt using XTS -- -- the first key is the normal block encryption key -- the second key is used for the initial block tweak {-# NOINLINE encryptXTS #-} encryptXTS :: ByteArray ba => (AES,AES) -- ^ AES cipher and tweak context -> IV AES -- ^ a 128 bits IV, typically a sector or a block offset in XTS -> Word32 -- ^ number of rounds to skip, also seen a 16 byte offset in the sector or block. -> ba -- ^ input to encrypt -> ba -- ^ output encrypted encryptXTS = doXTS c_aes_encrypt_xts -- | decrypt using Electronic Code Book (ECB) {-# NOINLINE decryptECB #-} decryptECB :: ByteArray ba => AES -> ba -> ba decryptECB = doECB c_aes_decrypt_ecb -- | decrypt using Cipher block chaining (CBC) {-# NOINLINE decryptCBC #-} decryptCBC :: ByteArray ba => AES -> IV AES -> ba -> ba decryptCBC = doCBC c_aes_decrypt_cbc -- | decrypt using Counter mode (CTR). -- -- in CTR mode encryption and decryption is the same operation. decryptCTR :: ByteArray ba => AES -- ^ AES Context -> IV AES -- ^ initial vector, usually representing a 128 bit integer -> ba -- ^ ciphertext input -> ba -- ^ plaintext output decryptCTR = encryptCTR -- | decrypt using XTS {-# NOINLINE decryptXTS #-} decryptXTS :: ByteArray ba => (AES,AES) -- ^ AES cipher and tweak context -> IV AES -- ^ a 128 bits IV, typically a sector or a block offset in XTS -> Word32 -- ^ number of rounds to skip, also seen a 16 byte offset in the sector or block. -> ba -- ^ input to decrypt -> ba -- ^ output decrypted decryptXTS = doXTS c_aes_decrypt_xts {-# INLINE doECB #-} doECB :: ByteArray ba => (Ptr b -> Ptr AES -> CString -> CUInt -> IO ()) -> AES -> ba -> ba doECB f ctx input | len == 0 = B.empty | r /= 0 = error $ "Encryption error: input length must be a multiple of block size (16). Its length is: " ++ (show len) | otherwise = B.allocAndFreeze len $ \o -> keyToPtr ctx $ \k -> withByteArray input $ \i -> f (castPtr o) k i (fromIntegral nbBlocks) where (nbBlocks, r) = len `quotRem` 16 len = B.length input {-# INLINE doCBC #-} doCBC :: ByteArray ba => (Ptr b -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO ()) -> AES -> IV AES -> ba -> ba doCBC f ctx (IV iv) input | len == 0 = B.empty | r /= 0 = error $ "Encryption error: input length must be a multiple of block size (16). Its length is: " ++ (show len) | otherwise = B.allocAndFreeze len $ \o -> withKeyAndIV ctx iv $ \k v -> withByteArray input $ \i -> f (castPtr o) k v i (fromIntegral nbBlocks) where (nbBlocks, r) = len `quotRem` 16 len = B.length input {-# INLINE doXTS #-} doXTS :: ByteArray ba => (Ptr b -> Ptr AES -> Ptr AES -> Ptr Word8 -> CUInt -> CString -> CUInt -> IO ()) -> (AES, AES) -> IV AES -> Word32 -> ba -> ba doXTS f (key1,key2) iv spoint input | len == 0 = B.empty | r /= 0 = error $ "Encryption error: input length must be a multiple of block size (16) for now. Its length is: " ++ (show len) | otherwise = B.allocAndFreeze len $ \o -> withKey2AndIV key1 key2 iv $ \k1 k2 v -> withByteArray input $ \i -> f (castPtr o) k1 k2 v (fromIntegral spoint) i (fromIntegral nbBlocks) where (nbBlocks, r) = len `quotRem` 16 len = B.length input ------------------------------------------------------------------------ -- GCM ------------------------------------------------------------------------ -- | initialize a gcm context {-# NOINLINE gcmInit #-} gcmInit :: ByteArrayAccess iv => AES -> iv -> AESGCM gcmInit ctx iv = unsafeDoIO $ do sm <- B.alloc sizeGCM $ \gcmStPtr -> withKeyAndIV ctx iv $ \k v -> c_aes_gcm_init (castPtr gcmStPtr) k v (fromIntegral $ B.length iv) return $ AESGCM sm -- | append data which is only going to be authenticated to the GCM context. -- -- needs to happen after initialization and before appending encryption/decryption data. {-# NOINLINE gcmAppendAAD #-} gcmAppendAAD :: ByteArrayAccess aad => AESGCM -> aad -> AESGCM gcmAppendAAD gcmSt input = unsafeDoIO doAppend where doAppend = withNewGCMSt gcmSt $ \gcmStPtr -> withByteArray input $ \i -> c_aes_gcm_aad gcmStPtr i (fromIntegral $ B.length input) -- | append data to encrypt and append to the GCM context -- -- the bytearray needs to be a multiple of AES block size, unless it's the last call to this function. -- needs to happen after AAD appending, or after initialization if no AAD data. {-# NOINLINE gcmAppendEncrypt #-} gcmAppendEncrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM) gcmAppendEncrypt ctx gcm input = unsafeDoIO $ withGCMKeyAndCopySt ctx gcm doEnc where len = B.length input doEnc gcmStPtr aesPtr = B.alloc len $ \o -> withByteArray input $ \i -> c_aes_gcm_encrypt (castPtr o) gcmStPtr aesPtr i (fromIntegral len) -- | append data to decrypt and append to the GCM context -- -- the bytearray needs to be a multiple of AES block size, unless it's the last call to this function. -- needs to happen after AAD appending, or after initialization if no AAD data. {-# NOINLINE gcmAppendDecrypt #-} gcmAppendDecrypt :: ByteArray ba => AES -> AESGCM -> ba -> (ba, AESGCM) gcmAppendDecrypt ctx gcm input = unsafeDoIO $ withGCMKeyAndCopySt ctx gcm doDec where len = B.length input doDec gcmStPtr aesPtr = B.alloc len $ \o -> withByteArray input $ \i -> c_aes_gcm_decrypt (castPtr o) gcmStPtr aesPtr i (fromIntegral len) -- | Generate the Tag from GCM context {-# NOINLINE gcmFinish #-} gcmFinish :: AES -> AESGCM -> Int -> AuthTag gcmFinish ctx gcm taglen = AuthTag $ B.take taglen computeTag where computeTag = B.allocAndFreeze 16 $ \t -> withGCMKeyAndCopySt ctx gcm (c_aes_gcm_finish (castPtr t)) >> return () ------------------------------------------------------------------------ -- OCB v3 ------------------------------------------------------------------------ -- | initialize an ocb context {-# NOINLINE ocbInit #-} ocbInit :: ByteArrayAccess iv => AES -> iv -> AESOCB ocbInit ctx iv = unsafeDoIO $ do sm <- B.alloc sizeOCB $ \ocbStPtr -> withKeyAndIV ctx iv $ \k v -> c_aes_ocb_init (castPtr ocbStPtr) k v (fromIntegral $ B.length iv) return $ AESOCB sm -- | append data which is going to just be authenticated to the OCB context. -- -- need to happen after initialization and before appending encryption/decryption data. {-# NOINLINE ocbAppendAAD #-} ocbAppendAAD :: ByteArrayAccess aad => AES -> AESOCB -> aad -> AESOCB ocbAppendAAD ctx ocb input = unsafeDoIO (snd `fmap` withOCBKeyAndCopySt ctx ocb doAppend) where doAppend ocbStPtr aesPtr = withByteArray input $ \i -> c_aes_ocb_aad ocbStPtr aesPtr i (fromIntegral $ B.length input) -- | append data to encrypt and append to the OCB context -- -- the bytearray needs to be a multiple of the AES block size, unless it's the last call to this function. -- need to happen after AAD appending, or after initialization if no AAD data. {-# NOINLINE ocbAppendEncrypt #-} ocbAppendEncrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB) ocbAppendEncrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doEnc where len = B.length input doEnc ocbStPtr aesPtr = B.alloc len $ \o -> withByteArray input $ \i -> c_aes_ocb_encrypt (castPtr o) ocbStPtr aesPtr i (fromIntegral len) -- | append data to decrypt and append to the OCB context -- -- the bytearray needs to be a multiple of the AES block size, unless it's the last call to this function. -- need to happen after AAD appending, or after initialization if no AAD data. {-# NOINLINE ocbAppendDecrypt #-} ocbAppendDecrypt :: ByteArray ba => AES -> AESOCB -> ba -> (ba, AESOCB) ocbAppendDecrypt ctx ocb input = unsafeDoIO $ withOCBKeyAndCopySt ctx ocb doDec where len = B.length input doDec ocbStPtr aesPtr = B.alloc len $ \o -> withByteArray input $ \i -> c_aes_ocb_decrypt (castPtr o) ocbStPtr aesPtr i (fromIntegral len) -- | Generate the Tag from OCB context {-# NOINLINE ocbFinish #-} ocbFinish :: AES -> AESOCB -> Int -> AuthTag ocbFinish ctx ocb taglen = AuthTag $ B.take taglen computeTag where computeTag = B.allocAndFreeze 16 $ \t -> withOCBKeyAndCopySt ctx ocb (c_aes_ocb_finish (castPtr t)) >> return () ------------------------------------------------------------------------ foreign import ccall "cryptonite_aes.h cryptonite_aes_initkey" c_aes_init :: Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_encrypt_ecb" c_aes_encrypt_ecb :: CString -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_decrypt_ecb" c_aes_decrypt_ecb :: CString -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_encrypt_cbc" c_aes_encrypt_cbc :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_decrypt_cbc" c_aes_decrypt_cbc :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_encrypt_xts" c_aes_encrypt_xts :: CString -> Ptr AES -> Ptr AES -> Ptr Word8 -> CUInt -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_decrypt_xts" c_aes_decrypt_xts :: CString -> Ptr AES -> Ptr AES -> Ptr Word8 -> CUInt -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_gen_ctr" c_aes_gen_ctr :: CString -> Ptr AES -> Ptr Word8 -> CUInt -> IO () foreign import ccall unsafe "cryptonite_aes.h cryptonite_aes_gen_ctr_cont" c_aes_gen_ctr_cont :: CString -> Ptr AES -> Ptr Word8 -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_encrypt_ctr" c_aes_encrypt_ctr :: CString -> Ptr AES -> Ptr Word8 -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_gcm_init" c_aes_gcm_init :: Ptr AESGCM -> Ptr AES -> Ptr Word8 -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_gcm_aad" c_aes_gcm_aad :: Ptr AESGCM -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_gcm_encrypt" c_aes_gcm_encrypt :: CString -> Ptr AESGCM -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_gcm_decrypt" c_aes_gcm_decrypt :: CString -> Ptr AESGCM -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_gcm_finish" c_aes_gcm_finish :: CString -> Ptr AESGCM -> Ptr AES -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ocb_init" c_aes_ocb_init :: Ptr AESOCB -> Ptr AES -> Ptr Word8 -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ocb_aad" c_aes_ocb_aad :: Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ocb_encrypt" c_aes_ocb_encrypt :: CString -> Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ocb_decrypt" c_aes_ocb_decrypt :: CString -> Ptr AESOCB -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ocb_finish" c_aes_ocb_finish :: CString -> Ptr AESOCB -> Ptr AES -> IO () cryptonite-0.23/Crypto/Cipher/Blowfish/Box.hs0000644000000000000000000004505212567557234017405 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Blowfish.Box -- License : BSD-style -- Stability : experimental -- Portability : Good {-# LANGUAGE MagicHash #-} module Crypto.Cipher.Blowfish.Box ( createKeySchedule ) where import Crypto.Internal.WordArray (mutableArray32FromAddrBE, MutableArray32) -- | Create a key schedule mutable array of the pbox followed by -- all the sboxes. createKeySchedule :: IO MutableArray32 createKeySchedule = mutableArray32FromAddrBE 1042 "\ \\x24\x3f\x6a\x88\x85\xa3\x08\xd3\x13\x19\x8a\x2e\x03\x70\x73\x44\ \\xa4\x09\x38\x22\x29\x9f\x31\xd0\x08\x2e\xfa\x98\xec\x4e\x6c\x89\ \\x45\x28\x21\xe6\x38\xd0\x13\x77\xbe\x54\x66\xcf\x34\xe9\x0c\x6c\ \\xc0\xac\x29\xb7\xc9\x7c\x50\xdd\x3f\x84\xd5\xb5\xb5\x47\x09\x17\ \\x92\x16\xd5\xd9\x89\x79\xfb\x1b\ \\xd1\x31\x0b\xa6\x98\xdf\xb5\xac\x2f\xfd\x72\xdb\xd0\x1a\xdf\xb7\ \\xb8\xe1\xaf\xed\x6a\x26\x7e\x96\xba\x7c\x90\x45\xf1\x2c\x7f\x99\ \\x24\xa1\x99\x47\xb3\x91\x6c\xf7\x08\x01\xf2\xe2\x85\x8e\xfc\x16\ \\x63\x69\x20\xd8\x71\x57\x4e\x69\xa4\x58\xfe\xa3\xf4\x93\x3d\x7e\ \\x0d\x95\x74\x8f\x72\x8e\xb6\x58\x71\x8b\xcd\x58\x82\x15\x4a\xee\ \\x7b\x54\xa4\x1d\xc2\x5a\x59\xb5\x9c\x30\xd5\x39\x2a\xf2\x60\x13\ \\xc5\xd1\xb0\x23\x28\x60\x85\xf0\xca\x41\x79\x18\xb8\xdb\x38\xef\ \\x8e\x79\xdc\xb0\x60\x3a\x18\x0e\x6c\x9e\x0e\x8b\xb0\x1e\x8a\x3e\ \\xd7\x15\x77\xc1\xbd\x31\x4b\x27\x78\xaf\x2f\xda\x55\x60\x5c\x60\ \\xe6\x55\x25\xf3\xaa\x55\xab\x94\x57\x48\x98\x62\x63\xe8\x14\x40\ \\x55\xca\x39\x6a\x2a\xab\x10\xb6\xb4\xcc\x5c\x34\x11\x41\xe8\xce\ \\xa1\x54\x86\xaf\x7c\x72\xe9\x93\xb3\xee\x14\x11\x63\x6f\xbc\x2a\ \\x2b\xa9\xc5\x5d\x74\x18\x31\xf6\xce\x5c\x3e\x16\x9b\x87\x93\x1e\ \\xaf\xd6\xba\x33\x6c\x24\xcf\x5c\x7a\x32\x53\x81\x28\x95\x86\x77\ \\x3b\x8f\x48\x98\x6b\x4b\xb9\xaf\xc4\xbf\xe8\x1b\x66\x28\x21\x93\ \\x61\xd8\x09\xcc\xfb\x21\xa9\x91\x48\x7c\xac\x60\x5d\xec\x80\x32\ \\xef\x84\x5d\x5d\xe9\x85\x75\xb1\xdc\x26\x23\x02\xeb\x65\x1b\x88\ \\x23\x89\x3e\x81\xd3\x96\xac\xc5\x0f\x6d\x6f\xf3\x83\xf4\x42\x39\ \\x2e\x0b\x44\x82\xa4\x84\x20\x04\x69\xc8\xf0\x4a\x9e\x1f\x9b\x5e\ \\x21\xc6\x68\x42\xf6\xe9\x6c\x9a\x67\x0c\x9c\x61\xab\xd3\x88\xf0\ \\x6a\x51\xa0\xd2\xd8\x54\x2f\x68\x96\x0f\xa7\x28\xab\x51\x33\xa3\ \\x6e\xef\x0b\x6c\x13\x7a\x3b\xe4\xba\x3b\xf0\x50\x7e\xfb\x2a\x98\ \\xa1\xf1\x65\x1d\x39\xaf\x01\x76\x66\xca\x59\x3e\x82\x43\x0e\x88\ \\x8c\xee\x86\x19\x45\x6f\x9f\xb4\x7d\x84\xa5\xc3\x3b\x8b\x5e\xbe\ \\xe0\x6f\x75\xd8\x85\xc1\x20\x73\x40\x1a\x44\x9f\x56\xc1\x6a\xa6\ \\x4e\xd3\xaa\x62\x36\x3f\x77\x06\x1b\xfe\xdf\x72\x42\x9b\x02\x3d\ \\x37\xd0\xd7\x24\xd0\x0a\x12\x48\xdb\x0f\xea\xd3\x49\xf1\xc0\x9b\ \\x07\x53\x72\xc9\x80\x99\x1b\x7b\x25\xd4\x79\xd8\xf6\xe8\xde\xf7\ \\xe3\xfe\x50\x1a\xb6\x79\x4c\x3b\x97\x6c\xe0\xbd\x04\xc0\x06\xba\ \\xc1\xa9\x4f\xb6\x40\x9f\x60\xc4\x5e\x5c\x9e\xc2\x19\x6a\x24\x63\ \\x68\xfb\x6f\xaf\x3e\x6c\x53\xb5\x13\x39\xb2\xeb\x3b\x52\xec\x6f\ \\x6d\xfc\x51\x1f\x9b\x30\x95\x2c\xcc\x81\x45\x44\xaf\x5e\xbd\x09\ \\xbe\xe3\xd0\x04\xde\x33\x4a\xfd\x66\x0f\x28\x07\x19\x2e\x4b\xb3\ \\xc0\xcb\xa8\x57\x45\xc8\x74\x0f\xd2\x0b\x5f\x39\xb9\xd3\xfb\xdb\ \\x55\x79\xc0\xbd\x1a\x60\x32\x0a\xd6\xa1\x00\xc6\x40\x2c\x72\x79\ \\x67\x9f\x25\xfe\xfb\x1f\xa3\xcc\x8e\xa5\xe9\xf8\xdb\x32\x22\xf8\ \\x3c\x75\x16\xdf\xfd\x61\x6b\x15\x2f\x50\x1e\xc8\xad\x05\x52\xab\ \\x32\x3d\xb5\xfa\xfd\x23\x87\x60\x53\x31\x7b\x48\x3e\x00\xdf\x82\ \\x9e\x5c\x57\xbb\xca\x6f\x8c\xa0\x1a\x87\x56\x2e\xdf\x17\x69\xdb\ \\xd5\x42\xa8\xf6\x28\x7e\xff\xc3\xac\x67\x32\xc6\x8c\x4f\x55\x73\ \\x69\x5b\x27\xb0\xbb\xca\x58\xc8\xe1\xff\xa3\x5d\xb8\xf0\x11\xa0\ \\x10\xfa\x3d\x98\xfd\x21\x83\xb8\x4a\xfc\xb5\x6c\x2d\xd1\xd3\x5b\ \\x9a\x53\xe4\x79\xb6\xf8\x45\x65\xd2\x8e\x49\xbc\x4b\xfb\x97\x90\ \\xe1\xdd\xf2\xda\xa4\xcb\x7e\x33\x62\xfb\x13\x41\xce\xe4\xc6\xe8\ \\xef\x20\xca\xda\x36\x77\x4c\x01\xd0\x7e\x9e\xfe\x2b\xf1\x1f\xb4\ \\x95\xdb\xda\x4d\xae\x90\x91\x98\xea\xad\x8e\x71\x6b\x93\xd5\xa0\ \\xd0\x8e\xd1\xd0\xaf\xc7\x25\xe0\x8e\x3c\x5b\x2f\x8e\x75\x94\xb7\ \\x8f\xf6\xe2\xfb\xf2\x12\x2b\x64\x88\x88\xb8\x12\x90\x0d\xf0\x1c\ \\x4f\xad\x5e\xa0\x68\x8f\xc3\x1c\xd1\xcf\xf1\x91\xb3\xa8\xc1\xad\ \\x2f\x2f\x22\x18\xbe\x0e\x17\x77\xea\x75\x2d\xfe\x8b\x02\x1f\xa1\ \\xe5\xa0\xcc\x0f\xb5\x6f\x74\xe8\x18\xac\xf3\xd6\xce\x89\xe2\x99\ \\xb4\xa8\x4f\xe0\xfd\x13\xe0\xb7\x7c\xc4\x3b\x81\xd2\xad\xa8\xd9\ \\x16\x5f\xa2\x66\x80\x95\x77\x05\x93\xcc\x73\x14\x21\x1a\x14\x77\ \\xe6\xad\x20\x65\x77\xb5\xfa\x86\xc7\x54\x42\xf5\xfb\x9d\x35\xcf\ \\xeb\xcd\xaf\x0c\x7b\x3e\x89\xa0\xd6\x41\x1b\xd3\xae\x1e\x7e\x49\ \\x00\x25\x0e\x2d\x20\x71\xb3\x5e\x22\x68\x00\xbb\x57\xb8\xe0\xaf\ \\x24\x64\x36\x9b\xf0\x09\xb9\x1e\x55\x63\x91\x1d\x59\xdf\xa6\xaa\ \\x78\xc1\x43\x89\xd9\x5a\x53\x7f\x20\x7d\x5b\xa2\x02\xe5\xb9\xc5\ \\x83\x26\x03\x76\x62\x95\xcf\xa9\x11\xc8\x19\x68\x4e\x73\x4a\x41\ \\xb3\x47\x2d\xca\x7b\x14\xa9\x4a\x1b\x51\x00\x52\x9a\x53\x29\x15\ \\xd6\x0f\x57\x3f\xbc\x9b\xc6\xe4\x2b\x60\xa4\x76\x81\xe6\x74\x00\ \\x08\xba\x6f\xb5\x57\x1b\xe9\x1f\xf2\x96\xec\x6b\x2a\x0d\xd9\x15\ \\xb6\x63\x65\x21\xe7\xb9\xf9\xb6\xff\x34\x05\x2e\xc5\x85\x56\x64\ \\x53\xb0\x2d\x5d\xa9\x9f\x8f\xa1\x08\xba\x47\x99\x6e\x85\x07\x6a\ \\x4b\x7a\x70\xe9\xb5\xb3\x29\x44\xdb\x75\x09\x2e\xc4\x19\x26\x23\ \\xad\x6e\xa6\xb0\x49\xa7\xdf\x7d\x9c\xee\x60\xb8\x8f\xed\xb2\x66\ \\xec\xaa\x8c\x71\x69\x9a\x17\xff\x56\x64\x52\x6c\xc2\xb1\x9e\xe1\ \\x19\x36\x02\xa5\x75\x09\x4c\x29\xa0\x59\x13\x40\xe4\x18\x3a\x3e\ \\x3f\x54\x98\x9a\x5b\x42\x9d\x65\x6b\x8f\xe4\xd6\x99\xf7\x3f\xd6\ \\xa1\xd2\x9c\x07\xef\xe8\x30\xf5\x4d\x2d\x38\xe6\xf0\x25\x5d\xc1\ \\x4c\xdd\x20\x86\x84\x70\xeb\x26\x63\x82\xe9\xc6\x02\x1e\xcc\x5e\ \\x09\x68\x6b\x3f\x3e\xba\xef\xc9\x3c\x97\x18\x14\x6b\x6a\x70\xa1\ \\x68\x7f\x35\x84\x52\xa0\xe2\x86\xb7\x9c\x53\x05\xaa\x50\x07\x37\ \\x3e\x07\x84\x1c\x7f\xde\xae\x5c\x8e\x7d\x44\xec\x57\x16\xf2\xb8\ \\xb0\x3a\xda\x37\xf0\x50\x0c\x0d\xf0\x1c\x1f\x04\x02\x00\xb3\xff\ \\xae\x0c\xf5\x1a\x3c\xb5\x74\xb2\x25\x83\x7a\x58\xdc\x09\x21\xbd\ \\xd1\x91\x13\xf9\x7c\xa9\x2f\xf6\x94\x32\x47\x73\x22\xf5\x47\x01\ \\x3a\xe5\xe5\x81\x37\xc2\xda\xdc\xc8\xb5\x76\x34\x9a\xf3\xdd\xa7\ \\xa9\x44\x61\x46\x0f\xd0\x03\x0e\xec\xc8\xc7\x3e\xa4\x75\x1e\x41\ \\xe2\x38\xcd\x99\x3b\xea\x0e\x2f\x32\x80\xbb\xa1\x18\x3e\xb3\x31\ \\x4e\x54\x8b\x38\x4f\x6d\xb9\x08\x6f\x42\x0d\x03\xf6\x0a\x04\xbf\ \\x2c\xb8\x12\x90\x24\x97\x7c\x79\x56\x79\xb0\x72\xbc\xaf\x89\xaf\ \\xde\x9a\x77\x1f\xd9\x93\x08\x10\xb3\x8b\xae\x12\xdc\xcf\x3f\x2e\ \\x55\x12\x72\x1f\x2e\x6b\x71\x24\x50\x1a\xdd\xe6\x9f\x84\xcd\x87\ \\x7a\x58\x47\x18\x74\x08\xda\x17\xbc\x9f\x9a\xbc\xe9\x4b\x7d\x8c\ \\xec\x7a\xec\x3a\xdb\x85\x1d\xfa\x63\x09\x43\x66\xc4\x64\xc3\xd2\ \\xef\x1c\x18\x47\x32\x15\xd9\x08\xdd\x43\x3b\x37\x24\xc2\xba\x16\ \\x12\xa1\x4d\x43\x2a\x65\xc4\x51\x50\x94\x00\x02\x13\x3a\xe4\xdd\ \\x71\xdf\xf8\x9e\x10\x31\x4e\x55\x81\xac\x77\xd6\x5f\x11\x19\x9b\ \\x04\x35\x56\xf1\xd7\xa3\xc7\x6b\x3c\x11\x18\x3b\x59\x24\xa5\x09\ \\xf2\x8f\xe6\xed\x97\xf1\xfb\xfa\x9e\xba\xbf\x2c\x1e\x15\x3c\x6e\ \\x86\xe3\x45\x70\xea\xe9\x6f\xb1\x86\x0e\x5e\x0a\x5a\x3e\x2a\xb3\ \\x77\x1f\xe7\x1c\x4e\x3d\x06\xfa\x29\x65\xdc\xb9\x99\xe7\x1d\x0f\ \\x80\x3e\x89\xd6\x52\x66\xc8\x25\x2e\x4c\xc9\x78\x9c\x10\xb3\x6a\ \\xc6\x15\x0e\xba\x94\xe2\xea\x78\xa5\xfc\x3c\x53\x1e\x0a\x2d\xf4\ \\xf2\xf7\x4e\xa7\x36\x1d\x2b\x3d\x19\x39\x26\x0f\x19\xc2\x79\x60\ \\x52\x23\xa7\x08\xf7\x13\x12\xb6\xeb\xad\xfe\x6e\xea\xc3\x1f\x66\ \\xe3\xbc\x45\x95\xa6\x7b\xc8\x83\xb1\x7f\x37\xd1\x01\x8c\xff\x28\ \\xc3\x32\xdd\xef\xbe\x6c\x5a\xa5\x65\x58\x21\x85\x68\xab\x98\x02\ \\xee\xce\xa5\x0f\xdb\x2f\x95\x3b\x2a\xef\x7d\xad\x5b\x6e\x2f\x84\ \\x15\x21\xb6\x28\x29\x07\x61\x70\xec\xdd\x47\x75\x61\x9f\x15\x10\ \\x13\xcc\xa8\x30\xeb\x61\xbd\x96\x03\x34\xfe\x1e\xaa\x03\x63\xcf\ \\xb5\x73\x5c\x90\x4c\x70\xa2\x39\xd5\x9e\x9e\x0b\xcb\xaa\xde\x14\ \\xee\xcc\x86\xbc\x60\x62\x2c\xa7\x9c\xab\x5c\xab\xb2\xf3\x84\x6e\ \\x64\x8b\x1e\xaf\x19\xbd\xf0\xca\xa0\x23\x69\xb9\x65\x5a\xbb\x50\ \\x40\x68\x5a\x32\x3c\x2a\xb4\xb3\x31\x9e\xe9\xd5\xc0\x21\xb8\xf7\ \\x9b\x54\x0b\x19\x87\x5f\xa0\x99\x95\xf7\x99\x7e\x62\x3d\x7d\xa8\ \\xf8\x37\x88\x9a\x97\xe3\x2d\x77\x11\xed\x93\x5f\x16\x68\x12\x81\ \\x0e\x35\x88\x29\xc7\xe6\x1f\xd6\x96\xde\xdf\xa1\x78\x58\xba\x99\ \\x57\xf5\x84\xa5\x1b\x22\x72\x63\x9b\x83\xc3\xff\x1a\xc2\x46\x96\ \\xcd\xb3\x0a\xeb\x53\x2e\x30\x54\x8f\xd9\x48\xe4\x6d\xbc\x31\x28\ \\x58\xeb\xf2\xef\x34\xc6\xff\xea\xfe\x28\xed\x61\xee\x7c\x3c\x73\ \\x5d\x4a\x14\xd9\xe8\x64\xb7\xe3\x42\x10\x5d\x14\x20\x3e\x13\xe0\ \\x45\xee\xe2\xb6\xa3\xaa\xab\xea\xdb\x6c\x4f\x15\xfa\xcb\x4f\xd0\ \\xc7\x42\xf4\x42\xef\x6a\xbb\xb5\x65\x4f\x3b\x1d\x41\xcd\x21\x05\ \\xd8\x1e\x79\x9e\x86\x85\x4d\xc7\xe4\x4b\x47\x6a\x3d\x81\x62\x50\ \\xcf\x62\xa1\xf2\x5b\x8d\x26\x46\xfc\x88\x83\xa0\xc1\xc7\xb6\xa3\ \\x7f\x15\x24\xc3\x69\xcb\x74\x92\x47\x84\x8a\x0b\x56\x92\xb2\x85\ \\x09\x5b\xbf\x00\xad\x19\x48\x9d\x14\x62\xb1\x74\x23\x82\x0e\x00\ \\x58\x42\x8d\x2a\x0c\x55\xf5\xea\x1d\xad\xf4\x3e\x23\x3f\x70\x61\ \\x33\x72\xf0\x92\x8d\x93\x7e\x41\xd6\x5f\xec\xf1\x6c\x22\x3b\xdb\ \\x7c\xde\x37\x59\xcb\xee\x74\x60\x40\x85\xf2\xa7\xce\x77\x32\x6e\ \\xa6\x07\x80\x84\x19\xf8\x50\x9e\xe8\xef\xd8\x55\x61\xd9\x97\x35\ \\xa9\x69\xa7\xaa\xc5\x0c\x06\xc2\x5a\x04\xab\xfc\x80\x0b\xca\xdc\ \\x9e\x44\x7a\x2e\xc3\x45\x34\x84\xfd\xd5\x67\x05\x0e\x1e\x9e\xc9\ \\xdb\x73\xdb\xd3\x10\x55\x88\xcd\x67\x5f\xda\x79\xe3\x67\x43\x40\ \\xc5\xc4\x34\x65\x71\x3e\x38\xd8\x3d\x28\xf8\x9e\xf1\x6d\xff\x20\ \\x15\x3e\x21\xe7\x8f\xb0\x3d\x4a\xe6\xe3\x9f\x2b\xdb\x83\xad\xf7\ \\xe9\x3d\x5a\x68\x94\x81\x40\xf7\xf6\x4c\x26\x1c\x94\x69\x29\x34\ \\x41\x15\x20\xf7\x76\x02\xd4\xf7\xbc\xf4\x6b\x2e\xd4\xa2\x00\x68\ \\xd4\x08\x24\x71\x33\x20\xf4\x6a\x43\xb7\xd4\xb7\x50\x00\x61\xaf\ \\x1e\x39\xf6\x2e\x97\x24\x45\x46\x14\x21\x4f\x74\xbf\x8b\x88\x40\ \\x4d\x95\xfc\x1d\x96\xb5\x91\xaf\x70\xf4\xdd\xd3\x66\xa0\x2f\x45\ \\xbf\xbc\x09\xec\x03\xbd\x97\x85\x7f\xac\x6d\xd0\x31\xcb\x85\x04\ \\x96\xeb\x27\xb3\x55\xfd\x39\x41\xda\x25\x47\xe6\xab\xca\x0a\x9a\ \\x28\x50\x78\x25\x53\x04\x29\xf4\x0a\x2c\x86\xda\xe9\xb6\x6d\xfb\ \\x68\xdc\x14\x62\xd7\x48\x69\x00\x68\x0e\xc0\xa4\x27\xa1\x8d\xee\ \\x4f\x3f\xfe\xa2\xe8\x87\xad\x8c\xb5\x8c\xe0\x06\x7a\xf4\xd6\xb6\ \\xaa\xce\x1e\x7c\xd3\x37\x5f\xec\xce\x78\xa3\x99\x40\x6b\x2a\x42\ \\x20\xfe\x9e\x35\xd9\xf3\x85\xb9\xee\x39\xd7\xab\x3b\x12\x4e\x8b\ \\x1d\xc9\xfa\xf7\x4b\x6d\x18\x56\x26\xa3\x66\x31\xea\xe3\x97\xb2\ \\x3a\x6e\xfa\x74\xdd\x5b\x43\x32\x68\x41\xe7\xf7\xca\x78\x20\xfb\ \\xfb\x0a\xf5\x4e\xd8\xfe\xb3\x97\x45\x40\x56\xac\xba\x48\x95\x27\ \\x55\x53\x3a\x3a\x20\x83\x8d\x87\xfe\x6b\xa9\xb7\xd0\x96\x95\x4b\ \\x55\xa8\x67\xbc\xa1\x15\x9a\x58\xcc\xa9\x29\x63\x99\xe1\xdb\x33\ \\xa6\x2a\x4a\x56\x3f\x31\x25\xf9\x5e\xf4\x7e\x1c\x90\x29\x31\x7c\ \\xfd\xf8\xe8\x02\x04\x27\x2f\x70\x80\xbb\x15\x5c\x05\x28\x2c\xe3\ \\x95\xc1\x15\x48\xe4\xc6\x6d\x22\x48\xc1\x13\x3f\xc7\x0f\x86\xdc\ \\x07\xf9\xc9\xee\x41\x04\x1f\x0f\x40\x47\x79\xa4\x5d\x88\x6e\x17\ \\x32\x5f\x51\xeb\xd5\x9b\xc0\xd1\xf2\xbc\xc1\x8f\x41\x11\x35\x64\ \\x25\x7b\x78\x34\x60\x2a\x9c\x60\xdf\xf8\xe8\xa3\x1f\x63\x6c\x1b\ \\x0e\x12\xb4\xc2\x02\xe1\x32\x9e\xaf\x66\x4f\xd1\xca\xd1\x81\x15\ \\x6b\x23\x95\xe0\x33\x3e\x92\xe1\x3b\x24\x0b\x62\xee\xbe\xb9\x22\ \\x85\xb2\xa2\x0e\xe6\xba\x0d\x99\xde\x72\x0c\x8c\x2d\xa2\xf7\x28\ \\xd0\x12\x78\x45\x95\xb7\x94\xfd\x64\x7d\x08\x62\xe7\xcc\xf5\xf0\ \\x54\x49\xa3\x6f\x87\x7d\x48\xfa\xc3\x9d\xfd\x27\xf3\x3e\x8d\x1e\ \\x0a\x47\x63\x41\x99\x2e\xff\x74\x3a\x6f\x6e\xab\xf4\xf8\xfd\x37\ \\xa8\x12\xdc\x60\xa1\xeb\xdd\xf8\x99\x1b\xe1\x4c\xdb\x6e\x6b\x0d\ \\xc6\x7b\x55\x10\x6d\x67\x2c\x37\x27\x65\xd4\x3b\xdc\xd0\xe8\x04\ \\xf1\x29\x0d\xc7\xcc\x00\xff\xa3\xb5\x39\x0f\x92\x69\x0f\xed\x0b\ \\x66\x7b\x9f\xfb\xce\xdb\x7d\x9c\xa0\x91\xcf\x0b\xd9\x15\x5e\xa3\ \\xbb\x13\x2f\x88\x51\x5b\xad\x24\x7b\x94\x79\xbf\x76\x3b\xd6\xeb\ \\x37\x39\x2e\xb3\xcc\x11\x59\x79\x80\x26\xe2\x97\xf4\x2e\x31\x2d\ \\x68\x42\xad\xa7\xc6\x6a\x2b\x3b\x12\x75\x4c\xcc\x78\x2e\xf1\x1c\ \\x6a\x12\x42\x37\xb7\x92\x51\xe7\x06\xa1\xbb\xe6\x4b\xfb\x63\x50\ \\x1a\x6b\x10\x18\x11\xca\xed\xfa\x3d\x25\xbd\xd8\xe2\xe1\xc3\xc9\ \\x44\x42\x16\x59\x0a\x12\x13\x86\xd9\x0c\xec\x6e\xd5\xab\xea\x2a\ \\x64\xaf\x67\x4e\xda\x86\xa8\x5f\xbe\xbf\xe9\x88\x64\xe4\xc3\xfe\ \\x9d\xbc\x80\x57\xf0\xf7\xc0\x86\x60\x78\x7b\xf8\x60\x03\x60\x4d\ \\xd1\xfd\x83\x46\xf6\x38\x1f\xb0\x77\x45\xae\x04\xd7\x36\xfc\xcc\ \\x83\x42\x6b\x33\xf0\x1e\xab\x71\xb0\x80\x41\x87\x3c\x00\x5e\x5f\ \\x77\xa0\x57\xbe\xbd\xe8\xae\x24\x55\x46\x42\x99\xbf\x58\x2e\x61\ \\x4e\x58\xf4\x8f\xf2\xdd\xfd\xa2\xf4\x74\xef\x38\x87\x89\xbd\xc2\ \\x53\x66\xf9\xc3\xc8\xb3\x8e\x74\xb4\x75\xf2\x55\x46\xfc\xd9\xb9\ \\x7a\xeb\x26\x61\x8b\x1d\xdf\x84\x84\x6a\x0e\x79\x91\x5f\x95\xe2\ \\x46\x6e\x59\x8e\x20\xb4\x57\x70\x8c\xd5\x55\x91\xc9\x02\xde\x4c\ \\xb9\x0b\xac\xe1\xbb\x82\x05\xd0\x11\xa8\x62\x48\x75\x74\xa9\x9e\ \\xb7\x7f\x19\xb6\xe0\xa9\xdc\x09\x66\x2d\x09\xa1\xc4\x32\x46\x33\ \\xe8\x5a\x1f\x02\x09\xf0\xbe\x8c\x4a\x99\xa0\x25\x1d\x6e\xfe\x10\ \\x1a\xb9\x3d\x1d\x0b\xa5\xa4\xdf\xa1\x86\xf2\x0f\x28\x68\xf1\x69\ \\xdc\xb7\xda\x83\x57\x39\x06\xfe\xa1\xe2\xce\x9b\x4f\xcd\x7f\x52\ \\x50\x11\x5e\x01\xa7\x06\x83\xfa\xa0\x02\xb5\xc4\x0d\xe6\xd0\x27\ \\x9a\xf8\x8c\x27\x77\x3f\x86\x41\xc3\x60\x4c\x06\x61\xa8\x06\xb5\ \\xf0\x17\x7a\x28\xc0\xf5\x86\xe0\x00\x60\x58\xaa\x30\xdc\x7d\x62\ \\x11\xe6\x9e\xd7\x23\x38\xea\x63\x53\xc2\xdd\x94\xc2\xc2\x16\x34\ \\xbb\xcb\xee\x56\x90\xbc\xb6\xde\xeb\xfc\x7d\xa1\xce\x59\x1d\x76\ \\x6f\x05\xe4\x09\x4b\x7c\x01\x88\x39\x72\x0a\x3d\x7c\x92\x7c\x24\ \\x86\xe3\x72\x5f\x72\x4d\x9d\xb9\x1a\xc1\x5b\xb4\xd3\x9e\xb8\xfc\ \\xed\x54\x55\x78\x08\xfc\xa5\xb5\xd8\x3d\x7c\xd3\x4d\xad\x0f\xc4\ \\x1e\x50\xef\x5e\xb1\x61\xe6\xf8\xa2\x85\x14\xd9\x6c\x51\x13\x3c\ \\x6f\xd5\xc7\xe7\x56\xe1\x4e\xc4\x36\x2a\xbf\xce\xdd\xc6\xc8\x37\ \\xd7\x9a\x32\x34\x92\x63\x82\x12\x67\x0e\xfa\x8e\x40\x60\x00\xe0\ \\x3a\x39\xce\x37\xd3\xfa\xf5\xcf\xab\xc2\x77\x37\x5a\xc5\x2d\x1b\ \\x5c\xb0\x67\x9e\x4f\xa3\x37\x42\xd3\x82\x27\x40\x99\xbc\x9b\xbe\ \\xd5\x11\x8e\x9d\xbf\x0f\x73\x15\xd6\x2d\x1c\x7e\xc7\x00\xc4\x7b\ \\xb7\x8c\x1b\x6b\x21\xa1\x90\x45\xb2\x6e\xb1\xbe\x6a\x36\x6e\xb4\ \\x57\x48\xab\x2f\xbc\x94\x6e\x79\xc6\xa3\x76\xd2\x65\x49\xc2\xc8\ \\x53\x0f\xf8\xee\x46\x8d\xde\x7d\xd5\x73\x0a\x1d\x4c\xd0\x4d\xc6\ \\x29\x39\xbb\xdb\xa9\xba\x46\x50\xac\x95\x26\xe8\xbe\x5e\xe3\x04\ \\xa1\xfa\xd5\xf0\x6a\x2d\x51\x9a\x63\xef\x8c\xe2\x9a\x86\xee\x22\ \\xc0\x89\xc2\xb8\x43\x24\x2e\xf6\xa5\x1e\x03\xaa\x9c\xf2\xd0\xa4\ \\x83\xc0\x61\xba\x9b\xe9\x6a\x4d\x8f\xe5\x15\x50\xba\x64\x5b\xd6\ \\x28\x26\xa2\xf9\xa7\x3a\x3a\xe1\x4b\xa9\x95\x86\xef\x55\x62\xe9\ \\xc7\x2f\xef\xd3\xf7\x52\xf7\xda\x3f\x04\x6f\x69\x77\xfa\x0a\x59\ \\x80\xe4\xa9\x15\x87\xb0\x86\x01\x9b\x09\xe6\xad\x3b\x3e\xe5\x93\ \\xe9\x90\xfd\x5a\x9e\x34\xd7\x97\x2c\xf0\xb7\xd9\x02\x2b\x8b\x51\ \\x96\xd5\xac\x3a\x01\x7d\xa6\x7d\xd1\xcf\x3e\xd6\x7c\x7d\x2d\x28\ \\x1f\x9f\x25\xcf\xad\xf2\xb8\x9b\x5a\xd6\xb4\x72\x5a\x88\xf5\x4c\ \\xe0\x29\xac\x71\xe0\x19\xa5\xe6\x47\xb0\xac\xfd\xed\x93\xfa\x9b\ \\xe8\xd3\xc4\x8d\x28\x3b\x57\xcc\xf8\xd5\x66\x29\x79\x13\x2e\x28\ \\x78\x5f\x01\x91\xed\x75\x60\x55\xf7\x96\x0e\x44\xe3\xd3\x5e\x8c\ \\x15\x05\x6d\xd4\x88\xf4\x6d\xba\x03\xa1\x61\x25\x05\x64\xf0\xbd\ \\xc3\xeb\x9e\x15\x3c\x90\x57\xa2\x97\x27\x1a\xec\xa9\x3a\x07\x2a\ \\x1b\x3f\x6d\x9b\x1e\x63\x21\xf5\xf5\x9c\x66\xfb\x26\xdc\xf3\x19\ \\x75\x33\xd9\x28\xb1\x55\xfd\xf5\x03\x56\x34\x82\x8a\xba\x3c\xbb\ \\x28\x51\x77\x11\xc2\x0a\xd9\xf8\xab\xcc\x51\x67\xcc\xad\x92\x5f\ \\x4d\xe8\x17\x51\x38\x30\xdc\x8e\x37\x9d\x58\x62\x93\x20\xf9\x91\ \\xea\x7a\x90\xc2\xfb\x3e\x7b\xce\x51\x21\xce\x64\x77\x4f\xbe\x32\ \\xa8\xb6\xe3\x7e\xc3\x29\x3d\x46\x48\xde\x53\x69\x64\x13\xe6\x80\ \\xa2\xae\x08\x10\xdd\x6d\xb2\x24\x69\x85\x2d\xfd\x09\x07\x21\x66\ \\xb3\x9a\x46\x0a\x64\x45\xc0\xdd\x58\x6c\xde\xcf\x1c\x20\xc8\xae\ \\x5b\xbe\xf7\xdd\x1b\x58\x8d\x40\xcc\xd2\x01\x7f\x6b\xb4\xe3\xbb\ \\xdd\xa2\x6a\x7e\x3a\x59\xff\x45\x3e\x35\x0a\x44\xbc\xb4\xcd\xd5\ \\x72\xea\xce\xa8\xfa\x64\x84\xbb\x8d\x66\x12\xae\xbf\x3c\x6f\x47\ \\xd2\x9b\xe4\x63\x54\x2f\x5d\x9e\xae\xc2\x77\x1b\xf6\x4e\x63\x70\ \\x74\x0e\x0d\x8d\xe7\x5b\x13\x57\xf8\x72\x16\x71\xaf\x53\x7d\x5d\ \\x40\x40\xcb\x08\x4e\xb4\xe2\xcc\x34\xd2\x46\x6a\x01\x15\xaf\x84\ \\xe1\xb0\x04\x28\x95\x98\x3a\x1d\x06\xb8\x9f\xb4\xce\x6e\xa0\x48\ \\x6f\x3f\x3b\x82\x35\x20\xab\x82\x01\x1a\x1d\x4b\x27\x72\x27\xf8\ \\x61\x15\x60\xb1\xe7\x93\x3f\xdc\xbb\x3a\x79\x2b\x34\x45\x25\xbd\ \\xa0\x88\x39\xe1\x51\xce\x79\x4b\x2f\x32\xc9\xb7\xa0\x1f\xba\xc9\ \\xe0\x1c\xc8\x7e\xbc\xc7\xd1\xf6\xcf\x01\x11\xc3\xa1\xe8\xaa\xc7\ \\x1a\x90\x87\x49\xd4\x4f\xbd\x9a\xd0\xda\xde\xcb\xd5\x0a\xda\x38\ \\x03\x39\xc3\x2a\xc6\x91\x36\x67\x8d\xf9\x31\x7c\xe0\xb1\x2b\x4f\ \\xf7\x9e\x59\xb7\x43\xf5\xbb\x3a\xf2\xd5\x19\xff\x27\xd9\x45\x9c\ \\xbf\x97\x22\x2c\x15\xe6\xfc\x2a\x0f\x91\xfc\x71\x9b\x94\x15\x25\ \\xfa\xe5\x93\x61\xce\xb6\x9c\xeb\xc2\xa8\x64\x59\x12\xba\xa8\xd1\ \\xb6\xc1\x07\x5e\xe3\x05\x6a\x0c\x10\xd2\x50\x65\xcb\x03\xa4\x42\ \\xe0\xec\x6e\x0e\x16\x98\xdb\x3b\x4c\x98\xa0\xbe\x32\x78\xe9\x64\ \\x9f\x1f\x95\x32\xe0\xd3\x92\xdf\xd3\xa0\x34\x2b\x89\x71\xf2\x1e\ \\x1b\x0a\x74\x41\x4b\xa3\x34\x8c\xc5\xbe\x71\x20\xc3\x76\x32\xd8\ \\xdf\x35\x9f\x8d\x9b\x99\x2f\x2e\xe6\x0b\x6f\x47\x0f\xe3\xf1\x1d\ \\xe5\x4c\xda\x54\x1e\xda\xd8\x91\xce\x62\x79\xcf\xcd\x3e\x7e\x6f\ \\x16\x18\xb1\x66\xfd\x2c\x1d\x05\x84\x8f\xd2\xc5\xf6\xfb\x22\x99\ \\xf5\x23\xf3\x57\xa6\x32\x76\x23\x93\xa8\x35\x31\x56\xcc\xcd\x02\ \\xac\xf0\x81\x62\x5a\x75\xeb\xb5\x6e\x16\x36\x97\x88\xd2\x73\xcc\ \\xde\x96\x62\x92\x81\xb9\x49\xd0\x4c\x50\x90\x1b\x71\xc6\x56\x14\ \\xe6\xc6\xc7\xbd\x32\x7a\x14\x0a\x45\xe1\xd0\x06\xc3\xf2\x7b\x9a\ \\xc9\xaa\x53\xfd\x62\xa8\x0f\x00\xbb\x25\xbf\xe2\x35\xbd\xd2\xf6\ \\x71\x12\x69\x05\xb2\x04\x02\x22\xb6\xcb\xcf\x7c\xcd\x76\x9c\x2b\ \\x53\x11\x3e\xc0\x16\x40\xe3\xd3\x38\xab\xbd\x60\x25\x47\xad\xf0\ \\xba\x38\x20\x9c\xf7\x46\xce\x76\x77\xaf\xa1\xc5\x20\x75\x60\x60\ \\x85\xcb\xfe\x4e\x8a\xe8\x8d\xd8\x7a\xaa\xf9\xb0\x4c\xf9\xaa\x7e\ \\x19\x48\xc2\x5c\x02\xfb\x8a\x8c\x01\xc3\x6a\xe4\xd6\xeb\xe1\xf9\ \\x90\xd4\xf8\x69\xa6\x5c\xde\xa0\x3f\x09\x25\x2d\xc2\x08\xe6\x9f\ \\xb7\x4e\x61\x32\xce\x77\xe2\x5b\x57\x8f\xdf\xe3\x3a\xc3\x72\xe6\ \"# cryptonite-0.23/Crypto/Cipher/Blowfish/Primitive.hs0000644000000000000000000002016112746570656020621 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Blowfish.Primitive -- License : BSD-style -- Stability : experimental -- Portability : Good -- Rewritten by Vincent Hanquez (c) 2015 -- -- Original code: -- Crypto.Cipher.Blowfish.Primitive, copyright (c) 2012 Stijn van Drongelen -- based on: BlowfishAux.hs (C) 2002 HardCore SoftWare, Doug Hoyte -- (as found in Crypto-4.2.4) module Crypto.Cipher.Blowfish.Primitive ( Context , initBlowfish , encrypt , decrypt , eksBlowfish ) where import Control.Monad (when) import Data.Bits import Data.Memory.Endian import Data.Word import Crypto.Error import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Words import Crypto.Internal.WordArray import Crypto.Cipher.Blowfish.Box -- | variable keyed blowfish state data Context = BF (Int -> Word32) -- p (Int -> Word32) -- sbox0 (Int -> Word32) -- sbox1 (Int -> Word32) -- sbox2 (Int -> Word32) -- sbox2 instance NFData Context where rnf (BF p a b c d) = p `seq` a `seq` b `seq` c `seq` d `seq` () -- | Encrypt blocks -- -- Input need to be a multiple of 8 bytes encrypt :: ByteArray ba => Context -> ba -> ba encrypt = cipher -- | Decrypt blocks -- -- Input need to be a multiple of 8 bytes decrypt :: ByteArray ba => Context -> ba -> ba decrypt = cipher . decryptContext decryptContext :: Context -> Context decryptContext (BF p s0 s1 s2 s3) = BF (\i -> p (17-i)) s0 s1 s2 s3 cipher :: ByteArray ba => Context -> ba -> ba cipher ctx b | B.length b == 0 = B.empty | B.length b `mod` 8 /= 0 = error "invalid data length" | otherwise = B.mapAsWord64 (coreCrypto ctx) b -- | Initialize a new Blowfish context from a key. -- -- key needs to be between 0 and 448 bits. initBlowfish :: ByteArrayAccess key => key -> CryptoFailable Context initBlowfish key | len > (448 `div` 8) = CryptoFailed CryptoError_KeySizeInvalid | otherwise = CryptoPassed $ makeKeySchedule key (Nothing :: Maybe (Bytes, Int)) where len = B.length key -- | The BCrypt "expensive key schedule" version of blowfish. -- -- Salt must be 128 bits -- Cost must be between 4 and 31 inclusive -- See eksBlowfish :: (ByteArrayAccess salt, ByteArrayAccess password) => Int -> salt -> password -> Context eksBlowfish cost salt key | B.length salt /= 16 = error "bcrypt salt must be 16 bytes" | otherwise = makeKeySchedule key (Just (salt, cost)) coreCrypto :: Context -> Word64 -> Word64 coreCrypto (BF p s0 s1 s2 s3) input = doRound input 0 where -- transform the input over 16 rounds doRound :: Word64 -> Int -> Word64 doRound i roundIndex | roundIndex == 16 = let final = (fromIntegral (p 16) `shiftL` 32) .|. fromIntegral (p 17) in rotateL (i `xor` final) 32 | otherwise = let newr = fromIntegral (i `shiftR` 32) `xor` (p roundIndex) newi = ((i `shiftL` 32) `xor` (f newr)) .|. (fromIntegral newr) in doRound newi (roundIndex+1) f :: Word32 -> Word64 f t = let a = s0 (fromIntegral $ (t `shiftR` 24) .&. 0xff) b = s1 (fromIntegral $ (t `shiftR` 16) .&. 0xff) c = s2 (fromIntegral $ (t `shiftR` 8) .&. 0xff) d = s3 (fromIntegral $ t .&. 0xff) in fromIntegral (((a + b) `xor` c) + d) `shiftL` 32 -- | Create a key schedule for either plain Blowfish or the BCrypt "EKS" version -- For the expensive version, the salt and cost factor are supplied. Salt must be -- a 128-bit byte array. -- -- The standard case is just a single key expansion with the salt set to zero. makeKeySchedule :: (ByteArrayAccess key, ByteArrayAccess salt) => key-> Maybe (salt, Int) -> Context makeKeySchedule keyBytes saltCost = let v = unsafeDoIO $ do mv <- createKeySchedule case saltCost of -- Standard blowfish Nothing -> expandKey mv 0 0 keyBytes -- The expensive case Just (s, cost) -> do let (salt1, salt2) = splitSalt s expandKey mv salt1 salt2 keyBytes forM_ [1..2^cost :: Int] $ \_ -> do expandKey mv 0 0 keyBytes expandKey mv 0 0 s mutableArray32Freeze mv in BF (\i -> arrayRead32 v i) (\i -> arrayRead32 v (s0+i)) (\i -> arrayRead32 v (s1+i)) (\i -> arrayRead32 v (s2+i)) (\i -> arrayRead32 v (s3+i)) where splitSalt s = (fromBE (B.toW64BE s 0), fromBE (B.toW64BE s 8)) -- Indices of the S-Box arrays, each containing 256 32-bit words -- The first 18 words contain the P-Array of subkeys s0 = 18 s1 = 274 s2 = 530 s3 = 786 expandKey :: ByteArrayAccess ba => MutableArray32 -- ^ The key schedule -> Word64 -- ^ First word of the salt -> Word64 -- ^ Second word of the salt -> ba -- ^ The key -> IO () expandKey mv salt1 salt2 key = do when (len > 0) $ forM_ [0..17] $ \i -> do let a = B.index key ((i * 4 + 0) `mod` len) b = B.index key ((i * 4 + 1) `mod` len) c = B.index key ((i * 4 + 2) `mod` len) d = B.index key ((i * 4 + 3) `mod` len) k = (fromIntegral a `shiftL` 24) .|. (fromIntegral b `shiftL` 16) .|. (fromIntegral c `shiftL` 8) .|. (fromIntegral d) mutableArrayWriteXor32 mv i k prepare mv return () where len = B.length key -- | Go through the entire key schedule overwriting the P-Array and S-Boxes prepare mctx = loop 0 salt1 salt1 salt2 where loop i input slt1 slt2 | i == 1042 = return () | otherwise = do ninput <- coreCryptoMutable input let (nl, nr) = w64to32 ninput mutableArrayWrite32 mctx i nl mutableArrayWrite32 mctx (i+1) nr loop (i+2) (ninput `xor` slt2) slt2 slt1 -- | Blowfish encrypt a Word using the current state of the key schedule coreCryptoMutable :: Word64 -> IO Word64 coreCryptoMutable input = doRound input 0 where doRound i roundIndex | roundIndex == 16 = do pVal1 <- mutableArrayRead32 mctx 16 pVal2 <- mutableArrayRead32 mctx 17 let final = (fromIntegral pVal1 `shiftL` 32) .|. fromIntegral pVal2 return $ rotateL (i `xor` final) 32 | otherwise = do pVal <- mutableArrayRead32 mctx roundIndex let newr = fromIntegral (i `shiftR` 32) `xor` pVal newr' <- f newr let newi = ((i `shiftL` 32) `xor` newr') .|. (fromIntegral newr) doRound newi (roundIndex+1) -- The Blowfish Feistel function F f :: Word32 -> IO Word64 f t = do a <- mutableArrayRead32 mctx (s0 + fromIntegral ((t `shiftR` 24) .&. 0xff)) b <- mutableArrayRead32 mctx (s1 + fromIntegral ((t `shiftR` 16) .&. 0xff)) c <- mutableArrayRead32 mctx (s2 + fromIntegral ((t `shiftR` 8) .&. 0xff)) d <- mutableArrayRead32 mctx (s3 + fromIntegral (t .&. 0xff)) return (fromIntegral (((a + b) `xor` c) + d) `shiftL` 32) where s0 = 18 s1 = 274 s2 = 530 s3 = 786 cryptonite-0.23/Crypto/Cipher/Camellia/Primitive.hs0000644000000000000000000002511612526640717020550 0ustar0000000000000000 -- | -- Module : Crypto.Cipher.Camellia.Primitive -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- this only cover Camellia 128 bits for now, API will change once -- 192 and 256 mode are implemented too {-# LANGUAGE MagicHash #-} module Crypto.Cipher.Camellia.Primitive ( Camellia , initCamellia , encrypt , decrypt ) where import Data.Word import Data.Bits import Crypto.Error import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Words import Crypto.Internal.WordArray import Data.Memory.Endian data Mode = Decrypt | Encrypt w64tow128 :: (Word64, Word64) -> Word128 w64tow128 (x1, x2) = Word128 x1 x2 w64tow8 :: Word64 -> (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8) w64tow8 x = (t1, t2, t3, t4, t5, t6, t7, t8) where t1 = fromIntegral (x `shiftR` 56) t2 = fromIntegral (x `shiftR` 48) t3 = fromIntegral (x `shiftR` 40) t4 = fromIntegral (x `shiftR` 32) t5 = fromIntegral (x `shiftR` 24) t6 = fromIntegral (x `shiftR` 16) t7 = fromIntegral (x `shiftR` 8) t8 = fromIntegral (x) w8tow64 :: (Word8, Word8, Word8, Word8, Word8, Word8, Word8, Word8) -> Word64 w8tow64 (t1,t2,t3,t4,t5,t6,t7,t8) = (fromIntegral t1 `shiftL` 56) .|. (fromIntegral t2 `shiftL` 48) .|. (fromIntegral t3 `shiftL` 40) .|. (fromIntegral t4 `shiftL` 32) .|. (fromIntegral t5 `shiftL` 24) .|. (fromIntegral t6 `shiftL` 16) .|. (fromIntegral t7 `shiftL` 8) .|. (fromIntegral t8) sbox :: Int -> Word8 sbox = arrayRead8 t where t = array8 "\x70\x82\x2c\xec\xb3\x27\xc0\xe5\xe4\x85\x57\x35\xea\x0c\xae\x41\ \\x23\xef\x6b\x93\x45\x19\xa5\x21\xed\x0e\x4f\x4e\x1d\x65\x92\xbd\ \\x86\xb8\xaf\x8f\x7c\xeb\x1f\xce\x3e\x30\xdc\x5f\x5e\xc5\x0b\x1a\ \\xa6\xe1\x39\xca\xd5\x47\x5d\x3d\xd9\x01\x5a\xd6\x51\x56\x6c\x4d\ \\x8b\x0d\x9a\x66\xfb\xcc\xb0\x2d\x74\x12\x2b\x20\xf0\xb1\x84\x99\ \\xdf\x4c\xcb\xc2\x34\x7e\x76\x05\x6d\xb7\xa9\x31\xd1\x17\x04\xd7\ \\x14\x58\x3a\x61\xde\x1b\x11\x1c\x32\x0f\x9c\x16\x53\x18\xf2\x22\ \\xfe\x44\xcf\xb2\xc3\xb5\x7a\x91\x24\x08\xe8\xa8\x60\xfc\x69\x50\ \\xaa\xd0\xa0\x7d\xa1\x89\x62\x97\x54\x5b\x1e\x95\xe0\xff\x64\xd2\ \\x10\xc4\x00\x48\xa3\xf7\x75\xdb\x8a\x03\xe6\xda\x09\x3f\xdd\x94\ \\x87\x5c\x83\x02\xcd\x4a\x90\x33\x73\x67\xf6\xf3\x9d\x7f\xbf\xe2\ \\x52\x9b\xd8\x26\xc8\x37\xc6\x3b\x81\x96\x6f\x4b\x13\xbe\x63\x2e\ \\xe9\x79\xa7\x8c\x9f\x6e\xbc\x8e\x29\xf5\xf9\xb6\x2f\xfd\xb4\x59\ \\x78\x98\x06\x6a\xe7\x46\x71\xba\xd4\x25\xab\x42\x88\xa2\x8d\xfa\ \\x72\x07\xb9\x55\xf8\xee\xac\x0a\x36\x49\x2a\x68\x3c\x38\xf1\xa4\ \\x40\x28\xd3\x7b\xbb\xc9\x43\xc1\x15\xe3\xad\xf4\x77\xc7\x80\x9e"# sbox1 :: Word8 -> Word8 sbox1 x = sbox (fromIntegral x) sbox2 :: Word8 -> Word8 sbox2 x = sbox1 x `rotateL` 1 sbox3 :: Word8 -> Word8 sbox3 x = sbox1 x `rotateL` 7 sbox4 :: Word8 -> Word8 sbox4 x = sbox1 (x `rotateL` 1) sigma1, sigma2, sigma3, sigma4, sigma5, sigma6 :: Word64 sigma1 = 0xA09E667F3BCC908B sigma2 = 0xB67AE8584CAA73B2 sigma3 = 0xC6EF372FE94F82BE sigma4 = 0x54FF53A5F1D36F1C sigma5 = 0x10E527FADE682D1D sigma6 = 0xB05688C2B3E6C1FD rotl128 :: Word128 -> Int -> Word128 rotl128 v 0 = v rotl128 (Word128 x1 x2) 64 = Word128 x2 x1 rotl128 v@(Word128 x1 x2) w | w > 64 = (v `rotl128` 64) `rotl128` (w - 64) | otherwise = Word128 (x1high .|. x2low) (x2high .|. x1low) where splitBits i = (i .&. complement x, i .&. x) where x = 2 ^ w - 1 (x1high, x1low) = splitBits (x1 `rotateL` w) (x2high, x2low) = splitBits (x2 `rotateL` w) -- | Camellia context data Camellia = Camellia { k :: Array64 , kw :: Array64 , ke :: Array64 } setKeyInterim :: ByteArrayAccess key => key -> (Word128, Word128, Word128, Word128) setKeyInterim keyseed = (w64tow128 kL, w64tow128 kR, w64tow128 kA, w64tow128 kB) where kL = (fromBE $ B.toW64BE keyseed 0, fromBE $ B.toW64BE keyseed 8) kR = (0, 0) kA = let d1 = (fst kL `xor` fst kR) d2 = (snd kL `xor` snd kR) d3 = d2 `xor` feistel d1 sigma1 d4 = d1 `xor` feistel d3 sigma2 d5 = d4 `xor` (fst kL) d6 = d3 `xor` (snd kL) d7 = d6 `xor` feistel d5 sigma3 d8 = d5 `xor` feistel d7 sigma4 in (d8, d7) kB = let d1 = (fst kA `xor` fst kR) d2 = (snd kA `xor` snd kR) d3 = d2 `xor` feistel d1 sigma5 d4 = d1 `xor` feistel d3 sigma6 in (d4, d3) -- | Initialize a 128-bit key -- -- Return the initialized key or a error message if the given -- keyseed was not 16-bytes in length. initCamellia :: ByteArray key => key -- ^ The key to create the camellia context -> CryptoFailable Camellia initCamellia key | B.length key /= 16 = CryptoFailed $ CryptoError_KeySizeInvalid | otherwise = let (kL, _, kA, _) = setKeyInterim key in let (Word128 kw1 kw2) = (kL `rotl128` 0) in let (Word128 k1 k2) = (kA `rotl128` 0) in let (Word128 k3 k4) = (kL `rotl128` 15) in let (Word128 k5 k6) = (kA `rotl128` 15) in let (Word128 ke1 ke2) = (kA `rotl128` 30) in --ke1 = (KA <<< 30) >> 64; ke2 = (KA <<< 30) & MASK64; let (Word128 k7 k8) = (kL `rotl128` 45) in --k7 = (KL <<< 45) >> 64; k8 = (KL <<< 45) & MASK64; let (Word128 k9 _) = (kA `rotl128` 45) in --k9 = (KA <<< 45) >> 64; let (Word128 _ k10) = (kL `rotl128` 60) in let (Word128 k11 k12) = (kA `rotl128` 60) in let (Word128 ke3 ke4) = (kL `rotl128` 77) in let (Word128 k13 k14) = (kL `rotl128` 94) in let (Word128 k15 k16) = (kA `rotl128` 94) in let (Word128 k17 k18) = (kL `rotl128` 111) in let (Word128 kw3 kw4) = (kA `rotl128` 111) in CryptoPassed $ Camellia { kw = array64 4 [ kw1, kw2, kw3, kw4 ] , ke = array64 4 [ ke1, ke2, ke3, ke4 ] , k = array64 18 [ k1, k2, k3, k4, k5, k6, k7, k8, k9, k10, k11, k12, k13, k14, k15, k16, k17, k18 ] } feistel :: Word64 -> Word64 -> Word64 feistel fin sk = let x = fin `xor` sk in let (t1, t2, t3, t4, t5, t6, t7, t8) = w64tow8 x in let t1' = sbox1 t1 in let t2' = sbox2 t2 in let t3' = sbox3 t3 in let t4' = sbox4 t4 in let t5' = sbox2 t5 in let t6' = sbox3 t6 in let t7' = sbox4 t7 in let t8' = sbox1 t8 in let y1 = t1' `xor` t3' `xor` t4' `xor` t6' `xor` t7' `xor` t8' in let y2 = t1' `xor` t2' `xor` t4' `xor` t5' `xor` t7' `xor` t8' in let y3 = t1' `xor` t2' `xor` t3' `xor` t5' `xor` t6' `xor` t8' in let y4 = t2' `xor` t3' `xor` t4' `xor` t5' `xor` t6' `xor` t7' in let y5 = t1' `xor` t2' `xor` t6' `xor` t7' `xor` t8' in let y6 = t2' `xor` t3' `xor` t5' `xor` t7' `xor` t8' in let y7 = t3' `xor` t4' `xor` t5' `xor` t6' `xor` t8' in let y8 = t1' `xor` t4' `xor` t5' `xor` t6' `xor` t7' in w8tow64 (y1, y2, y3, y4, y5, y6, y7, y8) fl :: Word64 -> Word64 -> Word64 fl fin sk = let (x1, x2) = w64to32 fin in let (k1, k2) = w64to32 sk in let y2 = x2 `xor` ((x1 .&. k1) `rotateL` 1) in let y1 = x1 `xor` (y2 .|. k2) in w32to64 (y1, y2) flinv :: Word64 -> Word64 -> Word64 flinv fin sk = let (y1, y2) = w64to32 fin in let (k1, k2) = w64to32 sk in let x1 = y1 `xor` (y2 .|. k2) in let x2 = y2 `xor` ((x1 .&. k1) `rotateL` 1) in w32to64 (x1, x2) {- in decrypt mode 0->17 1->16 ... -} getKeyK :: Mode -> Camellia -> Int -> Word64 getKeyK Encrypt key i = k key `arrayRead64` i getKeyK Decrypt key i = k key `arrayRead64` (17 - i) {- in decrypt mode 0->3 1->2 2->1 3->0 -} getKeyKe :: Mode -> Camellia -> Int -> Word64 getKeyKe Encrypt key i = ke key `arrayRead64` i getKeyKe Decrypt key i = ke key `arrayRead64` (3 - i) {- in decrypt mode 0->2 1->3 2->0 3->1 -} getKeyKw :: Mode -> Camellia -> Int -> Word64 getKeyKw Encrypt key i = (kw key) `arrayRead64` i getKeyKw Decrypt key i = (kw key) `arrayRead64` ((i + 2) `mod` 4) {- perform the following D2 = D2 ^ F(D1, k1); // Round 1 D1 = D1 ^ F(D2, k2); // Round 2 D2 = D2 ^ F(D1, k3); // Round 3 D1 = D1 ^ F(D2, k4); // Round 4 D2 = D2 ^ F(D1, k5); // Round 5 D1 = D1 ^ F(D2, k6); // Round 6 -} doBlockRound :: Mode -> Camellia -> Word64 -> Word64 -> Int -> (Word64, Word64) doBlockRound mode key d1 d2 i = let r1 = d2 `xor` feistel d1 (getKeyK mode key (0+i)) in {- Round 1+i -} let r2 = d1 `xor` feistel r1 (getKeyK mode key (1+i)) in {- Round 2+i -} let r3 = r1 `xor` feistel r2 (getKeyK mode key (2+i)) in {- Round 3+i -} let r4 = r2 `xor` feistel r3 (getKeyK mode key (3+i)) in {- Round 4+i -} let r5 = r3 `xor` feistel r4 (getKeyK mode key (4+i)) in {- Round 5+i -} let r6 = r4 `xor` feistel r5 (getKeyK mode key (5+i)) in {- Round 6+i -} (r6, r5) doBlock :: Mode -> Camellia -> Word128 -> Word128 doBlock mode key (Word128 d1 d2) = let d1a = d1 `xor` (getKeyKw mode key 0) in {- Prewhitening -} let d2a = d2 `xor` (getKeyKw mode key 1) in let (d1b, d2b) = doBlockRound mode key d1a d2a 0 in let d1c = fl d1b (getKeyKe mode key 0) in {- FL -} let d2c = flinv d2b (getKeyKe mode key 1) in {- FLINV -} let (d1d, d2d) = doBlockRound mode key d1c d2c 6 in let d1e = fl d1d (getKeyKe mode key 2) in {- FL -} let d2e = flinv d2d (getKeyKe mode key 3) in {- FLINV -} let (d1f, d2f) = doBlockRound mode key d1e d2e 12 in let d2g = d2f `xor` (getKeyKw mode key 2) in {- Postwhitening -} let d1g = d1f `xor` (getKeyKw mode key 3) in w64tow128 (d2g, d1g) {- encryption for 128 bits blocks -} encryptBlock :: Camellia -> Word128 -> Word128 encryptBlock = doBlock Encrypt {- decryption for 128 bits blocks -} decryptBlock :: Camellia -> Word128 -> Word128 decryptBlock = doBlock Decrypt -- | Encrypts the given ByteString using the given Key encrypt :: ByteArray ba => Camellia -- ^ The key to use -> ba -- ^ The data to encrypt -> ba encrypt key = B.mapAsWord128 (encryptBlock key) -- | Decrypts the given ByteString using the given Key decrypt :: ByteArray ba => Camellia -- ^ The key to use -> ba -- ^ The data to decrypt -> ba decrypt key = B.mapAsWord128 (decryptBlock key) cryptonite-0.23/Crypto/Cipher/DES/Primitive.hs0000644000000000000000000002137612526641043017451 0ustar0000000000000000{-# LANGUAGE FlexibleInstances #-} ----------------------------------------------------------------------------- -- | -- Module : Crypto.Cipher.DES.Primitive -- License : BSD-style -- -- This module is copy of DES module from Crypto package. -- http://hackage.haskell.org/package/Crypto -- ----------------------------------------------------------------------------- module Crypto.Cipher.DES.Primitive ( encrypt , decrypt , Block(..) ) where import Data.Word import Data.Bits -- | a DES block (64 bits) newtype Block = Block { unBlock :: Word64 } type Rotation = Int type Key = Word64 type Bits4 = [Bool] type Bits6 = [Bool] type Bits32 = [Bool] type Bits48 = [Bool] type Bits56 = [Bool] type Bits64 = [Bool] desXor :: [Bool] -> [Bool] -> [Bool] desXor a b = zipWith (/=) a b desRotate :: [Bool] -> Int -> [Bool] desRotate bits rot = drop rot' bits ++ take rot' bits where rot' = rot `mod` length bits bitify :: Word64 -> Bits64 bitify w = map (\b -> w .&. (shiftL 1 b) /= 0) [63,62..0] unbitify :: Bits64 -> Word64 unbitify bs = foldl (\i b -> if b then 1 + shiftL i 1 else shiftL i 1) 0 bs initial_permutation :: Bits64 -> Bits64 initial_permutation mb = map ((!!) mb) i where i = [57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6] {- "\x39\x31\x29\x21\x19\x11\x09\x01\x3b\x33\x2b\x23\x1b\x13\ \\x0b\x03\x3d\x35\x2d\x25\x1d\x15\x0d\x05\x3f\x37\x2f\x27\ \\x1f\x17\x0f\x07\x38\x30\x28\x20\x18\x10\x08\x00\x3a\x32\ \\x2a\x22\x1a\x12\x0a\x02\x3c\x34\x2c\x24\x1c\x14\x0c\x04\ \\x3e\x36\x2e\x26\x1e\x16\x0e\x06" -} key_transformation :: Bits64 -> Bits56 key_transformation kb = map ((!!) kb) i where i = [56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3] {- "\x38\x30\x28\x20\x18\x10\x08\x00\x39\x31\x29\x21\x19\x11\ \\x09\x01\x3a\x32\x2a\x22\x1a\x12\x0a\x02\x3b\x33\x2b\x23\ \\x3e\x36\x2e\x26\x1e\x16\x0e\x06\x3d\x35\x2d\x25\x1d\x15\ \\x0d\x05\x3c\x34\x2c\x24\x1c\x14\x0c\x04\x1b\x13\x0b\x03" -} des_enc :: Block -> Key -> Block des_enc = do_des [1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28] des_dec :: Block -> Key -> Block des_dec = do_des [28,27,25,23,21,19,17,15,14,12,10,8,6,4,2,1] do_des :: [Rotation] -> Block -> Key -> Block do_des rots (Block m) k = Block $ des_work rots (takeDrop 32 mb) kb where kb = key_transformation $ bitify k mb = initial_permutation $ bitify m des_work :: [Rotation] -> (Bits32, Bits32) -> Bits56 -> Word64 des_work [] (ml, mr) _ = unbitify $ final_perm $ (mr ++ ml) des_work (r:rs) mb kb = des_work rs mb' kb where mb' = do_round r mb kb do_round :: Rotation -> (Bits32, Bits32) -> Bits56 -> (Bits32, Bits32) do_round r (ml, mr) kb = (mr, m') where kb' = get_key kb r comp_kb = compression_permutation kb' expa_mr = expansion_permutation mr res = comp_kb `desXor` expa_mr res' = tail $ iterate (trans 6) ([], res) trans n (_, b) = (take n b, drop n b) res_s = concat $ zipWith (\f (x,_) -> f x) [s_box_1, s_box_2, s_box_3, s_box_4, s_box_5, s_box_6, s_box_7, s_box_8] res' res_p = p_box res_s m' = res_p `desXor` ml get_key :: Bits56 -> Rotation -> Bits56 get_key kb r = kb' where (kl, kr) = takeDrop 28 kb kb' = desRotate kl r ++ desRotate kr r compression_permutation :: Bits56 -> Bits48 compression_permutation kb = map ((!!) kb) i where i = [13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31] expansion_permutation :: Bits32 -> Bits48 expansion_permutation mb = map ((!!) mb) i where i = [31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7, 8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20, 19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31, 0] s_box :: [[Word8]] -> Bits6 -> Bits4 s_box s [a,b,c,d,e,f] = to_bool 4 $ (s !! row) !! col where row = sum $ zipWith numericise [a,f] [1, 0] col = sum $ zipWith numericise [b,c,d,e] [3, 2, 1, 0] numericise :: Bool -> Int -> Int numericise = (\x y -> if x then 2^y else 0) to_bool :: Int -> Word8 -> [Bool] to_bool 0 _ = [] to_bool n i = ((i .&. 8) == 8):to_bool (n-1) (shiftL i 1) s_box _ _ = error "DES: internal error bits6 more than 6 elements" s_box_1 :: Bits6 -> Bits4 s_box_1 = s_box i where i = [[14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7], [ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8], [ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0], [15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13]] s_box_2 :: Bits6 -> Bits4 s_box_2 = s_box i where i = [[15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10], [3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5], [0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15], [13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9]] s_box_3 :: Bits6 -> Bits4 s_box_3 = s_box i where i = [[10, 0, 9, 14 , 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8], [13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1], [13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7], [1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12]] s_box_4 :: Bits6 -> Bits4 s_box_4 = s_box i where i = [[7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15], [13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9], [10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4], [3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14]] s_box_5 :: Bits6 -> Bits4 s_box_5 = s_box i where i = [[2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9], [14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6], [4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14], [11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3]] s_box_6 :: Bits6 -> Bits4 s_box_6 = s_box i where i = [[12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11], [10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8], [9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6], [4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13]] s_box_7 :: Bits6 -> Bits4 s_box_7 = s_box i where i = [[4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1], [13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6], [1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2], [6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12]] s_box_8 :: Bits6 -> Bits4 s_box_8 = s_box i where i = [[13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7], [1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2], [7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8], [2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11]] p_box :: Bits32 -> Bits32 p_box kb = map ((!!) kb) i where i = [15, 6, 19, 20, 28, 11, 27, 16, 0, 14, 22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5, 21, 10, 3, 24] final_perm :: Bits64 -> Bits64 final_perm kb = map ((!!) kb) i where i = [39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25, 32, 0, 40 , 8, 48, 16, 56, 24] takeDrop :: Int -> [a] -> ([a], [a]) takeDrop _ [] = ([], []) takeDrop 0 xs = ([], xs) takeDrop n (x:xs) = (x:ys, zs) where (ys, zs) = takeDrop (n-1) xs -- | Basic DES encryption which takes a key and a block of plaintext -- and returns the encrypted block of ciphertext according to the standard. encrypt :: Word64 -> Block -> Block encrypt = flip des_enc -- | Basic DES decryption which takes a key and a block of ciphertext and -- returns the decrypted block of plaintext according to the standard. decrypt :: Word64 -> Block -> Block decrypt = flip des_dec cryptonite-0.23/Crypto/Cipher/Twofish/Primitive.hs0000644000000000000000000004277213075454604020471 0ustar0000000000000000{-# LANGUAGE MagicHash #-} {-# LANGUAGE BangPatterns #-} module Crypto.Cipher.Twofish.Primitive ( Twofish , initTwofish , encrypt , decrypt ) where import Crypto.Error import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.WordArray import Crypto.Internal.Words import Data.Word import Data.Int import Data.Bits import Data.List import Control.Monad -- Based on the Golang referance implementation -- https://github.com/golang/crypto/blob/master/twofish/twofish.go -- BlockSize is the constant block size of Twofish. blockSize :: Int blockSize = 16 mdsPolynomial, rsPolynomial :: Word32 mdsPolynomial = 0x169 -- x^8 + x^6 + x^5 + x^3 + 1, see [TWOFISH] 4.2 rsPolynomial = 0x14d -- x^8 + x^6 + x^3 + x^2 + 1, see [TWOFISH] 4.3 data Twofish = Twofish { s :: (Array32, Array32, Array32, Array32) , k :: Array32 } data ByteSize = Bytes16 | Bytes24 | Bytes32 deriving (Eq) data KeyPackage ba = KeyPackage { rawKeyBytes :: ba , byteSize :: ByteSize } buildPackage :: ByteArray ba => ba -> Maybe (KeyPackage ba) buildPackage key | B.length key == 16 = return $ KeyPackage key Bytes16 | B.length key == 24 = return $ KeyPackage key Bytes24 | B.length key == 32 = return $ KeyPackage key Bytes32 | otherwise = Nothing -- | Initialize a 128-bit, 192-bit, or 256-bit key -- -- Return the initialized key or a error message if the given -- keyseed was not 16-bytes in length. initTwofish :: ByteArray key => key -- ^ The key to create the twofish context -> CryptoFailable Twofish initTwofish key = case buildPackage key of Nothing -> CryptoFailed CryptoError_KeySizeInvalid Just keyPackage -> CryptoPassed Twofish { k = generatedK, s = generatedS } where generatedK = array32 40 $ genK keyPackage generatedS = genSboxes keyPackage $ sWords key mapBlocks :: ByteArray ba => (ba -> ba) -> ba -> ba mapBlocks operation input | B.null rest = blockOutput | otherwise = blockOutput `B.append` mapBlocks operation rest where (block, rest) = B.splitAt blockSize input blockOutput = operation block -- | Encrypts the given ByteString using the given Key encrypt :: ByteArray ba => Twofish -- ^ The key to use -> ba -- ^ The data to encrypt -> ba encrypt cipher = mapBlocks (encryptBlock cipher) encryptBlock :: ByteArray ba => Twofish -> ba -> ba encryptBlock Twofish { s = (s1, s2, s3, s4), k = ks } message = store32ls ts where (a, b, c, d) = load32ls message a' = a `xor` arrayRead32 ks 0 b' = b `xor` arrayRead32 ks 1 c' = c `xor` arrayRead32 ks 2 d' = d `xor` arrayRead32 ks 3 (!a'', !b'', !c'', !d'') = foldl' shuffle (a', b', c', d') [0..7] ts = (c'' `xor` arrayRead32 ks 4, d'' `xor` arrayRead32 ks 5, a'' `xor` arrayRead32 ks 6, b'' `xor` arrayRead32 ks 7) shuffle :: (Word32, Word32, Word32, Word32) -> Int -> (Word32, Word32, Word32, Word32) shuffle (!retA, !retB, !retC, !retD) ind = (retA', retB', retC', retD') where [k0, k1, k2, k3] = fmap (\offset -> arrayRead32 ks $ (8 + 4 * ind) + offset) [0..3] t2 = byteIndex s2 retB `xor` byteIndex s3 (shiftR retB 8) `xor` byteIndex s4 (shiftR retB 16) `xor` byteIndex s1 (shiftR retB 24) t1 = (byteIndex s1 retA `xor` byteIndex s2 (shiftR retA 8) `xor` byteIndex s3 (shiftR retA 16) `xor` byteIndex s4 (shiftR retA 24)) + t2 retC' = rotateR (retC `xor` (t1 + k0)) 1 retD' = rotateL retD 1 `xor` (t1 + t2 + k1) t2' = byteIndex s2 retD' `xor` byteIndex s3 (shiftR retD' 8) `xor` byteIndex s4 (shiftR retD' 16) `xor` byteIndex s1 (shiftR retD' 24) t1' = (byteIndex s1 retC' `xor` byteIndex s2 (shiftR retC' 8) `xor` byteIndex s3 (shiftR retC' 16) `xor` byteIndex s4 (shiftR retC' 24)) + t2' retA' = rotateR (retA `xor` (t1' + k2)) 1 retB' = rotateL retB 1 `xor` (t1' + t2' + k3) -- Unsafe, no bounds checking byteIndex :: Array32 -> Word32 -> Word32 byteIndex xs ind = arrayRead32 xs $ fromIntegral byte where byte = ind `mod` 256 -- | Decrypts the given ByteString using the given Key decrypt :: ByteArray ba => Twofish -- ^ The key to use -> ba -- ^ The data to decrypt -> ba decrypt cipher = mapBlocks (decryptBlock cipher) {- decryption for 128 bits blocks -} decryptBlock :: ByteArray ba => Twofish -> ba -> ba decryptBlock Twofish { s = (s1, s2, s3, s4), k = ks } message = store32ls ixs where (a, b, c, d) = load32ls message a' = c `xor` arrayRead32 ks 6 b' = d `xor` arrayRead32 ks 7 c' = a `xor` arrayRead32 ks 4 d' = b `xor` arrayRead32 ks 5 (!a'', !b'', !c'', !d'') = foldl' unshuffle (a', b', c', d') [8, 7..1] ixs = (a'' `xor` arrayRead32 ks 0, b'' `xor` arrayRead32 ks 1, c'' `xor` arrayRead32 ks 2, d'' `xor` arrayRead32 ks 3) unshuffle :: (Word32, Word32, Word32, Word32) -> Int -> (Word32, Word32, Word32, Word32) unshuffle (!retA, !retB, !retC, !retD) ind = (retA', retB', retC', retD') where [k0, k1, k2, k3] = fmap (\offset -> arrayRead32 ks $ (4 + 4 * ind) + offset) [0..3] t2 = byteIndex s2 retD `xor` byteIndex s3 (shiftR retD 8) `xor` byteIndex s4 (shiftR retD 16) `xor` byteIndex s1 (shiftR retD 24) t1 = (byteIndex s1 retC `xor` byteIndex s2 (shiftR retC 8) `xor` byteIndex s3 (shiftR retC 16) `xor` byteIndex s4 (shiftR retC 24)) + t2 retA' = rotateL retA 1 `xor` (t1 + k2) retB' = rotateR (retB `xor` (t2 + t1 + k3)) 1 t2' = byteIndex s2 retB' `xor` byteIndex s3 (shiftR retB' 8) `xor` byteIndex s4 (shiftR retB' 16) `xor` byteIndex s1 (shiftR retB' 24) t1' = (byteIndex s1 retA' `xor` byteIndex s2 (shiftR retA' 8) `xor` byteIndex s3 (shiftR retA' 16) `xor` byteIndex s4 (shiftR retA' 24)) + t2' retC' = rotateL retC 1 `xor` (t1' + k0) retD' = rotateR (retD `xor` (t2' + t1' + k1)) 1 sbox0 :: Int -> Word8 sbox0 = arrayRead8 t where t = array8 "\xa9\x67\xb3\xe8\x04\xfd\xa3\x76\x9a\x92\x80\x78\xe4\xdd\xd1\x38\ \\x0d\xc6\x35\x98\x18\xf7\xec\x6c\x43\x75\x37\x26\xfa\x13\x94\x48\ \\xf2\xd0\x8b\x30\x84\x54\xdf\x23\x19\x5b\x3d\x59\xf3\xae\xa2\x82\ \\x63\x01\x83\x2e\xd9\x51\x9b\x7c\xa6\xeb\xa5\xbe\x16\x0c\xe3\x61\ \\xc0\x8c\x3a\xf5\x73\x2c\x25\x0b\xbb\x4e\x89\x6b\x53\x6a\xb4\xf1\ \\xe1\xe6\xbd\x45\xe2\xf4\xb6\x66\xcc\x95\x03\x56\xd4\x1c\x1e\xd7\ \\xfb\xc3\x8e\xb5\xe9\xcf\xbf\xba\xea\x77\x39\xaf\x33\xc9\x62\x71\ \\x81\x79\x09\xad\x24\xcd\xf9\xd8\xe5\xc5\xb9\x4d\x44\x08\x86\xe7\ \\xa1\x1d\xaa\xed\x06\x70\xb2\xd2\x41\x7b\xa0\x11\x31\xc2\x27\x90\ \\x20\xf6\x60\xff\x96\x5c\xb1\xab\x9e\x9c\x52\x1b\x5f\x93\x0a\xef\ \\x91\x85\x49\xee\x2d\x4f\x8f\x3b\x47\x87\x6d\x46\xd6\x3e\x69\x64\ \\x2a\xce\xcb\x2f\xfc\x97\x05\x7a\xac\x7f\xd5\x1a\x4b\x0e\xa7\x5a\ \\x28\x14\x3f\x29\x88\x3c\x4c\x02\xb8\xda\xb0\x17\x55\x1f\x8a\x7d\ \\x57\xc7\x8d\x74\xb7\xc4\x9f\x72\x7e\x15\x22\x12\x58\x07\x99\x34\ \\x6e\x50\xde\x68\x65\xbc\xdb\xf8\xc8\xa8\x2b\x40\xdc\xfe\x32\xa4\ \\xca\x10\x21\xf0\xd3\x5d\x0f\x00\x6f\x9d\x36\x42\x4a\x5e\xc1\xe0"# sbox1 :: Int -> Word8 sbox1 = arrayRead8 t where t = array8 "\x75\xf3\xc6\xf4\xdb\x7b\xfb\xc8\x4a\xd3\xe6\x6b\x45\x7d\xe8\x4b\ \\xd6\x32\xd8\xfd\x37\x71\xf1\xe1\x30\x0f\xf8\x1b\x87\xfa\x06\x3f\ \\x5e\xba\xae\x5b\x8a\x00\xbc\x9d\x6d\xc1\xb1\x0e\x80\x5d\xd2\xd5\ \\xa0\x84\x07\x14\xb5\x90\x2c\xa3\xb2\x73\x4c\x54\x92\x74\x36\x51\ \\x38\xb0\xbd\x5a\xfc\x60\x62\x96\x6c\x42\xf7\x10\x7c\x28\x27\x8c\ \\x13\x95\x9c\xc7\x24\x46\x3b\x70\xca\xe3\x85\xcb\x11\xd0\x93\xb8\ \\xa6\x83\x20\xff\x9f\x77\xc3\xcc\x03\x6f\x08\xbf\x40\xe7\x2b\xe2\ \\x79\x0c\xaa\x82\x41\x3a\xea\xb9\xe4\x9a\xa4\x97\x7e\xda\x7a\x17\ \\x66\x94\xa1\x1d\x3d\xf0\xde\xb3\x0b\x72\xa7\x1c\xef\xd1\x53\x3e\ \\x8f\x33\x26\x5f\xec\x76\x2a\x49\x81\x88\xee\x21\xc4\x1a\xeb\xd9\ \\xc5\x39\x99\xcd\xad\x31\x8b\x01\x18\x23\xdd\x1f\x4e\x2d\xf9\x48\ \\x4f\xf2\x65\x8e\x78\x5c\x58\x19\x8d\xe5\x98\x57\x67\x7f\x05\x64\ \\xaf\x63\xb6\xfe\xf5\xb7\x3c\xa5\xce\xe9\x68\x44\xe0\x4d\x43\x69\ \\x29\x2e\xac\x15\x59\xa8\x0a\x9e\x6e\x47\xdf\x34\x35\x6a\xcf\xdc\ \\x22\xc9\xc0\x9b\x89\xd4\xed\xab\x12\xa2\x0d\x52\xbb\x02\x2f\xa9\ \\xd7\x61\x1e\xb4\x50\x04\xf6\xc2\x16\x25\x86\x56\x55\x09\xbe\x91"# rs :: [[Word8]] rs = [ [0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E] , [0xA4, 0x56, 0x82, 0xF3, 0x1E, 0xC6, 0x68, 0xE5] , [0x02, 0xA1, 0xFC, 0xC1, 0x47, 0xAE, 0x3D, 0x19] , [0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E, 0x03] ] load32ls :: ByteArray ba => ba -> (Word32, Word32, Word32, Word32) load32ls message = (intify q1, intify q2, intify q3, intify q4) where (half1, half2) = B.splitAt 8 message (q1, q2) = B.splitAt 4 half1 (q3, q4) = B.splitAt 4 half2 intify :: ByteArray ba => ba -> Word32 intify bytes = foldl' (\int (!word, !ind) -> int .|. shiftL (fromIntegral word) (ind * 8) ) 0 (zip (B.unpack bytes) [0..]) store32ls :: ByteArray ba => (Word32, Word32, Word32, Word32) -> ba store32ls (a, b, c, d) = B.pack $ concatMap splitWordl [a, b, c, d] where splitWordl :: Word32 -> [Word8] splitWordl w = fmap (\ind -> fromIntegral $ shiftR w (8 * ind)) [0..3] -- Create S words sWords :: ByteArray ba => ba -> [Word8] sWords key = sWord where word64Count = B.length key `div` 2 sWord = concatMap (\wordIndex -> map (\rsRow -> foldl' (\acc (!rsVal, !colIndex) -> acc `xor` gfMult rsPolynomial (B.index key $ 8 * wordIndex + colIndex) rsVal ) 0 (zip rsRow [0..]) ) rs ) [0..word64Count - 1] data Column = Zero | One | Two | Three deriving (Show, Eq, Enum, Bounded) genSboxes :: ByteArray ba => KeyPackage ba -> [Word8] -> (Array32, Array32, Array32, Array32) genSboxes keyPackage ws = (mkArray b0', mkArray b1', mkArray b2', mkArray b3') where range = [0..255] mkArray = array32 256 [w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15] = take 16 ws (b0', b1', b2', b3') = sboxBySize $ byteSize keyPackage sboxBySize :: ByteSize -> ([Word32], [Word32], [Word32], [Word32]) sboxBySize Bytes16 = (b0, b1, b2, b3) where !b0 = fmap mapper range where mapper :: Int -> Word32 mapper byte = mdsColumnMult ((sbox1 . fromIntegral) ((sbox0 . fromIntegral $ sbox0 byte `xor` w0) `xor` w4)) Zero !b1 = fmap mapper range where mapper byte = mdsColumnMult ((sbox0 . fromIntegral) ((sbox0 . fromIntegral $ sbox1 byte `xor` w1) `xor` w5)) One !b2 = fmap mapper range where mapper byte = mdsColumnMult ((sbox1 . fromIntegral) ((sbox1 . fromIntegral $ sbox0 byte `xor` w2) `xor` w6)) Two !b3 = fmap mapper range where mapper byte = mdsColumnMult ((sbox0 . fromIntegral) ((sbox1 . fromIntegral $ sbox1 byte `xor` w3) `xor` w7)) Three sboxBySize Bytes24 = (b0, b1, b2, b3) where !b0 = fmap mapper range where mapper byte = mdsColumnMult ((sbox1 . fromIntegral) ((sbox0 . fromIntegral) ((sbox0 . fromIntegral $ sbox1 byte `xor` w0) `xor` w4) `xor` w8)) Zero !b1 = fmap mapper range where mapper byte = mdsColumnMult ((sbox0 . fromIntegral) ((sbox0 . fromIntegral) ((sbox1 . fromIntegral $ sbox1 byte `xor` w1) `xor` w5) `xor` w9)) One !b2 = fmap mapper range where mapper byte = mdsColumnMult ((sbox1 . fromIntegral) ((sbox1 . fromIntegral) ((sbox0 . fromIntegral $ sbox0 byte `xor` w2) `xor` w6) `xor` w10)) Two !b3 = fmap mapper range where mapper byte = mdsColumnMult ((sbox0 . fromIntegral) ((sbox1 . fromIntegral) ((sbox1 . fromIntegral $ sbox0 byte `xor` w3) `xor` w7) `xor` w11)) Three sboxBySize Bytes32 = (b0, b1, b2, b3) where !b0 = fmap mapper range where mapper byte = mdsColumnMult ((sbox1 . fromIntegral) ((sbox0 . fromIntegral) ((sbox0 . fromIntegral) ((sbox1 . fromIntegral $ sbox1 byte `xor` w0) `xor` w4) `xor` w8) `xor` w12)) Zero !b1 = fmap mapper range where mapper byte = mdsColumnMult ((sbox0 . fromIntegral) ((sbox0 . fromIntegral) ((sbox1 . fromIntegral) ((sbox1 . fromIntegral $ sbox0 byte `xor` w1) `xor` w5) `xor` w9) `xor` w13)) One !b2 = fmap mapper range where mapper byte = mdsColumnMult ((sbox1 . fromIntegral) ((sbox1 . fromIntegral) ((sbox0 . fromIntegral) ((sbox0 . fromIntegral $ sbox0 byte `xor` w2) `xor` w6) `xor` w10) `xor` w14)) Two !b3 = fmap mapper range where mapper byte = mdsColumnMult ((sbox0 . fromIntegral) ((sbox1 . fromIntegral) ((sbox1 . fromIntegral) ((sbox0 . fromIntegral $ sbox1 byte `xor` w3) `xor` w7) `xor` w11) `xor` w15)) Three genK :: (ByteArray ba) => KeyPackage ba -> [Word32] genK keyPackage = concatMap makeTuple [0..19] where makeTuple :: Word8 -> [Word32] makeTuple idx = [a + b', rotateL (2 * b' + a) 9] where tmp1 = replicate 4 $ 2 * idx tmp2 = fmap (+1) tmp1 a = h tmp1 keyPackage 0 b = h tmp2 keyPackage 1 b' = rotateL b 8 h :: (ByteArray ba) => [Word8] -> KeyPackage ba -> Int -> Word32 h input keyPackage offset = foldl' xorMdsColMult 0 $ zip [y0f, y1f, y2f, y3f] $ enumFrom Zero where key = rawKeyBytes keyPackage [y0, y1, y2, y3] = take 4 input (!y0f, !y1f, !y2f, !y3f) = run (y0, y1, y2, y3) $ byteSize keyPackage run :: (Word8, Word8, Word8, Word8) -> ByteSize -> (Word8, Word8, Word8, Word8) run (!y0'', !y1'', !y2'', !y3'') Bytes32 = run (y0', y1', y2', y3') Bytes24 where y0' = sbox1 (fromIntegral y0'') `xor` B.index key (4 * (6 + offset) + 0) y1' = sbox0 (fromIntegral y1'') `xor` B.index key (4 * (6 + offset) + 1) y2' = sbox0 (fromIntegral y2'') `xor` B.index key (4 * (6 + offset) + 2) y3' = sbox1 (fromIntegral y3'') `xor` B.index key (4 * (6 + offset) + 3) run (!y0'', !y1'', !y2'', !y3'') Bytes24 = run (y0', y1', y2', y3') Bytes16 where y0' = sbox1 (fromIntegral y0'') `xor` B.index key (4 * (4 + offset) + 0) y1' = sbox1 (fromIntegral y1'') `xor` B.index key (4 * (4 + offset) + 1) y2' = sbox0 (fromIntegral y2'') `xor` B.index key (4 * (4 + offset) + 2) y3' = sbox0 (fromIntegral y3'') `xor` B.index key (4 * (4 + offset) + 3) run (!y0'', !y1'', !y2'', !y3'') Bytes16 = (y0', y1', y2', y3') where y0' = sbox1 . fromIntegral $ (sbox0 . fromIntegral $ (sbox0 (fromIntegral y0'') `xor` B.index key (4 * (2 + offset) + 0))) `xor` B.index key (4 * (0 + offset) + 0) y1' = sbox0 . fromIntegral $ (sbox0 . fromIntegral $ (sbox1 (fromIntegral y1'') `xor` B.index key (4 * (2 + offset) + 1))) `xor` B.index key (4 * (0 + offset) + 1) y2' = sbox1 . fromIntegral $ (sbox1 . fromIntegral $ (sbox0 (fromIntegral y2'') `xor` B.index key (4 * (2 + offset) + 2))) `xor` B.index key (4 * (0 + offset) + 2) y3' = sbox0 . fromIntegral $ (sbox1 . fromIntegral $ (sbox1 (fromIntegral y3'') `xor` B.index key (4 * (2 + offset) + 3))) `xor` B.index key (4 * (0 + offset) + 3) xorMdsColMult :: Word32 -> (Word8, Column) -> Word32 xorMdsColMult acc wordAndIndex = acc `xor` uncurry mdsColumnMult wordAndIndex mdsColumnMult :: Word8 -> Column -> Word32 mdsColumnMult !byte !col = case col of Zero -> input .|. rotateL mul5B 8 .|. rotateL mulEF 16 .|. rotateL mulEF 24 One -> mulEF .|. rotateL mulEF 8 .|. rotateL mul5B 16 .|. rotateL input 24 Two -> mul5B .|. rotateL mulEF 8 .|. rotateL input 16 .|. rotateL mulEF 24 Three -> mul5B .|. rotateL input 8 .|. rotateL mulEF 16 .|. rotateL mul5B 24 where input = fromIntegral byte mul5B = fromIntegral $ gfMult mdsPolynomial byte 0x5B mulEF = fromIntegral $ gfMult mdsPolynomial byte 0xEF tupInd :: (Bits b) => b -> (a, a) -> a tupInd b | testBit b 0 = snd | otherwise = fst gfMult :: Word32 -> Word8 -> Word8 -> Word8 gfMult p a b = fromIntegral $ run a b' p' result 0 where b' = (0, fromIntegral b) p' = (0, p) result = 0 run :: Word8 -> (Word32, Word32) -> (Word32, Word32) -> Word32 -> Int -> Word32 run a' b'' p'' result' count = if count == 7 then result'' else run a'' b''' p'' result'' (count + 1) where result'' = result' `xor` tupInd (a' .&. 1) b'' a'' = shiftR a' 1 b''' = (fst b'', tupInd (shiftR (snd b'') 7) p'' `xor` shiftL (snd b'') 1) cryptonite-0.23/Crypto/Cipher/Types/AEAD.hs0000644000000000000000000000614712535566225016673 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Types.AEAD -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- -- AEAD cipher basic types -- {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE Rank2Types #-} module Crypto.Cipher.Types.AEAD where import Crypto.Cipher.Types.Base import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Imports -- | AEAD Implementation data AEADModeImpl st = AEADModeImpl { aeadImplAppendHeader :: forall ba . ByteArrayAccess ba => st -> ba -> st , aeadImplEncrypt :: forall ba . ByteArray ba => st -> ba -> (ba, st) , aeadImplDecrypt :: forall ba . ByteArray ba => st -> ba -> (ba, st) , aeadImplFinalize :: st -> Int -> AuthTag } -- | Authenticated Encryption with Associated Data algorithms data AEAD cipher = forall st . AEAD { aeadModeImpl :: AEADModeImpl st , aeadState :: st } -- | Append some header information to an AEAD context aeadAppendHeader :: ByteArrayAccess aad => AEAD cipher -> aad -> AEAD cipher aeadAppendHeader (AEAD impl st) aad = AEAD impl $ (aeadImplAppendHeader impl) st aad -- | Encrypt some data and update the AEAD context aeadEncrypt :: ByteArray ba => AEAD cipher -> ba -> (ba, AEAD cipher) aeadEncrypt (AEAD impl st) ba = second (AEAD impl) $ (aeadImplEncrypt impl) st ba -- | Decrypt some data and update the AEAD context aeadDecrypt :: ByteArray ba => AEAD cipher -> ba -> (ba, AEAD cipher) aeadDecrypt (AEAD impl st) ba = second (AEAD impl) $ (aeadImplDecrypt impl) st ba -- | Finalize the AEAD context and return the authentication tag aeadFinalize :: AEAD cipher -> Int -> AuthTag aeadFinalize (AEAD impl st) n = (aeadImplFinalize impl) st n -- | Simple AEAD encryption aeadSimpleEncrypt :: (ByteArrayAccess aad, ByteArray ba) => AEAD a -- ^ A new AEAD Context -> aad -- ^ Optional Authentication data header -> ba -- ^ Optional Plaintext -> Int -- ^ Tag length -> (AuthTag, ba) -- ^ Authentication tag and ciphertext aeadSimpleEncrypt aeadIni header input taglen = (tag, output) where aead = aeadAppendHeader aeadIni header (output, aeadFinal) = aeadEncrypt aead input tag = aeadFinalize aeadFinal taglen -- | Simple AEAD decryption aeadSimpleDecrypt :: (ByteArrayAccess aad, ByteArray ba) => AEAD a -- ^ A new AEAD Context -> aad -- ^ Optional Authentication data header -> ba -- ^ Ciphertext -> AuthTag -- ^ The authentication tag -> Maybe ba -- ^ Plaintext aeadSimpleDecrypt aeadIni header input authTag | tag == authTag = Just output | otherwise = Nothing where aead = aeadAppendHeader aeadIni header (output, aeadFinal) = aeadDecrypt aead input tag = aeadFinalize aeadFinal (B.length authTag) cryptonite-0.23/Crypto/Cipher/Types/Base.hs0000644000000000000000000000325412535566225017047 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Types.Base -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- -- symmetric cipher basic types -- {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Cipher.Types.Base ( KeySizeSpecifier(..) , Cipher(..) , AuthTag(..) , AEADMode(..) , DataUnitOffset ) where import Data.Word import Crypto.Internal.ByteArray (Bytes, ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Error -- | Different specifier for key size in bytes data KeySizeSpecifier = KeySizeRange Int Int -- ^ in the range [min,max] | KeySizeEnum [Int] -- ^ one of the specified values | KeySizeFixed Int -- ^ a specific size deriving (Show,Eq) -- | Offset inside an XTS data unit, measured in block size. type DataUnitOffset = Word32 -- | Authentication Tag for AE cipher mode newtype AuthTag = AuthTag { unAuthTag :: Bytes } deriving (Show, ByteArrayAccess) instance Eq AuthTag where (AuthTag a) == (AuthTag b) = B.constEq a b -- | AEAD Mode data AEADMode = AEAD_OCB -- OCB3 | AEAD_CCM | AEAD_EAX | AEAD_CWC | AEAD_GCM deriving (Show,Eq) -- | Symmetric cipher class. class Cipher cipher where -- | Initialize a cipher context from a key cipherInit :: ByteArray key => key -> CryptoFailable cipher -- | Cipher name cipherName :: cipher -> String -- | return the size of the key required for this cipher. -- Some cipher accept any size for key cipherKeySize :: cipher -> KeySizeSpecifier cryptonite-0.23/Crypto/Cipher/Types/Block.hs0000644000000000000000000002433012540350077017215 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Types.Block -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- -- block cipher basic types -- {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE Rank2Types #-} module Crypto.Cipher.Types.Block ( -- * BlockCipher BlockCipher(..) , BlockCipher128(..) -- * initialization vector (IV) , IV(..) , makeIV , nullIV , ivAdd -- * XTS , XTS -- * AEAD , AEAD(..) -- , AEADState(..) , AEADModeImpl(..) , aeadAppendHeader , aeadEncrypt , aeadDecrypt , aeadFinalize -- * CFB 8 bits --, cfb8Encrypt --, cfb8Decrypt ) where import Data.Word import Data.Monoid import Crypto.Error import Crypto.Cipher.Types.Base import Crypto.Cipher.Types.GF import Crypto.Cipher.Types.AEAD import Crypto.Cipher.Types.Utils import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray, withByteArray, Bytes) import qualified Crypto.Internal.ByteArray as B import Foreign.Ptr import Foreign.Storable -- | an IV parametrized by the cipher data IV c = forall byteArray . ByteArray byteArray => IV byteArray instance BlockCipher c => ByteArrayAccess (IV c) where withByteArray (IV z) f = withByteArray z f length (IV z) = B.length z instance Eq (IV c) where (IV a) == (IV b) = B.eq a b -- | XTS callback type XTS ba cipher = (cipher, cipher) -> IV cipher -- ^ Usually represent the Data Unit (e.g. disk sector) -> DataUnitOffset -- ^ Offset in the data unit in number of blocks -> ba -- ^ Data -> ba -- ^ Processed Data -- | Symmetric block cipher class class Cipher cipher => BlockCipher cipher where -- | Return the size of block required for this block cipher blockSize :: cipher -> Int -- | Encrypt blocks -- -- the input string need to be multiple of the block size ecbEncrypt :: ByteArray ba => cipher -> ba -> ba -- | Decrypt blocks -- -- the input string need to be multiple of the block size ecbDecrypt :: ByteArray ba => cipher -> ba -> ba -- | encrypt using the CBC mode. -- -- input need to be a multiple of the blocksize cbcEncrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba cbcEncrypt = cbcEncryptGeneric -- | decrypt using the CBC mode. -- -- input need to be a multiple of the blocksize cbcDecrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba cbcDecrypt = cbcDecryptGeneric -- | encrypt using the CFB mode. -- -- input need to be a multiple of the blocksize cfbEncrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba cfbEncrypt = cfbEncryptGeneric -- | decrypt using the CFB mode. -- -- input need to be a multiple of the blocksize cfbDecrypt :: ByteArray ba => cipher -> IV cipher -> ba -> ba cfbDecrypt = cfbDecryptGeneric -- | combine using the CTR mode. -- -- CTR mode produce a stream of randomized data that is combined -- (by XOR operation) with the input stream. -- -- encryption and decryption are the same operation. -- -- input can be of any size ctrCombine :: ByteArray ba => cipher -> IV cipher -> ba -> ba ctrCombine = ctrCombineGeneric -- | Initialize a new AEAD State -- -- When Nothing is returns, it means the mode is not handled. aeadInit :: ByteArrayAccess iv => AEADMode -> cipher -> iv -> CryptoFailable (AEAD cipher) aeadInit _ _ _ = CryptoFailed CryptoError_AEADModeNotSupported -- | class of block cipher with a 128 bits block size class BlockCipher cipher => BlockCipher128 cipher where -- | encrypt using the XTS mode. -- -- input need to be a multiple of the blocksize, and the cipher -- need to process 128 bits block only xtsEncrypt :: ByteArray ba => (cipher, cipher) -> IV cipher -- ^ Usually represent the Data Unit (e.g. disk sector) -> DataUnitOffset -- ^ Offset in the data unit in number of blocks -> ba -- ^ Plaintext -> ba -- ^ Ciphertext xtsEncrypt = xtsEncryptGeneric -- | decrypt using the XTS mode. -- -- input need to be a multiple of the blocksize, and the cipher -- need to process 128 bits block only xtsDecrypt :: ByteArray ba => (cipher, cipher) -> IV cipher -- ^ Usually represent the Data Unit (e.g. disk sector) -> DataUnitOffset -- ^ Offset in the data unit in number of blocks -> ba -- ^ Ciphertext -> ba -- ^ Plaintext xtsDecrypt = xtsDecryptGeneric -- | Create an IV for a specified block cipher makeIV :: (ByteArrayAccess b, BlockCipher c) => b -> Maybe (IV c) makeIV b = toIV undefined where toIV :: BlockCipher c => c -> Maybe (IV c) toIV cipher | B.length b == sz = Just $ IV (B.convert b :: Bytes) | otherwise = Nothing where sz = blockSize cipher -- | Create an IV that is effectively representing the number 0 nullIV :: BlockCipher c => IV c nullIV = toIV undefined where toIV :: BlockCipher c => c -> IV c toIV cipher = IV (B.zero (blockSize cipher) :: Bytes) -- | Increment an IV by a number. -- -- Assume the IV is in Big Endian format. ivAdd :: BlockCipher c => IV c -> Int -> IV c ivAdd (IV b) i = IV $ copy b where copy :: ByteArray bs => bs -> bs copy bs = B.copyAndFreeze bs $ \p -> do let until0 accu = do r <- loop accu (B.length bs - 1) p case r of 0 -> return () _ -> until0 r until0 i loop :: Int -> Int -> Ptr Word8 -> IO Int loop 0 _ _ = return 0 loop acc ofs p = do v <- peek (p `plusPtr` ofs) :: IO Word8 let accv = acc + fromIntegral v (hi,lo) = accv `divMod` 256 poke (p `plusPtr` ofs) (fromIntegral lo :: Word8) if ofs == 0 then return hi else loop hi (ofs - 1) p cbcEncryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba cbcEncryptGeneric cipher ivini input = mconcat $ doEnc ivini $ chunk (blockSize cipher) input where doEnc _ [] = [] doEnc iv (i:is) = let o = ecbEncrypt cipher $ B.xor iv i in o : doEnc (IV o) is cbcDecryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba cbcDecryptGeneric cipher ivini input = mconcat $ doDec ivini $ chunk (blockSize cipher) input where doDec _ [] = [] doDec iv (i:is) = let o = B.xor iv $ ecbDecrypt cipher i in o : doDec (IV i) is cfbEncryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba cfbEncryptGeneric cipher ivini input = mconcat $ doEnc ivini $ chunk (blockSize cipher) input where doEnc _ [] = [] doEnc (IV iv) (i:is) = let o = B.xor i $ ecbEncrypt cipher iv in o : doEnc (IV o) is cfbDecryptGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba cfbDecryptGeneric cipher ivini input = mconcat $ doDec ivini $ chunk (blockSize cipher) input where doDec _ [] = [] doDec (IV iv) (i:is) = let o = B.xor i $ ecbEncrypt cipher iv in o : doDec (IV i) is ctrCombineGeneric :: (ByteArray ba, BlockCipher cipher) => cipher -> IV cipher -> ba -> ba ctrCombineGeneric cipher ivini input = mconcat $ doCnt ivini $ chunk (blockSize cipher) input where doCnt _ [] = [] doCnt iv@(IV ivd) (i:is) = let ivEnc = ecbEncrypt cipher ivd in B.xor i ivEnc : doCnt (ivAdd iv 1) is xtsEncryptGeneric :: (ByteArray ba, BlockCipher128 cipher) => XTS ba cipher xtsEncryptGeneric = xtsGeneric ecbEncrypt xtsDecryptGeneric :: (ByteArray ba, BlockCipher128 cipher) => XTS ba cipher xtsDecryptGeneric = xtsGeneric ecbDecrypt xtsGeneric :: (ByteArray ba, BlockCipher128 cipher) => (cipher -> ba -> ba) -> (cipher, cipher) -> IV cipher -> DataUnitOffset -> ba -> ba xtsGeneric f (cipher, tweakCipher) (IV iv) sPoint input = mconcat $ doXts iniTweak $ chunk (blockSize cipher) input where encTweak = ecbEncrypt tweakCipher iv iniTweak = iterate xtsGFMul encTweak !! fromIntegral sPoint doXts _ [] = [] doXts tweak (i:is) = let o = B.xor (f cipher $ B.xor i tweak) tweak in o : doXts (xtsGFMul tweak) is {- -- | Encrypt using CFB mode in 8 bit output -- -- Effectively turn a Block cipher in CFB mode into a Stream cipher cfb8Encrypt :: BlockCipher a => a -> IV a -> B.byteString -> B.byteString cfb8Encrypt ctx origIv msg = B.unsafeCreate (B.length msg) $ \dst -> loop dst origIv msg where loop d iv@(IV i) m | B.null m = return () | otherwise = poke d out >> loop (d `plusPtr` 1) ni (B.drop 1 m) where m' = if B.length m < blockSize ctx then m `B.append` B.replicate (blockSize ctx - B.length m) 0 else B.take (blockSize ctx) m r = cfbEncrypt ctx iv m' out = B.head r ni = IV (B.drop 1 i `B.snoc` out) -- | Decrypt using CFB mode in 8 bit output -- -- Effectively turn a Block cipher in CFB mode into a Stream cipher cfb8Decrypt :: BlockCipher a => a -> IV a -> B.byteString -> B.byteString cfb8Decrypt ctx origIv msg = B.unsafeCreate (B.length msg) $ \dst -> loop dst origIv msg where loop d iv@(IV i) m | B.null m = return () | otherwise = poke d out >> loop (d `plusPtr` 1) ni (B.drop 1 m) where m' = if B.length m < blockSize ctx then m `B.append` B.replicate (blockSize ctx - B.length m) 0 else B.take (blockSize ctx) m r = cfbDecrypt ctx iv m' out = B.head r ni = IV (B.drop 1 i `B.snoc` B.head m') -} cryptonite-0.23/Crypto/Cipher/Types/GF.hs0000644000000000000000000000323012526636055016462 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Types.GF -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- -- Slow Galois Field arithmetic for generic XTS and GCM implementation -- module Crypto.Cipher.Types.GF ( -- * XTS support xtsGFMul ) where import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArray, withByteArray) import qualified Crypto.Internal.ByteArray as B import Foreign.Storable import Foreign.Ptr import Data.Bits -- | Compute the gfmul with the XTS polynomial -- -- block size need to be 128 bits. -- -- FIXME: add support for big endian. xtsGFMul :: ByteArray ba => ba -> ba xtsGFMul b | len == 16 = B.allocAndFreeze len $ \dst -> withByteArray b $ \src -> do (hi,lo) <- gf <$> peek (castPtr src) <*> peek (castPtr src `plusPtr` 8) poke (castPtr dst) lo poke (castPtr dst `plusPtr` 8) hi | otherwise = error "unsupported block size in GF" where gf :: Word64 -> Word64 -> (Word64, Word64) gf srcLo srcHi = ((if carryLo then (.|. 1) else id) (srcHi `shiftL` 1) ,(if carryHi then xor 0x87 else id) $ (srcLo `shiftL` 1) ) where carryHi = srcHi `testBit` 63 carryLo = srcLo `testBit` 63 len = B.length b {- const uint64_t gf_mask = cpu_to_le64(0x8000000000000000ULL); uint64_t r = ((a->q[1] & gf_mask) ? cpu_to_le64(0x87) : 0); a->q[1] = cpu_to_le64((le64_to_cpu(a->q[1]) << 1) | (a->q[0] & gf_mask ? 1 : 0)); a->q[0] = cpu_to_le64(le64_to_cpu(a->q[0]) << 1) ^ r; -} cryptonite-0.23/Crypto/Cipher/Types/Stream.hs0000644000000000000000000000105212521152601017402 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Types.Stream -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- -- stream cipher basic types -- module Crypto.Cipher.Types.Stream ( StreamCipher(..) ) where import Crypto.Cipher.Types.Base import Crypto.Internal.ByteArray (ByteArray) -- | Symmetric stream cipher class class Cipher cipher => StreamCipher cipher where -- | Combine using the stream cipher streamCombine :: ByteArray ba => cipher -> ba -> (ba, cipher) cryptonite-0.23/Crypto/Cipher/Types/Utils.hs0000644000000000000000000000124312526636147017272 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Types.Utils -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Stable -- Portability : Excellent -- -- basic utility for cipher related stuff -- module Crypto.Cipher.Types.Utils where import Crypto.Internal.ByteArray (ByteArray) import qualified Crypto.Internal.ByteArray as B -- | Chunk some input byte array into @sz byte list of byte array. chunk :: ByteArray b => Int -> b -> [b] chunk sz bs = split bs where split b | B.length b <= sz = [b] | otherwise = let (b1, b2) = B.splitAt sz b in b1 : split b2 cryptonite-0.23/Crypto/Error/Types.hs0000644000000000000000000000725313054050744016046 0ustar0000000000000000-- | -- Module : Crypto.Error.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- Cryptographic Error enumeration and handling -- {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Error.Types ( CryptoError(..) , CryptoFailable(..) , throwCryptoErrorIO , throwCryptoError , onCryptoFailure , eitherCryptoError , maybeCryptoError ) where import qualified Control.Exception as E import Data.Data import Crypto.Internal.Imports -- | Enumeration of all possible errors that can be found in this library data CryptoError = -- symmetric cipher errors CryptoError_KeySizeInvalid | CryptoError_IvSizeInvalid | CryptoError_AEADModeNotSupported -- public key cryptography error | CryptoError_SecretKeySizeInvalid | CryptoError_SecretKeyStructureInvalid | CryptoError_PublicKeySizeInvalid | CryptoError_SharedSecretSizeInvalid -- elliptic cryptography error | CryptoError_EcScalarOutOfBounds | CryptoError_PointSizeInvalid | CryptoError_PointFormatInvalid | CryptoError_PointFormatUnsupported | CryptoError_PointCoordinatesInvalid -- Message authentification error | CryptoError_MacKeyInvalid | CryptoError_AuthenticationTagSizeInvalid -- Prime generation error | CryptoError_PrimeSizeInvalid -- Parameter errors | CryptoError_SaltTooSmall | CryptoError_OutputLengthTooSmall | CryptoError_OutputLengthTooBig deriving (Show,Eq,Enum,Data,Typeable) instance E.Exception CryptoError -- | A simple Either like type to represent a computation that can fail -- -- 2 possibles values are: -- -- * 'CryptoPassed' : The computation succeeded, and contains the result of the computation -- -- * 'CryptoFailed' : The computation failed, and contains the cryptographic error associated -- data CryptoFailable a = CryptoPassed a | CryptoFailed CryptoError deriving (Show) instance Eq a => Eq (CryptoFailable a) where (==) (CryptoPassed a) (CryptoPassed b) = a == b (==) (CryptoFailed e1) (CryptoFailed e2) = e1 == e2 (==) _ _ = False instance Functor CryptoFailable where fmap f (CryptoPassed a) = CryptoPassed (f a) fmap _ (CryptoFailed r) = CryptoFailed r instance Applicative CryptoFailable where pure a = CryptoPassed a (<*>) fm m = fm >>= \p -> m >>= \r2 -> return (p r2) instance Monad CryptoFailable where return a = CryptoPassed a (>>=) m1 m2 = do case m1 of CryptoPassed a -> m2 a CryptoFailed e -> CryptoFailed e -- | Throw an CryptoError as exception on CryptoFailed result, -- otherwise return the computed value throwCryptoErrorIO :: CryptoFailable a -> IO a throwCryptoErrorIO (CryptoFailed e) = E.throwIO e throwCryptoErrorIO (CryptoPassed r) = return r -- | Same as 'throwCryptoErrorIO' but throw the error asynchronously. throwCryptoError :: CryptoFailable a -> a throwCryptoError (CryptoFailed e) = E.throw e throwCryptoError (CryptoPassed r) = r -- | Simple 'either' like combinator for CryptoFailable type onCryptoFailure :: (CryptoError -> r) -> (a -> r) -> CryptoFailable a -> r onCryptoFailure onError _ (CryptoFailed e) = onError e onCryptoFailure _ onSuccess (CryptoPassed r) = onSuccess r -- | Transform a CryptoFailable to an Either eitherCryptoError :: CryptoFailable a -> Either CryptoError a eitherCryptoError (CryptoFailed e) = Left e eitherCryptoError (CryptoPassed a) = Right a -- | Transform a CryptoFailable to a Maybe maybeCryptoError :: CryptoFailable a -> Maybe a maybeCryptoError (CryptoFailed _) = Nothing maybeCryptoError (CryptoPassed r) = Just r cryptonite-0.23/Crypto/Number/Compat.hs0000644000000000000000000001122412673727640016331 0ustar0000000000000000-- | -- Module : Crypto.Number.Compat -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE UnboxedTuples #-} module Crypto.Number.Compat ( GmpSupported(..) , onGmpUnsupported , gmpGcde , gmpLog2 , gmpPowModSecInteger , gmpPowModInteger , gmpInverse , gmpNextPrime , gmpTestPrimeMillerRabin , gmpSizeInBytes , gmpSizeInBits , gmpExportInteger , gmpImportInteger ) where #ifndef MIN_VERSION_integer_gmp #define MIN_VERSION_integer_gmp(a,b,c) 0 #endif #if MIN_VERSION_integer_gmp(0,5,1) import GHC.Integer.GMP.Internals import GHC.Base import GHC.Integer.Logarithms (integerLog2#) #endif import Data.Word import GHC.Ptr (Ptr(..)) -- | GMP Supported / Unsupported data GmpSupported a = GmpSupported a | GmpUnsupported deriving (Show,Eq) -- | Simple combinator in case the operation is not supported through GMP onGmpUnsupported :: GmpSupported a -> a -> a onGmpUnsupported (GmpSupported a) _ = a onGmpUnsupported GmpUnsupported f = f -- | Compute the GCDE of a two integer through GMP gmpGcde :: Integer -> Integer -> GmpSupported (Integer, Integer, Integer) #if MIN_VERSION_integer_gmp(0,5,1) gmpGcde a b = GmpSupported (s, t, g) where (# g, s #) = gcdExtInteger a b t = (g - s * a) `div` b #else gmpGcde _ _ = GmpUnsupported #endif -- | Compute the binary logarithm of an integer through GMP gmpLog2 :: Integer -> GmpSupported Int #if MIN_VERSION_integer_gmp(0,5,1) gmpLog2 0 = GmpSupported 0 gmpLog2 x = GmpSupported (I# (integerLog2# x)) #else gmpLog2 _ = GmpUnsupported #endif -- | Compute the power modulus using extra security to remain constant -- time wise through GMP gmpPowModSecInteger :: Integer -> Integer -> Integer -> GmpSupported Integer #if MIN_VERSION_integer_gmp(1,0,0) gmpPowModSecInteger _ _ _ = GmpUnsupported #elif MIN_VERSION_integer_gmp(0,5,1) gmpPowModSecInteger b e m = GmpSupported (powModSecInteger b e m) #else gmpPowModSecInteger _ _ _ = GmpUnsupported #endif -- | Compute the power modulus through GMP gmpPowModInteger :: Integer -> Integer -> Integer -> GmpSupported Integer #if MIN_VERSION_integer_gmp(0,5,1) gmpPowModInteger b e m = GmpSupported (powModInteger b e m) #else gmpPowModInteger _ _ _ = GmpUnsupported #endif -- | Inverse modulus of a number through GMP gmpInverse :: Integer -> Integer -> GmpSupported (Maybe Integer) #if MIN_VERSION_integer_gmp(0,5,1) gmpInverse g m | r == 0 = GmpSupported Nothing | otherwise = GmpSupported (Just r) where r = recipModInteger g m #else gmpInverse _ _ = GmpUnsupported #endif -- | Get the next prime from a specific value through GMP gmpNextPrime :: Integer -> GmpSupported Integer #if MIN_VERSION_integer_gmp(0,5,1) gmpNextPrime n = GmpSupported (nextPrimeInteger n) #else gmpNextPrime _ = GmpUnsupported #endif -- | Test if a number is prime using Miller Rabin gmpTestPrimeMillerRabin :: Int -> Integer -> GmpSupported Bool #if MIN_VERSION_integer_gmp(0,5,1) gmpTestPrimeMillerRabin (I# tries) !n = GmpSupported $ case testPrimeInteger n tries of 0# -> False _ -> True #else gmpTestPrimeMillerRabin _ _ = GmpUnsupported #endif -- | Return the size in bytes of an integer gmpSizeInBytes :: Integer -> GmpSupported Int #if MIN_VERSION_integer_gmp(0,5,1) gmpSizeInBytes n = GmpSupported (I# (word2Int# (sizeInBaseInteger n 256#))) #else gmpSizeInBytes _ = GmpUnsupported #endif -- | Return the size in bits of an integer gmpSizeInBits :: Integer -> GmpSupported Int #if MIN_VERSION_integer_gmp(0,5,1) gmpSizeInBits n = GmpSupported (I# (word2Int# (sizeInBaseInteger n 2#))) #else gmpSizeInBits _ = GmpUnsupported #endif -- | Export an integer to a memory gmpExportInteger :: Integer -> Ptr Word8 -> GmpSupported (IO ()) #if MIN_VERSION_integer_gmp(1,0,0) gmpExportInteger n (Ptr addr) = GmpSupported $ do _ <- exportIntegerToAddr n addr 1# return () #elif MIN_VERSION_integer_gmp(0,5,1) gmpExportInteger n (Ptr addr) = GmpSupported $ IO $ \s -> case exportIntegerToAddr n addr 1# s of (# s2, _ #) -> (# s2, () #) #else gmpExportInteger _ _ = GmpUnsupported #endif -- | Import an integer from a memory gmpImportInteger :: Int -> Ptr Word8 -> GmpSupported (IO Integer) #if MIN_VERSION_integer_gmp(1,0,0) gmpImportInteger (I# n) (Ptr addr) = GmpSupported $ importIntegerFromAddr addr (int2Word# n) 1# #elif MIN_VERSION_integer_gmp(0,5,1) gmpImportInteger (I# n) (Ptr addr) = GmpSupported $ IO $ \s -> importIntegerFromAddr addr (int2Word# n) 1# s #else gmpImportInteger _ _ = GmpUnsupported #endif cryptonite-0.23/Crypto/Hash/Types.hs0000644000000000000000000000416413077673501015645 0ustar0000000000000000-- | -- Module : Crypto.Hash.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Crypto hash types definitions -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Hash.Types ( HashAlgorithm(..) , Context(..) , Digest(..) ) where import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess, Bytes) import qualified Crypto.Internal.ByteArray as B import Foreign.Ptr (Ptr) import qualified Foundation.Array as F import qualified Foundation as F -- | Class representing hashing algorithms. -- -- The interface presented here is update in place -- and lowlevel. the Hash module takes care of -- hidding the mutable interface properly. class HashAlgorithm a where -- | Get the block size of a hash algorithm hashBlockSize :: a -> Int -- | Get the digest size of a hash algorithm hashDigestSize :: a -> Int -- | Get the size of the context used for a hash algorithm hashInternalContextSize :: a -> Int --hashAlgorithmFromProxy :: Proxy a -> a -- | Initialize a context pointer to the initial state of a hash algorithm hashInternalInit :: Ptr (Context a) -> IO () -- | Update the context with some raw data hashInternalUpdate :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () -- | Finalize the context and set the digest raw memory to the right value hashInternalFinalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () {- hashContextGetAlgorithm :: HashAlgorithm a => Context a -> a hashContextGetAlgorithm = undefined -} -- | Represent a context for a given hash algorithm. newtype Context a = Context Bytes deriving (ByteArrayAccess,NFData) -- | Represent a digest for a given hash algorithm. newtype Digest a = Digest (F.UArray Word8) deriving (Eq,Ord,ByteArrayAccess) instance NFData (Digest a) where rnf (Digest u) = u `F.deepseq` () instance Show (Digest a) where show (Digest bs) = map (toEnum . fromIntegral) $ B.unpack (B.convertToBase B.Base16 bs :: Bytes) cryptonite-0.23/Crypto/Hash/Blake2s.hs0000644000000000000000000000434313050705562016015 0ustar0000000000000000-- | -- Module : Crypto.Hash.Blake2s -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Blake2s cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Blake2s ( Blake2s_160 (..), Blake2s_224 (..), Blake2s_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Blake2s (160 bits) cryptographic hash algorithm data Blake2s_160 = Blake2s_160 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2s_160 where hashBlockSize _ = 64 hashDigestSize _ = 20 hashInternalContextSize _ = 185 hashInternalInit p = c_blake2s_init p 160 hashInternalUpdate = c_blake2s_update hashInternalFinalize p = c_blake2s_finalize p 160 -- | Blake2s (224 bits) cryptographic hash algorithm data Blake2s_224 = Blake2s_224 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2s_224 where hashBlockSize _ = 64 hashDigestSize _ = 28 hashInternalContextSize _ = 185 hashInternalInit p = c_blake2s_init p 224 hashInternalUpdate = c_blake2s_update hashInternalFinalize p = c_blake2s_finalize p 224 -- | Blake2s (256 bits) cryptographic hash algorithm data Blake2s_256 = Blake2s_256 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2s_256 where hashBlockSize _ = 64 hashDigestSize _ = 32 hashInternalContextSize _ = 185 hashInternalInit p = c_blake2s_init p 256 hashInternalUpdate = c_blake2s_update hashInternalFinalize p = c_blake2s_finalize p 256 foreign import ccall unsafe "cryptonite_blake2s_init" c_blake2s_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2s_update" c_blake2s_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2s_finalize" c_blake2s_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Blake2sp.hs0000644000000000000000000000350213050705560016167 0ustar0000000000000000-- | -- Module : Crypto.Hash.Blake2sp -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Blake2sp cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Blake2sp ( Blake2sp_224 (..), Blake2sp_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Blake2sp (224 bits) cryptographic hash algorithm data Blake2sp_224 = Blake2sp_224 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2sp_224 where hashBlockSize _ = 64 hashDigestSize _ = 28 hashInternalContextSize _ = 2185 hashInternalInit p = c_blake2sp_init p 224 hashInternalUpdate = c_blake2sp_update hashInternalFinalize p = c_blake2sp_finalize p 224 -- | Blake2sp (256 bits) cryptographic hash algorithm data Blake2sp_256 = Blake2sp_256 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2sp_256 where hashBlockSize _ = 64 hashDigestSize _ = 32 hashInternalContextSize _ = 2185 hashInternalInit p = c_blake2sp_init p 256 hashInternalUpdate = c_blake2sp_update hashInternalFinalize p = c_blake2sp_finalize p 256 foreign import ccall unsafe "cryptonite_blake2sp_init" c_blake2sp_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2sp_update" c_blake2sp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2sp_finalize" c_blake2sp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Blake2b.hs0000644000000000000000000000614013050705562015771 0ustar0000000000000000-- | -- Module : Crypto.Hash.Blake2b -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Blake2b cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Blake2b ( Blake2b_160 (..), Blake2b_224 (..), Blake2b_256 (..), Blake2b_384 (..), Blake2b_512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Blake2b (160 bits) cryptographic hash algorithm data Blake2b_160 = Blake2b_160 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2b_160 where hashBlockSize _ = 128 hashDigestSize _ = 20 hashInternalContextSize _ = 361 hashInternalInit p = c_blake2b_init p 160 hashInternalUpdate = c_blake2b_update hashInternalFinalize p = c_blake2b_finalize p 160 -- | Blake2b (224 bits) cryptographic hash algorithm data Blake2b_224 = Blake2b_224 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2b_224 where hashBlockSize _ = 128 hashDigestSize _ = 28 hashInternalContextSize _ = 361 hashInternalInit p = c_blake2b_init p 224 hashInternalUpdate = c_blake2b_update hashInternalFinalize p = c_blake2b_finalize p 224 -- | Blake2b (256 bits) cryptographic hash algorithm data Blake2b_256 = Blake2b_256 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2b_256 where hashBlockSize _ = 128 hashDigestSize _ = 32 hashInternalContextSize _ = 361 hashInternalInit p = c_blake2b_init p 256 hashInternalUpdate = c_blake2b_update hashInternalFinalize p = c_blake2b_finalize p 256 -- | Blake2b (384 bits) cryptographic hash algorithm data Blake2b_384 = Blake2b_384 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2b_384 where hashBlockSize _ = 128 hashDigestSize _ = 48 hashInternalContextSize _ = 361 hashInternalInit p = c_blake2b_init p 384 hashInternalUpdate = c_blake2b_update hashInternalFinalize p = c_blake2b_finalize p 384 -- | Blake2b (512 bits) cryptographic hash algorithm data Blake2b_512 = Blake2b_512 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2b_512 where hashBlockSize _ = 128 hashDigestSize _ = 64 hashInternalContextSize _ = 361 hashInternalInit p = c_blake2b_init p 512 hashInternalUpdate = c_blake2b_update hashInternalFinalize p = c_blake2b_finalize p 512 foreign import ccall unsafe "cryptonite_blake2b_init" c_blake2b_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2b_update" c_blake2b_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2b_finalize" c_blake2b_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Blake2bp.hs0000644000000000000000000000257613050705560016160 0ustar0000000000000000-- | -- Module : Crypto.Hash.Blake2bp -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Blake2bp cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Blake2bp ( Blake2bp_512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Blake2bp (512 bits) cryptographic hash algorithm data Blake2bp_512 = Blake2bp_512 deriving (Show,Data,Typeable) instance HashAlgorithm Blake2bp_512 where hashBlockSize _ = 128 hashDigestSize _ = 64 hashInternalContextSize _ = 2325 hashInternalInit p = c_blake2sp_init p 512 hashInternalUpdate = c_blake2sp_update hashInternalFinalize p = c_blake2sp_finalize p 512 foreign import ccall unsafe "cryptonite_blake2sp_init" c_blake2sp_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2sp_update" c_blake2sp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2sp_finalize" c_blake2sp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/SHA1.hs0000644000000000000000000000236013050705560015221 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA1 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA1 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.SHA1 ( SHA1 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | SHA1 cryptographic hash algorithm data SHA1 = SHA1 deriving (Show,Data,Typeable) instance HashAlgorithm SHA1 where hashBlockSize _ = 64 hashDigestSize _ = 20 hashInternalContextSize _ = 96 hashInternalInit = c_sha1_init hashInternalUpdate = c_sha1_update hashInternalFinalize = c_sha1_finalize foreign import ccall unsafe "cryptonite_sha1_init" c_sha1_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_sha1_update" c_sha1_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha1_finalize" c_sha1_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/SHA224.hs0000644000000000000000000000242313050705560015370 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA224 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA224 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.SHA224 ( SHA224 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | SHA224 cryptographic hash algorithm data SHA224 = SHA224 deriving (Show,Data,Typeable) instance HashAlgorithm SHA224 where hashBlockSize _ = 64 hashDigestSize _ = 28 hashInternalContextSize _ = 192 hashInternalInit = c_sha224_init hashInternalUpdate = c_sha224_update hashInternalFinalize = c_sha224_finalize foreign import ccall unsafe "cryptonite_sha224_init" c_sha224_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_sha224_update" c_sha224_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha224_finalize" c_sha224_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/SHA256.hs0000644000000000000000000000242313050705560015375 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA256 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA256 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.SHA256 ( SHA256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | SHA256 cryptographic hash algorithm data SHA256 = SHA256 deriving (Show,Data,Typeable) instance HashAlgorithm SHA256 where hashBlockSize _ = 64 hashDigestSize _ = 32 hashInternalContextSize _ = 192 hashInternalInit = c_sha256_init hashInternalUpdate = c_sha256_update hashInternalFinalize = c_sha256_finalize foreign import ccall unsafe "cryptonite_sha256_init" c_sha256_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_sha256_update" c_sha256_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha256_finalize" c_sha256_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/SHA384.hs0000644000000000000000000000242413050705560015400 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA384 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA384 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.SHA384 ( SHA384 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | SHA384 cryptographic hash algorithm data SHA384 = SHA384 deriving (Show,Data,Typeable) instance HashAlgorithm SHA384 where hashBlockSize _ = 128 hashDigestSize _ = 48 hashInternalContextSize _ = 256 hashInternalInit = c_sha384_init hashInternalUpdate = c_sha384_update hashInternalFinalize = c_sha384_finalize foreign import ccall unsafe "cryptonite_sha384_init" c_sha384_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_sha384_update" c_sha384_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha384_finalize" c_sha384_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/SHA512.hs0000644000000000000000000000242413050705560015371 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA512 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA512 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.SHA512 ( SHA512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | SHA512 cryptographic hash algorithm data SHA512 = SHA512 deriving (Show,Data,Typeable) instance HashAlgorithm SHA512 where hashBlockSize _ = 128 hashDigestSize _ = 64 hashInternalContextSize _ = 256 hashInternalInit = c_sha512_init hashInternalUpdate = c_sha512_update hashInternalFinalize = c_sha512_finalize foreign import ccall unsafe "cryptonite_sha512_init" c_sha512_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_sha512_update" c_sha512_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha512_finalize" c_sha512_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/SHA512t.hs0000644000000000000000000000345113050705560015556 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA512t -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA512t cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.SHA512t ( SHA512t_224 (..), SHA512t_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | SHA512t (224 bits) cryptographic hash algorithm data SHA512t_224 = SHA512t_224 deriving (Show,Data,Typeable) instance HashAlgorithm SHA512t_224 where hashBlockSize _ = 128 hashDigestSize _ = 28 hashInternalContextSize _ = 256 hashInternalInit p = c_sha512t_init p 224 hashInternalUpdate = c_sha512t_update hashInternalFinalize p = c_sha512t_finalize p 224 -- | SHA512t (256 bits) cryptographic hash algorithm data SHA512t_256 = SHA512t_256 deriving (Show,Data,Typeable) instance HashAlgorithm SHA512t_256 where hashBlockSize _ = 128 hashDigestSize _ = 32 hashInternalContextSize _ = 256 hashInternalInit p = c_sha512t_init p 256 hashInternalUpdate = c_sha512t_update hashInternalFinalize p = c_sha512t_finalize p 256 foreign import ccall unsafe "cryptonite_sha512t_init" c_sha512t_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_sha512t_update" c_sha512t_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha512t_finalize" c_sha512t_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/SHA3.hs0000644000000000000000000000504513052512546015230 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHA3 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA3 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.SHA3 ( SHA3_224 (..), SHA3_256 (..), SHA3_384 (..), SHA3_512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | SHA3 (224 bits) cryptographic hash algorithm data SHA3_224 = SHA3_224 deriving (Show,Data,Typeable) instance HashAlgorithm SHA3_224 where hashBlockSize _ = 144 hashDigestSize _ = 28 hashInternalContextSize _ = 352 hashInternalInit p = c_sha3_init p 224 hashInternalUpdate = c_sha3_update hashInternalFinalize p = c_sha3_finalize p 224 -- | SHA3 (256 bits) cryptographic hash algorithm data SHA3_256 = SHA3_256 deriving (Show,Data,Typeable) instance HashAlgorithm SHA3_256 where hashBlockSize _ = 136 hashDigestSize _ = 32 hashInternalContextSize _ = 344 hashInternalInit p = c_sha3_init p 256 hashInternalUpdate = c_sha3_update hashInternalFinalize p = c_sha3_finalize p 256 -- | SHA3 (384 bits) cryptographic hash algorithm data SHA3_384 = SHA3_384 deriving (Show,Data,Typeable) instance HashAlgorithm SHA3_384 where hashBlockSize _ = 104 hashDigestSize _ = 48 hashInternalContextSize _ = 312 hashInternalInit p = c_sha3_init p 384 hashInternalUpdate = c_sha3_update hashInternalFinalize p = c_sha3_finalize p 384 -- | SHA3 (512 bits) cryptographic hash algorithm data SHA3_512 = SHA3_512 deriving (Show,Data,Typeable) instance HashAlgorithm SHA3_512 where hashBlockSize _ = 72 hashDigestSize _ = 64 hashInternalContextSize _ = 280 hashInternalInit p = c_sha3_init p 512 hashInternalUpdate = c_sha3_update hashInternalFinalize p = c_sha3_finalize p 512 foreign import ccall unsafe "cryptonite_sha3_init" c_sha3_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_sha3_update" c_sha3_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha3_finalize" c_sha3_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Keccak.hs0000644000000000000000000000517113050705560015711 0ustar0000000000000000-- | -- Module : Crypto.Hash.Keccak -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Keccak cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Keccak ( Keccak_224 (..), Keccak_256 (..), Keccak_384 (..), Keccak_512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Keccak (224 bits) cryptographic hash algorithm data Keccak_224 = Keccak_224 deriving (Show,Data,Typeable) instance HashAlgorithm Keccak_224 where hashBlockSize _ = 144 hashDigestSize _ = 28 hashInternalContextSize _ = 352 hashInternalInit p = c_keccak_init p 224 hashInternalUpdate = c_keccak_update hashInternalFinalize p = c_keccak_finalize p 224 -- | Keccak (256 bits) cryptographic hash algorithm data Keccak_256 = Keccak_256 deriving (Show,Data,Typeable) instance HashAlgorithm Keccak_256 where hashBlockSize _ = 136 hashDigestSize _ = 32 hashInternalContextSize _ = 344 hashInternalInit p = c_keccak_init p 256 hashInternalUpdate = c_keccak_update hashInternalFinalize p = c_keccak_finalize p 256 -- | Keccak (384 bits) cryptographic hash algorithm data Keccak_384 = Keccak_384 deriving (Show,Data,Typeable) instance HashAlgorithm Keccak_384 where hashBlockSize _ = 104 hashDigestSize _ = 48 hashInternalContextSize _ = 312 hashInternalInit p = c_keccak_init p 384 hashInternalUpdate = c_keccak_update hashInternalFinalize p = c_keccak_finalize p 384 -- | Keccak (512 bits) cryptographic hash algorithm data Keccak_512 = Keccak_512 deriving (Show,Data,Typeable) instance HashAlgorithm Keccak_512 where hashBlockSize _ = 72 hashDigestSize _ = 64 hashInternalContextSize _ = 280 hashInternalInit p = c_keccak_init p 512 hashInternalUpdate = c_keccak_update hashInternalFinalize p = c_keccak_finalize p 512 foreign import ccall unsafe "cryptonite_keccak_init" c_keccak_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_keccak_update" c_keccak_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_keccak_finalize" c_keccak_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/MD2.hs0000644000000000000000000000233713050705560015113 0ustar0000000000000000-- | -- Module : Crypto.Hash.MD2 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- MD2 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.MD2 ( MD2 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | MD2 cryptographic hash algorithm data MD2 = MD2 deriving (Show,Data,Typeable) instance HashAlgorithm MD2 where hashBlockSize _ = 16 hashDigestSize _ = 16 hashInternalContextSize _ = 96 hashInternalInit = c_md2_init hashInternalUpdate = c_md2_update hashInternalFinalize = c_md2_finalize foreign import ccall unsafe "cryptonite_md2_init" c_md2_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_md2_update" c_md2_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_md2_finalize" c_md2_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/MD4.hs0000644000000000000000000000233713050705560015115 0ustar0000000000000000-- | -- Module : Crypto.Hash.MD4 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- MD4 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.MD4 ( MD4 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | MD4 cryptographic hash algorithm data MD4 = MD4 deriving (Show,Data,Typeable) instance HashAlgorithm MD4 where hashBlockSize _ = 64 hashDigestSize _ = 16 hashInternalContextSize _ = 96 hashInternalInit = c_md4_init hashInternalUpdate = c_md4_update hashInternalFinalize = c_md4_finalize foreign import ccall unsafe "cryptonite_md4_init" c_md4_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_md4_update" c_md4_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_md4_finalize" c_md4_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/MD5.hs0000644000000000000000000000233713050705560015116 0ustar0000000000000000-- | -- Module : Crypto.Hash.MD5 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- MD5 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.MD5 ( MD5 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | MD5 cryptographic hash algorithm data MD5 = MD5 deriving (Show,Data,Typeable) instance HashAlgorithm MD5 where hashBlockSize _ = 64 hashDigestSize _ = 16 hashInternalContextSize _ = 96 hashInternalInit = c_md5_init hashInternalUpdate = c_md5_update hashInternalFinalize = c_md5_finalize foreign import ccall unsafe "cryptonite_md5_init" c_md5_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_md5_update" c_md5_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_md5_finalize" c_md5_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/RIPEMD160.hs0000644000000000000000000000250613050705560015736 0ustar0000000000000000-- | -- Module : Crypto.Hash.RIPEMD160 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- RIPEMD160 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.RIPEMD160 ( RIPEMD160 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | RIPEMD160 cryptographic hash algorithm data RIPEMD160 = RIPEMD160 deriving (Show,Data,Typeable) instance HashAlgorithm RIPEMD160 where hashBlockSize _ = 64 hashDigestSize _ = 20 hashInternalContextSize _ = 128 hashInternalInit = c_ripemd160_init hashInternalUpdate = c_ripemd160_update hashInternalFinalize = c_ripemd160_finalize foreign import ccall unsafe "cryptonite_ripemd160_init" c_ripemd160_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_ripemd160_update" c_ripemd160_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_ripemd160_finalize" c_ripemd160_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Skein256.hs0000644000000000000000000000347613050705560016044 0ustar0000000000000000-- | -- Module : Crypto.Hash.Skein256 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Skein256 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Skein256 ( Skein256_224 (..), Skein256_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Skein256 (224 bits) cryptographic hash algorithm data Skein256_224 = Skein256_224 deriving (Show,Data,Typeable) instance HashAlgorithm Skein256_224 where hashBlockSize _ = 32 hashDigestSize _ = 28 hashInternalContextSize _ = 96 hashInternalInit p = c_skein256_init p 224 hashInternalUpdate = c_skein256_update hashInternalFinalize p = c_skein256_finalize p 224 -- | Skein256 (256 bits) cryptographic hash algorithm data Skein256_256 = Skein256_256 deriving (Show,Data,Typeable) instance HashAlgorithm Skein256_256 where hashBlockSize _ = 32 hashDigestSize _ = 32 hashInternalContextSize _ = 96 hashInternalInit p = c_skein256_init p 256 hashInternalUpdate = c_skein256_update hashInternalFinalize p = c_skein256_finalize p 256 foreign import ccall unsafe "cryptonite_skein256_init" c_skein256_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_skein256_update" c_skein256_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_skein256_finalize" c_skein256_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Skein512.hs0000644000000000000000000000531013050705560016024 0ustar0000000000000000-- | -- Module : Crypto.Hash.Skein512 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Skein512 cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Skein512 ( Skein512_224 (..), Skein512_256 (..), Skein512_384 (..), Skein512_512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Skein512 (224 bits) cryptographic hash algorithm data Skein512_224 = Skein512_224 deriving (Show,Data,Typeable) instance HashAlgorithm Skein512_224 where hashBlockSize _ = 64 hashDigestSize _ = 28 hashInternalContextSize _ = 160 hashInternalInit p = c_skein512_init p 224 hashInternalUpdate = c_skein512_update hashInternalFinalize p = c_skein512_finalize p 224 -- | Skein512 (256 bits) cryptographic hash algorithm data Skein512_256 = Skein512_256 deriving (Show,Data,Typeable) instance HashAlgorithm Skein512_256 where hashBlockSize _ = 64 hashDigestSize _ = 32 hashInternalContextSize _ = 160 hashInternalInit p = c_skein512_init p 256 hashInternalUpdate = c_skein512_update hashInternalFinalize p = c_skein512_finalize p 256 -- | Skein512 (384 bits) cryptographic hash algorithm data Skein512_384 = Skein512_384 deriving (Show,Data,Typeable) instance HashAlgorithm Skein512_384 where hashBlockSize _ = 64 hashDigestSize _ = 48 hashInternalContextSize _ = 160 hashInternalInit p = c_skein512_init p 384 hashInternalUpdate = c_skein512_update hashInternalFinalize p = c_skein512_finalize p 384 -- | Skein512 (512 bits) cryptographic hash algorithm data Skein512_512 = Skein512_512 deriving (Show,Data,Typeable) instance HashAlgorithm Skein512_512 where hashBlockSize _ = 64 hashDigestSize _ = 64 hashInternalContextSize _ = 160 hashInternalInit p = c_skein512_init p 512 hashInternalUpdate = c_skein512_update hashInternalFinalize p = c_skein512_finalize p 512 foreign import ccall unsafe "cryptonite_skein512_init" c_skein512_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_skein512_update" c_skein512_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_skein512_finalize" c_skein512_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Tiger.hs0000644000000000000000000000240113050705560015573 0ustar0000000000000000-- | -- Module : Crypto.Hash.Tiger -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Tiger cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Tiger ( Tiger (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Tiger cryptographic hash algorithm data Tiger = Tiger deriving (Show,Data,Typeable) instance HashAlgorithm Tiger where hashBlockSize _ = 64 hashDigestSize _ = 24 hashInternalContextSize _ = 96 hashInternalInit = c_tiger_init hashInternalUpdate = c_tiger_update hashInternalFinalize = c_tiger_finalize foreign import ccall unsafe "cryptonite_tiger_init" c_tiger_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_tiger_update" c_tiger_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_tiger_finalize" c_tiger_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Hash/Whirlpool.hs0000644000000000000000000000250613050705560016506 0ustar0000000000000000-- | -- Module : Crypto.Hash.Whirlpool -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Whirlpool cryptographic hash. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} module Crypto.Hash.Whirlpool ( Whirlpool (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) -- | Whirlpool cryptographic hash algorithm data Whirlpool = Whirlpool deriving (Show,Data,Typeable) instance HashAlgorithm Whirlpool where hashBlockSize _ = 64 hashDigestSize _ = 64 hashInternalContextSize _ = 168 hashInternalInit = c_whirlpool_init hashInternalUpdate = c_whirlpool_update hashInternalFinalize = c_whirlpool_finalize foreign import ccall unsafe "cryptonite_whirlpool_init" c_whirlpool_init :: Ptr (Context a)-> IO () foreign import ccall "cryptonite_whirlpool_update" c_whirlpool_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_whirlpool_finalize" c_whirlpool_finalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Random/Entropy/Source.hs0000644000000000000000000000127612516347336020000 0ustar0000000000000000-- | -- Module : Crypto.Random.Entropy.Source -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.Random.Entropy.Source where import Foreign.Ptr import Data.Word (Word8) -- | A handle to an entropy maker, either a system capability -- or a hardware generator. class EntropySource a where -- | try to open an handle for this source entropyOpen :: IO (Maybe a) -- | try to gather a number of entropy bytes into a buffer. -- return the number of actual bytes gathered entropyGather :: a -> Ptr Word8 -> Int -> IO Int -- | Close an open handle entropyClose :: a -> IO () cryptonite-0.23/Crypto/Random/Entropy/Backend.hs0000644000000000000000000000317312541772364020066 0ustar0000000000000000-- | -- Module : Crypto.Random.Entropy.Backend -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- {-# LANGUAGE CPP #-} {-# LANGUAGE ExistentialQuantification #-} module Crypto.Random.Entropy.Backend ( EntropyBackend , supportedBackends , gatherBackend ) where import Foreign.Ptr import Data.Word (Word8) import Crypto.Random.Entropy.Source #ifdef SUPPORT_RDRAND import Crypto.Random.Entropy.RDRand #endif #ifdef WINDOWS import Crypto.Random.Entropy.Windows #else import Crypto.Random.Entropy.Unix #endif -- | All supported backends supportedBackends :: [IO (Maybe EntropyBackend)] supportedBackends = [ #ifdef SUPPORT_RDRAND openBackend (undefined :: RDRand), #endif #ifdef WINDOWS openBackend (undefined :: WinCryptoAPI) #else openBackend (undefined :: DevRandom), openBackend (undefined :: DevURandom) #endif ] -- | Any Entropy Backend data EntropyBackend = forall b . EntropySource b => EntropyBackend b -- | Open a backend handle openBackend :: EntropySource b => b -> IO (Maybe EntropyBackend) openBackend b = fmap EntropyBackend `fmap` callOpen b where callOpen :: EntropySource b => b -> IO (Maybe b) callOpen _ = entropyOpen -- | Gather randomness from an open handle gatherBackend :: EntropyBackend -- ^ An open Entropy Backend -> Ptr Word8 -- ^ Pointer to a buffer to write to -> Int -- ^ number of bytes to write -> IO Int -- ^ return the number of bytes actually written gatherBackend (EntropyBackend backend) ptr n = entropyGather backend ptr n cryptonite-0.23/Crypto/Random/ChaChaDRG.hs0000644000000000000000000000326612527651034016540 0ustar0000000000000000-- | -- Module : Crypto.Random.ChaChaDRG -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : good -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.Random.ChaChaDRG ( ChaChaDRG , initialize , initializeWords ) where import Crypto.Random.Types import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArray, ScrubbedBytes) import qualified Crypto.Internal.ByteArray as B import Foreign.Storable (pokeElemOff) import qualified Crypto.Cipher.ChaCha as C instance DRG ChaChaDRG where randomBytesGenerate = generate -- | ChaCha Deterministic Random Generator newtype ChaChaDRG = ChaChaDRG C.StateSimple deriving (NFData) -- | Initialize a new ChaCha context with the number of rounds, -- the key and the nonce associated. initialize :: ByteArray seed => seed -- ^ 40 bytes of seed -> ChaChaDRG -- ^ the initial ChaCha state initialize seed = ChaChaDRG $ C.initializeSimple seed -- | Initialize a new ChaCha context from 5-tuple of words64. -- This interface is useful when creating a RNG out of tests generators (e.g. QuickCheck). initializeWords :: (Word64, Word64, Word64, Word64, Word64) -> ChaChaDRG initializeWords (a,b,c,d,e) = initialize (B.allocAndFreeze 40 fill :: ScrubbedBytes) where fill s = mapM_ (uncurry (pokeElemOff s)) [(0,a), (1,b), (2,c), (3,d), (4,e)] generate :: ByteArray output => Int -> ChaChaDRG -> (output, ChaChaDRG) generate nbBytes st@(ChaChaDRG prevSt) | nbBytes <= 0 = (B.empty, st) | otherwise = let (output, newSt) = C.generateSimple prevSt nbBytes in (output, ChaChaDRG newSt) cryptonite-0.23/Crypto/Random/SystemDRG.hs0000644000000000000000000000456312541276545016724 0ustar0000000000000000-- | -- Module : Crypto.Random.SystemDRG -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- {-# LANGUAGE BangPatterns #-} module Crypto.Random.SystemDRG ( SystemDRG , getSystemDRG ) where import Crypto.Random.Types import Crypto.Random.Entropy.Unsafe import Crypto.Internal.Compat import Crypto.Internal.Imports import Data.ByteArray (ScrubbedBytes, ByteArray) import Data.Memory.PtrMethods as B (memCopy) import Data.Maybe (catMaybes) import Data.Tuple (swap) import Foreign.Ptr import qualified Data.ByteArray as B import System.IO.Unsafe (unsafeInterleaveIO) -- | A referentially transparent System representation of -- the random evaluated out of the system. -- -- Holding onto a specific DRG means that all the already -- evaluated bytes will be consistently replayed. -- -- There's no need to reseed this DRG, as only pure -- entropy is represented here. data SystemDRG = SystemDRG !Int [ScrubbedBytes] instance DRG SystemDRG where randomBytesGenerate = generate systemChunkSize :: Int systemChunkSize = 256 -- | Grab one instance of the System DRG getSystemDRG :: IO SystemDRG getSystemDRG = do backends <- catMaybes `fmap` sequence supportedBackends let getNext = unsafeInterleaveIO $ do bs <- B.alloc systemChunkSize (replenish systemChunkSize backends) more <- getNext return (bs:more) SystemDRG 0 <$> getNext generate :: ByteArray output => Int -> SystemDRG -> (output, SystemDRG) generate nbBytes (SystemDRG ofs sysChunks) = swap $ unsafeDoIO $ B.allocRet nbBytes $ loop ofs sysChunks nbBytes where loop currentOfs chunks 0 _ = return $! SystemDRG currentOfs chunks loop _ [] _ _ = error "SystemDRG: the impossible happened: empty chunk" loop currentOfs oChunks@(c:cs) n d = do let currentLeft = B.length c - currentOfs toCopy = min n currentLeft nextOfs = currentOfs + toCopy n' = n - toCopy B.withByteArray c $ \src -> B.memCopy d (src `plusPtr` currentOfs) toCopy if nextOfs == B.length c then loop 0 cs n' (d `plusPtr` toCopy) else loop nextOfs oChunks n' (d `plusPtr` toCopy) cryptonite-0.23/Crypto/Random/Probabilistic.hs0000644000000000000000000000156012530065253017651 0ustar0000000000000000-- | -- Module : Crypto.Random.Probabilistic -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.Random.Probabilistic ( probabilistic ) where import Crypto.Internal.Compat import Crypto.Random.Types import Crypto.Random -- | This create a random number generator out of thin air with -- the system entropy; don't generally use as the IO is not exposed -- this can have unexpected random for. -- -- This is useful for probabilistic algorithm like Miller Rabin -- probably prime algorithm, given appropriate choice of the heuristic -- -- Generally, it's advise not to use this function. probabilistic :: MonadPseudoRandom ChaChaDRG a -> a probabilistic f = fst $ withDRG drg f where {-# NOINLINE drg #-} drg = unsafeDoIO drgNew {-# NOINLINE probabilistic #-} cryptonite-0.23/Crypto/PubKey/Internal.hs0000644000000000000000000000101513020303656016606 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Internal -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.PubKey.Internal ( and' , (&&!) ) where import Data.List (foldl') -- | This is a strict version of and and' :: [Bool] -> Bool and' l = foldl' (&&!) True l -- | This is a strict version of &&. (&&!) :: Bool -> Bool -> Bool True &&! True = True True &&! False = False False &&! True = False False &&! False = False cryptonite-0.23/Crypto/PubKey/ElGamal.hs0000644000000000000000000001245212702176335016353 0ustar0000000000000000-- | -- Module : Crypto.PubKey.ElGamal -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- This module is a work in progress. do not use: -- it might eat your dog, your data or even both. -- -- TODO: provide a mapping between integer and ciphertext -- generate numbers correctly -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.PubKey.ElGamal ( Params , PublicNumber , PrivateNumber , EphemeralKey(..) , SharedKey , Signature -- * generation , generatePrivate , generatePublic -- * encryption and decryption with no scheme , encryptWith , encrypt , decrypt -- * signature primitives , signWith , sign -- * verification primitives , verify ) where import Data.Maybe (fromJust) import Crypto.Internal.Imports import Crypto.Internal.ByteArray (ByteArrayAccess) import Crypto.Number.ModArithmetic (expSafe, expFast, inverse) import Crypto.Number.Generate (generateMax) import Crypto.Number.Serialize (os2ip) import Crypto.Number.Basic (gcde) import Crypto.Random.Types import Crypto.PubKey.DH (PrivateNumber(..), PublicNumber(..), Params(..), SharedKey(..)) import Crypto.Hash -- | ElGamal Signature data Signature = Signature (Integer, Integer) -- | ElGamal Ephemeral key. also called Temporary key. newtype EphemeralKey = EphemeralKey Integer deriving (NFData) -- | generate a private number with no specific property -- this number is usually called a and need to be between -- 0 and q (order of the group G). -- generatePrivate :: MonadRandom m => Integer -> m PrivateNumber generatePrivate q = PrivateNumber <$> generateMax q -- | generate an ephemeral key which is a number with no specific property, -- and need to be between 0 and q (order of the group G). -- generateEphemeral :: MonadRandom m => Integer -> m EphemeralKey generateEphemeral q = toEphemeral <$> generatePrivate q where toEphemeral (PrivateNumber n) = EphemeralKey n -- | generate a public number that is for the other party benefits. -- this number is usually called h=g^a generatePublic :: Params -> PrivateNumber -> PublicNumber generatePublic (Params p g _) (PrivateNumber a) = PublicNumber $ expSafe g a p -- | encrypt with a specified ephemeral key -- do not reuse ephemeral key. encryptWith :: EphemeralKey -> Params -> PublicNumber -> Integer -> (Integer,Integer) encryptWith (EphemeralKey b) (Params p g _) (PublicNumber h) m = (c1,c2) where s = expSafe h b p c1 = expSafe g b p c2 = (s * m) `mod` p -- | encrypt a message using params and public keys -- will generate b (called the ephemeral key) encrypt :: MonadRandom m => Params -> PublicNumber -> Integer -> m (Integer,Integer) encrypt params@(Params p _ _) public m = (\b -> encryptWith b params public m) <$> generateEphemeral q where q = p-1 -- p is prime, hence order of the group is p-1 -- | decrypt message decrypt :: Params -> PrivateNumber -> (Integer, Integer) -> Integer decrypt (Params p _ _) (PrivateNumber a) (c1,c2) = (c2 * sm1) `mod` p where s = expSafe c1 a p sm1 = fromJust $ inverse s p -- always inversible in Zp -- | sign a message with an explicit k number -- -- if k is not appropriate, then no signature is returned. -- -- with some appropriate value of k, the signature generation can fail, -- and no signature is returned. User of this function need to retry -- with a different k value. signWith :: (ByteArrayAccess msg, HashAlgorithm hash) => Integer -- ^ random number k, between 0 and p-1 and gcd(k,p-1)=1 -> Params -- ^ DH params (p,g) -> PrivateNumber -- ^ DH private key -> hash -- ^ collision resistant hash algorithm -> msg -- ^ message to sign -> Maybe Signature signWith k (Params p g _) (PrivateNumber x) hashAlg msg | k >= p-1 || d > 1 = Nothing -- gcd(k,p-1) is not 1 | s == 0 = Nothing | otherwise = Just $ Signature (r,s) where r = expSafe g k p h = os2ip $ hashWith hashAlg msg s = ((h - x*r) * kInv) `mod` (p-1) (kInv,_,d) = gcde k (p-1) -- | sign message -- -- This function will generate a random number, however -- as the signature might fail, the function will automatically retry -- until a proper signature has been created. -- sign :: (ByteArrayAccess msg, HashAlgorithm hash, MonadRandom m) => Params -- ^ DH params (p,g) -> PrivateNumber -- ^ DH private key -> hash -- ^ collision resistant hash algorithm -> msg -- ^ message to sign -> m Signature sign params@(Params p _ _) priv hashAlg msg = do k <- generateMax (p-1) case signWith k params priv hashAlg msg of Nothing -> sign params priv hashAlg msg Just sig -> return sig -- | verify a signature verify :: (ByteArrayAccess msg, HashAlgorithm hash) => Params -> PublicNumber -> hash -> msg -> Signature -> Bool verify (Params p g _) (PublicNumber y) hashAlg msg (Signature (r,s)) | or [r <= 0,r >= p,s <= 0,s >= (p-1)] = False | otherwise = lhs == rhs where h = os2ip $ hashWith hashAlg msg lhs = expFast g h p rhs = (expFast y r p * expFast r s p) `mod` p cryptonite-0.23/Crypto/ECC/Simple/Types.hs0000644000000000000000000007033413020740134016570 0ustar0000000000000000{-# LANGUAGE DeriveDataTypeable #-} -- | -- Module : Crypto.ECC.Simple.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : Experimental -- Portability : Excellent -- -- references: -- -- {-# OPTIONS_GHC -fno-warn-missing-signatures #-} module Crypto.ECC.Simple.Types ( Curve(..) , Point(..) , Scalar(..) , CurveType(..) , CurveBinaryParam(..) , CurvePrimeParam(..) , curveSizeBits , curveSizeBytes , CurveParameters(..) -- * specific curves definition , SEC_p112r1(..) , SEC_p112r2(..) , SEC_p128r1(..) , SEC_p128r2(..) , SEC_p160k1(..) , SEC_p160r1(..) , SEC_p160r2(..) , SEC_p192k1(..) , SEC_p192r1(..) -- aka prime192v1 , SEC_p224k1(..) , SEC_p224r1(..) , SEC_p256k1(..) , SEC_p256r1(..) -- aka prime256v1 , SEC_p384r1(..) , SEC_p521r1(..) , SEC_t113r1(..) , SEC_t113r2(..) , SEC_t131r1(..) , SEC_t131r2(..) , SEC_t163k1(..) , SEC_t163r1(..) , SEC_t163r2(..) , SEC_t193r1(..) , SEC_t193r2(..) , SEC_t233k1(..) -- aka NIST K-233 , SEC_t233r1(..) , SEC_t239k1(..) , SEC_t283k1(..) , SEC_t283r1(..) , SEC_t409k1(..) , SEC_t409r1(..) , SEC_t571k1(..) , SEC_t571r1(..) ) where import Data.Data import Crypto.Internal.Imports import Crypto.Number.Basic (numBits) class Curve curve where curveParameters :: proxy curve -> CurveParameters curve curveType :: proxy curve -> CurveType -- | get the size of the curve in bits curveSizeBits :: Curve curve => proxy curve -> Int curveSizeBits proxy = case curveType proxy of CurvePrime (CurvePrimeParam p) -> numBits p CurveBinary (CurveBinaryParam c) -> numBits c - 1 -- | get the size of the curve in bytes curveSizeBytes :: Curve curve => proxy curve -> Int curveSizeBytes proxy = (curveSizeBits proxy + 7) `div` 8 -- | Define common parameters in a curve definition -- of the form: y^2 = x^3 + ax + b. data CurveParameters curve = CurveParameters { curveEccA :: Integer -- ^ curve parameter a , curveEccB :: Integer -- ^ curve parameter b , curveEccG :: Point curve -- ^ base point , curveEccN :: Integer -- ^ order of G , curveEccH :: Integer -- ^ cofactor } deriving (Show,Eq,Data,Typeable) newtype CurveBinaryParam = CurveBinaryParam Integer deriving (Show,Read,Eq,Data,Typeable) newtype CurvePrimeParam = CurvePrimeParam Integer deriving (Show,Read,Eq,Data,Typeable) data CurveType = CurveBinary CurveBinaryParam | CurvePrime CurvePrimeParam deriving (Show,Read,Eq,Data,Typeable) -- | ECC Private Number newtype Scalar curve = Scalar Integer deriving (Show,Read,Eq,Data,Typeable) -- | Define a point on a curve. data Point curve = Point Integer Integer | PointO -- ^ Point at Infinity deriving (Show,Read,Eq,Data,Typeable) instance NFData (Point curve) where rnf (Point x y) = x `seq` y `seq` () rnf PointO = () data SEC_p112r1 = SEC_p112r1 deriving (Show,Read,Eq) data SEC_p112r2 = SEC_p112r2 deriving (Show,Read,Eq) data SEC_p128r1 = SEC_p128r1 deriving (Show,Read,Eq) data SEC_p128r2 = SEC_p128r2 deriving (Show,Read,Eq) data SEC_p160k1 = SEC_p160k1 deriving (Show,Read,Eq) data SEC_p160r1 = SEC_p160r1 deriving (Show,Read,Eq) data SEC_p160r2 = SEC_p160r2 deriving (Show,Read,Eq) data SEC_p192k1 = SEC_p192k1 deriving (Show,Read,Eq) data SEC_p192r1 = SEC_p192r1 deriving (Show,Read,Eq) data SEC_p224k1 = SEC_p224k1 deriving (Show,Read,Eq) data SEC_p224r1 = SEC_p224r1 deriving (Show,Read,Eq) data SEC_p256k1 = SEC_p256k1 deriving (Show,Read,Eq) data SEC_p256r1 = SEC_p256r1 deriving (Show,Read,Eq) data SEC_p384r1 = SEC_p384r1 deriving (Show,Read,Eq) data SEC_p521r1 = SEC_p521r1 deriving (Show,Read,Eq) data SEC_t113r1 = SEC_t113r1 deriving (Show,Read,Eq) data SEC_t113r2 = SEC_t113r2 deriving (Show,Read,Eq) data SEC_t131r1 = SEC_t131r1 deriving (Show,Read,Eq) data SEC_t131r2 = SEC_t131r2 deriving (Show,Read,Eq) data SEC_t163k1 = SEC_t163k1 deriving (Show,Read,Eq) data SEC_t163r1 = SEC_t163r1 deriving (Show,Read,Eq) data SEC_t163r2 = SEC_t163r2 deriving (Show,Read,Eq) data SEC_t193r1 = SEC_t193r1 deriving (Show,Read,Eq) data SEC_t193r2 = SEC_t193r2 deriving (Show,Read,Eq) data SEC_t233k1 = SEC_t233k1 deriving (Show,Read,Eq) data SEC_t233r1 = SEC_t233r1 deriving (Show,Read,Eq) data SEC_t239k1 = SEC_t239k1 deriving (Show,Read,Eq) data SEC_t283k1 = SEC_t283k1 deriving (Show,Read,Eq) data SEC_t283r1 = SEC_t283r1 deriving (Show,Read,Eq) data SEC_t409k1 = SEC_t409k1 deriving (Show,Read,Eq) data SEC_t409r1 = SEC_t409r1 deriving (Show,Read,Eq) data SEC_t571k1 = SEC_t571k1 deriving (Show,Read,Eq) data SEC_t571r1 = SEC_t571r1 deriving (Show,Read,Eq) -- | Define names for known recommended curves. instance Curve SEC_p112r1 where curveType _ = typeSEC_p112r1 curveParameters _ = paramSEC_p112r1 instance Curve SEC_p112r2 where curveType _ = typeSEC_p112r2 curveParameters _ = paramSEC_p112r2 instance Curve SEC_p128r1 where curveType _ = typeSEC_p128r1 curveParameters _ = paramSEC_p128r1 instance Curve SEC_p128r2 where curveType _ = typeSEC_p128r2 curveParameters _ = paramSEC_p128r2 instance Curve SEC_p160k1 where curveType _ = typeSEC_p160k1 curveParameters _ = paramSEC_p160k1 instance Curve SEC_p160r1 where curveType _ = typeSEC_p160r1 curveParameters _ = paramSEC_p160r1 instance Curve SEC_p160r2 where curveType _ = typeSEC_p160r2 curveParameters _ = paramSEC_p160r2 instance Curve SEC_p192k1 where curveType _ = typeSEC_p192k1 curveParameters _ = paramSEC_p192k1 instance Curve SEC_p192r1 where curveType _ = typeSEC_p192r1 curveParameters _ = paramSEC_p192r1 instance Curve SEC_p224k1 where curveType _ = typeSEC_p224k1 curveParameters _ = paramSEC_p224k1 instance Curve SEC_p224r1 where curveType _ = typeSEC_p224r1 curveParameters _ = paramSEC_p224r1 instance Curve SEC_p256k1 where curveType _ = typeSEC_p256k1 curveParameters _ = paramSEC_p256k1 instance Curve SEC_p256r1 where curveType _ = typeSEC_p256r1 curveParameters _ = paramSEC_p256r1 instance Curve SEC_p384r1 where curveType _ = typeSEC_p384r1 curveParameters _ = paramSEC_p384r1 instance Curve SEC_p521r1 where curveType _ = typeSEC_p521r1 curveParameters _ = paramSEC_p521r1 instance Curve SEC_t113r1 where curveType _ = typeSEC_t113r1 curveParameters _ = paramSEC_t113r1 instance Curve SEC_t113r2 where curveType _ = typeSEC_t113r2 curveParameters _ = paramSEC_t113r2 instance Curve SEC_t131r1 where curveType _ = typeSEC_t131r1 curveParameters _ = paramSEC_t131r1 instance Curve SEC_t131r2 where curveType _ = typeSEC_t131r2 curveParameters _ = paramSEC_t131r2 instance Curve SEC_t163k1 where curveType _ = typeSEC_t163k1 curveParameters _ = paramSEC_t163k1 instance Curve SEC_t163r1 where curveType _ = typeSEC_t163r1 curveParameters _ = paramSEC_t163r1 instance Curve SEC_t163r2 where curveType _ = typeSEC_t163r2 curveParameters _ = paramSEC_t163r2 instance Curve SEC_t193r1 where curveType _ = typeSEC_t193r1 curveParameters _ = paramSEC_t193r1 instance Curve SEC_t193r2 where curveType _ = typeSEC_t193r2 curveParameters _ = paramSEC_t193r2 instance Curve SEC_t233k1 where curveType _ = typeSEC_t233k1 curveParameters _ = paramSEC_t233k1 instance Curve SEC_t233r1 where curveType _ = typeSEC_t233r1 curveParameters _ = paramSEC_t233r1 instance Curve SEC_t239k1 where curveType _ = typeSEC_t239k1 curveParameters _ = paramSEC_t239k1 instance Curve SEC_t283k1 where curveType _ = typeSEC_t283k1 curveParameters _ = paramSEC_t283k1 instance Curve SEC_t283r1 where curveType _ = typeSEC_t283r1 curveParameters _ = paramSEC_t283r1 instance Curve SEC_t409k1 where curveType _ = typeSEC_t409k1 curveParameters _ = paramSEC_t409k1 instance Curve SEC_t409r1 where curveType _ = typeSEC_t409r1 curveParameters _ = paramSEC_t409r1 instance Curve SEC_t571k1 where curveType _ = typeSEC_t571k1 curveParameters _ = paramSEC_t571k1 instance Curve SEC_t571r1 where curveType _ = typeSEC_t571r1 curveParameters _ = paramSEC_t571r1 {- curvesOIDs :: [ (CurveName, [Integer]) ] curvesOIDs = [ (SEC_p112r1, [1,3,132,0,6]) , (SEC_p112r2, [1,3,132,0,7]) , (SEC_p128r1, [1,3,132,0,28]) , (SEC_p128r2, [1,3,132,0,29]) , (SEC_p160k1, [1,3,132,0,9]) , (SEC_p160r1, [1,3,132,0,8]) , (SEC_p160r2, [1,3,132,0,30]) , (SEC_p192k1, [1,3,132,0,31]) , (SEC_p192r1, [1,2,840,10045,3,1,1]) , (SEC_p224k1, [1,3,132,0,32]) , (SEC_p224r1, [1,3,132,0,33]) , (SEC_p256k1, [1,3,132,0,10]) , (SEC_p256r1, [1,2,840,10045,3,1,7]) , (SEC_p384r1, [1,3,132,0,34]) , (SEC_p521r1, [1,3,132,0,35]) , (SEC_t113r1, [1,3,132,0,4]) , (SEC_t113r2, [1,3,132,0,5]) , (SEC_t131r1, [1,3,132,0,22]) , (SEC_t131r2, [1,3,132,0,23]) , (SEC_t163k1, [1,3,132,0,1]) , (SEC_t163r1, [1,3,132,0,2]) , (SEC_t163r2, [1,3,132,0,15]) , (SEC_t193r1, [1,3,132,0,24]) , (SEC_t193r2, [1,3,132,0,25]) , (SEC_t233k1, [1,3,132,0,26]) , (SEC_t233r1, [1,3,132,0,27]) , (SEC_t239k1, [1,3,132,0,3]) , (SEC_t283k1, [1,3,132,0,16]) , (SEC_t283r1, [1,3,132,0,17]) , (SEC_t409k1, [1,3,132,0,36]) , (SEC_t409r1, [1,3,132,0,37]) , (SEC_t571k1, [1,3,132,0,38]) , (SEC_t571r1, [1,3,132,0,39]) ] -} typeSEC_p112r1 = CurvePrime $ CurvePrimeParam 0xdb7c2abf62e35e668076bead208b paramSEC_p112r1 = CurveParameters { curveEccA = 0xdb7c2abf62e35e668076bead2088 , curveEccB = 0x659ef8ba043916eede8911702b22 , curveEccG = Point 0x09487239995a5ee76b55f9c2f098 0xa89ce5af8724c0a23e0e0ff77500 , curveEccN = 0xdb7c2abf62e35e7628dfac6561c5 , curveEccH = 1 } typeSEC_p112r2 = CurvePrime $ CurvePrimeParam 0xdb7c2abf62e35e668076bead208b paramSEC_p112r2 = CurveParameters { curveEccA = 0x6127c24c05f38a0aaaf65c0ef02c , curveEccB = 0x51def1815db5ed74fcc34c85d709 , curveEccG = Point 0x4ba30ab5e892b4e1649dd0928643 0xadcd46f5882e3747def36e956e97 , curveEccN = 0x36df0aafd8b8d7597ca10520d04b , curveEccH = 4 } typeSEC_p128r1 = CurvePrime $ CurvePrimeParam 0xfffffffdffffffffffffffffffffffff paramSEC_p128r1 = CurveParameters { curveEccA = 0xfffffffdfffffffffffffffffffffffc , curveEccB = 0xe87579c11079f43dd824993c2cee5ed3 , curveEccG = Point 0x161ff7528b899b2d0c28607ca52c5b86 0xcf5ac8395bafeb13c02da292dded7a83 , curveEccN = 0xfffffffe0000000075a30d1b9038a115 , curveEccH = 1 } typeSEC_p128r2 = CurvePrime $ CurvePrimeParam 0xfffffffdffffffffffffffffffffffff paramSEC_p128r2 = CurveParameters { curveEccA = 0xd6031998d1b3bbfebf59cc9bbff9aee1 , curveEccB = 0x5eeefca380d02919dc2c6558bb6d8a5d , curveEccG = Point 0x7b6aa5d85e572983e6fb32a7cdebc140 0x27b6916a894d3aee7106fe805fc34b44 , curveEccN = 0x3fffffff7fffffffbe0024720613b5a3 , curveEccH = 4 } typeSEC_p160k1 = CurvePrime $ CurvePrimeParam 0x00fffffffffffffffffffffffffffffffeffffac73 paramSEC_p160k1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000 , curveEccB = 0x000000000000000000000000000000000000000007 , curveEccG = Point 0x003b4c382ce37aa192a4019e763036f4f5dd4d7ebb 0x00938cf935318fdced6bc28286531733c3f03c4fee , curveEccN = 0x0100000000000000000001b8fa16dfab9aca16b6b3 , curveEccH = 1 } typeSEC_p160r1 = CurvePrime $ CurvePrimeParam 0x00ffffffffffffffffffffffffffffffff7fffffff paramSEC_p160r1 = CurveParameters { curveEccA = 0x00ffffffffffffffffffffffffffffffff7ffffffc , curveEccB = 0x001c97befc54bd7a8b65acf89f81d4d4adc565fa45 , curveEccG = Point 0x004a96b5688ef573284664698968c38bb913cbfc82 0x0023a628553168947d59dcc912042351377ac5fb32 , curveEccN = 0x0100000000000000000001f4c8f927aed3ca752257 , curveEccH = 1 } typeSEC_p160r2 = CurvePrime $ CurvePrimeParam 0x00fffffffffffffffffffffffffffffffeffffac73 paramSEC_p160r2 = CurveParameters { curveEccA = 0x00fffffffffffffffffffffffffffffffeffffac70 , curveEccB = 0x00b4e134d3fb59eb8bab57274904664d5af50388ba , curveEccG = Point 0x0052dcb034293a117e1f4ff11b30f7199d3144ce6d 0x00feaffef2e331f296e071fa0df9982cfea7d43f2e , curveEccN = 0x0100000000000000000000351ee786a818f3a1a16b , curveEccH = 1 } typeSEC_p192k1 = CurvePrime $ CurvePrimeParam 0xfffffffffffffffffffffffffffffffffffffffeffffee37 paramSEC_p192k1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000 , curveEccB = 0x000000000000000000000000000000000000000000000003 , curveEccG = Point 0xdb4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7d 0x9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9d , curveEccN = 0xfffffffffffffffffffffffe26f2fc170f69466a74defd8d , curveEccH = 1 } typeSEC_p192r1 = CurvePrime $ CurvePrimeParam 0xfffffffffffffffffffffffffffffffeffffffffffffffff paramSEC_p192r1 = CurveParameters { curveEccA = 0xfffffffffffffffffffffffffffffffefffffffffffffffc , curveEccB = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1 , curveEccG = Point 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811 , curveEccN = 0xffffffffffffffffffffffff99def836146bc9b1b4d22831 , curveEccH = 1 } typeSEC_p224k1 = CurvePrime $ CurvePrimeParam 0x00fffffffffffffffffffffffffffffffffffffffffffffffeffffe56d paramSEC_p224k1 = CurveParameters { curveEccA = 0x0000000000000000000000000000000000000000000000000000000000 , curveEccB = 0x0000000000000000000000000000000000000000000000000000000005 , curveEccG = Point 0x00a1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45c 0x007e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5 , curveEccN = 0x010000000000000000000000000001dce8d2ec6184caf0a971769fb1f7 , curveEccH = 1 } typeSEC_p224r1 = CurvePrime $ CurvePrimeParam 0xffffffffffffffffffffffffffffffff000000000000000000000001 paramSEC_p224r1 = CurveParameters { curveEccA = 0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe , curveEccB = 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4 , curveEccG = Point 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34 , curveEccN = 0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d , curveEccH = 1 } typeSEC_p256k1 = CurvePrime $ CurvePrimeParam 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f paramSEC_p256k1 = CurveParameters { curveEccA = 0x0000000000000000000000000000000000000000000000000000000000000000 , curveEccB = 0x0000000000000000000000000000000000000000000000000000000000000007 , curveEccG = Point 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 , curveEccN = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 , curveEccH = 1 } typeSEC_p256r1 = CurvePrime $ CurvePrimeParam 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff paramSEC_p256r1 = CurveParameters { curveEccA = 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc , curveEccB = 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b , curveEccG = Point 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5 , curveEccN = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 , curveEccH = 1 } typeSEC_p384r1 = CurvePrime $ CurvePrimeParam 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff paramSEC_p384r1 = CurveParameters { curveEccA = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc , curveEccB = 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef , curveEccG = Point 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f , curveEccN = 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973 , curveEccH = 1 } typeSEC_p521r1 = CurvePrime $ CurvePrimeParam 0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff paramSEC_p521r1 = CurveParameters { curveEccA = 0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc , curveEccB = 0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00 , curveEccG = Point 0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66 0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650 , curveEccN = 0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409 , curveEccH = 1 } typeSEC_t113r1 = CurveBinary $ CurveBinaryParam 0x020000000000000000000000000201 paramSEC_t113r1 = CurveParameters { curveEccA = 0x003088250ca6e7c7fe649ce85820f7 , curveEccB = 0x00e8bee4d3e2260744188be0e9c723 , curveEccG = Point 0x009d73616f35f4ab1407d73562c10f 0x00a52830277958ee84d1315ed31886 , curveEccN = 0x0100000000000000d9ccec8a39e56f , curveEccH = 2 } typeSEC_t113r2 = CurveBinary $ CurveBinaryParam 0x020000000000000000000000000201 paramSEC_t113r2 = CurveParameters { curveEccA = 0x00689918dbec7e5a0dd6dfc0aa55c7 , curveEccB = 0x0095e9a9ec9b297bd4bf36e059184f , curveEccG = Point 0x01a57a6a7b26ca5ef52fcdb8164797 0x00b3adc94ed1fe674c06e695baba1d , curveEccN = 0x010000000000000108789b2496af93 , curveEccH = 2 } typeSEC_t131r1 = CurveBinary $ CurveBinaryParam 0x080000000000000000000000000000010d paramSEC_t131r1 = CurveParameters { curveEccA = 0x07a11b09a76b562144418ff3ff8c2570b8 , curveEccB = 0x0217c05610884b63b9c6c7291678f9d341 , curveEccG = Point 0x0081baf91fdf9833c40f9c181343638399 0x078c6e7ea38c001f73c8134b1b4ef9e150 , curveEccN = 0x0400000000000000023123953a9464b54d , curveEccH = 2 } typeSEC_t131r2 = CurveBinary $ CurveBinaryParam 0x080000000000000000000000000000010d paramSEC_t131r2 = CurveParameters { curveEccA = 0x03e5a88919d7cafcbf415f07c2176573b2 , curveEccB = 0x04b8266a46c55657ac734ce38f018f2192 , curveEccG = Point 0x0356dcd8f2f95031ad652d23951bb366a8 0x0648f06d867940a5366d9e265de9eb240f , curveEccN = 0x0400000000000000016954a233049ba98f , curveEccH = 2 } typeSEC_t163k1 = CurveBinary $ CurveBinaryParam 0x0800000000000000000000000000000000000000c9 paramSEC_t163k1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000001 , curveEccB = 0x000000000000000000000000000000000000000001 , curveEccG = Point 0x02fe13c0537bbc11acaa07d793de4e6d5e5c94eee8 0x0289070fb05d38ff58321f2e800536d538ccdaa3d9 , curveEccN = 0x04000000000000000000020108a2e0cc0d99f8a5ef , curveEccH = 2 } typeSEC_t163r1 = CurveBinary $ CurveBinaryParam 0x0800000000000000000000000000000000000000c9 paramSEC_t163r1 = CurveParameters { curveEccA = 0x07b6882caaefa84f9554ff8428bd88e246d2782ae2 , curveEccB = 0x0713612dcddcb40aab946bda29ca91f73af958afd9 , curveEccG = Point 0x0369979697ab43897789566789567f787a7876a654 0x00435edb42efafb2989d51fefce3c80988f41ff883 , curveEccN = 0x03ffffffffffffffffffff48aab689c29ca710279b , curveEccH = 2 } typeSEC_t163r2 = CurveBinary $ CurveBinaryParam 0x0800000000000000000000000000000000000000c9 paramSEC_t163r2 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000001 , curveEccB = 0x020a601907b8c953ca1481eb10512f78744a3205fd , curveEccG = Point 0x03f0eba16286a2d57ea0991168d4994637e8343e36 0x00d51fbc6c71a0094fa2cdd545b11c5c0c797324f1 , curveEccN = 0x040000000000000000000292fe77e70c12a4234c33 , curveEccH = 2 } typeSEC_t193r1 = CurveBinary $ CurveBinaryParam 0x02000000000000000000000000000000000000000000008001 paramSEC_t193r1 = CurveParameters { curveEccA = 0x0017858feb7a98975169e171f77b4087de098ac8a911df7b01 , curveEccB = 0x00fdfb49bfe6c3a89facadaa7a1e5bbc7cc1c2e5d831478814 , curveEccG = Point 0x01f481bc5f0ff84a74ad6cdf6fdef4bf6179625372d8c0c5e1 0x0025e399f2903712ccf3ea9e3a1ad17fb0b3201b6af7ce1b05 , curveEccN = 0x01000000000000000000000000c7f34a778f443acc920eba49 , curveEccH = 2 } typeSEC_t193r2 = CurveBinary $ CurveBinaryParam 0x02000000000000000000000000000000000000000000008001 paramSEC_t193r2 = CurveParameters { curveEccA = 0x0163f35a5137c2ce3ea6ed8667190b0bc43ecd69977702709b , curveEccB = 0x00c9bb9e8927d4d64c377e2ab2856a5b16e3efb7f61d4316ae , curveEccG = Point 0x00d9b67d192e0367c803f39e1a7e82ca14a651350aae617e8f 0x01ce94335607c304ac29e7defbd9ca01f596f927224cdecf6c , curveEccN = 0x010000000000000000000000015aab561b005413ccd4ee99d5 , curveEccH = 2 } typeSEC_t233k1 = CurveBinary $ CurveBinaryParam 0x020000000000000000000000000000000000000004000000000000000001 paramSEC_t233k1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000000000000000 , curveEccB = 0x000000000000000000000000000000000000000000000000000000000001 , curveEccG = Point 0x017232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126 0x01db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3 , curveEccN = 0x008000000000000000000000000000069d5bb915bcd46efb1ad5f173abdf , curveEccH = 4 } typeSEC_t233r1 = CurveBinary $ CurveBinaryParam 0x020000000000000000000000000000000000000004000000000000000001 paramSEC_t233r1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000000000000001 , curveEccB = 0x0066647ede6c332c7f8c0923bb58213b333b20e9ce4281fe115f7d8f90ad , curveEccG = Point 0x00fac9dfcbac8313bb2139f1bb755fef65bc391f8b36f8f8eb7371fd558b 0x01006a08a41903350678e58528bebf8a0beff867a7ca36716f7e01f81052 , curveEccN = 0x01000000000000000000000000000013e974e72f8a6922031d2603cfe0d7 , curveEccH = 2 } typeSEC_t239k1 = CurveBinary $ CurveBinaryParam 0x800000000000000000004000000000000000000000000000000000000001 paramSEC_t239k1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000000000000000 , curveEccB = 0x000000000000000000000000000000000000000000000000000000000001 , curveEccG = Point 0x29a0b6a887a983e9730988a68727a8b2d126c44cc2cc7b2a6555193035dc 0x76310804f12e549bdb011c103089e73510acb275fc312a5dc6b76553f0ca , curveEccN = 0x2000000000000000000000000000005a79fec67cb6e91f1c1da800e478a5 , curveEccH = 4 } typeSEC_t283k1 = CurveBinary $ CurveBinaryParam 0x0800000000000000000000000000000000000000000000000000000000000000000010a1 paramSEC_t283k1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000000000000000000000000000 , curveEccB = 0x000000000000000000000000000000000000000000000000000000000000000000000001 , curveEccG = Point 0x0503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836 0x01ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259 , curveEccN = 0x01ffffffffffffffffffffffffffffffffffe9ae2ed07577265dff7f94451e061e163c61 , curveEccH = 4 } typeSEC_t283r1 = CurveBinary $ CurveBinaryParam 0x0800000000000000000000000000000000000000000000000000000000000000000010a1 paramSEC_t283r1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000000000000000000000000001 , curveEccB = 0x027b680ac8b8596da5a4af8a19a0303fca97fd7645309fa2a581485af6263e313b79a2f5 , curveEccG = Point 0x05f939258db7dd90e1934f8c70b0dfec2eed25b8557eac9c80e2e198f8cdbecd86b12053 0x03676854fe24141cb98fe6d4b20d02b4516ff702350eddb0826779c813f0df45be8112f4 , curveEccN = 0x03ffffffffffffffffffffffffffffffffffef90399660fc938a90165b042a7cefadb307 , curveEccH = 2 } typeSEC_t409k1 = CurveBinary $ CurveBinaryParam 0x02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001 paramSEC_t409k1 = CurveParameters { curveEccA = 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 , curveEccB = 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , curveEccG = Point 0x0060f05f658f49c1ad3ab1890f7184210efd0987e307c84c27accfb8f9f67cc2c460189eb5aaaa62ee222eb1b35540cfe9023746 0x01e369050b7c4e42acba1dacbf04299c3460782f918ea427e6325165e9ea10e3da5f6c42e9c55215aa9ca27a5863ec48d8e0286b , curveEccN = 0x007ffffffffffffffffffffffffffffffffffffffffffffffffffe5f83b2d4ea20400ec4557d5ed3e3e7ca5b4b5c83b8e01e5fcf , curveEccH = 4 } typeSEC_t409r1 = CurveBinary $ CurveBinaryParam 0x02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001 paramSEC_t409r1 = CurveParameters { curveEccA = 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , curveEccB = 0x0021a5c2c8ee9feb5c4b9a753b7b476b7fd6422ef1f3dd674761fa99d6ac27c8a9a197b272822f6cd57a55aa4f50ae317b13545f , curveEccG = Point 0x015d4860d088ddb3496b0c6064756260441cde4af1771d4db01ffe5b34e59703dc255a868a1180515603aeab60794e54bb7996a7 0x0061b1cfab6be5f32bbfa78324ed106a7636b9c5a7bd198d0158aa4f5488d08f38514f1fdf4b4f40d2181b3681c364ba0273c706 , curveEccN = 0x010000000000000000000000000000000000000000000000000001e2aad6a612f33307be5fa47c3c9e052f838164cd37d9a21173 , curveEccH = 2 } typeSEC_t571k1 = CurveBinary $ CurveBinaryParam 0x080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425 paramSEC_t571k1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 , curveEccB = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , curveEccG = Point 0x026eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972 0x0349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3 , curveEccN = 0x020000000000000000000000000000000000000000000000000000000000000000000000131850e1f19a63e4b391a8db917f4138b630d84be5d639381e91deb45cfe778f637c1001 , curveEccH = 4 } typeSEC_t571r1 = CurveBinary $ CurveBinaryParam 0x080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425 paramSEC_t571r1 = CurveParameters { curveEccA = 0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001 , curveEccB = 0x02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a , curveEccG = Point 0x0303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19 0x037bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b , curveEccN = 0x03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47 , curveEccH = 2 } cryptonite-0.23/Crypto/ECC/Simple/Prim.hs0000644000000000000000000001635013020740134016371 0ustar0000000000000000-- | Elliptic Curve Arithmetic. -- -- /WARNING:/ These functions are vulnerable to timing attacks. {-# LANGUAGE ScopedTypeVariables #-} module Crypto.ECC.Simple.Prim ( scalarGenerate , scalarFromInteger , pointAdd , pointDouble , pointBaseMul , pointMul , pointAddTwoMuls , pointFromIntegers , isPointAtInfinity , isPointValid ) where import Data.Maybe import Crypto.Internal.Imports import Crypto.Internal.Proxy import Crypto.Number.ModArithmetic import Crypto.Number.F2m import Crypto.Number.Generate (generateBetween) import Crypto.ECC.Simple.Types import Crypto.Error import Crypto.Random -- | Generate a valid scalar for a specific Curve scalarGenerate :: forall randomly curve . (MonadRandom randomly, Curve curve) => randomly (Scalar curve) scalarGenerate = Scalar <$> generateBetween 1 (n - 1) where n = curveEccN $ curveParameters (Proxy :: Proxy curve) scalarFromInteger :: forall curve . Curve curve => Integer -> CryptoFailable (Scalar curve) scalarFromInteger n | n < 0 || n >= mx = CryptoFailed $ CryptoError_EcScalarOutOfBounds | otherwise = CryptoPassed $ Scalar n where mx = case curveType (Proxy :: Proxy curve) of CurveBinary (CurveBinaryParam b) -> b CurvePrime (CurvePrimeParam p) -> p --TODO: Extract helper function for `fromMaybe PointO...` -- | Elliptic Curve point negation: -- @pointNegate p@ returns point @q@ such that @pointAdd p q == PointO@. pointNegate :: Curve curve => Point curve -> Point curve pointNegate PointO = PointO pointNegate point@(Point x y) = case curveType point of CurvePrime {} -> Point x (-y) CurveBinary {} -> Point x (x `addF2m` y) -- | Elliptic Curve point addition. -- -- /WARNING:/ Vulnerable to timing attacks. pointAdd :: Curve curve => Point curve -> Point curve -> Point curve pointAdd PointO PointO = PointO pointAdd PointO q = q pointAdd p PointO = p pointAdd p q | p == q = pointDouble p | p == pointNegate q = PointO pointAdd point@(Point xp yp) (Point xq yq) = case ty of CurvePrime (CurvePrimeParam pr) -> fromMaybe PointO $ do s <- divmod (yp - yq) (xp - xq) pr let xr = (s ^ (2::Int) - xp - xq) `mod` pr yr = (s * (xp - xr) - yp) `mod` pr return $ Point xr yr CurveBinary (CurveBinaryParam fx) -> fromMaybe PointO $ do s <- divF2m fx (yp `addF2m` yq) (xp `addF2m` xq) let xr = mulF2m fx s s `addF2m` s `addF2m` xp `addF2m` xq `addF2m` a yr = mulF2m fx s (xp `addF2m` xr) `addF2m` xr `addF2m` yp return $ Point xr yr where ty = curveType point cc = curveParameters point a = curveEccA cc -- | Elliptic Curve point doubling. -- -- /WARNING:/ Vulnerable to timing attacks. -- -- This perform the following calculation: -- > lambda = (3 * xp ^ 2 + a) / 2 yp -- > xr = lambda ^ 2 - 2 xp -- > yr = lambda (xp - xr) - yp -- -- With binary curve: -- > xp == 0 => P = O -- > otherwise => -- > s = xp + (yp / xp) -- > xr = s ^ 2 + s + a -- > yr = xp ^ 2 + (s+1) * xr -- pointDouble :: Curve curve => Point curve -> Point curve pointDouble PointO = PointO pointDouble point@(Point xp yp) = case ty of CurvePrime (CurvePrimeParam pr) -> fromMaybe PointO $ do lambda <- divmod (3 * xp ^ (2::Int) + a) (2 * yp) pr let xr = (lambda ^ (2::Int) - 2 * xp) `mod` pr yr = (lambda * (xp - xr) - yp) `mod` pr return $ Point xr yr CurveBinary (CurveBinaryParam fx) | xp == 0 -> PointO | otherwise -> fromMaybe PointO $ do s <- return . addF2m xp =<< divF2m fx yp xp let xr = mulF2m fx s s `addF2m` s `addF2m` a yr = mulF2m fx xp xp `addF2m` mulF2m fx xr (s `addF2m` 1) return $ Point xr yr where ty = curveType point cc = curveParameters point a = curveEccA cc -- | Elliptic curve point multiplication using the base -- -- /WARNING:/ Vulnerable to timing attacks. pointBaseMul :: Curve curve => Scalar curve -> Point curve pointBaseMul n = pointMul n (curveEccG $ curveParameters (Proxy :: Proxy curve)) -- | Elliptic curve point multiplication (double and add algorithm). -- -- /WARNING:/ Vulnerable to timing attacks. pointMul :: Curve curve => Scalar curve -> Point curve -> Point curve pointMul _ PointO = PointO pointMul (Scalar n) p | n == 0 = PointO | n == 1 = p | odd n = pointAdd p (pointMul (Scalar (n - 1)) p) | otherwise = pointMul (Scalar (n `div` 2)) (pointDouble p) -- | Elliptic curve double-scalar multiplication (uses Shamir's trick). -- -- > pointAddTwoMuls n1 p1 n2 p2 == pointAdd (pointMul n1 p1) -- > (pointMul n2 p2) -- -- /WARNING:/ Vulnerable to timing attacks. pointAddTwoMuls :: Curve curve => Scalar curve -> Point curve -> Scalar curve -> Point curve -> Point curve pointAddTwoMuls _ PointO _ PointO = PointO pointAddTwoMuls _ PointO n2 p2 = pointMul n2 p2 pointAddTwoMuls n1 p1 _ PointO = pointMul n1 p1 pointAddTwoMuls (Scalar n1) p1 (Scalar n2) p2 = go (n1, n2) where p0 = pointAdd p1 p2 go (0, 0 ) = PointO go (k1, k2) = let q = pointDouble $ go (k1 `div` 2, k2 `div` 2) in case (odd k1, odd k2) of (True , True ) -> pointAdd p0 q (True , False ) -> pointAdd p1 q (False , True ) -> pointAdd p2 q (False , False ) -> q -- | Check if a point is the point at infinity. isPointAtInfinity :: Point curve -> Bool isPointAtInfinity PointO = True isPointAtInfinity _ = False -- | Make a point on a curve from integer (x,y) coordinate -- -- if the point is not valid related to the curve then an error is -- returned instead of a point pointFromIntegers :: forall curve . Curve curve => (Integer, Integer) -> CryptoFailable (Point curve) pointFromIntegers (x,y) | isPointValid (Proxy :: Proxy curve) x y = CryptoPassed $ Point x y | otherwise = CryptoFailed $ CryptoError_PointCoordinatesInvalid -- | check if a point is on specific curve -- -- This perform three checks: -- -- * x is not out of range -- * y is not out of range -- * the equation @y^2 = x^3 + a*x + b (mod p)@ holds isPointValid :: Curve curve => proxy curve -> Integer -> Integer -> Bool isPointValid proxy x y = case ty of CurvePrime (CurvePrimeParam p) -> let a = curveEccA cc b = curveEccB cc eqModP z1 z2 = (z1 `mod` p) == (z2 `mod` p) isValid e = e >= 0 && e < p in isValid x && isValid y && (y ^ (2 :: Int)) `eqModP` (x ^ (3 :: Int) + a * x + b) CurveBinary (CurveBinaryParam fx) -> let a = curveEccA cc b = curveEccB cc add = addF2m mul = mulF2m fx isValid e = modF2m fx e == e in and [ isValid x , isValid y , ((((x `add` a) `mul` x `add` y) `mul` x) `add` b `add` (squareF2m fx y)) == 0 ] where ty = curveType proxy cc = curveParameters proxy -- | div and mod divmod :: Integer -> Integer -> Integer -> Maybe Integer divmod y x m = do i <- inverse (x `mod` m) m return $ y * i `mod` m cryptonite-0.23/Crypto/Internal/Proxy.hs0000644000000000000000000000045613020740134016534 0ustar0000000000000000-- | -- Module : Crypto.Internal.Proxy -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.Internal.Proxy ( Proxy(..) ) where -- | A type witness for 'a' as phantom type data Proxy a = Proxy cryptonite-0.23/Crypto/Internal/ByteArray.hs0000644000000000000000000000074013020025533017310 0ustar0000000000000000-- | -- Module : Crypto.Internal.ByteArray -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- Simple and efficient byte array types -- {-# OPTIONS_HADDOCK hide #-} module Crypto.Internal.ByteArray ( module Data.ByteArray , module Data.ByteArray.Mapping , module Data.ByteArray.Encoding ) where import Data.ByteArray import Data.ByteArray.Mapping import Data.ByteArray.Encoding cryptonite-0.23/Crypto/Internal/Compat.hs0000644000000000000000000000263012517714566016656 0ustar0000000000000000-- | -- Module : Crypto.Internal.Compat -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- This module try to keep all the difference between versions of base -- or other needed packages, so that modules don't need to use CPP -- {-# LANGUAGE CPP #-} module Crypto.Internal.Compat ( unsafeDoIO , popCount , byteSwap64 ) where import System.IO.Unsafe import Data.Word import Data.Bits -- | perform io for hashes that do allocation and ffi. -- unsafeDupablePerformIO is used when possible as the -- computation is pure and the output is directly linked -- to the input. we also do not modify anything after it has -- been returned to the user. unsafeDoIO :: IO a -> a #if __GLASGOW_HASKELL__ > 704 unsafeDoIO = unsafeDupablePerformIO #else unsafeDoIO = unsafePerformIO #endif #if !(MIN_VERSION_base(4,5,0)) popCount :: Word64 -> Int popCount n = loop 0 n where loop c 0 = c loop c i = loop (c + if testBit c 0 then 1 else 0) (i `shiftR` 1) #endif #if !(MIN_VERSION_base(4,7,0)) byteSwap64 :: Word64 -> Word64 byteSwap64 w = (w `shiftR` 56) .|. (w `shiftL` 56) .|. ((w `shiftR` 40) .&. 0xff00) .|. ((w .&. 0xff00) `shiftL` 40) .|. ((w `shiftR` 24) .&. 0xff0000) .|. ((w .&. 0xff0000) `shiftL` 24) .|. ((w `shiftR` 8) .&. 0xff000000) .|. ((w .&. 0xff000000) `shiftL` 8) #endif cryptonite-0.23/Crypto/Internal/CompatPrim.hs0000644000000000000000000000645112570103261017472 0ustar0000000000000000-- | -- Module : Crypto.Internal.CompatPrim -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Compat -- -- This module try to keep all the difference between versions of ghc primitive -- or other needed packages, so that modules don't need to use CPP. -- -- Note that MagicHash and CPP conflicts in places, making it "more interesting" -- to write compat code for primitives -- {-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} module Crypto.Internal.CompatPrim ( be32Prim , le32Prim , byteswap32Prim , booleanPrim , convert4To32 ) where import GHC.Prim #if !defined(ARCH_IS_LITTLE_ENDIAN) && !defined(ARCH_IS_BIG_ENDIAN) import Data.Memory.Endian (getSystemEndianness, Endianness(..)) #endif -- | byteswap Word# to or from Big Endian -- -- on a big endian machine, this function is a nop. be32Prim :: Word# -> Word# #ifdef ARCH_IS_LITTLE_ENDIAN be32Prim = byteswap32Prim #elif defined(ARCH_IS_BIG_ENDIAN) be32Prim = id #else be32Prim w = if getSystemEndianness == LittleEndian then byteswap32Prim w else w #endif -- | byteswap Word# to or from Little Endian -- -- on a little endian machine, this function is a nop. le32Prim :: Word# -> Word# #ifdef ARCH_IS_LITTLE_ENDIAN le32Prim w = w #elif defined(ARCH_IS_BIG_ENDIAN) le32Prim = byteswap32Prim #else le32Prim w = if getSystemEndianness == LittleEndian then w else byteswap32Prim w #endif -- | Simple compatibility for byteswap the lower 32 bits of a Word# -- at the primitive level byteswap32Prim :: Word# -> Word# #if __GLASGOW_HASKELL__ >= 708 byteswap32Prim w = byteSwap32# w #else byteswap32Prim w = let !a = uncheckedShiftL# w 24# !b = and# (uncheckedShiftL# w 8#) 0x00ff0000## !c = and# (uncheckedShiftRL# w 8#) 0x0000ff00## !d = and# (uncheckedShiftRL# w 24#) 0x000000ff## in or# a (or# b (or# c d)) #endif -- | combine 4 word8 [a,b,c,d] to a word32 representing [a,b,c,d] convert4To32 :: Word# -> Word# -> Word# -> Word# -> Word# convert4To32 a b c d = or# (or# c1 c2) (or# c3 c4) where #ifdef ARCH_IS_LITTLE_ENDIAN !c1 = uncheckedShiftL# a 24# !c2 = uncheckedShiftL# b 16# !c3 = uncheckedShiftL# c 8# !c4 = d #elif defined(ARCH_IS_BIG_ENDIAN) !c1 = uncheckedShiftL# d 24# !c2 = uncheckedShiftL# c 16# !c3 = uncheckedShiftL# b 8# !c4 = a #else !c1 | getSystemEndianness == LittleEndian = uncheckedShiftL# a 24# | otherwise = uncheckedShiftL# d 24# !c2 | getSystemEndianness == LittleEndian = uncheckedShiftL# b 16# | otherwise = uncheckedShiftL# c 16# !c3 | getSystemEndianness == LittleEndian = uncheckedShiftL# c 8# | otherwise = uncheckedShiftL# b 8# !c4 | getSystemEndianness == LittleEndian = d | otherwise = a #endif -- | Simple wrapper to handle pre 7.8 and future, where -- most comparaison functions don't returns a boolean -- anymore. #if __GLASGOW_HASKELL__ >= 708 booleanPrim :: Int# -> Bool booleanPrim v = tagToEnum# v #else booleanPrim :: Bool -> Bool booleanPrim b = b #endif cryptonite-0.23/Crypto/Internal/DeepSeq.hs0000644000000000000000000000152113020007525016733 0ustar0000000000000000-- | -- Module : Crypto.Internal.DeepSeq -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Simple abstraction module to allow compilation without deepseq -- by defining our own NFData class if not compiling with deepseq -- support. -- {-# LANGUAGE CPP #-} module Crypto.Internal.DeepSeq ( NFData(..) ) where #ifdef WITH_DEEPSEQ_SUPPORT import Control.DeepSeq #else import Data.Word import Data.ByteArray class NFData a where rnf :: a -> () instance NFData Word8 where rnf w = w `seq` () instance NFData Word16 where rnf w = w `seq` () instance NFData Word32 where rnf w = w `seq` () instance NFData Word64 where rnf w = w `seq` () instance NFData Bytes where rnf b = b `seq` () instance NFData ScrubbedBytes where rnf b = b `seq` () #endif cryptonite-0.23/Crypto/Internal/Imports.hs0000644000000000000000000000071312527645261017064 0ustar0000000000000000-- | -- Module : Crypto.Internal.Imports -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- module Crypto.Internal.Imports ( module X ) where import Data.Word as X import Control.Applicative as X import Control.Monad as X (forM, forM_, void) import Control.Arrow as X (first, second) import Crypto.Internal.DeepSeq as X cryptonite-0.23/Crypto/Internal/Words.hs0000644000000000000000000000124212526642362016521 0ustar0000000000000000-- | -- Module : Crypto.Internal.Words -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Extra Word size -- module Crypto.Internal.Words ( Word128(..) , w64to32 , w32to64 ) where import Data.Word import Data.Bits import Data.Memory.ExtendedWords -- | Split a 'Word64' into the highest and lowest 'Word32' w64to32 :: Word64 -> (Word32, Word32) w64to32 w = (fromIntegral (w `shiftR` 32), fromIntegral w) -- | Reconstruct a 'Word64' from two 'Word32' w32to64 :: (Word32, Word32) -> Word64 w32to64 (x1, x2) = ((fromIntegral x1) `shiftL` 32) .|. (fromIntegral x2) cryptonite-0.23/Crypto/Internal/WordArray.hs0000644000000000000000000001236312526642214017337 0ustar0000000000000000-- | -- Module : Crypto.Internal.Compat -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- Small and self contained array representation -- with limited safety for internal use. -- -- the array produced should never be exposed to the user directly -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE UnboxedTuples #-} module Crypto.Internal.WordArray ( Array8 , Array32 , Array64 , MutableArray32 , array8 , array32 , mutableArray32 , array64 , arrayRead8 , arrayRead32 , arrayRead64 , mutableArrayRead32 , mutableArrayWrite32 , mutableArrayWriteXor32 , mutableArray32FromAddrBE , mutableArray32Freeze ) where import Data.Word import Data.Bits (xor) import Crypto.Internal.Compat import Crypto.Internal.CompatPrim import GHC.Prim import GHC.Types import GHC.Word -- | Array of Word8 data Array8 = Array8 Addr# -- | Array of Word32 data Array32 = Array32 ByteArray# -- | Array of Word64 data Array64 = Array64 ByteArray# -- | Array of mutable Word32 data MutableArray32 = MutableArray32 (MutableByteArray# RealWorld) -- | Create an array of Word8 aliasing an Addr# array8 :: Addr# -> Array8 array8 = Array8 -- | Create an Array of Word32 of specific size from a list of Word32 array32 :: Int -> [Word32] -> Array32 array32 (I# n) l = unsafeDoIO $ IO $ \s -> case newAlignedPinnedByteArray# (n *# 4#) 4# s of (# s', mbarr #) -> loop 0# s' mbarr l where loop _ st mb [] = freezeArray mb st loop i st mb ((W32# x):xs) | booleanPrim (i ==# n) = freezeArray mb st | otherwise = let !st' = writeWord32Array# mb i x st in loop (i +# 1#) st' mb xs freezeArray mb st = case unsafeFreezeByteArray# mb st of (# st', b #) -> (# st', Array32 b #) {-# NOINLINE array32 #-} -- | Create an Array of Word64 of specific size from a list of Word64 array64 :: Int -> [Word64] -> Array64 array64 (I# n) l = unsafeDoIO $ IO $ \s -> case newAlignedPinnedByteArray# (n *# 8#) 8# s of (# s', mbarr #) -> loop 0# s' mbarr l where loop _ st mb [] = freezeArray mb st loop i st mb ((W64# x):xs) | booleanPrim (i ==# n) = freezeArray mb st | otherwise = let !st' = writeWord64Array# mb i x st in loop (i +# 1#) st' mb xs freezeArray mb st = case unsafeFreezeByteArray# mb st of (# st', b #) -> (# st', Array64 b #) {-# NOINLINE array64 #-} -- | Create a Mutable Array of Word32 of specific size from a list of Word32 mutableArray32 :: Int -> [Word32] -> IO MutableArray32 mutableArray32 (I# n) l = IO $ \s -> case newAlignedPinnedByteArray# (n *# 4#) 4# s of (# s', mbarr #) -> loop 0# s' mbarr l where loop _ st mb [] = (# st, MutableArray32 mb #) loop i st mb ((W32# x):xs) | booleanPrim (i ==# n) = (# st, MutableArray32 mb #) | otherwise = let !st' = writeWord32Array# mb i x st in loop (i +# 1#) st' mb xs -- | Create a Mutable Array of BE Word32 aliasing an Addr mutableArray32FromAddrBE :: Int -> Addr# -> IO MutableArray32 mutableArray32FromAddrBE (I# n) a = IO $ \s -> case newAlignedPinnedByteArray# (n *# 4#) 4# s of (# s', mbarr #) -> loop 0# s' mbarr where loop i st mb | booleanPrim (i ==# n) = (# st, MutableArray32 mb #) | otherwise = let !st' = writeWord32Array# mb i (be32Prim (indexWord32OffAddr# a i)) st in loop (i +# 1#) st' mb -- | freeze a Mutable Array of Word32 into a immutable Array of Word32 mutableArray32Freeze :: MutableArray32 -> IO Array32 mutableArray32Freeze (MutableArray32 mb) = IO $ \st -> case unsafeFreezeByteArray# mb st of (# st', b #) -> (# st', Array32 b #) -- | Read a Word8 from an Array arrayRead8 :: Array8 -> Int -> Word8 arrayRead8 (Array8 a) (I# o) = W8# (indexWord8OffAddr# a o) {-# INLINE arrayRead8 #-} -- | Read a Word32 from an Array arrayRead32 :: Array32 -> Int -> Word32 arrayRead32 (Array32 b) (I# o) = W32# (indexWord32Array# b o) {-# INLINE arrayRead32 #-} -- | Read a Word64 from an Array arrayRead64 :: Array64 -> Int -> Word64 arrayRead64 (Array64 b) (I# o) = W64# (indexWord64Array# b o) {-# INLINE arrayRead64 #-} -- | Read a Word32 from a Mutable Array of Word32 mutableArrayRead32 :: MutableArray32 -> Int -> IO Word32 mutableArrayRead32 (MutableArray32 m) (I# o) = IO $ \s -> case readWord32Array# m o s of (# s', e #) -> (# s', W32# e #) {-# INLINE mutableArrayRead32 #-} -- | Write a Word32 from a Mutable Array of Word32 mutableArrayWrite32 :: MutableArray32 -> Int -> Word32 -> IO () mutableArrayWrite32 (MutableArray32 m) (I# o) (W32# w) = IO $ \s -> let !s' = writeWord32Array# m o w s in (# s', () #) {-# INLINE mutableArrayWrite32 #-} -- | Write into the Mutable Array of Word32 by combining through xor the current value and the new value. -- -- > x[i] = x[i] xor value mutableArrayWriteXor32 :: MutableArray32 -> Int -> Word32 -> IO () mutableArrayWriteXor32 m o w = mutableArrayRead32 m o >>= \wOld -> mutableArrayWrite32 m o (wOld `xor` w) {-# INLINE mutableArrayWriteXor32 #-} cryptonite-0.23/Crypto/Hash/SHAKE.hs0000644000000000000000000000643413063753164015375 0ustar0000000000000000-- | -- Module : Crypto.Hash.SHAKE -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- SHA3 extendable output functions (SHAKE). -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module Crypto.Hash.SHAKE ( SHAKE128 (..), SHAKE256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Typeable import Data.Word (Word8, Word32) import Data.Proxy (Proxy(..)) import GHC.TypeLits (Nat, KnownNat, natVal) import Crypto.Internal.Nat -- | SHAKE128 (128 bits) extendable output function. Supports an arbitrary -- digest size (multiple of 8 bits), to be specified as a type parameter -- of kind 'Nat'. -- -- Note: outputs from @'SHAKE128' n@ and @'SHAKE128' m@ for the same input are -- correlated (one being a prefix of the other). Results are unrelated to -- 'SHAKE256' results. data SHAKE128 (bitlen :: Nat) = SHAKE128 deriving (Show, Typeable) instance (IsDivisibleBy8 bitLen, KnownNat bitLen) => HashAlgorithm (SHAKE128 bitLen) where hashBlockSize _ = 168 hashDigestSize _ = byteLen (Proxy :: Proxy bitLen) hashInternalContextSize _ = 376 hashInternalInit p = c_sha3_init p 128 hashInternalUpdate = c_sha3_update hashInternalFinalize = shakeFinalizeOutput (Proxy :: Proxy bitLen) -- | SHAKE256 (256 bits) extendable output function. Supports an arbitrary -- digest size (multiple of 8 bits), to be specified as a type parameter -- of kind 'Nat'. -- -- Note: outputs from @'SHAKE256' n@ and @'SHAKE256' m@ for the same input are -- correlated (one being a prefix of the other). Results are unrelated to -- 'SHAKE128' results. data SHAKE256 (bitlen :: Nat) = SHAKE256 deriving (Show, Typeable) instance (IsDivisibleBy8 bitLen, KnownNat bitLen) => HashAlgorithm (SHAKE256 bitLen) where hashBlockSize _ = 136 hashDigestSize _ = byteLen (Proxy :: Proxy bitLen) hashInternalContextSize _ = 344 hashInternalInit p = c_sha3_init p 256 hashInternalUpdate = c_sha3_update hashInternalFinalize = shakeFinalizeOutput (Proxy :: Proxy bitLen) shakeFinalizeOutput :: (IsDivisibleBy8 bitLen, KnownNat bitLen) => proxy bitLen -> Ptr (Context a) -> Ptr (Digest a) -> IO () shakeFinalizeOutput d ctx dig = do c_sha3_finalize_shake ctx c_sha3_output ctx dig (byteLen d) foreign import ccall unsafe "cryptonite_sha3_init" c_sha3_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_sha3_update" c_sha3_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_sha3_finalize_shake" c_sha3_finalize_shake :: Ptr (Context a) -> IO () foreign import ccall unsafe "cryptonite_sha3_output" c_sha3_output :: Ptr (Context a) -> Ptr (Digest a) -> Word32 -> IO () cryptonite-0.23/Crypto/Hash/Blake2.hs0000644000000000000000000001356013063753164015640 0ustar0000000000000000-- | -- Module : Crypto.Hash.Blake2 -- License : BSD-style -- Maintainer : Nicolas Di Prima -- Stability : experimental -- Portability : unknown -- -- module containing the binding functions to work with the -- Blake2 -- -- Implementation based from [RFC7693](https://tools.ietf.org/html/rfc7693) -- -- Please consider the following when chosing a hash: -- -- Algorithm | Target | Collision | Digest Size | -- Identifier | Arch | Security | in bytes | -- ---------------+--------+-----------+-------------+ -- id-blake2b160 | 64-bit | 2**80 | 20 | -- id-blake2b256 | 64-bit | 2**128 | 32 | -- id-blake2b384 | 64-bit | 2**192 | 48 | -- id-blake2b512 | 64-bit | 2**256 | 64 | -- ---------------+--------+-----------+-------------+ -- id-blake2s128 | 32-bit | 2**64 | 16 | -- id-blake2s160 | 32-bit | 2**80 | 20 | -- id-blake2s224 | 32-bit | 2**112 | 28 | -- id-blake2s256 | 32-bit | 2**128 | 32 | -- ---------------+--------+-----------+-------------+ -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Blake2 ( Blake2s(..) , Blake2sp(..) , Blake2b(..) , Blake2bp(..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Typeable import Data.Word (Word8, Word32) import GHC.TypeLits (Nat, KnownNat, natVal) import Crypto.Internal.Nat -- | Fast and secure alternative to SHA1 and HMAC-SHA1 -- -- It is espacially known to target 32bits architectures. -- -- known supported digest sizes: -- -- * Blake2s 160 -- * Blake2s 224 -- * Blake2s 256 -- data Blake2s (bitlen :: Nat) = Blake2s deriving (Show, Typeable) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256) => HashAlgorithm (Blake2s bitlen) where hashBlockSize _ = 64 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) hashInternalContextSize _ = 185 hashInternalInit p = c_blake2s_init p (integralNatVal (Proxy :: Proxy bitlen)) hashInternalUpdate = c_blake2s_update hashInternalFinalize p = c_blake2s_finalize p (integralNatVal (Proxy :: Proxy bitlen)) foreign import ccall unsafe "cryptonite_blake2s_init" c_blake2s_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2s_update" c_blake2s_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2s_finalize" c_blake2s_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () -- | Fast cryptographic hash. -- -- It is especially known to target 64bits architectures. -- -- Known supported digest sizes: -- -- * Blake2b 160 -- * Blake2b 224 -- * Blake2b 256 -- * Blake2b 384 -- * Blake2b 512 -- data Blake2b (bitlen :: Nat) = Blake2b deriving (Show, Typeable) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512) => HashAlgorithm (Blake2b bitlen) where hashBlockSize _ = 128 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) hashInternalContextSize _ = 361 hashInternalInit p = c_blake2b_init p (integralNatVal (Proxy :: Proxy bitlen)) hashInternalUpdate = c_blake2b_update hashInternalFinalize p = c_blake2b_finalize p (integralNatVal (Proxy :: Proxy bitlen)) foreign import ccall unsafe "cryptonite_blake2b_init" c_blake2b_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2b_update" c_blake2b_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2b_finalize" c_blake2b_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () data Blake2sp (bitlen :: Nat) = Blake2sp deriving (Show, Typeable) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256) => HashAlgorithm (Blake2sp bitlen) where hashBlockSize _ = 64 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) hashInternalContextSize _ = 2185 hashInternalInit p = c_blake2sp_init p (integralNatVal (Proxy :: Proxy bitlen)) hashInternalUpdate = c_blake2sp_update hashInternalFinalize p = c_blake2sp_finalize p (integralNatVal (Proxy :: Proxy bitlen)) foreign import ccall unsafe "cryptonite_blake2sp_init" c_blake2sp_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2sp_update" c_blake2sp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2sp_finalize" c_blake2sp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () data Blake2bp (bitlen :: Nat) = Blake2bp deriving (Show, Typeable) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512) => HashAlgorithm (Blake2bp bitlen) where hashBlockSize _ = 128 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) hashInternalContextSize _ = 2325 hashInternalInit p = c_blake2bp_init p (integralNatVal (Proxy :: Proxy bitlen)) hashInternalUpdate = c_blake2bp_update hashInternalFinalize p = c_blake2bp_finalize p (integralNatVal (Proxy :: Proxy bitlen)) foreign import ccall unsafe "cryptonite_blake2bp_init" c_blake2bp_init :: Ptr (Context a) -> Word32 -> IO () foreign import ccall "cryptonite_blake2bp_update" c_blake2bp_update :: Ptr (Context a) -> Ptr Word8 -> Word32 -> IO () foreign import ccall unsafe "cryptonite_blake2bp_finalize" c_blake2bp_finalize :: Ptr (Context a) -> Word32 -> Ptr (Digest a) -> IO () cryptonite-0.23/Crypto/Internal/Nat.hs0000644000000000000000000000760613063753164016157 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module Crypto.Internal.Nat ( type IsDivisibleBy8 , type IsAtMost, type IsAtLeast , byteLen , integralNatVal ) where import GHC.TypeLits byteLen :: (KnownNat bitlen, IsDivisibleBy8 bitlen, Num a) => proxy bitlen -> a byteLen d = fromInteger (natVal d `div` 8) integralNatVal :: (KnownNat bitlen, Num a) => proxy bitlen -> a integralNatVal = fromInteger . natVal type family IsLE (bitlen :: Nat) (n :: Nat) (c :: Bool) where IsLE bitlen n 'True = 'True #if MIN_VERSION_base(4,9,0) IsLE bitlen n 'False = TypeError ( ('Text "bitlen " ':<>: 'ShowType bitlen ':<>: 'Text " is greater than " ':<>: 'ShowType n) ':$$: ('Text "You have tried to use an invalid Digest size. Please, refer to the documentation.") ) #else IsLE bitlen n 'False = 'False #endif -- | ensure the given `bitlen` is lesser or equal to `n` -- type IsAtMost (bitlen :: Nat) (n :: Nat) = IsLE bitlen n (bitlen <=? n) ~ 'True type family IsGE (bitlen :: Nat) (n :: Nat) (c :: Bool) where IsGE bitlen n 'True = 'True #if MIN_VERSION_base(4,9,0) IsGE bitlen n 'False = TypeError ( ('Text "bitlen " ':<>: 'ShowType bitlen ':<>: 'Text " is lesser than " ':<>: 'ShowType n) ':$$: ('Text "You have tried to use an invalid Digest size. Please, refer to the documentation.") ) #else IsGE bitlen n 'False = 'False #endif -- | ensure the given `bitlen` is greater or equal to `n` -- type IsAtLeast (bitlen :: Nat) (n :: Nat) = IsGE bitlen n (n <=? bitlen) ~ 'True type family IsDiv8 (bitLen :: Nat) (n :: Nat) where IsDiv8 bitLen 0 = 'True #if MIN_VERSION_base(4,9,0) IsDiv8 bitLen 1 = TypeError ('Text "bitLen " ':<>: 'ShowType bitLen ':<>: 'Text " is not divisible by 8") IsDiv8 bitLen 2 = TypeError ('Text "bitLen " ':<>: 'ShowType bitLen ':<>: 'Text " is not divisible by 8") IsDiv8 bitLen 3 = TypeError ('Text "bitLen " ':<>: 'ShowType bitLen ':<>: 'Text " is not divisible by 8") IsDiv8 bitLen 4 = TypeError ('Text "bitLen " ':<>: 'ShowType bitLen ':<>: 'Text " is not divisible by 8") IsDiv8 bitLen 5 = TypeError ('Text "bitLen " ':<>: 'ShowType bitLen ':<>: 'Text " is not divisible by 8") IsDiv8 bitLen 6 = TypeError ('Text "bitLen " ':<>: 'ShowType bitLen ':<>: 'Text " is not divisible by 8") IsDiv8 bitLen 7 = TypeError ('Text "bitLen " ':<>: 'ShowType bitLen ':<>: 'Text " is not divisible by 8") #else IsDiv8 bitLen 1 = 'False IsDiv8 bitLen 2 = 'False IsDiv8 bitLen 3 = 'False IsDiv8 bitLen 4 = 'False IsDiv8 bitLen 5 = 'False IsDiv8 bitLen 6 = 'False IsDiv8 bitLen 7 = 'False #endif IsDiv8 bitLen n = IsDiv8 n (Mod8 n) type family Mod8 (n :: Nat) where Mod8 0 = 0 Mod8 1 = 1 Mod8 2 = 2 Mod8 3 = 3 Mod8 4 = 4 Mod8 5 = 5 Mod8 6 = 6 Mod8 7 = 7 Mod8 8 = 0 Mod8 9 = 1 Mod8 10 = 2 Mod8 11 = 3 Mod8 12 = 4 Mod8 13 = 5 Mod8 14 = 6 Mod8 15 = 7 Mod8 16 = 0 Mod8 17 = 1 Mod8 18 = 2 Mod8 19 = 3 Mod8 20 = 4 Mod8 21 = 5 Mod8 22 = 6 Mod8 23 = 7 Mod8 24 = 0 Mod8 25 = 1 Mod8 26 = 2 Mod8 27 = 3 Mod8 28 = 4 Mod8 29 = 5 Mod8 30 = 6 Mod8 31 = 7 Mod8 32 = 0 Mod8 33 = 1 Mod8 34 = 2 Mod8 35 = 3 Mod8 36 = 4 Mod8 37 = 5 Mod8 38 = 6 Mod8 39 = 7 Mod8 40 = 0 Mod8 41 = 1 Mod8 42 = 2 Mod8 43 = 3 Mod8 44 = 4 Mod8 45 = 5 Mod8 46 = 6 Mod8 47 = 7 Mod8 48 = 0 Mod8 49 = 1 Mod8 50 = 2 Mod8 51 = 3 Mod8 52 = 4 Mod8 53 = 5 Mod8 54 = 6 Mod8 55 = 7 Mod8 56 = 0 Mod8 57 = 1 Mod8 58 = 2 Mod8 59 = 3 Mod8 60 = 4 Mod8 61 = 5 Mod8 62 = 6 Mod8 63 = 7 Mod8 n = Mod8 (n - 64) type IsDivisibleBy8 bitLen = IsDiv8 bitLen bitLen ~ 'True cryptonite-0.23/Crypto/Random/Entropy/RDRand.hs0000644000000000000000000000207012516347336017643 0ustar0000000000000000-- | -- Module : Crypto.Random.Entropy.RDRand -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- {-# LANGUAGE ForeignFunctionInterface #-} module Crypto.Random.Entropy.RDRand ( RDRand ) where import Foreign.Ptr import Foreign.C.Types import Data.Word (Word8) import Crypto.Random.Entropy.Source foreign import ccall unsafe "cryptonite_cpu_has_rdrand" c_cpu_has_rdrand :: IO CInt foreign import ccall unsafe "cryptonite_get_rand_bytes" c_get_rand_bytes :: Ptr Word8 -> CInt -> IO CInt -- | fake handle to Intel RDRand entropy cpu instruction data RDRand = RDRand instance EntropySource RDRand where entropyOpen = rdrandGrab entropyGather _ = rdrandGetBytes entropyClose _ = return () rdrandGrab :: IO (Maybe RDRand) rdrandGrab = supported `fmap` c_cpu_has_rdrand where supported 0 = Nothing supported _ = Just RDRand rdrandGetBytes :: Ptr Word8 -> Int -> IO Int rdrandGetBytes ptr sz = fromIntegral `fmap` c_get_rand_bytes ptr (fromIntegral sz) cryptonite-0.23/Crypto/Random/Entropy/Windows.hs0000644000000000000000000000604612533034410020153 0ustar0000000000000000-- | -- Module : Crypto.Random.Entropy.Windows -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- code originally from the entropy package and thus is: -- Copyright (c) Thomas DuBuisson. -- {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE CPP #-} module Crypto.Random.Entropy.Windows ( WinCryptoAPI ) where import Data.Int (Int32) import Data.Word import Foreign.C.String (CString, withCString) import Foreign.Ptr (Ptr, nullPtr) import Foreign.Marshal.Alloc (alloca) import Foreign.Marshal.Utils (toBool) import Foreign.Storable (peek) import System.Win32.Types (getLastError) import Crypto.Random.Entropy.Source -- | handle to windows crypto API for random generation data WinCryptoAPI = WinCryptoAPI instance EntropySource WinCryptoAPI where entropyOpen = do mctx <- cryptAcquireCtx maybe (return Nothing) (\ctx -> cryptReleaseCtx ctx >> return (Just WinCryptoAPI)) mctx entropyGather WinCryptoAPI ptr n = do mctx <- cryptAcquireCtx case mctx of Nothing -> do lastError <- getLastError fail $ "cannot re-grab win crypto api: error " ++ show lastError Just ctx -> do r <- cryptGenRandom ctx ptr n cryptReleaseCtx ctx return r entropyClose WinCryptoAPI = return () type DWORD = Word32 type BOOL = Int32 type BYTE = Word8 #if defined(ARCH_X86) # define WINDOWS_CCONV stdcall type CryptCtx = Word32 #elif defined(ARCH_X86_64) # define WINDOWS_CCONV ccall type CryptCtx = Word64 #else # error Unknown mingw32 arch #endif -- Declare the required CryptoAPI imports foreign import WINDOWS_CCONV unsafe "CryptAcquireContextA" c_cryptAcquireCtx :: Ptr CryptCtx -> CString -> CString -> DWORD -> DWORD -> IO BOOL foreign import WINDOWS_CCONV unsafe "CryptGenRandom" c_cryptGenRandom :: CryptCtx -> DWORD -> Ptr BYTE -> IO BOOL foreign import WINDOWS_CCONV unsafe "CryptReleaseContext" c_cryptReleaseCtx :: CryptCtx -> DWORD -> IO BOOL -- Define the constants we need from WinCrypt.h msDefProv :: String msDefProv = "Microsoft Base Cryptographic Provider v1.0" provRSAFull :: DWORD provRSAFull = 1 cryptVerifyContext :: DWORD cryptVerifyContext = 0xF0000000 cryptAcquireCtx :: IO (Maybe CryptCtx) cryptAcquireCtx = alloca $ \handlePtr -> withCString msDefProv $ \provName -> do r <- toBool `fmap` c_cryptAcquireCtx handlePtr nullPtr provName provRSAFull cryptVerifyContext if r then Just `fmap` peek handlePtr else return Nothing cryptGenRandom :: CryptCtx -> Ptr Word8 -> Int -> IO Int cryptGenRandom h buf n = do success <- toBool `fmap` c_cryptGenRandom h (fromIntegral n) buf return $ if success then n else 0 cryptReleaseCtx :: CryptCtx -> IO () cryptReleaseCtx h = do success <- toBool `fmap` c_cryptReleaseCtx h 0 if success then return () else do lastError <- getLastError fail $ "cryptReleaseCtx: error " ++ show lastError cryptonite-0.23/Crypto/Random/Entropy/Unix.hs0000644000000000000000000000446312545472546017470 0ustar0000000000000000-- | -- Module : Crypto.Random.Entropy.Unix -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- {-# LANGUAGE ScopedTypeVariables #-} module Crypto.Random.Entropy.Unix ( DevRandom , DevURandom ) where import Foreign.Ptr import Data.Word (Word8) import Crypto.Random.Entropy.Source import Control.Exception as E --import System.Posix.Types (Fd) import System.IO type H = Handle type DeviceName = String -- | Entropy device /dev/random on unix system newtype DevRandom = DevRandom DeviceName -- | Entropy device /dev/urandom on unix system newtype DevURandom = DevURandom DeviceName instance EntropySource DevRandom where entropyOpen = fmap DevRandom `fmap` testOpen "/dev/random" entropyGather (DevRandom name) ptr n = withDev name $ \h -> gatherDevEntropyNonBlock h ptr n entropyClose (DevRandom _) = return () instance EntropySource DevURandom where entropyOpen = fmap DevURandom `fmap` testOpen "/dev/urandom" entropyGather (DevURandom name) ptr n = withDev name $ \h -> gatherDevEntropy h ptr n entropyClose (DevURandom _) = return () testOpen :: DeviceName -> IO (Maybe DeviceName) testOpen filepath = do d <- openDev filepath case d of Nothing -> return Nothing Just h -> closeDev h >> return (Just filepath) openDev :: String -> IO (Maybe H) openDev filepath = (Just `fmap` openAndNoBuffering) `E.catch` \(_ :: IOException) -> return Nothing where openAndNoBuffering = do h <- openBinaryFile filepath ReadMode hSetBuffering h NoBuffering return h withDev :: String -> (H -> IO a) -> IO a withDev filepath f = openDev filepath >>= \h -> case h of Nothing -> error ("device " ++ filepath ++ " cannot be grabbed") Just fd -> f fd >>= \r -> (closeDev fd >> return r) closeDev :: H -> IO () closeDev h = hClose h gatherDevEntropy :: H -> Ptr Word8 -> Int -> IO Int gatherDevEntropy h ptr sz = (fromIntegral `fmap` hGetBufSome h ptr (fromIntegral sz)) `E.catch` \(_ :: IOException) -> return 0 gatherDevEntropyNonBlock :: H -> Ptr Word8 -> Int -> IO Int gatherDevEntropyNonBlock h ptr sz = (fromIntegral `fmap` hGetBufNonBlocking h ptr (fromIntegral sz)) `E.catch` \(_ :: IOException) -> return 0 cryptonite-0.23/cbits/cryptonite_chacha.c0000644000000000000000000002027313022512225016761 0ustar0000000000000000/* * Copyright (c) 2014-2015 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include "cryptonite_chacha.h" #include "cryptonite_bitfn.h" #include "cryptonite_align.h" #include #define QR(a,b,c,d) \ a += b; d = rol32(d ^ a,16); \ c += d; b = rol32(b ^ c,12); \ a += b; d = rol32(d ^ a, 8); \ c += d; b = rol32(b ^ c, 7); #define ALIGNED64(PTR) \ (((uintptr_t)(const void *)(PTR)) % 8 == 0) static const uint8_t sigma[16] = "expand 32-byte k"; static const uint8_t tau[16] = "expand 16-byte k"; static void chacha_core(int rounds, block *out, const cryptonite_chacha_state *in) { uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; int i; x0 = in->d[0]; x1 = in->d[1]; x2 = in->d[2]; x3 = in->d[3]; x4 = in->d[4]; x5 = in->d[5]; x6 = in->d[6]; x7 = in->d[7]; x8 = in->d[8]; x9 = in->d[9]; x10 = in->d[10]; x11 = in->d[11]; x12 = in->d[12]; x13 = in->d[13]; x14 = in->d[14]; x15 = in->d[15]; for (i = rounds; i > 0; i -= 2) { QR(x0, x4, x8, x12); QR(x1, x5, x9, x13); QR(x2, x6, x10, x14); QR(x3, x7, x11, x15); QR(x0, x5, x10, x15); QR(x1, x6, x11, x12); QR(x2, x7, x8, x13); QR(x3, x4, x9, x14); } x0 += in->d[0]; x1 += in->d[1]; x2 += in->d[2]; x3 += in->d[3]; x4 += in->d[4]; x5 += in->d[5]; x6 += in->d[6]; x7 += in->d[7]; x8 += in->d[8]; x9 += in->d[9]; x10 += in->d[10]; x11 += in->d[11]; x12 += in->d[12]; x13 += in->d[13]; x14 += in->d[14]; x15 += in->d[15]; out->d[0] = cpu_to_le32(x0); out->d[1] = cpu_to_le32(x1); out->d[2] = cpu_to_le32(x2); out->d[3] = cpu_to_le32(x3); out->d[4] = cpu_to_le32(x4); out->d[5] = cpu_to_le32(x5); out->d[6] = cpu_to_le32(x6); out->d[7] = cpu_to_le32(x7); out->d[8] = cpu_to_le32(x8); out->d[9] = cpu_to_le32(x9); out->d[10] = cpu_to_le32(x10); out->d[11] = cpu_to_le32(x11); out->d[12] = cpu_to_le32(x12); out->d[13] = cpu_to_le32(x13); out->d[14] = cpu_to_le32(x14); out->d[15] = cpu_to_le32(x15); } /* only 2 valids values are 256 (32) and 128 (16) */ void cryptonite_chacha_init_core(cryptonite_chacha_state *st, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv) { const uint8_t *constants = (keylen == 32) ? sigma : tau; int i; ASSERT_ALIGNMENT(constants, 4); st->d[0] = load_le32_aligned(constants + 0); st->d[1] = load_le32_aligned(constants + 4); st->d[2] = load_le32_aligned(constants + 8); st->d[3] = load_le32_aligned(constants + 12); st->d[4] = load_le32(key + 0); st->d[5] = load_le32(key + 4); st->d[6] = load_le32(key + 8); st->d[7] = load_le32(key + 12); /* we repeat the key on 128 bits */ if (keylen == 32) key += 16; st->d[8] = load_le32(key + 0); st->d[9] = load_le32(key + 4); st->d[10] = load_le32(key + 8); st->d[11] = load_le32(key + 12); st->d[12] = 0; switch (ivlen) { case 8: st->d[13] = 0; st->d[14] = load_le32(iv + 0); st->d[15] = load_le32(iv + 4); break; case 12: st->d[13] = load_le32(iv + 0); st->d[14] = load_le32(iv + 4); st->d[15] = load_le32(iv + 8); default: return; } } void cryptonite_chacha_init(cryptonite_chacha_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv) { memset(ctx, 0, sizeof(*ctx)); ctx->nb_rounds = nb_rounds; cryptonite_chacha_init_core(&ctx->st, keylen, key, ivlen, iv); } void cryptonite_chacha_combine(uint8_t *dst, cryptonite_chacha_context *ctx, const uint8_t *src, uint32_t bytes) { block out; cryptonite_chacha_state *st; int i; if (!bytes) return; /* xor the previous buffer first (if any) */ if (ctx->prev_len > 0) { int to_copy = (ctx->prev_len < bytes) ? ctx->prev_len : bytes; for (i = 0; i < to_copy; i++) dst[i] = src[i] ^ ctx->prev[ctx->prev_ofs+i]; memset(ctx->prev + ctx->prev_ofs, 0, to_copy); ctx->prev_len -= to_copy; ctx->prev_ofs += to_copy; src += to_copy; dst += to_copy; bytes -= to_copy; } if (bytes == 0) return; st = &ctx->st; /* xor new 64-bytes chunks and store the left over if any */ for (; bytes >= 64; bytes -= 64, src += 64, dst += 64) { /* generate new chunk and update state */ chacha_core(ctx->nb_rounds, &out, st); st->d[12] += 1; if (st->d[12] == 0) st->d[13] += 1; for (i = 0; i < 64; ++i) dst[i] = src[i] ^ out.b[i]; } if (bytes > 0) { /* generate new chunk and update state */ chacha_core(ctx->nb_rounds, &out, st); st->d[12] += 1; if (st->d[12] == 0) st->d[13] += 1; /* xor as much as needed */ for (i = 0; i < bytes; i++) dst[i] = src[i] ^ out.b[i]; /* copy the left over in the buffer */ ctx->prev_len = 64 - bytes; ctx->prev_ofs = i; for (; i < 64; i++) { ctx->prev[i] = out.b[i]; } } } void cryptonite_chacha_generate(uint8_t *dst, cryptonite_chacha_context *ctx, uint32_t bytes) { cryptonite_chacha_state *st; block out; int i; if (!bytes) return; /* xor the previous buffer first (if any) */ if (ctx->prev_len > 0) { int to_copy = (ctx->prev_len < bytes) ? ctx->prev_len : bytes; for (i = 0; i < to_copy; i++) dst[i] = ctx->prev[ctx->prev_ofs+i]; memset(ctx->prev + ctx->prev_ofs, 0, to_copy); ctx->prev_len -= to_copy; ctx->prev_ofs += to_copy; dst += to_copy; bytes -= to_copy; } if (bytes == 0) return; st = &ctx->st; if (ALIGNED64(dst)) { /* xor new 64-bytes chunks and store the left over if any */ for (; bytes >= 64; bytes -= 64, dst += 64) { /* generate new chunk and update state */ chacha_core(ctx->nb_rounds, (block *) dst, st); st->d[12] += 1; if (st->d[12] == 0) st->d[13] += 1; } } else { /* xor new 64-bytes chunks and store the left over if any */ for (; bytes >= 64; bytes -= 64, dst += 64) { /* generate new chunk and update state */ chacha_core(ctx->nb_rounds, &out, st); st->d[12] += 1; if (st->d[12] == 0) st->d[13] += 1; for (i = 0; i < 64; ++i) dst[i] = out.b[i]; } } if (bytes > 0) { /* generate new chunk and update state */ chacha_core(ctx->nb_rounds, &out, st); st->d[12] += 1; if (st->d[12] == 0) st->d[13] += 1; /* xor as much as needed */ for (i = 0; i < bytes; i++) dst[i] = out.b[i]; /* copy the left over in the buffer */ ctx->prev_len = 64 - bytes; ctx->prev_ofs = i; for (; i < 64; i++) ctx->prev[i] = out.b[i]; } } void cryptonite_chacha_random(uint32_t rounds, uint8_t *dst, cryptonite_chacha_state *st, uint32_t bytes) { block out; if (!bytes) return; for (; bytes >= 16; bytes -= 16, dst += 16) { chacha_core(rounds, &out, st); memcpy(dst, out.b + 40, 16); cryptonite_chacha_init_core(st, 32, out.b, 8, out.b + 32); } if (bytes) { chacha_core(rounds, &out, st); memcpy(dst, out.b + 40, bytes); cryptonite_chacha_init_core(st, 32, out.b, 8, out.b + 32); } } cryptonite-0.23/cbits/cryptonite_salsa.c0000644000000000000000000002063112527623710016666 0ustar0000000000000000/* * Copyright (c) 2014-2015 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include "cryptonite_salsa.h" #include "cryptonite_bitfn.h" static const uint8_t sigma[16] = "expand 32-byte k"; static const uint8_t tau[16] = "expand 16-byte k"; #define QR(a,b,c,d) \ b ^= rol32(a+d, 7); \ c ^= rol32(b+a, 9); \ d ^= rol32(c+b, 13); \ a ^= rol32(d+c, 18); #define ALIGNED64(PTR) \ (((uintptr_t)(const void *)(PTR)) % 8 == 0) #define SALSA_CORE_LOOP \ for (i = rounds; i > 0; i -= 2) { \ QR (x0,x4,x8,x12); \ QR (x5,x9,x13,x1); \ QR (x10,x14,x2,x6); \ QR (x15,x3,x7,x11); \ QR (x0,x1,x2,x3); \ QR (x5,x6,x7,x4); \ QR (x10,x11,x8,x9); \ QR (x15,x12,x13,x14); \ } static inline uint32_t load32(const uint8_t *p) { return le32_to_cpu(*((uint32_t *) p)); } static void salsa_core(int rounds, block *out, const cryptonite_salsa_state *in) { uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; int i; x0 = in->d[0]; x1 = in->d[1]; x2 = in->d[2]; x3 = in->d[3]; x4 = in->d[4]; x5 = in->d[5]; x6 = in->d[6]; x7 = in->d[7]; x8 = in->d[8]; x9 = in->d[9]; x10 = in->d[10]; x11 = in->d[11]; x12 = in->d[12]; x13 = in->d[13]; x14 = in->d[14]; x15 = in->d[15]; SALSA_CORE_LOOP; x0 += in->d[0]; x1 += in->d[1]; x2 += in->d[2]; x3 += in->d[3]; x4 += in->d[4]; x5 += in->d[5]; x6 += in->d[6]; x7 += in->d[7]; x8 += in->d[8]; x9 += in->d[9]; x10 += in->d[10]; x11 += in->d[11]; x12 += in->d[12]; x13 += in->d[13]; x14 += in->d[14]; x15 += in->d[15]; out->d[0] = cpu_to_le32(x0); out->d[1] = cpu_to_le32(x1); out->d[2] = cpu_to_le32(x2); out->d[3] = cpu_to_le32(x3); out->d[4] = cpu_to_le32(x4); out->d[5] = cpu_to_le32(x5); out->d[6] = cpu_to_le32(x6); out->d[7] = cpu_to_le32(x7); out->d[8] = cpu_to_le32(x8); out->d[9] = cpu_to_le32(x9); out->d[10] = cpu_to_le32(x10); out->d[11] = cpu_to_le32(x11); out->d[12] = cpu_to_le32(x12); out->d[13] = cpu_to_le32(x13); out->d[14] = cpu_to_le32(x14); out->d[15] = cpu_to_le32(x15); } void cryptonite_salsa_core_xor(int rounds, block *out, block *in) { uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; int i; #define LOAD(i) (out->d[i] ^= in->d[i]) x0 = LOAD(0); x1 = LOAD(1); x2 = LOAD(2); x3 = LOAD(3); x4 = LOAD(4); x5 = LOAD(5); x6 = LOAD(6); x7 = LOAD(7); x8 = LOAD(8); x9 = LOAD(9); x10 = LOAD(10); x11 = LOAD(11); x12 = LOAD(12); x13 = LOAD(13); x14 = LOAD(14); x15 = LOAD(15); #undef LOAD SALSA_CORE_LOOP; out->d[0] += x0; out->d[1] += x1; out->d[2] += x2; out->d[3] += x3; out->d[4] += x4; out->d[5] += x5; out->d[6] += x6; out->d[7] += x7; out->d[8] += x8; out->d[9] += x9; out->d[10] += x10; out->d[11] += x11; out->d[12] += x12; out->d[13] += x13; out->d[14] += x14; out->d[15] += x15; } /* only 2 valid values for keylen are 256 (32) and 128 (16) */ void cryptonite_salsa_init_core(cryptonite_salsa_state *st, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv) { const uint8_t *constants = (keylen == 32) ? sigma : tau; int i; st->d[0] = load32(constants + 0); st->d[5] = load32(constants + 4); st->d[10] = load32(constants + 8); st->d[15] = load32(constants + 12); st->d[1] = load32(key + 0); st->d[2] = load32(key + 4); st->d[3] = load32(key + 8); st->d[4] = load32(key + 12); /* we repeat the key on 128 bits */ if (keylen == 32) key += 16; st->d[11] = load32(key + 0); st->d[12] = load32(key + 4); st->d[13] = load32(key + 8); st->d[14] = load32(key + 12); st->d[9] = 0; switch (ivlen) { case 8: st->d[6] = load32(iv + 0); st->d[7] = load32(iv + 4); st->d[8] = 0; break; case 12: st->d[6] = load32(iv + 0); st->d[7] = load32(iv + 4); st->d[8] = load32(iv + 8); default: return; } } void cryptonite_salsa_init(cryptonite_salsa_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv) { memset(ctx, 0, sizeof(*ctx)); ctx->nb_rounds = nb_rounds; cryptonite_salsa_init_core(&ctx->st, keylen, key, ivlen, iv); } void cryptonite_salsa_combine(uint8_t *dst, cryptonite_salsa_context *ctx, const uint8_t *src, uint32_t bytes) { block out; cryptonite_salsa_state *st; int i; if (!bytes) return; /* xor the previous buffer first (if any) */ if (ctx->prev_len > 0) { int to_copy = (ctx->prev_len < bytes) ? ctx->prev_len : bytes; for (i = 0; i < to_copy; i++) dst[i] = src[i] ^ ctx->prev[ctx->prev_ofs+i]; memset(ctx->prev + ctx->prev_ofs, 0, to_copy); ctx->prev_len -= to_copy; ctx->prev_ofs += to_copy; src += to_copy; dst += to_copy; bytes -= to_copy; } if (bytes == 0) return; st = &ctx->st; /* xor new 64-bytes chunks and store the left over if any */ for (; bytes >= 64; bytes -= 64, src += 64, dst += 64) { /* generate new chunk and update state */ salsa_core(ctx->nb_rounds, &out, st); st->d[8] += 1; if (st->d[8] == 0) st->d[9] += 1; for (i = 0; i < 64; ++i) dst[i] = src[i] ^ out.b[i]; } if (bytes > 0) { /* generate new chunk and update state */ salsa_core(ctx->nb_rounds, &out, st); st->d[8] += 1; if (st->d[8] == 0) st->d[9] += 1; /* xor as much as needed */ for (i = 0; i < bytes; i++) dst[i] = src[i] ^ out.b[i]; /* copy the left over in the buffer */ ctx->prev_len = 64 - bytes; ctx->prev_ofs = i; for (; i < 64; i++) { ctx->prev[i] = out.b[i]; } } } void cryptonite_salsa_generate(uint8_t *dst, cryptonite_salsa_context *ctx, uint32_t bytes) { cryptonite_salsa_state *st; block out; int i; if (!bytes) return; /* xor the previous buffer first (if any) */ if (ctx->prev_len > 0) { int to_copy = (ctx->prev_len < bytes) ? ctx->prev_len : bytes; for (i = 0; i < to_copy; i++) dst[i] = ctx->prev[ctx->prev_ofs+i]; memset(ctx->prev + ctx->prev_ofs, 0, to_copy); ctx->prev_len -= to_copy; ctx->prev_ofs += to_copy; dst += to_copy; bytes -= to_copy; } if (bytes == 0) return; st = &ctx->st; if (ALIGNED64(dst)) { /* xor new 64-bytes chunks and store the left over if any */ for (; bytes >= 64; bytes -= 64, dst += 64) { /* generate new chunk and update state */ salsa_core(ctx->nb_rounds, (block *) dst, st); st->d[8] += 1; if (st->d[8] == 0) st->d[9] += 1; } } else { /* xor new 64-bytes chunks and store the left over if any */ for (; bytes >= 64; bytes -= 64, dst += 64) { /* generate new chunk and update state */ salsa_core(ctx->nb_rounds, &out, st); st->d[8] += 1; if (st->d[8] == 0) st->d[9] += 1; for (i = 0; i < 64; ++i) dst[i] = out.b[i]; } } if (bytes > 0) { /* generate new chunk and update state */ salsa_core(ctx->nb_rounds, &out, st); st->d[8] += 1; if (st->d[8] == 0) st->d[9] += 1; /* xor as much as needed */ for (i = 0; i < bytes; i++) dst[i] = out.b[i]; /* copy the left over in the buffer */ ctx->prev_len = 64 - bytes; ctx->prev_ofs = i; for (; i < 64; i++) ctx->prev[i] = out.b[i]; } } cryptonite-0.23/cbits/cryptonite_xsalsa.c0000644000000000000000000000670313016276773017071 0ustar0000000000000000/* * Copyright (c) 2016 Brandon Hamilton * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include "cryptonite_xsalsa.h" #include "cryptonite_bitfn.h" static inline uint32_t load32(const uint8_t *p) { return le32_to_cpu(*((uint32_t *) p)); } /* XSalsa20 algorithm as described in https://cr.yp.to/snuffle/xsalsa-20081128.pdf */ void cryptonite_xsalsa_init(cryptonite_salsa_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv) { memset(ctx, 0, sizeof(*ctx)); ctx->nb_rounds = nb_rounds; /* Create initial 512-bit input block: (x0, x5, x10, x15) is the Salsa20 constant (x1, x2, x3, x4, x11, x12, x13, x14) is a 256-bit key (x6, x7, x8, x9) is the first 128 bits of a 192-bit nonce */ cryptonite_salsa_init_core(&ctx->st, keylen, key, 8, iv); ctx->st.d[ 8] = load32(iv + 8); ctx->st.d[ 9] = load32(iv + 12); /* Compute (z0, z1, . . . , z15) = doubleround ^(r/2) (x0, x1, . . . , x15) */ block hSalsa; memset(&hSalsa, 0, sizeof(block)); cryptonite_salsa_core_xor(nb_rounds, &hSalsa, &ctx->st); /* Build a new 512-bit input block (x′0, x′1, . . . , x′15): (x′0, x′5, x′10, x′15) is the Salsa20 constant (x′1,x′2,x′3,x′4,x′11,x′12,x′13,x′14) = (z0,z5,z10,z15,z6,z7,z8,z9) (x′6,x′7) is the last 64 bits of the 192-bit nonce (x′8, x′9) is a 64-bit block counter. */ ctx->st.d[ 1] = hSalsa.d[ 0] - ctx->st.d[ 0]; ctx->st.d[ 2] = hSalsa.d[ 5] - ctx->st.d[ 5]; ctx->st.d[ 3] = hSalsa.d[10] - ctx->st.d[10]; ctx->st.d[ 4] = hSalsa.d[15] - ctx->st.d[15]; ctx->st.d[11] = hSalsa.d[ 6] - ctx->st.d[ 6]; ctx->st.d[12] = hSalsa.d[ 7] - ctx->st.d[ 7]; ctx->st.d[13] = hSalsa.d[ 8] - ctx->st.d[ 8]; ctx->st.d[14] = hSalsa.d[ 9] - ctx->st.d[ 9]; ctx->st.d[ 6] = load32(iv + 16); ctx->st.d[ 7] = load32(iv + 20); ctx->st.d[ 8] = 0; ctx->st.d[ 9] = 0; }cryptonite-0.23/cbits/cryptonite_rc4.c0000644000000000000000000000260512400310060016231 0ustar0000000000000000/* initial implementation by * Peter White */ /* C Standard includes */ #include #include #include #include /* Local include */ #include "cryptonite_rc4.h" /* Swap array elements i=State[i] and b=State[j]. */ static void swap(uint8_t *i, uint8_t *j) { uint8_t temp; temp = *i; *i = *j; *j = temp; } /* Key scheduling algorithm. Swap array elements based on the key. */ void cryptonite_rc4_init(uint8_t *key, uint32_t keylen, struct rc4_ctx *ctx) { uint32_t i, j; memset(ctx, 0, sizeof(struct rc4_ctx)); /* initialize context */ for (i = 0; i < 256; i++) ctx->state[i] = i; for (i = j = 0; i < 256; i++) { j = (j + ctx->state[i] + key[i % keylen]) % 256; swap(&ctx->state[i], &ctx->state[j]); } } /* Combine the stream generated by the rc4 with some input */ void cryptonite_rc4_combine(struct rc4_ctx *ctx, uint8_t *input, uint32_t len, uint8_t *output) { uint32_t i = ctx->i; uint32_t j = ctx->j; uint32_t m; uint8_t si, sj; /* The RC4 algorithm */ for (m = 0; m < len; m++) { i = (i + 1) & 0xff; si = ctx->state[i]; j = (j + si) & 0xff; sj = ctx->state[j]; /* swap(&state[i], &state[j]); */ ctx->state[i] = sj; ctx->state[j] = si; /* Xor the key stream value into the input */ *output++ = *input++ ^ (ctx->state[(si + sj) & 0xff]); } /* Output new S-box indices */ ctx->i = i; ctx->j = j; } cryptonite-0.23/cbits/cryptonite_cpu.c0000644000000000000000000000460312541542071016347 0ustar0000000000000000/* * Copyright (C) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "cryptonite_cpu.h" #include #ifdef ARCH_X86 static void cpuid(uint32_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) { *eax = info; asm volatile ( #ifdef __x86_64__ "mov %%rbx, %%rdi;" #else "mov %%ebx, %%edi;" #endif "cpuid;" "mov %%ebx, %%esi;" #ifdef __x86_64__ "mov %%rdi, %%rbx;" #else "mov %%edi, %%ebx;" #endif :"+a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) : :"edi"); } #ifdef USE_AESNI void cryptonite_aesni_initialize_hw(void (*init_table)(int, int)) { static int inited = 0; if (inited == 0) { uint32_t eax, ebx, ecx, edx; int aesni, pclmul; inited = 1; cpuid(1, &eax, &ebx, &ecx, &edx); aesni = (ecx & 0x02000000); pclmul = (ecx & 0x00000001); init_table(aesni, pclmul); } } #else #define cryptonite_aesni_initialize_hw(init_table) (0) #endif #endif cryptonite-0.23/cbits/ed25519/ed25519.c0000644000000000000000000000655012514663134015303 0ustar0000000000000000/* Public domain by Andrew M. Ed25519 reference implementation using Ed25519-donna */ #define ED25519_FN(fn) cryptonite_##fn #include "ed25519-donna.h" #include "ed25519.h" #include "ed25519-randombytes.h" #include "ed25519-hash.h" /* Generates a (extsk[0..31]) and aExt (extsk[32..63]) */ DONNA_INLINE static void ed25519_extsk(hash_512bits extsk, const ed25519_secret_key sk) { ed25519_hash(extsk, sk, 32); extsk[0] &= 248; extsk[31] &= 127; extsk[31] |= 64; } static void ed25519_hram(hash_512bits hram, const ed25519_signature RS, const ed25519_public_key pk, const unsigned char *m, size_t mlen) { ed25519_hash_context ctx; ed25519_hash_init(&ctx); ed25519_hash_update(&ctx, RS, 32); ed25519_hash_update(&ctx, pk, 32); ed25519_hash_update(&ctx, m, mlen); ed25519_hash_final(&ctx, hram); } void ED25519_FN(ed25519_publickey) (const ed25519_secret_key sk, ed25519_public_key pk) { bignum256modm a; ge25519 ALIGN(16) A; hash_512bits extsk; /* A = aB */ ed25519_extsk(extsk, sk); expand256_modm(a, extsk, 32); ge25519_scalarmult_base_niels(&A, ge25519_niels_base_multiples, a); ge25519_pack(pk, &A); } void ED25519_FN(ed25519_sign) (const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS) { ed25519_hash_context ctx; bignum256modm r, S, a; ge25519 ALIGN(16) R; hash_512bits extsk, hashr, hram; ed25519_extsk(extsk, sk); /* r = H(aExt[32..64], m) */ ed25519_hash_init(&ctx); ed25519_hash_update(&ctx, extsk + 32, 32); ed25519_hash_update(&ctx, m, mlen); ed25519_hash_final(&ctx, hashr); expand256_modm(r, hashr, 64); /* R = rB */ ge25519_scalarmult_base_niels(&R, ge25519_niels_base_multiples, r); ge25519_pack(RS, &R); /* S = H(R,A,m).. */ ed25519_hram(hram, RS, pk, m, mlen); expand256_modm(S, hram, 64); /* S = H(R,A,m)a */ expand256_modm(a, extsk, 32); mul256_modm(S, S, a); /* S = (r + H(R,A,m)a) */ add256_modm(S, S, r); /* S = (r + H(R,A,m)a) mod L */ contract256_modm(RS + 32, S); } int ED25519_FN(ed25519_sign_open) (const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS) { ge25519 ALIGN(16) R, A; hash_512bits hash; bignum256modm hram, S; unsigned char checkR[32]; if ((RS[63] & 224) || !ge25519_unpack_negative_vartime(&A, pk)) return -1; /* hram = H(R,A,m) */ ed25519_hram(hash, RS, pk, m, mlen); expand256_modm(hram, hash, 64); /* S */ expand256_modm(S, RS + 32, 32); /* SB - H(R,A,m)A */ ge25519_double_scalarmult_vartime(&R, &A, hram, S); ge25519_pack(checkR, &R); /* check that R = SB - H(R,A,m)A */ return ed25519_verify(RS, checkR, 32) ? 0 : -1; } #include "ed25519-donna-batchverify.h" /* Fast Curve25519 basepoint scalar multiplication */ void ED25519_FN(curved25519_scalarmult_basepoint) (curved25519_key pk, const curved25519_key e) { curved25519_key ec; bignum256modm s; bignum25519 ALIGN(16) yplusz, zminusy; ge25519 ALIGN(16) p; size_t i; /* clamp */ for (i = 0; i < 32; i++) ec[i] = e[i]; ec[0] &= 248; ec[31] &= 127; ec[31] |= 64; expand_raw256_modm(s, ec); /* scalar * basepoint */ ge25519_scalarmult_base_niels(&p, ge25519_niels_base_multiples, s); /* u = (y + z) / (z - y) */ curve25519_add(yplusz, p.y, p.z); curve25519_sub(zminusy, p.z, p.y); curve25519_recip(zminusy, zminusy); curve25519_mul(yplusz, yplusz, zminusy); curve25519_contract(pk, yplusz); } cryptonite-0.23/cbits/ed448/x448.c0000644000000000000000000001777013054074213014646 0ustar0000000000000000/* Copyright (c) 2015 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ /** * @file decaf.c * @author Mike Hamburg * @brief Decaf high-level functions. */ #include #include "x448.h" #ifdef ARCH_X86_64 #define WBITS 64 #else #define WBITS 32 #endif #define LBITS (WBITS * 7 / 8) #define X448_LIMBS (448/LBITS) #if WBITS == 64 typedef uint64_t decaf_word_t; typedef int64_t decaf_sword_t; typedef __uint128_t decaf_dword_t; typedef __int128_t decaf_sdword_t; #elif WBITS == 32 typedef uint32_t decaf_word_t; typedef int32_t decaf_sword_t; typedef uint64_t decaf_dword_t; typedef int64_t decaf_sdword_t; #else #error "WBITS must be 32 or 64" #endif typedef struct { decaf_word_t limb[X448_LIMBS]; } gf_s, gf[1]; static const unsigned char X448_BASE_POINT[X448_BYTES] = {5}; static const gf ZERO = {{{0}}}, ONE = {{{1}}}; #define LMASK ((((decaf_word_t)1)<limb[i] = y->limb[i]); } /** Mostly-unoptimized multiply (PERF), but at least it's unrolled. */ static void gf_mul (gf c, const gf a, const gf b) { gf aa; gf_cpy(aa,a); decaf_dword_t accum[X448_LIMBS] = {0}; FOR_LIMB_U(i, { FOR_LIMB_U(j,{ accum[(i+j)%X448_LIMBS] += (decaf_dword_t)b->limb[i] * aa->limb[j]; }); aa->limb[(X448_LIMBS-1-i)^(X448_LIMBS/2)] += aa->limb[X448_LIMBS-1-i]; }); accum[X448_LIMBS-1] += accum[X448_LIMBS-2] >> LBITS; accum[X448_LIMBS-2] &= LMASK; accum[X448_LIMBS/2] += accum[X448_LIMBS-1] >> LBITS; FOR_LIMB_U(j,{ accum[j] += accum[(j-1)%X448_LIMBS] >> LBITS; accum[(j-1)%X448_LIMBS] &= LMASK; }); FOR_LIMB_U(j, c->limb[j] = accum[j] ); } /** No dedicated square (PERF) */ #define gf_sqr(c,a) gf_mul(c,a,a) /** Inverse square root using addition chain. */ static void gf_isqrt(gf y, const gf x) { int i; #define STEP(s,m,n) gf_mul(s,m,c); gf_cpy(c,s); for (i=0;ilimb[X448_LIMBS/2] += x->limb[X448_LIMBS-1] >> LBITS; FOR_LIMB_U(j,{ x->limb[j] += x->limb[(j-1)%X448_LIMBS] >> LBITS; x->limb[(j-1)%X448_LIMBS] &= LMASK; }); } /** Add mod p. Conservatively always weak-reduce. (PERF) */ static void gf_add ( gf x, const gf y, const gf z ) { FOR_LIMB_U(i, x->limb[i] = y->limb[i] + z->limb[i] ); gf_reduce(x); } /** Subtract mod p. Conservatively always weak-reduce. (PERF) */ static void gf_sub ( gf x, const gf y, const gf z ) { FOR_LIMB_U(i, x->limb[i] = y->limb[i] - z->limb[i] + 2*P->limb[i] ); gf_reduce(x); } /** Constant time, if (swap) (x,y) = (y,x); */ static void cond_swap(gf x, gf_s *__restrict__ y, decaf_word_t swap) { FOR_LIMB_U(i, { decaf_word_t s = (x->limb[i] ^ y->limb[i]) & swap; x->limb[i] ^= s; y->limb[i] ^= s; }); } /** * Mul by signed int. Not constant-time WRT the sign of that int. * Just uses a full mul (PERF) */ static inline void gf_mlw(gf a, const gf b, int w) { if (w>0) { gf ww = {{{w}}}; gf_mul(a,b,ww); } else { gf ww = {{{-w}}}; gf_mul(a,b,ww); gf_sub(a,ZERO,a); } } /** Canonicalize */ static void gf_canon ( gf a ) { gf_reduce(a); /* subtract p with borrow */ decaf_sdword_t carry = 0; FOR_LIMB(i, { carry = carry + a->limb[i] - P->limb[i]; a->limb[i] = carry & LMASK; carry >>= LBITS; }); decaf_word_t addback = carry; carry = 0; /* add it back */ FOR_LIMB(i, { carry = carry + a->limb[i] + (P->limb[i] & addback); a->limb[i] = carry & LMASK; carry >>= LBITS; }); } /* Deserialize */ static decaf_word_t gf_deser(gf s, const unsigned char ser[X448_BYTES]) { unsigned int i, k=0, bits=0; decaf_dword_t buf=0; for (i=0; i=LBITS || i==X448_BYTES-1) && k>=LBITS) { s->limb[k++] = buf & LMASK; } } decaf_sdword_t accum = 0; FOR_LIMB(i, accum = (accum + s->limb[i] - P->limb[i]) >> WBITS ); return accum; } /* Serialize */ static void gf_ser(uint8_t ser[X448_BYTES], gf a) { gf_canon(a); int k=0, bits=0; decaf_dword_t buf=0; FOR_LIMB(i, { buf |= (decaf_dword_t)a->limb[i]<=8 || i==X448_LIMBS-1) && k>=8) { ser[k++]=buf; } }); } int __attribute__((visibility("default"))) cryptonite_x448 ( unsigned char out[X448_BYTES], const unsigned char scalar[X448_BYTES], const unsigned char base[X448_BYTES] ) { gf x1, x2, z2, x3, z3, t1, t2; gf_deser(x1,base); gf_cpy(x2,ONE); gf_cpy(z2,ZERO); gf_cpy(x3,x1); gf_cpy(z3,ONE); int t; decaf_word_t swap = 0; for (t = 448-1; t>=0; t--) { uint8_t sb = scalar[t/8]; /* Scalar conditioning */ if (t/8==0) sb &= 0xFC; else if (t/8 == X448_BYTES-1) sb |= 0x80; decaf_word_t k_t = (sb>>(t%8)) & 1; k_t = -k_t; /* set to all 0s or all 1s */ swap ^= k_t; cond_swap(x2,x3,swap); cond_swap(z2,z3,swap); swap = k_t; gf_add(t1,x2,z2); /* A = x2 + z2 */ gf_sub(t2,x2,z2); /* B = x2 - z2 */ gf_sub(z2,x3,z3); /* D = x3 - z3 */ gf_mul(x2,t1,z2); /* DA */ gf_add(z2,z3,x3); /* C = x3 + z3 */ gf_mul(x3,t2,z2); /* CB */ gf_sub(z3,x2,x3); /* DA-CB */ gf_sqr(z2,z3); /* (DA-CB)^2 */ gf_mul(z3,x1,z2); /* z3 = x1(DA-CB)^2 */ gf_add(z2,x2,x3); /* (DA+CB) */ gf_sqr(x3,z2); /* x3 = (DA+CB)^2 */ gf_sqr(z2,t1); /* AA = A^2 */ gf_sqr(t1,t2); /* BB = B^2 */ gf_mul(x2,z2,t1); /* x2 = AA*BB */ gf_sub(t2,z2,t1); /* E = AA-BB */ gf_mlw(t1,t2,-EDWARDS_D); /* E*-d = a24*E */ gf_add(t1,t1,z2); /* AA + a24*E */ gf_mul(z2,t2,t1); /* z2 = E(AA+a24*E) */ } /* Finish */ cond_swap(x2,x3,swap); cond_swap(z2,z3,swap); gf_inv(z2,z2); gf_mul(x1,x2,z2); gf_ser(out,x1); decaf_sword_t nz = 0; for (t=0; t>8; /* 0 = succ, -1 = fail */ /* return value: 0 = succ, -1 = fail */ return nz; } int __attribute__((visibility("default"))) cryptonite_x448_base ( unsigned char out[X448_BYTES], const unsigned char scalar[X448_BYTES] ) { return cryptonite_x448(out,scalar,X448_BASE_POINT); } cryptonite-0.23/cbits/p256/p256.c0000644000000000000000000003217112777074127014506 0ustar0000000000000000/* * Copyright 2013 The Android Open Source Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Google Inc. nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This is an implementation of the P256 elliptic curve group. It's written to // be portable 32-bit, although it's still constant-time. // // WARNING: Implementing these functions in a constant-time manner is far from // obvious. Be careful when touching this code. // // See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background. #include #include #include #include #include "p256/p256.h" const cryptonite_p256_int cryptonite_SECP256r1_n = // curve order {{0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, -1, -1, 0, -1}}; const cryptonite_p256_int cryptonite_SECP256r1_p = // curve field size {{-1, -1, -1, 0, 0, 0, 1, -1 }}; const cryptonite_p256_int cryptonite_SECP256r1_b = // curve b {{0x27d2604b, 0x3bce3c3e, 0xcc53b0f6, 0x651d06b0, 0x769886bc, 0xb3ebbd55, 0xaa3a93e7, 0x5ac635d8}}; void cryptonite_p256_init(cryptonite_p256_int* a) { memset(a, 0, sizeof(*a)); } void cryptonite_p256_clear(cryptonite_p256_int* a) { cryptonite_p256_init(a); } int cryptonite_p256_get_bit(const cryptonite_p256_int* scalar, int bit) { return (P256_DIGIT(scalar, bit / P256_BITSPERDIGIT) >> (bit & (P256_BITSPERDIGIT - 1))) & 1; } int cryptonite_p256_is_zero(const cryptonite_p256_int* a) { int i, result = 0; for (i = 0; i < P256_NDIGITS; ++i) result |= P256_DIGIT(a, i); return !result; } // top, c[] += a[] * b // Returns new top static cryptonite_p256_digit mulAdd(const cryptonite_p256_int* a, cryptonite_p256_digit b, cryptonite_p256_digit top, cryptonite_p256_digit* c) { int i; cryptonite_p256_ddigit carry = 0; for (i = 0; i < P256_NDIGITS; ++i) { carry += *c; carry += (cryptonite_p256_ddigit)P256_DIGIT(a, i) * b; *c++ = (cryptonite_p256_digit)carry; carry >>= P256_BITSPERDIGIT; } return top + (cryptonite_p256_digit)carry; } // top, c[] -= top_a, a[] static cryptonite_p256_digit subTop(cryptonite_p256_digit top_a, const cryptonite_p256_digit* a, cryptonite_p256_digit top_c, cryptonite_p256_digit* c) { int i; cryptonite_p256_sddigit borrow = 0; for (i = 0; i < P256_NDIGITS; ++i) { borrow += *c; borrow -= *a++; *c++ = (cryptonite_p256_digit)borrow; borrow >>= P256_BITSPERDIGIT; } borrow += top_c; borrow -= top_a; top_c = (cryptonite_p256_digit)borrow; assert((borrow >> P256_BITSPERDIGIT) == 0); return top_c; } // top, c[] -= MOD[] & mask (0 or -1) // returns new top. static cryptonite_p256_digit subM(const cryptonite_p256_int* MOD, cryptonite_p256_digit top, cryptonite_p256_digit* c, cryptonite_p256_digit mask) { int i; cryptonite_p256_sddigit borrow = 0; for (i = 0; i < P256_NDIGITS; ++i) { borrow += *c; borrow -= P256_DIGIT(MOD, i) & mask; *c++ = (cryptonite_p256_digit)borrow; borrow >>= P256_BITSPERDIGIT; } return top + (cryptonite_p256_digit)borrow; } // top, c[] += MOD[] & mask (0 or -1) // returns new top. static cryptonite_p256_digit addM(const cryptonite_p256_int* MOD, cryptonite_p256_digit top, cryptonite_p256_digit* c, cryptonite_p256_digit mask) { int i; cryptonite_p256_ddigit carry = 0; for (i = 0; i < P256_NDIGITS; ++i) { carry += *c; carry += P256_DIGIT(MOD, i) & mask; *c++ = (cryptonite_p256_digit)carry; carry >>= P256_BITSPERDIGIT; } return top + (cryptonite_p256_digit)carry; } // c = a * b mod MOD. c can be a and/or b. void cryptonite_p256_modmul(const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, const cryptonite_p256_digit top_b, const cryptonite_p256_int* b, cryptonite_p256_int* c) { cryptonite_p256_digit tmp[P256_NDIGITS * 2 + 1] = { 0 }; cryptonite_p256_digit top = 0; int i; // Multiply/add into tmp. for (i = 0; i < P256_NDIGITS; ++i) { if (i) tmp[i + P256_NDIGITS - 1] = top; top = mulAdd(a, P256_DIGIT(b, i), 0, tmp + i); } // Multiply/add top digit tmp[i + P256_NDIGITS - 1] = top; top = mulAdd(a, top_b, 0, tmp + i); // Reduce tmp, digit by digit. for (; i >= 0; --i) { cryptonite_p256_digit reducer[P256_NDIGITS] = { 0 }; cryptonite_p256_digit top_reducer; // top can be any value at this point. // Guestimate reducer as top * MOD, since msw of MOD is -1. top_reducer = mulAdd(MOD, top, 0, reducer); // Subtract reducer from top | tmp. top = subTop(top_reducer, reducer, top, tmp + i); // top is now either 0 or 1. Make it 0, fixed-timing. assert(top <= 1); top = subM(MOD, top, tmp + i, ~(top - 1)); assert(top == 0); // We have now reduced the top digit off tmp. Fetch new top digit. top = tmp[i + P256_NDIGITS - 1]; } // tmp might still be larger than MOD, yet same bit length. // Make sure it is less, fixed-timing. addM(MOD, 0, tmp, subM(MOD, 0, tmp, -1)); memcpy(c, tmp, P256_NBYTES); } int cryptonite_p256_is_odd(const cryptonite_p256_int* a) { return P256_DIGIT(a, 0) & 1; } int cryptonite_p256_is_even(const cryptonite_p256_int* a) { return !(P256_DIGIT(a, 0) & 1); } cryptonite_p256_digit cryptonite_p256_shl(const cryptonite_p256_int* a, int n, cryptonite_p256_int* b) { int i; cryptonite_p256_digit top = P256_DIGIT(a, P256_NDIGITS - 1); n %= P256_BITSPERDIGIT; for (i = P256_NDIGITS - 1; i > 0; --i) { cryptonite_p256_digit accu = (P256_DIGIT(a, i) << n); accu |= (P256_DIGIT(a, i - 1) >> (P256_BITSPERDIGIT - n)); P256_DIGIT(b, i) = accu; } P256_DIGIT(b, i) = (P256_DIGIT(a, i) << n); top = (cryptonite_p256_digit)((((cryptonite_p256_ddigit)top) << n) >> P256_BITSPERDIGIT); return top; } void cryptonite_p256_shr(const cryptonite_p256_int* a, int n, cryptonite_p256_int* b) { int i; n %= P256_BITSPERDIGIT; for (i = 0; i < P256_NDIGITS - 1; ++i) { cryptonite_p256_digit accu = (P256_DIGIT(a, i) >> n); accu |= (P256_DIGIT(a, i + 1) << (P256_BITSPERDIGIT - n)); P256_DIGIT(b, i) = accu; } P256_DIGIT(b, i) = (P256_DIGIT(a, i) >> n); } static void cryptonite_p256_shr1(const cryptonite_p256_int* a, int highbit, cryptonite_p256_int* b) { int i; for (i = 0; i < P256_NDIGITS - 1; ++i) { cryptonite_p256_digit accu = (P256_DIGIT(a, i) >> 1); accu |= (P256_DIGIT(a, i + 1) << (P256_BITSPERDIGIT - 1)); P256_DIGIT(b, i) = accu; } P256_DIGIT(b, i) = (P256_DIGIT(a, i) >> 1) | (highbit << (P256_BITSPERDIGIT - 1)); } // Return -1, 0, 1 for a < b, a == b or a > b respectively. int cryptonite_p256_cmp(const cryptonite_p256_int* a, const cryptonite_p256_int* b) { int i; cryptonite_p256_sddigit borrow = 0; cryptonite_p256_digit notzero = 0; for (i = 0; i < P256_NDIGITS; ++i) { borrow += (cryptonite_p256_sddigit)P256_DIGIT(a, i) - P256_DIGIT(b, i); // Track whether any result digit is ever not zero. // Relies on !!(non-zero) evaluating to 1, e.g., !!(-1) evaluating to 1. notzero |= !!((cryptonite_p256_digit)borrow); borrow >>= P256_BITSPERDIGIT; } return (int)borrow | notzero; } // c = a - b. Returns borrow: 0 or -1. int cryptonite_p256_sub(const cryptonite_p256_int* a, const cryptonite_p256_int* b, cryptonite_p256_int* c) { int i; cryptonite_p256_sddigit borrow = 0; for (i = 0; i < P256_NDIGITS; ++i) { borrow += (cryptonite_p256_sddigit)P256_DIGIT(a, i) - P256_DIGIT(b, i); if (c) P256_DIGIT(c, i) = (cryptonite_p256_digit)borrow; borrow >>= P256_BITSPERDIGIT; } return (int)borrow; } // c = a + b. Returns carry: 0 or 1. int cryptonite_p256_add(const cryptonite_p256_int* a, const cryptonite_p256_int* b, cryptonite_p256_int* c) { int i; cryptonite_p256_ddigit carry = 0; for (i = 0; i < P256_NDIGITS; ++i) { carry += (cryptonite_p256_ddigit)P256_DIGIT(a, i) + P256_DIGIT(b, i); if (c) P256_DIGIT(c, i) = (cryptonite_p256_digit)carry; carry >>= P256_BITSPERDIGIT; } return (int)carry; } // b = a + d. Returns carry, 0 or 1. int cryptonite_p256_add_d(const cryptonite_p256_int* a, cryptonite_p256_digit d, cryptonite_p256_int* b) { int i; cryptonite_p256_ddigit carry = d; for (i = 0; i < P256_NDIGITS; ++i) { carry += (cryptonite_p256_ddigit)P256_DIGIT(a, i); if (b) P256_DIGIT(b, i) = (cryptonite_p256_digit)carry; carry >>= P256_BITSPERDIGIT; } return (int)carry; } // b = 1/a mod MOD, binary euclid. void cryptonite_p256_modinv_vartime(const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, cryptonite_p256_int* b) { cryptonite_p256_int R = P256_ZERO; cryptonite_p256_int S = P256_ONE; cryptonite_p256_int U = *MOD; cryptonite_p256_int V = *a; for (;;) { if (cryptonite_p256_is_even(&U)) { cryptonite_p256_shr1(&U, 0, &U); if (cryptonite_p256_is_even(&R)) { cryptonite_p256_shr1(&R, 0, &R); } else { // R = (R+MOD)/2 cryptonite_p256_shr1(&R, cryptonite_p256_add(&R, MOD, &R), &R); } } else if (cryptonite_p256_is_even(&V)) { cryptonite_p256_shr1(&V, 0, &V); if (cryptonite_p256_is_even(&S)) { cryptonite_p256_shr1(&S, 0, &S); } else { // S = (S+MOD)/2 cryptonite_p256_shr1(&S, cryptonite_p256_add(&S, MOD, &S) , &S); } } else { // U,V both odd. if (!cryptonite_p256_sub(&V, &U, NULL)) { cryptonite_p256_sub(&V, &U, &V); if (cryptonite_p256_sub(&S, &R, &S)) cryptonite_p256_add(&S, MOD, &S); if (cryptonite_p256_is_zero(&V)) break; // done. } else { cryptonite_p256_sub(&U, &V, &U); if (cryptonite_p256_sub(&R, &S, &R)) cryptonite_p256_add(&R, MOD, &R); } } } cryptonite_p256_mod(MOD, &R, b); } void cryptonite_p256_mod(const cryptonite_p256_int* MOD, const cryptonite_p256_int* in, cryptonite_p256_int* out) { if (out != in) *out = *in; addM(MOD, 0, P256_DIGITS(out), subM(MOD, 0, P256_DIGITS(out), -1)); } // Verify y^2 == x^3 - 3x + b mod p // and 0 < x < p and 0 < y < p int cryptonite_p256_is_valid_point(const cryptonite_p256_int* x, const cryptonite_p256_int* y) { cryptonite_p256_int y2, x3; if (cryptonite_p256_cmp(&cryptonite_SECP256r1_p, x) <= 0 || cryptonite_p256_cmp(&cryptonite_SECP256r1_p, y) <= 0 || cryptonite_p256_is_zero(x) || cryptonite_p256_is_zero(y)) return 0; cryptonite_p256_modmul(&cryptonite_SECP256r1_p, y, 0, y, &y2); // y^2 cryptonite_p256_modmul(&cryptonite_SECP256r1_p, x, 0, x, &x3); // x^2 cryptonite_p256_modmul(&cryptonite_SECP256r1_p, x, 0, &x3, &x3); // x^3 if (cryptonite_p256_sub(&x3, x, &x3)) cryptonite_p256_add(&x3, &cryptonite_SECP256r1_p, &x3); // x^3 - x if (cryptonite_p256_sub(&x3, x, &x3)) cryptonite_p256_add(&x3, &cryptonite_SECP256r1_p, &x3); // x^3 - 2x if (cryptonite_p256_sub(&x3, x, &x3)) cryptonite_p256_add(&x3, &cryptonite_SECP256r1_p, &x3); // x^3 - 3x if (cryptonite_p256_add(&x3, &cryptonite_SECP256r1_b, &x3)) // x^3 - 3x + b cryptonite_p256_sub(&x3, &cryptonite_SECP256r1_p, &x3); return cryptonite_p256_cmp(&y2, &x3) == 0; } void cryptonite_p256_from_bin(const uint8_t src[P256_NBYTES], cryptonite_p256_int* dst) { int i; const uint8_t* p = &src[0]; for (i = P256_NDIGITS - 1; i >= 0; --i) { P256_DIGIT(dst, i) = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; p += 4; } } void cryptonite_p256_to_bin(const cryptonite_p256_int* src, uint8_t dst[P256_NBYTES]) { int i; uint8_t* p = &dst[0]; for (i = P256_NDIGITS -1; i >= 0; --i) { const cryptonite_p256_digit dig = P256_DIGIT(src, i); p[0] = dig >> 24; p[1] = dig >> 16; p[2] = dig >> 8; p[3] = dig; p += 4; } } cryptonite-0.23/cbits/p256/p256_ec.c0000644000000000000000000014002013016276770015141 0ustar0000000000000000/* * Copyright 2013 The Android Open Source Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Google Inc. nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ // This is an implementation of the P256 elliptic curve group. It's written to // be portable 32-bit, although it's still constant-time. // // WARNING: Implementing these functions in a constant-time manner is far from // obvious. Be careful when touching this code. // // See http://www.imperialviolet.org/2010/12/04/ecc.html ([1]) for background. #include #include #include #include #include "p256/p256.h" typedef uint8_t u8; typedef uint32_t u32; typedef int32_t s32; typedef uint64_t u64; /* Our field elements are represented as nine 32-bit limbs. * * The value of an felem (field element) is: * x[0] + (x[1] * 2**29) + (x[2] * 2**57) + ... + (x[8] * 2**228) * * That is, each limb is alternately 29 or 28-bits wide in little-endian * order. * * This means that an felem hits 2**257, rather than 2**256 as we would like. A * 28, 29, ... pattern would cause us to hit 2**256, but that causes problems * when multiplying as terms end up one bit short of a limb which would require * much bit-shifting to correct. * * Finally, the values stored in an felem are in Montgomery form. So the value * |y| is stored as (y*R) mod p, where p is the P-256 prime and R is 2**257. */ typedef u32 limb; #define NLIMBS 9 typedef limb felem[NLIMBS]; static const limb kBottom28Bits = 0xfffffff; static const limb kBottom29Bits = 0x1fffffff; /* kOne is the number 1 as an felem. It's 2**257 mod p split up into 29 and * 28-bit words. */ static const felem kOne = { 2, 0, 0, 0xffff800, 0x1fffffff, 0xfffffff, 0x1fbfffff, 0x1ffffff, 0 }; static const felem kZero = {0}; static const felem kP = { 0x1fffffff, 0xfffffff, 0x1fffffff, 0x3ff, 0, 0, 0x200000, 0xf000000, 0xfffffff }; static const felem k2P = { 0x1ffffffe, 0xfffffff, 0x1fffffff, 0x7ff, 0, 0, 0x400000, 0xe000000, 0x1fffffff }; /* kPrecomputed contains precomputed values to aid the calculation of scalar * multiples of the base point, G. It's actually two, equal length, tables * concatenated. * * The first table contains (x,y) felem pairs for 16 multiples of the base * point, G. * * Index | Index (binary) | Value * 0 | 0000 | 0G (all zeros, omitted) * 1 | 0001 | G * 2 | 0010 | 2**64G * 3 | 0011 | 2**64G + G * 4 | 0100 | 2**128G * 5 | 0101 | 2**128G + G * 6 | 0110 | 2**128G + 2**64G * 7 | 0111 | 2**128G + 2**64G + G * 8 | 1000 | 2**192G * 9 | 1001 | 2**192G + G * 10 | 1010 | 2**192G + 2**64G * 11 | 1011 | 2**192G + 2**64G + G * 12 | 1100 | 2**192G + 2**128G * 13 | 1101 | 2**192G + 2**128G + G * 14 | 1110 | 2**192G + 2**128G + 2**64G * 15 | 1111 | 2**192G + 2**128G + 2**64G + G * * The second table follows the same style, but the terms are 2**32G, * 2**96G, 2**160G, 2**224G. * * This is ~2KB of data. */ static const limb kPrecomputed[NLIMBS * 2 * 15 * 2] = { 0x11522878, 0xe730d41, 0xdb60179, 0x4afe2ff, 0x12883add, 0xcaddd88, 0x119e7edc, 0xd4a6eab, 0x3120bee, 0x1d2aac15, 0xf25357c, 0x19e45cdd, 0x5c721d0, 0x1992c5a5, 0xa237487, 0x154ba21, 0x14b10bb, 0xae3fe3, 0xd41a576, 0x922fc51, 0x234994f, 0x60b60d3, 0x164586ae, 0xce95f18, 0x1fe49073, 0x3fa36cc, 0x5ebcd2c, 0xb402f2f, 0x15c70bf, 0x1561925c, 0x5a26704, 0xda91e90, 0xcdc1c7f, 0x1ea12446, 0xe1ade1e, 0xec91f22, 0x26f7778, 0x566847e, 0xa0bec9e, 0x234f453, 0x1a31f21a, 0xd85e75c, 0x56c7109, 0xa267a00, 0xb57c050, 0x98fb57, 0xaa837cc, 0x60c0792, 0xcfa5e19, 0x61bab9e, 0x589e39b, 0xa324c5, 0x7d6dee7, 0x2976e4b, 0x1fc4124a, 0xa8c244b, 0x1ce86762, 0xcd61c7e, 0x1831c8e0, 0x75774e1, 0x1d96a5a9, 0x843a649, 0xc3ab0fa, 0x6e2e7d5, 0x7673a2a, 0x178b65e8, 0x4003e9b, 0x1a1f11c2, 0x7816ea, 0xf643e11, 0x58c43df, 0xf423fc2, 0x19633ffa, 0x891f2b2, 0x123c231c, 0x46add8c, 0x54700dd, 0x59e2b17, 0x172db40f, 0x83e277d, 0xb0dd609, 0xfd1da12, 0x35c6e52, 0x19ede20c, 0xd19e0c0, 0x97d0f40, 0xb015b19, 0x449e3f5, 0xe10c9e, 0x33ab581, 0x56a67ab, 0x577734d, 0x1dddc062, 0xc57b10d, 0x149b39d, 0x26a9e7b, 0xc35df9f, 0x48764cd, 0x76dbcca, 0xca4b366, 0xe9303ab, 0x1a7480e7, 0x57e9e81, 0x1e13eb50, 0xf466cf3, 0x6f16b20, 0x4ba3173, 0xc168c33, 0x15cb5439, 0x6a38e11, 0x73658bd, 0xb29564f, 0x3f6dc5b, 0x53b97e, 0x1322c4c0, 0x65dd7ff, 0x3a1e4f6, 0x14e614aa, 0x9246317, 0x1bc83aca, 0xad97eed, 0xd38ce4a, 0xf82b006, 0x341f077, 0xa6add89, 0x4894acd, 0x9f162d5, 0xf8410ef, 0x1b266a56, 0xd7f223, 0x3e0cb92, 0xe39b672, 0x6a2901a, 0x69a8556, 0x7e7c0, 0x9b7d8d3, 0x309a80, 0x1ad05f7f, 0xc2fb5dd, 0xcbfd41d, 0x9ceb638, 0x1051825c, 0xda0cf5b, 0x812e881, 0x6f35669, 0x6a56f2c, 0x1df8d184, 0x345820, 0x1477d477, 0x1645db1, 0xbe80c51, 0xc22be3e, 0xe35e65a, 0x1aeb7aa0, 0xc375315, 0xf67bc99, 0x7fdd7b9, 0x191fc1be, 0x61235d, 0x2c184e9, 0x1c5a839, 0x47a1e26, 0xb7cb456, 0x93e225d, 0x14f3c6ed, 0xccc1ac9, 0x17fe37f3, 0x4988989, 0x1a90c502, 0x2f32042, 0xa17769b, 0xafd8c7c, 0x8191c6e, 0x1dcdb237, 0x16200c0, 0x107b32a1, 0x66c08db, 0x10d06a02, 0x3fc93, 0x5620023, 0x16722b27, 0x68b5c59, 0x270fcfc, 0xfad0ecc, 0xe5de1c2, 0xeab466b, 0x2fc513c, 0x407f75c, 0xbaab133, 0x9705fe9, 0xb88b8e7, 0x734c993, 0x1e1ff8f, 0x19156970, 0xabd0f00, 0x10469ea7, 0x3293ac0, 0xcdc98aa, 0x1d843fd, 0xe14bfe8, 0x15be825f, 0x8b5212, 0xeb3fb67, 0x81cbd29, 0xbc62f16, 0x2b6fcc7, 0xf5a4e29, 0x13560b66, 0xc0b6ac2, 0x51ae690, 0xd41e271, 0xf3e9bd4, 0x1d70aab, 0x1029f72, 0x73e1c35, 0xee70fbc, 0xad81baf, 0x9ecc49a, 0x86c741e, 0xfe6be30, 0x176752e7, 0x23d416, 0x1f83de85, 0x27de188, 0x66f70b8, 0x181cd51f, 0x96b6e4c, 0x188f2335, 0xa5df759, 0x17a77eb6, 0xfeb0e73, 0x154ae914, 0x2f3ec51, 0x3826b59, 0xb91f17d, 0x1c72949, 0x1362bf0a, 0xe23fddf, 0xa5614b0, 0xf7d8f, 0x79061, 0x823d9d2, 0x8213f39, 0x1128ae0b, 0xd095d05, 0xb85c0c2, 0x1ecb2ef, 0x24ddc84, 0xe35e901, 0x18411a4a, 0xf5ddc3d, 0x3786689, 0x52260e8, 0x5ae3564, 0x542b10d, 0x8d93a45, 0x19952aa4, 0x996cc41, 0x1051a729, 0x4be3499, 0x52b23aa, 0x109f307e, 0x6f5b6bb, 0x1f84e1e7, 0x77a0cfa, 0x10c4df3f, 0x25a02ea, 0xb048035, 0xe31de66, 0xc6ecaa3, 0x28ea335, 0x2886024, 0x1372f020, 0xf55d35, 0x15e4684c, 0xf2a9e17, 0x1a4a7529, 0xcb7beb1, 0xb2a78a1, 0x1ab21f1f, 0x6361ccf, 0x6c9179d, 0xb135627, 0x1267b974, 0x4408bad, 0x1cbff658, 0xe3d6511, 0xc7d76f, 0x1cc7a69, 0xe7ee31b, 0x54fab4f, 0x2b914f, 0x1ad27a30, 0xcd3579e, 0xc50124c, 0x50daa90, 0xb13f72, 0xb06aa75, 0x70f5cc6, 0x1649e5aa, 0x84a5312, 0x329043c, 0x41c4011, 0x13d32411, 0xb04a838, 0xd760d2d, 0x1713b532, 0xbaa0c03, 0x84022ab, 0x6bcf5c1, 0x2f45379, 0x18ae070, 0x18c9e11e, 0x20bca9a, 0x66f496b, 0x3eef294, 0x67500d2, 0xd7f613c, 0x2dbbeb, 0xb741038, 0xe04133f, 0x1582968d, 0xbe985f7, 0x1acbc1a, 0x1a6a939f, 0x33e50f6, 0xd665ed4, 0xb4b7bd6, 0x1e5a3799, 0x6b33847, 0x17fa56ff, 0x65ef930, 0x21dc4a, 0x2b37659, 0x450fe17, 0xb357b65, 0xdf5efac, 0x15397bef, 0x9d35a7f, 0x112ac15f, 0x624e62e, 0xa90ae2f, 0x107eecd2, 0x1f69bbe, 0x77d6bce, 0x5741394, 0x13c684fc, 0x950c910, 0x725522b, 0xdc78583, 0x40eeabb, 0x1fde328a, 0xbd61d96, 0xd28c387, 0x9e77d89, 0x12550c40, 0x759cb7d, 0x367ef34, 0xae2a960, 0x91b8bdc, 0x93462a9, 0xf469ef, 0xb2e9aef, 0xd2ca771, 0x54e1f42, 0x7aaa49, 0x6316abb, 0x2413c8e, 0x5425bf9, 0x1bed3e3a, 0xf272274, 0x1f5e7326, 0x6416517, 0xea27072, 0x9cedea7, 0x6e7633, 0x7c91952, 0xd806dce, 0x8e2a7e1, 0xe421e1a, 0x418c9e1, 0x1dbc890, 0x1b395c36, 0xa1dc175, 0x1dc4ef73, 0x8956f34, 0xe4b5cf2, 0x1b0d3a18, 0x3194a36, 0x6c2641f, 0xe44124c, 0xa2f4eaa, 0xa8c25ba, 0xf927ed7, 0x627b614, 0x7371cca, 0xba16694, 0x417bc03, 0x7c0a7e3, 0x9c35c19, 0x1168a205, 0x8b6b00d, 0x10e3edc9, 0x9c19bf2, 0x5882229, 0x1b2b4162, 0xa5cef1a, 0x1543622b, 0x9bd433e, 0x364e04d, 0x7480792, 0x5c9b5b3, 0xe85ff25, 0x408ef57, 0x1814cfa4, 0x121b41b, 0xd248a0f, 0x3b05222, 0x39bb16a, 0xc75966d, 0xa038113, 0xa4a1769, 0x11fbc6c, 0x917e50e, 0xeec3da8, 0x169d6eac, 0x10c1699, 0xa416153, 0xf724912, 0x15cd60b7, 0x4acbad9, 0x5efc5fa, 0xf150ed7, 0x122b51, 0x1104b40a, 0xcb7f442, 0xfbb28ff, 0x6ac53ca, 0x196142cc, 0x7bf0fa9, 0x957651, 0x4e0f215, 0xed439f8, 0x3f46bd5, 0x5ace82f, 0x110916b6, 0x6db078, 0xffd7d57, 0xf2ecaac, 0xca86dec, 0x15d6b2da, 0x965ecc9, 0x1c92b4c2, 0x1f3811, 0x1cb080f5, 0x2d8b804, 0x19d1c12d, 0xf20bd46, 0x1951fa7, 0xa3656c3, 0x523a425, 0xfcd0692, 0xd44ddc8, 0x131f0f5b, 0xaf80e4a, 0xcd9fc74, 0x99bb618, 0x2db944c, 0xa673090, 0x1c210e1, 0x178c8d23, 0x1474383, 0x10b8743d, 0x985a55b, 0x2e74779, 0x576138, 0x9587927, 0x133130fa, 0xbe05516, 0x9f4d619, 0xbb62570, 0x99ec591, 0xd9468fe, 0x1d07782d, 0xfc72e0b, 0x701b298, 0x1863863b, 0x85954b8, 0x121a0c36, 0x9e7fedf, 0xf64b429, 0x9b9d71e, 0x14e2f5d8, 0xf858d3a, 0x942eea8, 0xda5b765, 0x6edafff, 0xa9d18cc, 0xc65e4ba, 0x1c747e86, 0xe4ea915, 0x1981d7a1, 0x8395659, 0x52ed4e2, 0x87d43b7, 0x37ab11b, 0x19d292ce, 0xf8d4692, 0x18c3053f, 0x8863e13, 0x4c146c0, 0x6bdf55a, 0x4e4457d, 0x16152289, 0xac78ec2, 0x1a59c5a2, 0x2028b97, 0x71c2d01, 0x295851f, 0x404747b, 0x878558d, 0x7d29aa4, 0x13d8341f, 0x8daefd7, 0x139c972d, 0x6b7ea75, 0xd4a9dde, 0xff163d8, 0x81d55d7, 0xa5bef68, 0xb7b30d8, 0xbe73d6f, 0xaa88141, 0xd976c81, 0x7e7a9cc, 0x18beb771, 0xd773cbd, 0x13f51951, 0x9d0c177, 0x1c49a78, }; /* Field element operations: */ /* NON_ZERO_TO_ALL_ONES returns: * 0xffffffff for 0 < x <= 2**31 * 0 for x == 0 or x > 2**31. * * x must be a u32 or an equivalent type such as limb. */ #define NON_ZERO_TO_ALL_ONES(x) ((((u32)(x) - 1) >> 31) - 1) /* felem_reduce_carry adds a multiple of p in order to cancel |carry|, * which is a term at 2**257. * * On entry: carry < 2**3, inout[0,2,...] < 2**29, inout[1,3,...] < 2**28. * On exit: inout[0,2,..] < 2**30, inout[1,3,...] < 2**29. */ static void felem_reduce_carry(felem inout, limb carry) { const u32 carry_mask = NON_ZERO_TO_ALL_ONES(carry); inout[0] += carry << 1; inout[3] += 0x10000000 & carry_mask; /* carry < 2**3 thus (carry << 11) < 2**14 and we added 2**28 in the * previous line therefore this doesn't underflow. */ inout[3] -= carry << 11; inout[4] += (0x20000000 - 1) & carry_mask; inout[5] += (0x10000000 - 1) & carry_mask; inout[6] += (0x20000000 - 1) & carry_mask; inout[6] -= carry << 22; /* This may underflow if carry is non-zero but, if so, we'll fix it in the * next line. */ inout[7] -= 1 & carry_mask; inout[7] += carry << 25; } /* felem_sum sets out = in+in2. * * On entry, in[i]+in2[i] must not overflow a 32-bit word. * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29 */ static void felem_sum(felem out, const felem in, const felem in2) { limb carry = 0; unsigned i; for (i = 0;; i++) { out[i] = in[i] + in2[i]; out[i] += carry; carry = out[i] >> 29; out[i] &= kBottom29Bits; i++; if (i == NLIMBS) break; out[i] = in[i] + in2[i]; out[i] += carry; carry = out[i] >> 28; out[i] &= kBottom28Bits; } felem_reduce_carry(out, carry); } #define two31m3 (((limb)1) << 31) - (((limb)1) << 3) #define two30m2 (((limb)1) << 30) - (((limb)1) << 2) #define two30p13m2 (((limb)1) << 30) + (((limb)1) << 13) - (((limb)1) << 2) #define two31m2 (((limb)1) << 31) - (((limb)1) << 2) #define two31p24m2 (((limb)1) << 31) + (((limb)1) << 24) - (((limb)1) << 2) #define two30m27m2 (((limb)1) << 30) - (((limb)1) << 27) - (((limb)1) << 2) /* zero31 is 0 mod p. */ static const felem zero31 = { two31m3, two30m2, two31m2, two30p13m2, two31m2, two30m2, two31p24m2, two30m27m2, two31m2 }; /* felem_diff sets out = in-in2. * * On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29 and * in2[0,2,...] < 2**30, in2[1,3,...] < 2**29. * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */ static void felem_diff(felem out, const felem in, const felem in2) { limb carry = 0; unsigned i; for (i = 0;; i++) { out[i] = in[i] - in2[i]; out[i] += zero31[i]; out[i] += carry; carry = out[i] >> 29; out[i] &= kBottom29Bits; i++; if (i == NLIMBS) break; out[i] = in[i] - in2[i]; out[i] += zero31[i]; out[i] += carry; carry = out[i] >> 28; out[i] &= kBottom28Bits; } felem_reduce_carry(out, carry); } /* felem_reduce_degree sets out = tmp/R mod p where tmp contains 64-bit words * with the same 29,28,... bit positions as an felem. * * The values in felems are in Montgomery form: x*R mod p where R = 2**257. * Since we just multiplied two Montgomery values together, the result is * x*y*R*R mod p. We wish to divide by R in order for the result also to be * in Montgomery form. * * On entry: tmp[i] < 2**64 * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29 */ static void felem_reduce_degree(felem out, u64 tmp[17]) { /* The following table may be helpful when reading this code: * * Limb number: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10... * Width (bits): 29| 28| 29| 28| 29| 28| 29| 28| 29| 28| 29 * Start bit: 0 | 29| 57| 86|114|143|171|200|228|257|285 * (odd phase): 0 | 28| 57| 85|114|142|171|199|228|256|285 */ limb tmp2[18], carry, x, xMask; unsigned i; /* tmp contains 64-bit words with the same 29,28,29-bit positions as an * felem. So the top of an element of tmp might overlap with another * element two positions down. The following loop eliminates this * overlap. */ tmp2[0] = (limb)(tmp[0] & kBottom29Bits); /* In the following we use "(limb) tmp[x]" and "(limb) (tmp[x]>>32)" to try * and hint to the compiler that it can do a single-word shift by selecting * the right register rather than doing a double-word shift and truncating * afterwards. */ tmp2[1] = ((limb) tmp[0]) >> 29; tmp2[1] |= (((limb)(tmp[0] >> 32)) << 3) & kBottom28Bits; tmp2[1] += ((limb) tmp[1]) & kBottom28Bits; carry = tmp2[1] >> 28; tmp2[1] &= kBottom28Bits; for (i = 2; i < 17; i++) { tmp2[i] = ((limb)(tmp[i - 2] >> 32)) >> 25; tmp2[i] += ((limb)(tmp[i - 1])) >> 28; tmp2[i] += (((limb)(tmp[i - 1] >> 32)) << 4) & kBottom29Bits; tmp2[i] += ((limb) tmp[i]) & kBottom29Bits; tmp2[i] += carry; carry = tmp2[i] >> 29; tmp2[i] &= kBottom29Bits; i++; if (i == 17) break; tmp2[i] = ((limb)(tmp[i - 2] >> 32)) >> 25; tmp2[i] += ((limb)(tmp[i - 1])) >> 29; tmp2[i] += (((limb)(tmp[i - 1] >> 32)) << 3) & kBottom28Bits; tmp2[i] += ((limb) tmp[i]) & kBottom28Bits; tmp2[i] += carry; carry = tmp2[i] >> 28; tmp2[i] &= kBottom28Bits; } tmp2[17] = ((limb)(tmp[15] >> 32)) >> 25; tmp2[17] += ((limb)(tmp[16])) >> 29; tmp2[17] += (((limb)(tmp[16] >> 32)) << 3); tmp2[17] += carry; /* Montgomery elimination of terms. * * Since R is 2**257, we can divide by R with a bitwise shift if we can * ensure that the right-most 257 bits are all zero. We can make that true by * adding multiplies of p without affecting the value. * * So we eliminate limbs from right to left. Since the bottom 29 bits of p * are all ones, then by adding tmp2[0]*p to tmp2 we'll make tmp2[0] == 0. * We can do that for 8 further limbs and then right shift to eliminate the * extra factor of R. */ for (i = 0;; i += 2) { tmp2[i + 1] += tmp2[i] >> 29; x = tmp2[i] & kBottom29Bits; xMask = NON_ZERO_TO_ALL_ONES(x); tmp2[i] = 0; /* The bounds calculations for this loop are tricky. Each iteration of * the loop eliminates two words by adding values to words to their * right. * * The following table contains the amounts added to each word (as an * offset from the value of i at the top of the loop). The amounts are * accounted for from the first and second half of the loop separately * and are written as, for example, 28 to mean a value <2**28. * * Word: 3 4 5 6 7 8 9 10 * Added in top half: 28 11 29 21 29 28 * 28 29 * 29 * Added in bottom half: 29 10 28 21 28 28 * 29 * * The value that is currently offset 7 will be offset 5 for the next * iteration and then offset 3 for the iteration after that. Therefore * the total value added will be the values added at 7, 5 and 3. * * The following table accumulates these values. The sums at the bottom * are written as, for example, 29+28, to mean a value < 2**29+2**28. * * Word: 3 4 5 6 7 8 9 10 11 12 13 * 28 11 10 29 21 29 28 28 28 28 28 * 29 28 11 28 29 28 29 28 29 28 * 29 28 21 21 29 21 29 21 * 10 29 28 21 28 21 28 * 28 29 28 29 28 29 28 * 11 10 29 10 29 10 * 29 28 11 28 11 * 29 29 * -------------------------------------------- * 30+ 31+ 30+ 31+ 30+ * 28+ 29+ 28+ 29+ 21+ * 21+ 28+ 21+ 28+ 10 * 10 21+ 10 21+ * 11 11 * * So the greatest amount is added to tmp2[10] and tmp2[12]. If * tmp2[10/12] has an initial value of <2**29, then the maximum value * will be < 2**31 + 2**30 + 2**28 + 2**21 + 2**11, which is < 2**32, * as required. */ tmp2[i + 3] += (x << 10) & kBottom28Bits; tmp2[i + 4] += (x >> 18); tmp2[i + 6] += (x << 21) & kBottom29Bits; tmp2[i + 7] += x >> 8; /* At position 200, which is the starting bit position for word 7, we * have a factor of 0xf000000 = 2**28 - 2**24. */ tmp2[i + 7] += 0x10000000 & xMask; /* Word 7 is 28 bits wide, so the 2**28 term exactly hits word 8. */ tmp2[i + 8] += (x - 1) & xMask; tmp2[i + 7] -= (x << 24) & kBottom28Bits; tmp2[i + 8] -= x >> 4; tmp2[i + 8] += 0x20000000 & xMask; tmp2[i + 8] -= x; tmp2[i + 8] += (x << 28) & kBottom29Bits; tmp2[i + 9] += ((x >> 1) - 1) & xMask; if (i+1 == NLIMBS) break; tmp2[i + 2] += tmp2[i + 1] >> 28; x = tmp2[i + 1] & kBottom28Bits; xMask = NON_ZERO_TO_ALL_ONES(x); tmp2[i + 1] = 0; tmp2[i + 4] += (x << 11) & kBottom29Bits; tmp2[i + 5] += (x >> 18); tmp2[i + 7] += (x << 21) & kBottom28Bits; tmp2[i + 8] += x >> 7; /* At position 199, which is the starting bit of the 8th word when * dealing with a context starting on an odd word, we have a factor of * 0x1e000000 = 2**29 - 2**25. Since we have not updated i, the 8th * word from i+1 is i+8. */ tmp2[i + 8] += 0x20000000 & xMask; tmp2[i + 9] += (x - 1) & xMask; tmp2[i + 8] -= (x << 25) & kBottom29Bits; tmp2[i + 9] -= x >> 4; tmp2[i + 9] += 0x10000000 & xMask; tmp2[i + 9] -= x; tmp2[i + 10] += (x - 1) & xMask; } /* We merge the right shift with a carry chain. The words above 2**257 have * widths of 28,29,... which we need to correct when copying them down. */ carry = 0; for (i = 0; i < 8; i++) { /* The maximum value of tmp2[i + 9] occurs on the first iteration and * is < 2**30+2**29+2**28. Adding 2**29 (from tmp2[i + 10]) is * therefore safe. */ out[i] = tmp2[i + 9]; out[i] += carry; out[i] += (tmp2[i + 10] << 28) & kBottom29Bits; carry = out[i] >> 29; out[i] &= kBottom29Bits; i++; out[i] = tmp2[i + 9] >> 1; out[i] += carry; carry = out[i] >> 28; out[i] &= kBottom28Bits; } out[8] = tmp2[17]; out[8] += carry; carry = out[8] >> 29; out[8] &= kBottom29Bits; felem_reduce_carry(out, carry); } /* felem_square sets out=in*in. * * On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29. * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */ static void felem_square(felem out, const felem in) { u64 tmp[17]; tmp[0] = ((u64) in[0]) * in[0]; tmp[1] = ((u64) in[0]) * (in[1] << 1); tmp[2] = ((u64) in[0]) * (in[2] << 1) + ((u64) in[1]) * (in[1] << 1); tmp[3] = ((u64) in[0]) * (in[3] << 1) + ((u64) in[1]) * (in[2] << 1); tmp[4] = ((u64) in[0]) * (in[4] << 1) + ((u64) in[1]) * (in[3] << 2) + ((u64) in[2]) * in[2]; tmp[5] = ((u64) in[0]) * (in[5] << 1) + ((u64) in[1]) * (in[4] << 1) + ((u64) in[2]) * (in[3] << 1); tmp[6] = ((u64) in[0]) * (in[6] << 1) + ((u64) in[1]) * (in[5] << 2) + ((u64) in[2]) * (in[4] << 1) + ((u64) in[3]) * (in[3] << 1); tmp[7] = ((u64) in[0]) * (in[7] << 1) + ((u64) in[1]) * (in[6] << 1) + ((u64) in[2]) * (in[5] << 1) + ((u64) in[3]) * (in[4] << 1); /* tmp[8] has the greatest value of 2**61 + 2**60 + 2**61 + 2**60 + 2**60, * which is < 2**64 as required. */ tmp[8] = ((u64) in[0]) * (in[8] << 1) + ((u64) in[1]) * (in[7] << 2) + ((u64) in[2]) * (in[6] << 1) + ((u64) in[3]) * (in[5] << 2) + ((u64) in[4]) * in[4]; tmp[9] = ((u64) in[1]) * (in[8] << 1) + ((u64) in[2]) * (in[7] << 1) + ((u64) in[3]) * (in[6] << 1) + ((u64) in[4]) * (in[5] << 1); tmp[10] = ((u64) in[2]) * (in[8] << 1) + ((u64) in[3]) * (in[7] << 2) + ((u64) in[4]) * (in[6] << 1) + ((u64) in[5]) * (in[5] << 1); tmp[11] = ((u64) in[3]) * (in[8] << 1) + ((u64) in[4]) * (in[7] << 1) + ((u64) in[5]) * (in[6] << 1); tmp[12] = ((u64) in[4]) * (in[8] << 1) + ((u64) in[5]) * (in[7] << 2) + ((u64) in[6]) * in[6]; tmp[13] = ((u64) in[5]) * (in[8] << 1) + ((u64) in[6]) * (in[7] << 1); tmp[14] = ((u64) in[6]) * (in[8] << 1) + ((u64) in[7]) * (in[7] << 1); tmp[15] = ((u64) in[7]) * (in[8] << 1); tmp[16] = ((u64) in[8]) * in[8]; felem_reduce_degree(out, tmp); } /* felem_mul sets out=in*in2. * * On entry: in[0,2,...] < 2**30, in[1,3,...] < 2**29 and * in2[0,2,...] < 2**30, in2[1,3,...] < 2**29. * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */ static void felem_mul(felem out, const felem in, const felem in2) { u64 tmp[17]; tmp[0] = ((u64) in[0]) * in2[0]; tmp[1] = ((u64) in[0]) * (in2[1] << 0) + ((u64) in[1]) * (in2[0] << 0); tmp[2] = ((u64) in[0]) * (in2[2] << 0) + ((u64) in[1]) * (in2[1] << 1) + ((u64) in[2]) * (in2[0] << 0); tmp[3] = ((u64) in[0]) * (in2[3] << 0) + ((u64) in[1]) * (in2[2] << 0) + ((u64) in[2]) * (in2[1] << 0) + ((u64) in[3]) * (in2[0] << 0); tmp[4] = ((u64) in[0]) * (in2[4] << 0) + ((u64) in[1]) * (in2[3] << 1) + ((u64) in[2]) * (in2[2] << 0) + ((u64) in[3]) * (in2[1] << 1) + ((u64) in[4]) * (in2[0] << 0); tmp[5] = ((u64) in[0]) * (in2[5] << 0) + ((u64) in[1]) * (in2[4] << 0) + ((u64) in[2]) * (in2[3] << 0) + ((u64) in[3]) * (in2[2] << 0) + ((u64) in[4]) * (in2[1] << 0) + ((u64) in[5]) * (in2[0] << 0); tmp[6] = ((u64) in[0]) * (in2[6] << 0) + ((u64) in[1]) * (in2[5] << 1) + ((u64) in[2]) * (in2[4] << 0) + ((u64) in[3]) * (in2[3] << 1) + ((u64) in[4]) * (in2[2] << 0) + ((u64) in[5]) * (in2[1] << 1) + ((u64) in[6]) * (in2[0] << 0); tmp[7] = ((u64) in[0]) * (in2[7] << 0) + ((u64) in[1]) * (in2[6] << 0) + ((u64) in[2]) * (in2[5] << 0) + ((u64) in[3]) * (in2[4] << 0) + ((u64) in[4]) * (in2[3] << 0) + ((u64) in[5]) * (in2[2] << 0) + ((u64) in[6]) * (in2[1] << 0) + ((u64) in[7]) * (in2[0] << 0); /* tmp[8] has the greatest value but doesn't overflow. See logic in * felem_square. */ tmp[8] = ((u64) in[0]) * (in2[8] << 0) + ((u64) in[1]) * (in2[7] << 1) + ((u64) in[2]) * (in2[6] << 0) + ((u64) in[3]) * (in2[5] << 1) + ((u64) in[4]) * (in2[4] << 0) + ((u64) in[5]) * (in2[3] << 1) + ((u64) in[6]) * (in2[2] << 0) + ((u64) in[7]) * (in2[1] << 1) + ((u64) in[8]) * (in2[0] << 0); tmp[9] = ((u64) in[1]) * (in2[8] << 0) + ((u64) in[2]) * (in2[7] << 0) + ((u64) in[3]) * (in2[6] << 0) + ((u64) in[4]) * (in2[5] << 0) + ((u64) in[5]) * (in2[4] << 0) + ((u64) in[6]) * (in2[3] << 0) + ((u64) in[7]) * (in2[2] << 0) + ((u64) in[8]) * (in2[1] << 0); tmp[10] = ((u64) in[2]) * (in2[8] << 0) + ((u64) in[3]) * (in2[7] << 1) + ((u64) in[4]) * (in2[6] << 0) + ((u64) in[5]) * (in2[5] << 1) + ((u64) in[6]) * (in2[4] << 0) + ((u64) in[7]) * (in2[3] << 1) + ((u64) in[8]) * (in2[2] << 0); tmp[11] = ((u64) in[3]) * (in2[8] << 0) + ((u64) in[4]) * (in2[7] << 0) + ((u64) in[5]) * (in2[6] << 0) + ((u64) in[6]) * (in2[5] << 0) + ((u64) in[7]) * (in2[4] << 0) + ((u64) in[8]) * (in2[3] << 0); tmp[12] = ((u64) in[4]) * (in2[8] << 0) + ((u64) in[5]) * (in2[7] << 1) + ((u64) in[6]) * (in2[6] << 0) + ((u64) in[7]) * (in2[5] << 1) + ((u64) in[8]) * (in2[4] << 0); tmp[13] = ((u64) in[5]) * (in2[8] << 0) + ((u64) in[6]) * (in2[7] << 0) + ((u64) in[7]) * (in2[6] << 0) + ((u64) in[8]) * (in2[5] << 0); tmp[14] = ((u64) in[6]) * (in2[8] << 0) + ((u64) in[7]) * (in2[7] << 1) + ((u64) in[8]) * (in2[6] << 0); tmp[15] = ((u64) in[7]) * (in2[8] << 0) + ((u64) in[8]) * (in2[7] << 0); tmp[16] = ((u64) in[8]) * (in2[8] << 0); felem_reduce_degree(out, tmp); } static void felem_assign(felem out, const felem in) { memcpy(out, in, sizeof(felem)); } /* felem_inv calculates |out| = |in|^{-1} * * Based on Fermat's Little Theorem: * a^p = a (mod p) * a^{p-1} = 1 (mod p) * a^{p-2} = a^{-1} (mod p) */ static void felem_inv(felem out, const felem in) { felem ftmp, ftmp2; /* each e_I will hold |in|^{2^I - 1} */ felem e2, e4, e8, e16, e32, e64; unsigned i; felem_square(ftmp, in); /* 2^1 */ felem_mul(ftmp, in, ftmp); /* 2^2 - 2^0 */ felem_assign(e2, ftmp); felem_square(ftmp, ftmp); /* 2^3 - 2^1 */ felem_square(ftmp, ftmp); /* 2^4 - 2^2 */ felem_mul(ftmp, ftmp, e2); /* 2^4 - 2^0 */ felem_assign(e4, ftmp); felem_square(ftmp, ftmp); /* 2^5 - 2^1 */ felem_square(ftmp, ftmp); /* 2^6 - 2^2 */ felem_square(ftmp, ftmp); /* 2^7 - 2^3 */ felem_square(ftmp, ftmp); /* 2^8 - 2^4 */ felem_mul(ftmp, ftmp, e4); /* 2^8 - 2^0 */ felem_assign(e8, ftmp); for (i = 0; i < 8; i++) { felem_square(ftmp, ftmp); } /* 2^16 - 2^8 */ felem_mul(ftmp, ftmp, e8); /* 2^16 - 2^0 */ felem_assign(e16, ftmp); for (i = 0; i < 16; i++) { felem_square(ftmp, ftmp); } /* 2^32 - 2^16 */ felem_mul(ftmp, ftmp, e16); /* 2^32 - 2^0 */ felem_assign(e32, ftmp); for (i = 0; i < 32; i++) { felem_square(ftmp, ftmp); } /* 2^64 - 2^32 */ felem_assign(e64, ftmp); felem_mul(ftmp, ftmp, in); /* 2^64 - 2^32 + 2^0 */ for (i = 0; i < 192; i++) { felem_square(ftmp, ftmp); } /* 2^256 - 2^224 + 2^192 */ felem_mul(ftmp2, e64, e32); /* 2^64 - 2^0 */ for (i = 0; i < 16; i++) { felem_square(ftmp2, ftmp2); } /* 2^80 - 2^16 */ felem_mul(ftmp2, ftmp2, e16); /* 2^80 - 2^0 */ for (i = 0; i < 8; i++) { felem_square(ftmp2, ftmp2); } /* 2^88 - 2^8 */ felem_mul(ftmp2, ftmp2, e8); /* 2^88 - 2^0 */ for (i = 0; i < 4; i++) { felem_square(ftmp2, ftmp2); } /* 2^92 - 2^4 */ felem_mul(ftmp2, ftmp2, e4); /* 2^92 - 2^0 */ felem_square(ftmp2, ftmp2); /* 2^93 - 2^1 */ felem_square(ftmp2, ftmp2); /* 2^94 - 2^2 */ felem_mul(ftmp2, ftmp2, e2); /* 2^94 - 2^0 */ felem_square(ftmp2, ftmp2); /* 2^95 - 2^1 */ felem_square(ftmp2, ftmp2); /* 2^96 - 2^2 */ felem_mul(ftmp2, ftmp2, in); /* 2^96 - 3 */ felem_mul(out, ftmp2, ftmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */ } /* felem_scalar_3 sets out=3*out. * * On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29. * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */ static void felem_scalar_3(felem out) { limb carry = 0; unsigned i; for (i = 0;; i++) { out[i] *= 3; out[i] += carry; carry = out[i] >> 29; out[i] &= kBottom29Bits; i++; if (i == NLIMBS) break; out[i] *= 3; out[i] += carry; carry = out[i] >> 28; out[i] &= kBottom28Bits; } felem_reduce_carry(out, carry); } /* felem_scalar_4 sets out=4*out. * * On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29. * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */ static void felem_scalar_4(felem out) { limb carry = 0, next_carry; unsigned i; for (i = 0;; i++) { next_carry = out[i] >> 27; out[i] <<= 2; out[i] &= kBottom29Bits; out[i] += carry; carry = next_carry + (out[i] >> 29); out[i] &= kBottom29Bits; i++; if (i == NLIMBS) break; next_carry = out[i] >> 26; out[i] <<= 2; out[i] &= kBottom28Bits; out[i] += carry; carry = next_carry + (out[i] >> 28); out[i] &= kBottom28Bits; } felem_reduce_carry(out, carry); } /* felem_scalar_8 sets out=8*out. * * On entry: out[0,2,...] < 2**30, out[1,3,...] < 2**29. * On exit: out[0,2,...] < 2**30, out[1,3,...] < 2**29. */ static void felem_scalar_8(felem out) { limb carry = 0, next_carry; unsigned i; for (i = 0;; i++) { next_carry = out[i] >> 26; out[i] <<= 3; out[i] &= kBottom29Bits; out[i] += carry; carry = next_carry + (out[i] >> 29); out[i] &= kBottom29Bits; i++; if (i == NLIMBS) break; next_carry = out[i] >> 25; out[i] <<= 3; out[i] &= kBottom28Bits; out[i] += carry; carry = next_carry + (out[i] >> 28); out[i] &= kBottom28Bits; } felem_reduce_carry(out, carry); } /* felem_is_zero_vartime returns 1 iff |in| == 0. It takes a variable amount of * time depending on the value of |in|. */ static char felem_is_zero_vartime(const felem in) { limb carry; int i; limb tmp[NLIMBS]; felem_assign(tmp, in); /* First, reduce tmp to a minimal form. */ do { carry = 0; for (i = 0;; i++) { tmp[i] += carry; carry = tmp[i] >> 29; tmp[i] &= kBottom29Bits; i++; if (i == NLIMBS) break; tmp[i] += carry; carry = tmp[i] >> 28; tmp[i] &= kBottom28Bits; } felem_reduce_carry(tmp, carry); } while (carry); /* tmp < 2**257, so the only possible zero values are 0, p and 2p. */ return memcmp(tmp, kZero, sizeof(tmp)) == 0 || memcmp(tmp, kP, sizeof(tmp)) == 0 || memcmp(tmp, k2P, sizeof(tmp)) == 0; } /* Group operations: * * Elements of the elliptic curve group are represented in Jacobian * coordinates: (x, y, z). An affine point (x', y') is x'=x/z**2, y'=y/z**3 in * Jacobian form. */ /* point_double sets {x_out,y_out,z_out} = 2*{x,y,z}. * * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l */ static void point_double(felem x_out, felem y_out, felem z_out, const felem x, const felem y, const felem z) { felem delta, gamma, alpha, beta, tmp, tmp2; felem_square(delta, z); felem_square(gamma, y); felem_mul(beta, x, gamma); felem_sum(tmp, x, delta); felem_diff(tmp2, x, delta); felem_mul(alpha, tmp, tmp2); felem_scalar_3(alpha); felem_sum(tmp, y, z); felem_square(tmp, tmp); felem_diff(tmp, tmp, gamma); felem_diff(z_out, tmp, delta); felem_scalar_4(beta); felem_square(x_out, alpha); felem_diff(x_out, x_out, beta); felem_diff(x_out, x_out, beta); felem_diff(tmp, beta, x_out); felem_mul(tmp, alpha, tmp); felem_square(tmp2, gamma); felem_scalar_8(tmp2); felem_diff(y_out, tmp, tmp2); } /* point_add_mixed sets {x_out,y_out,z_out} = {x1,y1,z1} + {x2,y2,1}. * (i.e. the second point is affine.) * * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl * * Note that this function does not handle P+P, infinity+P nor P+infinity * correctly. */ static void point_add_mixed(felem x_out, felem y_out, felem z_out, const felem x1, const felem y1, const felem z1, const felem x2, const felem y2) { felem z1z1, z1z1z1, s2, u2, h, i, j, r, rr, v, tmp; felem_square(z1z1, z1); felem_sum(tmp, z1, z1); felem_mul(u2, x2, z1z1); felem_mul(z1z1z1, z1, z1z1); felem_mul(s2, y2, z1z1z1); felem_diff(h, u2, x1); felem_sum(i, h, h); felem_square(i, i); felem_mul(j, h, i); felem_diff(r, s2, y1); felem_sum(r, r, r); felem_mul(v, x1, i); felem_mul(z_out, tmp, h); felem_square(rr, r); felem_diff(x_out, rr, j); felem_diff(x_out, x_out, v); felem_diff(x_out, x_out, v); felem_diff(tmp, v, x_out); felem_mul(y_out, tmp, r); felem_mul(tmp, y1, j); felem_diff(y_out, y_out, tmp); felem_diff(y_out, y_out, tmp); } /* point_add sets {x_out,y_out,z_out} = {x1,y1,z1} + {x2,y2,z2}. * * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl * * Note that this function does not handle P+P, infinity+P nor P+infinity * correctly. */ static void point_add(felem x_out, felem y_out, felem z_out, const felem x1, const felem y1, const felem z1, const felem x2, const felem y2, const felem z2) { felem z1z1, z1z1z1, z2z2, z2z2z2, s1, s2, u1, u2, h, i, j, r, rr, v, tmp; felem_square(z1z1, z1); felem_square(z2z2, z2); felem_mul(u1, x1, z2z2); felem_sum(tmp, z1, z2); felem_square(tmp, tmp); felem_diff(tmp, tmp, z1z1); felem_diff(tmp, tmp, z2z2); felem_mul(z2z2z2, z2, z2z2); felem_mul(s1, y1, z2z2z2); felem_mul(u2, x2, z1z1); felem_mul(z1z1z1, z1, z1z1); felem_mul(s2, y2, z1z1z1); felem_diff(h, u2, u1); felem_sum(i, h, h); felem_square(i, i); felem_mul(j, h, i); felem_diff(r, s2, s1); felem_sum(r, r, r); felem_mul(v, u1, i); felem_mul(z_out, tmp, h); felem_square(rr, r); felem_diff(x_out, rr, j); felem_diff(x_out, x_out, v); felem_diff(x_out, x_out, v); felem_diff(tmp, v, x_out); felem_mul(y_out, tmp, r); felem_mul(tmp, s1, j); felem_diff(y_out, y_out, tmp); felem_diff(y_out, y_out, tmp); } /* point_add_or_double_vartime sets {x_out,y_out,z_out} = {x1,y1,z1} + * {x2,y2,z2}. * * See http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl * * This function handles the case where {x1,y1,z1}={x2,y2,z2}. */ static void point_add_or_double_vartime( felem x_out, felem y_out, felem z_out, const felem x1, const felem y1, const felem z1, const felem x2, const felem y2, const felem z2) { felem z1z1, z1z1z1, z2z2, z2z2z2, s1, s2, u1, u2, h, i, j, r, rr, v, tmp; char x_equal, y_equal; felem_square(z1z1, z1); felem_square(z2z2, z2); felem_mul(u1, x1, z2z2); felem_sum(tmp, z1, z2); felem_square(tmp, tmp); felem_diff(tmp, tmp, z1z1); felem_diff(tmp, tmp, z2z2); felem_mul(z2z2z2, z2, z2z2); felem_mul(s1, y1, z2z2z2); felem_mul(u2, x2, z1z1); felem_mul(z1z1z1, z1, z1z1); felem_mul(s2, y2, z1z1z1); felem_diff(h, u2, u1); x_equal = felem_is_zero_vartime(h); felem_sum(i, h, h); felem_square(i, i); felem_mul(j, h, i); felem_diff(r, s2, s1); y_equal = felem_is_zero_vartime(r); if (x_equal && y_equal) { point_double(x_out, y_out, z_out, x1, y1, z1); return; } felem_sum(r, r, r); felem_mul(v, u1, i); felem_mul(z_out, tmp, h); felem_square(rr, r); felem_diff(x_out, rr, j); felem_diff(x_out, x_out, v); felem_diff(x_out, x_out, v); felem_diff(tmp, v, x_out); felem_mul(y_out, tmp, r); felem_mul(tmp, s1, j); felem_diff(y_out, y_out, tmp); felem_diff(y_out, y_out, tmp); } /* copy_conditional sets out=in if mask = 0xffffffff in constant time. * * On entry: mask is either 0 or 0xffffffff. */ static void copy_conditional(felem out, const felem in, limb mask) { int i; for (i = 0; i < NLIMBS; i++) { const limb tmp = mask & (in[i] ^ out[i]); out[i] ^= tmp; } } /* select_affine_point sets {out_x,out_y} to the index'th entry of table. * On entry: index < 16, table[0] must be zero. */ static void select_affine_point(felem out_x, felem out_y, const limb* table, limb index) { limb i, j; memset(out_x, 0, sizeof(felem)); memset(out_y, 0, sizeof(felem)); for (i = 1; i < 16; i++) { limb mask = i ^ index; mask |= mask >> 2; mask |= mask >> 1; mask &= 1; mask--; for (j = 0; j < NLIMBS; j++, table++) { out_x[j] |= *table & mask; } for (j = 0; j < NLIMBS; j++, table++) { out_y[j] |= *table & mask; } } } /* select_jacobian_point sets {out_x,out_y,out_z} to the index'th entry of * table. On entry: index < 16, table[0] must be zero. */ static void select_jacobian_point(felem out_x, felem out_y, felem out_z, const limb* table, limb index) { limb i, j; memset(out_x, 0, sizeof(felem)); memset(out_y, 0, sizeof(felem)); memset(out_z, 0, sizeof(felem)); /* The implicit value at index 0 is all zero. We don't need to perform that * iteration of the loop because we already set out_* to zero. */ table += 3 * NLIMBS; // Hit all entries to obscure cache profiling. for (i = 1; i < 16; i++) { limb mask = i ^ index; mask |= mask >> 2; mask |= mask >> 1; mask &= 1; mask--; for (j = 0; j < NLIMBS; j++, table++) { out_x[j] |= *table & mask; } for (j = 0; j < NLIMBS; j++, table++) { out_y[j] |= *table & mask; } for (j = 0; j < NLIMBS; j++, table++) { out_z[j] |= *table & mask; } } } /* scalar_base_mult sets {nx,ny,nz} = scalar*G where scalar is a little-endian * number. Note that the value of scalar must be less than the order of the * group. */ static void scalar_base_mult(felem nx, felem ny, felem nz, const cryptonite_p256_int* scalar) { int i, j; limb n_is_infinity_mask = -1, p_is_noninfinite_mask, mask; u32 table_offset; felem px, py; felem tx, ty, tz; memset(nx, 0, sizeof(felem)); memset(ny, 0, sizeof(felem)); memset(nz, 0, sizeof(felem)); /* The loop adds bits at positions 0, 64, 128 and 192, followed by * positions 32,96,160 and 224 and does this 32 times. */ for (i = 0; i < 32; i++) { if (i) { point_double(nx, ny, nz, nx, ny, nz); } table_offset = 0; for (j = 0; j <= 32; j += 32) { char bit0 = cryptonite_p256_get_bit(scalar, 31 - i + j); char bit1 = cryptonite_p256_get_bit(scalar, 95 - i + j); char bit2 = cryptonite_p256_get_bit(scalar, 159 - i + j); char bit3 = cryptonite_p256_get_bit(scalar, 223 - i + j); limb index = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3); select_affine_point(px, py, kPrecomputed + table_offset, index); table_offset += 30 * NLIMBS; /* Since scalar is less than the order of the group, we know that * {nx,ny,nz} != {px,py,1}, unless both are zero, which we handle * below. */ point_add_mixed(tx, ty, tz, nx, ny, nz, px, py); /* The result of point_add_mixed is incorrect if {nx,ny,nz} is zero * (a.k.a. the point at infinity). We handle that situation by * copying the point from the table. */ copy_conditional(nx, px, n_is_infinity_mask); copy_conditional(ny, py, n_is_infinity_mask); copy_conditional(nz, kOne, n_is_infinity_mask); /* Equally, the result is also wrong if the point from the table is * zero, which happens when the index is zero. We handle that by * only copying from {tx,ty,tz} to {nx,ny,nz} if index != 0. */ p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index); mask = p_is_noninfinite_mask & ~n_is_infinity_mask; copy_conditional(nx, tx, mask); copy_conditional(ny, ty, mask); copy_conditional(nz, tz, mask); /* If p was not zero, then n is now non-zero. */ n_is_infinity_mask &= ~p_is_noninfinite_mask; } } } /* point_to_affine converts a Jacobian point to an affine point. If the input * is the point at infinity then it returns (0, 0) in constant time. */ static void point_to_affine(felem x_out, felem y_out, const felem nx, const felem ny, const felem nz) { felem z_inv, z_inv_sq; felem_inv(z_inv, nz); felem_square(z_inv_sq, z_inv); felem_mul(x_out, nx, z_inv_sq); felem_mul(z_inv, z_inv, z_inv_sq); felem_mul(y_out, ny, z_inv); } /* scalar_base_mult sets {nx,ny,nz} = scalar*{x,y}. */ static void scalar_mult(felem nx, felem ny, felem nz, const felem x, const felem y, const cryptonite_p256_int* scalar) { int i; felem px, py, pz, tx, ty, tz; felem precomp[16][3]; limb n_is_infinity_mask, index, p_is_noninfinite_mask, mask; /* We precompute 0,1,2,... times {x,y}. */ memset(precomp, 0, sizeof(felem) * 3); memcpy(&precomp[1][0], x, sizeof(felem)); memcpy(&precomp[1][1], y, sizeof(felem)); memcpy(&precomp[1][2], kOne, sizeof(felem)); for (i = 2; i < 16; i += 2) { point_double(precomp[i][0], precomp[i][1], precomp[i][2], precomp[i / 2][0], precomp[i / 2][1], precomp[i / 2][2]); point_add_mixed(precomp[i + 1][0], precomp[i + 1][1], precomp[i + 1][2], precomp[i][0], precomp[i][1], precomp[i][2], x, y); } memset(nx, 0, sizeof(felem)); memset(ny, 0, sizeof(felem)); memset(nz, 0, sizeof(felem)); n_is_infinity_mask = -1; /* We add in a window of four bits each iteration and do this 64 times. */ for (i = 0; i < 256; i += 4) { if (i) { point_double(nx, ny, nz, nx, ny, nz); point_double(nx, ny, nz, nx, ny, nz); point_double(nx, ny, nz, nx, ny, nz); point_double(nx, ny, nz, nx, ny, nz); } index = (cryptonite_p256_get_bit(scalar, 255 - i - 0) << 3) | (cryptonite_p256_get_bit(scalar, 255 - i - 1) << 2) | (cryptonite_p256_get_bit(scalar, 255 - i - 2) << 1) | cryptonite_p256_get_bit(scalar, 255 - i - 3); /* See the comments in scalar_base_mult about handling infinities. */ select_jacobian_point(px, py, pz, precomp[0][0], index); point_add(tx, ty, tz, nx, ny, nz, px, py, pz); copy_conditional(nx, px, n_is_infinity_mask); copy_conditional(ny, py, n_is_infinity_mask); copy_conditional(nz, pz, n_is_infinity_mask); p_is_noninfinite_mask = NON_ZERO_TO_ALL_ONES(index); mask = p_is_noninfinite_mask & ~n_is_infinity_mask; copy_conditional(nx, tx, mask); copy_conditional(ny, ty, mask); copy_conditional(nz, tz, mask); n_is_infinity_mask &= ~p_is_noninfinite_mask; } } #define kRDigits {2, 0, 0, 0xfffffffe, 0xffffffff, 0xffffffff, 0xfffffffd, 1} // 2^257 mod p256.p #define kRInvDigits {0x80000000, 1, 0xffffffff, 0, 0x80000001, 0xfffffffe, 1, 0x7fffffff} // 1 / 2^257 mod p256.p static const cryptonite_p256_int kR = { kRDigits }; static const cryptonite_p256_int kRInv = { kRInvDigits }; /* to_montgomery sets out = R*in. */ static void to_montgomery(felem out, const cryptonite_p256_int* in) { cryptonite_p256_int in_shifted; int i; cryptonite_p256_init(&in_shifted); cryptonite_p256_modmul(&cryptonite_SECP256r1_p, in, 0, &kR, &in_shifted); for (i = 0; i < NLIMBS; i++) { if ((i & 1) == 0) { out[i] = P256_DIGIT(&in_shifted, 0) & kBottom29Bits; cryptonite_p256_shr(&in_shifted, 29, &in_shifted); } else { out[i] = P256_DIGIT(&in_shifted, 0) & kBottom28Bits; cryptonite_p256_shr(&in_shifted, 28, &in_shifted); } } cryptonite_p256_clear(&in_shifted); } /* from_montgomery sets out=in/R. */ static void from_montgomery(cryptonite_p256_int* out, const felem in) { cryptonite_p256_int result, tmp; int i, top; cryptonite_p256_init(&result); cryptonite_p256_init(&tmp); cryptonite_p256_add_d(&tmp, in[NLIMBS - 1], &result); for (i = NLIMBS - 2; i >= 0; i--) { if ((i & 1) == 0) { top = cryptonite_p256_shl(&result, 29, &tmp); } else { top = cryptonite_p256_shl(&result, 28, &tmp); } top |= cryptonite_p256_add_d(&tmp, in[i], &result); } cryptonite_p256_modmul(&cryptonite_SECP256r1_p, &kRInv, top, &result, out); cryptonite_p256_clear(&result); cryptonite_p256_clear(&tmp); } /* cryptonite_p256_base_point_mul sets {out_x,out_y} = nG, where n is < the * order of the group. */ void cryptonite_p256_base_point_mul(const cryptonite_p256_int* n, cryptonite_p256_int* out_x, cryptonite_p256_int* out_y) { felem x, y, z; scalar_base_mult(x, y, z, n); { felem x_affine, y_affine; point_to_affine(x_affine, y_affine, x, y, z); from_montgomery(out_x, x_affine); from_montgomery(out_y, y_affine); } } /* cryptonite_p256_points_mul_vartime sets {out_x,out_y} = n1*G + n2*{in_x,in_y}, where * n1 and n2 are < the order of the group. * * As indicated by the name, this function operates in variable time. This * is safe because it's used for signature validation which doesn't deal * with secrets. */ void cryptonite_p256_points_mul_vartime( const cryptonite_p256_int* n1, const cryptonite_p256_int* n2, const cryptonite_p256_int* in_x, const cryptonite_p256_int* in_y, cryptonite_p256_int* out_x, cryptonite_p256_int* out_y) { felem x1, y1, z1, x2, y2, z2, px, py; /* If both scalars are zero, then the result is the point at infinity. */ if (cryptonite_p256_is_zero(n1) != 0 && cryptonite_p256_is_zero(n2) != 0) { cryptonite_p256_clear(out_x); cryptonite_p256_clear(out_y); return; } to_montgomery(px, in_x); to_montgomery(py, in_y); scalar_base_mult(x1, y1, z1, n1); scalar_mult(x2, y2, z2, px, py, n2); if (cryptonite_p256_is_zero(n2) != 0) { /* If n2 == 0, then {x2,y2,z2} is zero and the result is just * {x1,y1,z1}. */ } else if (cryptonite_p256_is_zero(n1) != 0) { /* If n1 == 0, then {x1,y1,z1} is zero and the result is just * {x2,y2,z2}. */ memcpy(x1, x2, sizeof(x2)); memcpy(y1, y2, sizeof(y2)); memcpy(z1, z2, sizeof(z2)); } else { /* This function handles the case where {x1,y1,z1} == {x2,y2,z2}. */ point_add_or_double_vartime(x1, y1, z1, x1, y1, z1, x2, y2, z2); } point_to_affine(px, py, x1, y1, z1); from_montgomery(out_x, px); from_montgomery(out_y, py); } /* this function is not part of the original source add 2 points together. so far untested. probably vartime, as it use point_add_or_double_vartime */ void cryptonite_p256e_point_add( const cryptonite_p256_int *in_x1, const cryptonite_p256_int *in_y1, const cryptonite_p256_int *in_x2, const cryptonite_p256_int *in_y2, cryptonite_p256_int *out_x, cryptonite_p256_int *out_y) { felem x1, y1, z1, x2, y2, z2, px1, py1, px2, py2; const cryptonite_p256_int one = P256_ONE; to_montgomery(px1, in_x1); to_montgomery(py1, in_y1); to_montgomery(px2, in_x2); to_montgomery(py2, in_y2); scalar_mult(x1, y1, z1, px1, py1, &one); scalar_mult(x2, y2, z2, px2, py2, &one); point_add_or_double_vartime(x1, y1, z1, x1, y1, z1, x2, y2, z2); point_to_affine(px1, py1, x1, y1, z1); from_montgomery(out_x, px1); from_montgomery(out_y, py1); } cryptonite-0.23/cbits/cryptonite_blake2s.c0000644000000000000000000000060012673727640017111 0ustar0000000000000000#include "cryptonite_blake2s.h" void cryptonite_blake2s_init(blake2s_ctx *ctx, uint32_t hashlen) { blake2s_init(ctx, hashlen / 8); } void cryptonite_blake2s_update(blake2s_ctx *ctx, const uint8_t *data, uint32_t len) { blake2s_update(ctx, data, len); } void cryptonite_blake2s_finalize(blake2s_ctx *ctx, uint32_t hashlen, uint8_t *out) { blake2s_final(ctx, out, hashlen / 8); } cryptonite-0.23/cbits/cryptonite_blake2sp.c0000644000000000000000000000061212673727640017274 0ustar0000000000000000#include "cryptonite_blake2sp.h" void cryptonite_blake2sp_init(blake2sp_ctx *ctx, uint32_t hashlen) { blake2sp_init(ctx, hashlen / 8); } void cryptonite_blake2sp_update(blake2sp_ctx *ctx, const uint8_t *data, uint32_t len) { blake2sp_update(ctx, data, len); } void cryptonite_blake2sp_finalize(blake2sp_ctx *ctx, uint32_t hashlen, uint8_t *out) { blake2sp_final(ctx, out, hashlen / 8); } cryptonite-0.23/cbits/cryptonite_blake2b.c0000644000000000000000000000060012673727640017070 0ustar0000000000000000#include "cryptonite_blake2b.h" void cryptonite_blake2b_init(blake2b_ctx *ctx, uint32_t hashlen) { blake2b_init(ctx, hashlen / 8); } void cryptonite_blake2b_update(blake2b_ctx *ctx, const uint8_t *data, uint32_t len) { blake2b_update(ctx, data, len); } void cryptonite_blake2b_finalize(blake2b_ctx *ctx, uint32_t hashlen, uint8_t *out) { blake2b_final(ctx, out, hashlen / 8); } cryptonite-0.23/cbits/cryptonite_blake2bp.c0000644000000000000000000000061212673727640017253 0ustar0000000000000000#include "cryptonite_blake2bp.h" void cryptonite_blake2bp_init(blake2bp_ctx *ctx, uint32_t hashlen) { blake2bp_init(ctx, hashlen / 8); } void cryptonite_blake2bp_update(blake2bp_ctx *ctx, const uint8_t *data, uint32_t len) { blake2bp_update(ctx, data, len); } void cryptonite_blake2bp_finalize(blake2bp_ctx *ctx, uint32_t hashlen, uint8_t *out) { blake2bp_final(ctx, out, hashlen / 8); } cryptonite-0.23/cbits/cryptonite_poly1305.c0000644000000000000000000001603013022507227017050 0ustar0000000000000000/* * Copyright (c) 2014 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * The following code contains some code copied from and inspired by poly1305-donna * in poly1305_do_chunk and poly1305_finalize which is licensed under MIT or PUBLIC DOMAIN. * see [poly1305-donna](https://github.com/floodyberry/poly1305-donna) * */ #include #include #include "cryptonite_poly1305.h" #include "cryptonite_bitfn.h" static inline uint32_t load32(uint8_t *p) { return (le32_to_cpu(*((uint32_t *) p))); } static void poly1305_do_chunk(poly1305_ctx *ctx, uint8_t *data, int blocks, int final) { /* following is a cleanup copy of code available poly1305-donna */ const uint32_t hibit = (final) ? 0 : (1 << 24); /* 1 << 128 */ uint32_t r0,r1,r2,r3,r4; uint32_t s1,s2,s3,s4; uint32_t h0,h1,h2,h3,h4; uint64_t d0,d1,d2,d3,d4; uint32_t c; /* load r[i], h[i] */ h0 = ctx->h[0]; h1 = ctx->h[1]; h2 = ctx->h[2]; h3 = ctx->h[3]; h4 = ctx->h[4]; r0 = ctx->r[0]; r1 = ctx->r[1]; r2 = ctx->r[2]; r3 = ctx->r[3]; r4 = ctx->r[4]; /* s[i] = r[i] * 5 */ s1 = r1 * 5; s2 = r2 * 5; s3 = r3 * 5; s4 = r4 * 5; while (blocks--) { h0 += (load32(data+ 0) ) & 0x3ffffff; h1 += (load32(data+ 3) >> 2) & 0x3ffffff; h2 += (load32(data+ 6) >> 4) & 0x3ffffff; h3 += (load32(data+ 9) >> 6) & 0x3ffffff; h4 += (load32(data+12) >> 8) | hibit; d0 = ((uint64_t)h0 * r0) + ((uint64_t)h1 * s4) + ((uint64_t)h2 * s3) + ((uint64_t)h3 * s2) + ((uint64_t)h4 * s1); d1 = ((uint64_t)h0 * r1) + ((uint64_t)h1 * r0) + ((uint64_t)h2 * s4) + ((uint64_t)h3 * s3) + ((uint64_t)h4 * s2); d2 = ((uint64_t)h0 * r2) + ((uint64_t)h1 * r1) + ((uint64_t)h2 * r0) + ((uint64_t)h3 * s4) + ((uint64_t)h4 * s3); d3 = ((uint64_t)h0 * r3) + ((uint64_t)h1 * r2) + ((uint64_t)h2 * r1) + ((uint64_t)h3 * r0) + ((uint64_t)h4 * s4); d4 = ((uint64_t)h0 * r4) + ((uint64_t)h1 * r3) + ((uint64_t)h2 * r2) + ((uint64_t)h3 * r1) + ((uint64_t)h4 * r0); c = (uint32_t)(d0 >> 26); h0 = (uint32_t)d0 & 0x3ffffff; d1 += c; c = (uint32_t)(d1 >> 26); h1 = (uint32_t)d1 & 0x3ffffff; d2 += c; c = (uint32_t)(d2 >> 26); h2 = (uint32_t)d2 & 0x3ffffff; d3 += c; c = (uint32_t)(d3 >> 26); h3 = (uint32_t)d3 & 0x3ffffff; d4 += c; c = (uint32_t)(d4 >> 26); h4 = (uint32_t)d4 & 0x3ffffff; h0 += c * 5; c = (h0 >> 26); h0 = h0 & 0x3ffffff; h1 += c; data += 16; } /* store h[i] */ ctx->h[0] = h0; ctx->h[1] = h1; ctx->h[2] = h2; ctx->h[3] = h3; ctx->h[4] = h4; } void cryptonite_poly1305_init(poly1305_ctx *ctx, poly1305_key *key) { uint8_t *k = (uint8_t *) key; memset(ctx, 0, sizeof(poly1305_ctx)); ctx->r[0] = (load32(&k[ 0]) ) & 0x3ffffff; ctx->r[1] = (load32(&k[ 3]) >> 2) & 0x3ffff03; ctx->r[2] = (load32(&k[ 6]) >> 4) & 0x3ffc0ff; ctx->r[3] = (load32(&k[ 9]) >> 6) & 0x3f03fff; ctx->r[4] = (load32(&k[12]) >> 8) & 0x00fffff; ctx->pad[0] = load32(&k[16]); ctx->pad[1] = load32(&k[20]); ctx->pad[2] = load32(&k[24]); ctx->pad[3] = load32(&k[28]); ctx->index = 0; } void cryptonite_poly1305_update(poly1305_ctx *ctx, uint8_t *data, uint32_t length) { uint32_t to_fill, nb_blocks_bytes; to_fill = 16 - ctx->index; /* process partial buffer if there's enough data to make a block */ if (ctx->index && length >= to_fill) { memcpy(ctx->buf + ctx->index, data, to_fill); poly1305_do_chunk(ctx, ctx->buf, 1, 0); ctx->index = 0; length -= to_fill; data += to_fill; } /* process as much 16-block as possible */ nb_blocks_bytes = length & ~(16 - 1); poly1305_do_chunk(ctx, data, nb_blocks_bytes >> 4, 0); data += nb_blocks_bytes; length &= 0xf; /* fill the remaining bytes in the partial buffer */ if (length) { memcpy(ctx->buf + ctx->index, data, length); ctx->index += length; } } void cryptonite_poly1305_finalize(poly1305_mac mac8, poly1305_ctx *ctx) { uint32_t h0,h1,h2,h3,h4,c; uint32_t g0,g1,g2,g3,g4; uint64_t f; uint32_t mask; uint32_t *mac = (uint32_t *) mac8; int i; if (ctx->index) { /* append partial final buffer with 10* then process */ ctx->buf[ctx->index] = 0x1; for (i = ctx->index + 1; i < 16; i++) ctx->buf[i] = 0x0; poly1305_do_chunk(ctx, ctx->buf, 1, 1); } /* following is a cleanup copy of code available poly1305-donna */ /* fully carry h */ h0 = ctx->h[0]; h1 = ctx->h[1]; h2 = ctx->h[2]; h3 = ctx->h[3]; h4 = ctx->h[4]; c = h1 >> 26; h1 = h1 & 0x3ffffff; h2 += c; c = h2 >> 26; h2 = h2 & 0x3ffffff; h3 += c; c = h3 >> 26; h3 = h3 & 0x3ffffff; h4 += c; c = h4 >> 26; h4 = h4 & 0x3ffffff; h0 += c * 5; c = h0 >> 26; h0 = h0 & 0x3ffffff; h1 += c; /* compute h + -p */ g0 = h0 + 5; c = g0 >> 26; g0 &= 0x3ffffff; g1 = h1 + c; c = g1 >> 26; g1 &= 0x3ffffff; g2 = h2 + c; c = g2 >> 26; g2 &= 0x3ffffff; g3 = h3 + c; c = g3 >> 26; g3 &= 0x3ffffff; g4 = h4 + c - (1 << 26); /* select h if h < p, or h + -p if h >= p */ mask = (g4 >> ((sizeof(uint32_t) * 8) - 1)) - 1; g0 &= mask; g1 &= mask; g2 &= mask; g3 &= mask; g4 &= mask; mask = ~mask; h0 = (h0 & mask) | g0; h1 = (h1 & mask) | g1; h2 = (h2 & mask) | g2; h3 = (h3 & mask) | g3; h4 = (h4 & mask) | g4; /* h = h % (2^128) */ h0 = ((h0 ) | (h1 << 26)) & 0xffffffff; h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; /* mac = (h + pad) % (2^128) */ f = (uint64_t)h0 + ctx->pad[0]; mac[0] = cpu_to_le32((uint32_t) f); f = (uint64_t)h1 + ctx->pad[1] + (f >> 32); mac[1] = cpu_to_le32((uint32_t) f); f = (uint64_t)h2 + ctx->pad[2] + (f >> 32); mac[2] = cpu_to_le32((uint32_t) f); f = (uint64_t)h3 + ctx->pad[3] + (f >> 32); mac[3] = cpu_to_le32((uint32_t) f); } cryptonite-0.23/cbits/cryptonite_sha1.c0000644000000000000000000001472513047773333016433 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "cryptonite_sha1.h" #include "cryptonite_bitfn.h" void cryptonite_sha1_init(struct sha1_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0x67452301; ctx->h[1] = 0xefcdab89; ctx->h[2] = 0x98badcfe; ctx->h[3] = 0x10325476; ctx->h[4] = 0xc3d2e1f0; } #define f1(x, y, z) (z ^ (x & (y ^ z))) #define f2(x, y, z) (x ^ y ^ z) #define f3(x, y, z) ((x & y) + (z & (x ^ y))) #define f4(x, y, z) f2(x, y, z) #define K1 0x5a827999 #define K2 0x6ed9eba1 #define K3 0x8f1bbcdc #define K4 0xca62c1d6 #define R(a, b, c, d, e, f, k, w) \ e += rol32(a, 5) + f(b, c, d) + k + w; b = rol32(b, 30) #define M(i) (w[i & 0x0f] = rol32(w[i & 0x0f] ^ w[(i - 14) & 0x0f] \ ^ w[(i - 8) & 0x0f] ^ w[(i - 3) & 0x0f], 1)) static inline void sha1_do_chunk(struct sha1_ctx *ctx, uint32_t *buf) { uint32_t a, b, c, d, e; uint32_t w[16]; #define CPY(i) w[i] = be32_to_cpu(buf[i]) CPY(0); CPY(1); CPY(2); CPY(3); CPY(4); CPY(5); CPY(6); CPY(7); CPY(8); CPY(9); CPY(10); CPY(11); CPY(12); CPY(13); CPY(14); CPY(15); #undef CPY a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; e = ctx->h[4]; R(a, b, c, d, e, f1, K1, w[0]); R(e, a, b, c, d, f1, K1, w[1]); R(d, e, a, b, c, f1, K1, w[2]); R(c, d, e, a, b, f1, K1, w[3]); R(b, c, d, e, a, f1, K1, w[4]); R(a, b, c, d, e, f1, K1, w[5]); R(e, a, b, c, d, f1, K1, w[6]); R(d, e, a, b, c, f1, K1, w[7]); R(c, d, e, a, b, f1, K1, w[8]); R(b, c, d, e, a, f1, K1, w[9]); R(a, b, c, d, e, f1, K1, w[10]); R(e, a, b, c, d, f1, K1, w[11]); R(d, e, a, b, c, f1, K1, w[12]); R(c, d, e, a, b, f1, K1, w[13]); R(b, c, d, e, a, f1, K1, w[14]); R(a, b, c, d, e, f1, K1, w[15]); R(e, a, b, c, d, f1, K1, M(16)); R(d, e, a, b, c, f1, K1, M(17)); R(c, d, e, a, b, f1, K1, M(18)); R(b, c, d, e, a, f1, K1, M(19)); R(a, b, c, d, e, f2, K2, M(20)); R(e, a, b, c, d, f2, K2, M(21)); R(d, e, a, b, c, f2, K2, M(22)); R(c, d, e, a, b, f2, K2, M(23)); R(b, c, d, e, a, f2, K2, M(24)); R(a, b, c, d, e, f2, K2, M(25)); R(e, a, b, c, d, f2, K2, M(26)); R(d, e, a, b, c, f2, K2, M(27)); R(c, d, e, a, b, f2, K2, M(28)); R(b, c, d, e, a, f2, K2, M(29)); R(a, b, c, d, e, f2, K2, M(30)); R(e, a, b, c, d, f2, K2, M(31)); R(d, e, a, b, c, f2, K2, M(32)); R(c, d, e, a, b, f2, K2, M(33)); R(b, c, d, e, a, f2, K2, M(34)); R(a, b, c, d, e, f2, K2, M(35)); R(e, a, b, c, d, f2, K2, M(36)); R(d, e, a, b, c, f2, K2, M(37)); R(c, d, e, a, b, f2, K2, M(38)); R(b, c, d, e, a, f2, K2, M(39)); R(a, b, c, d, e, f3, K3, M(40)); R(e, a, b, c, d, f3, K3, M(41)); R(d, e, a, b, c, f3, K3, M(42)); R(c, d, e, a, b, f3, K3, M(43)); R(b, c, d, e, a, f3, K3, M(44)); R(a, b, c, d, e, f3, K3, M(45)); R(e, a, b, c, d, f3, K3, M(46)); R(d, e, a, b, c, f3, K3, M(47)); R(c, d, e, a, b, f3, K3, M(48)); R(b, c, d, e, a, f3, K3, M(49)); R(a, b, c, d, e, f3, K3, M(50)); R(e, a, b, c, d, f3, K3, M(51)); R(d, e, a, b, c, f3, K3, M(52)); R(c, d, e, a, b, f3, K3, M(53)); R(b, c, d, e, a, f3, K3, M(54)); R(a, b, c, d, e, f3, K3, M(55)); R(e, a, b, c, d, f3, K3, M(56)); R(d, e, a, b, c, f3, K3, M(57)); R(c, d, e, a, b, f3, K3, M(58)); R(b, c, d, e, a, f3, K3, M(59)); R(a, b, c, d, e, f4, K4, M(60)); R(e, a, b, c, d, f4, K4, M(61)); R(d, e, a, b, c, f4, K4, M(62)); R(c, d, e, a, b, f4, K4, M(63)); R(b, c, d, e, a, f4, K4, M(64)); R(a, b, c, d, e, f4, K4, M(65)); R(e, a, b, c, d, f4, K4, M(66)); R(d, e, a, b, c, f4, K4, M(67)); R(c, d, e, a, b, f4, K4, M(68)); R(b, c, d, e, a, f4, K4, M(69)); R(a, b, c, d, e, f4, K4, M(70)); R(e, a, b, c, d, f4, K4, M(71)); R(d, e, a, b, c, f4, K4, M(72)); R(c, d, e, a, b, f4, K4, M(73)); R(b, c, d, e, a, f4, K4, M(74)); R(a, b, c, d, e, f4, K4, M(75)); R(e, a, b, c, d, f4, K4, M(76)); R(d, e, a, b, c, f4, K4, M(77)); R(c, d, e, a, b, f4, K4, M(78)); R(b, c, d, e, a, f4, K4, M(79)); ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; ctx->h[4] += e; } void cryptonite_sha1_update(struct sha1_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t index, to_fill; index = (uint32_t) (ctx->sz & 0x3f); to_fill = 64 - index; ctx->sz += len; /* process partial buffer if there's enough data to make a block */ if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); sha1_do_chunk(ctx, (uint32_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 64-block as possible */ for (; len >= 64; len -= 64, data += 64) sha1_do_chunk(ctx, (uint32_t *) data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_sha1_finalize(struct sha1_ctx *ctx, uint8_t *out) { static uint8_t padding[64] = { 0x80, }; uint64_t bits; uint32_t index, padlen; uint32_t *p = (uint32_t *) out; /* add padding and update data with it */ bits = cpu_to_be64(ctx->sz << 3); /* pad out to 56 */ index = (uint32_t) (ctx->sz & 0x3f); padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); cryptonite_sha1_update(ctx, padding, padlen); /* append length */ cryptonite_sha1_update(ctx, (uint8_t *) &bits, sizeof(bits)); /* output hash */ p[0] = cpu_to_be32(ctx->h[0]); p[1] = cpu_to_be32(ctx->h[1]); p[2] = cpu_to_be32(ctx->h[2]); p[3] = cpu_to_be32(ctx->h[3]); p[4] = cpu_to_be32(ctx->h[4]); } cryptonite-0.23/cbits/cryptonite_sha256.c0000644000000000000000000001333713047773333016605 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "cryptonite_sha256.h" #include "cryptonite_bitfn.h" void cryptonite_sha224_init(struct sha224_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0xc1059ed8; ctx->h[1] = 0x367cd507; ctx->h[2] = 0x3070dd17; ctx->h[3] = 0xf70e5939; ctx->h[4] = 0xffc00b31; ctx->h[5] = 0x68581511; ctx->h[6] = 0x64f98fa7; ctx->h[7] = 0xbefa4fa4; } void cryptonite_sha256_init(struct sha256_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0x6a09e667; ctx->h[1] = 0xbb67ae85; ctx->h[2] = 0x3c6ef372; ctx->h[3] = 0xa54ff53a; ctx->h[4] = 0x510e527f; ctx->h[5] = 0x9b05688c; ctx->h[6] = 0x1f83d9ab; ctx->h[7] = 0x5be0cd19; } /* 232 times the cube root of the first 64 primes 2..311 */ static const uint32_t k[] = { 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 }; #define e0(x) (ror32(x, 2) ^ ror32(x,13) ^ ror32(x,22)) #define e1(x) (ror32(x, 6) ^ ror32(x,11) ^ ror32(x,25)) #define s0(x) (ror32(x, 7) ^ ror32(x,18) ^ (x >> 3)) #define s1(x) (ror32(x,17) ^ ror32(x,19) ^ (x >> 10)) static void sha256_do_chunk(struct sha256_ctx *ctx, uint32_t buf[]) { uint32_t a, b, c, d, e, f, g, h, t1, t2; int i; uint32_t w[64]; cpu_to_be32_array(w, buf, 16); for (i = 16; i < 64; i++) w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16]; a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; #define R(a, b, c, d, e, f, g, h, k, w) \ t1 = h + e1(e) + (g ^ (e & (f ^ g))) + k + w; \ t2 = e0(a) + ((a & b) | (c & (a | b))); \ d += t1; \ h = t1 + t2; for (i = 0; i < 64; i += 8) { R(a, b, c, d, e, f, g, h, k[i + 0], w[i + 0]); R(h, a, b, c, d, e, f, g, k[i + 1], w[i + 1]); R(g, h, a, b, c, d, e, f, k[i + 2], w[i + 2]); R(f, g, h, a, b, c, d, e, k[i + 3], w[i + 3]); R(e, f, g, h, a, b, c, d, k[i + 4], w[i + 4]); R(d, e, f, g, h, a, b, c, k[i + 5], w[i + 5]); R(c, d, e, f, g, h, a, b, k[i + 6], w[i + 6]); R(b, c, d, e, f, g, h, a, k[i + 7], w[i + 7]); } #undef R ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; } void cryptonite_sha224_update(struct sha224_ctx *ctx, const uint8_t *data, uint32_t len) { return cryptonite_sha256_update(ctx, data, len); } void cryptonite_sha256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t index, to_fill; /* check for partial buffer */ index = (uint32_t) (ctx->sz & 0x3f); to_fill = 64 - index; ctx->sz += len; /* process partial buffer if there's enough data to make a block */ if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); sha256_do_chunk(ctx, (uint32_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 64-block as possible */ for (; len >= 64; len -= 64, data += 64) sha256_do_chunk(ctx, (uint32_t *) data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_sha224_finalize(struct sha224_ctx *ctx, uint8_t *out) { uint8_t intermediate[SHA256_DIGEST_SIZE]; cryptonite_sha256_finalize(ctx, intermediate); memcpy(out, intermediate, SHA224_DIGEST_SIZE); } void cryptonite_sha256_finalize(struct sha256_ctx *ctx, uint8_t *out) { static uint8_t padding[64] = { 0x80, }; uint64_t bits; uint32_t i, index, padlen; uint32_t *p = (uint32_t *) out; /* cpu -> big endian */ bits = cpu_to_be64(ctx->sz << 3); /* pad out to 56 */ index = (uint32_t) (ctx->sz & 0x3f); padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); cryptonite_sha256_update(ctx, padding, padlen); /* append length */ cryptonite_sha256_update(ctx, (uint8_t *) &bits, sizeof(bits)); /* store to digest */ for (i = 0; i < 8; i++) p[i] = cpu_to_be32(ctx->h[i]); } cryptonite-0.23/cbits/cryptonite_sha512.c0000644000000000000000000002132012673727640016573 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "cryptonite_bitfn.h" #include "cryptonite_sha512.h" void cryptonite_sha384_init(struct sha512_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0xcbbb9d5dc1059ed8ULL; ctx->h[1] = 0x629a292a367cd507ULL; ctx->h[2] = 0x9159015a3070dd17ULL; ctx->h[3] = 0x152fecd8f70e5939ULL; ctx->h[4] = 0x67332667ffc00b31ULL; ctx->h[5] = 0x8eb44a8768581511ULL; ctx->h[6] = 0xdb0c2e0d64f98fa7ULL; ctx->h[7] = 0x47b5481dbefa4fa4ULL; } void cryptonite_sha512_init(struct sha512_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0x6a09e667f3bcc908ULL; ctx->h[1] = 0xbb67ae8584caa73bULL; ctx->h[2] = 0x3c6ef372fe94f82bULL; ctx->h[3] = 0xa54ff53a5f1d36f1ULL; ctx->h[4] = 0x510e527fade682d1ULL; ctx->h[5] = 0x9b05688c2b3e6c1fULL; ctx->h[6] = 0x1f83d9abfb41bd6bULL; ctx->h[7] = 0x5be0cd19137e2179ULL; } /* 232 times the cube root of the first 64 primes 2..311 */ static const uint64_t k[] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL, }; #define e0(x) (ror64(x, 28) ^ ror64(x, 34) ^ ror64(x, 39)) #define e1(x) (ror64(x, 14) ^ ror64(x, 18) ^ ror64(x, 41)) #define s0(x) (ror64(x, 1) ^ ror64(x, 8) ^ (x >> 7)) #define s1(x) (ror64(x, 19) ^ ror64(x, 61) ^ (x >> 6)) static void sha512_do_chunk(struct sha512_ctx *ctx, uint64_t *buf) { uint64_t a, b, c, d, e, f, g, h, t1, t2; int i; uint64_t w[80]; cpu_to_be64_array(w, buf, 16); for (i = 16; i < 80; i++) w[i] = s1(w[i - 2]) + w[i - 7] + s0(w[i - 15]) + w[i - 16]; a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; e = ctx->h[4]; f = ctx->h[5]; g = ctx->h[6]; h = ctx->h[7]; #define R(a, b, c, d, e, f, g, h, k, w) \ t1 = h + e1(e) + (g ^ (e & (f ^ g))) + k + w; \ t2 = e0(a) + ((a & b) | (c & (a | b))); \ d += t1; \ h = t1 + t2 for (i = 0; i < 80; i += 8) { R(a, b, c, d, e, f, g, h, k[i + 0], w[i + 0]); R(h, a, b, c, d, e, f, g, k[i + 1], w[i + 1]); R(g, h, a, b, c, d, e, f, k[i + 2], w[i + 2]); R(f, g, h, a, b, c, d, e, k[i + 3], w[i + 3]); R(e, f, g, h, a, b, c, d, k[i + 4], w[i + 4]); R(d, e, f, g, h, a, b, c, k[i + 5], w[i + 5]); R(c, d, e, f, g, h, a, b, k[i + 6], w[i + 6]); R(b, c, d, e, f, g, h, a, k[i + 7], w[i + 7]); } #undef R ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; ctx->h[4] += e; ctx->h[5] += f; ctx->h[6] += g; ctx->h[7] += h; } void cryptonite_sha384_update(struct sha384_ctx *ctx, const uint8_t *data, uint32_t len) { return cryptonite_sha512_update(ctx, data, len); } void cryptonite_sha512_update(struct sha512_ctx *ctx, const uint8_t *data, uint32_t len) { unsigned int index, to_fill; /* check for partial buffer */ index = (unsigned int) (ctx->sz[0] & 0x7f); to_fill = 128 - index; ctx->sz[0] += len; if (ctx->sz[0] < len) ctx->sz[1]++; /* process partial buffer if there's enough data to make a block */ if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); sha512_do_chunk(ctx, (uint64_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 128-block as possible */ for (; len >= 128; len -= 128, data += 128) sha512_do_chunk(ctx, (uint64_t *) data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out) { uint8_t intermediate[SHA512_DIGEST_SIZE]; cryptonite_sha512_finalize(ctx, intermediate); memcpy(out, intermediate, SHA384_DIGEST_SIZE); } void cryptonite_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out) { static uint8_t padding[128] = { 0x80, }; uint32_t i, index, padlen; uint64_t bits[2]; uint64_t *p = (uint64_t *) out; /* cpu -> big endian */ bits[0] = cpu_to_be64((ctx->sz[1] << 3 | ctx->sz[0] >> 61)); bits[1] = cpu_to_be64((ctx->sz[0] << 3)); /* pad out to 56 */ index = (unsigned int) (ctx->sz[0] & 0x7f); padlen = (index < 112) ? (112 - index) : ((128 + 112) - index); cryptonite_sha512_update(ctx, padding, padlen); /* append length */ cryptonite_sha512_update(ctx, (uint8_t *) bits, sizeof(bits)); /* store to digest */ for (i = 0; i < 8; i++) p[i] = cpu_to_be64(ctx->h[i]); } #include void cryptonite_sha512t_init(struct sha512_ctx *ctx, uint32_t hashlen) { memset(ctx, 0, sizeof(*ctx)); if (hashlen >= 512) return; switch (hashlen) { case 224: ctx->h[0] = 0x8c3d37c819544da2ULL; ctx->h[1] = 0x73e1996689dcd4d6ULL; ctx->h[2] = 0x1dfab7ae32ff9c82ULL; ctx->h[3] = 0x679dd514582f9fcfULL; ctx->h[4] = 0x0f6d2b697bd44da8ULL; ctx->h[5] = 0x77e36f7304c48942ULL; ctx->h[6] = 0x3f9d85a86a1d36c8ULL; ctx->h[7] = 0x1112e6ad91d692a1ULL; break; case 256: ctx->h[0] = 0x22312194fc2bf72cULL; ctx->h[1] = 0x9f555fa3c84c64c2ULL; ctx->h[2] = 0x2393b86b6f53b151ULL; ctx->h[3] = 0x963877195940eabdULL; ctx->h[4] = 0x96283ee2a88effe3ULL; ctx->h[5] = 0xbe5e1e2553863992ULL; ctx->h[6] = 0x2b0199fc2c85b8aaULL; ctx->h[7] = 0x0eb72ddc81c52ca2ULL; break; default: { char buf[8+4]; uint8_t out[64]; int i; cryptonite_sha512_init(ctx); for (i = 0; i < 8; i++) ctx->h[i] ^= 0xa5a5a5a5a5a5a5a5ULL; i = sprintf(buf, "SHA-512/%d", hashlen); cryptonite_sha512_update(ctx, (uint8_t *) buf, i); cryptonite_sha512_finalize(ctx, out); /* re-init the context, otherwise len is changed */ memset(ctx, 0, sizeof(*ctx)); for (i = 0; i < 8; i++) ctx->h[i] = cpu_to_be64(((uint64_t *) out)[i]); } } } void cryptonite_sha512t_update(struct sha512_ctx *ctx, const uint8_t *data, uint32_t len) { return cryptonite_sha512_update(ctx, data, len); } void cryptonite_sha512t_finalize(struct sha512_ctx *ctx, uint32_t hashlen, uint8_t *out) { uint8_t intermediate[SHA512_DIGEST_SIZE]; cryptonite_sha512_finalize(ctx, intermediate); memcpy(out, intermediate, hashlen / 8); } cryptonite-0.23/cbits/cryptonite_sha3.c0000644000000000000000000001670313054050744016423 0ustar0000000000000000/* * Copyright (C) 2012 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "cryptonite_bitfn.h" #include "cryptonite_align.h" #include "cryptonite_sha3.h" #define KECCAK_NB_ROUNDS 24 /* rounds constants */ static const uint64_t keccak_rndc[24] = { 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL, }; /* triangular numbers constants */ static const int keccak_rotc[24] = { 1,3,6,10,15,21,28,36,45,55,2,14,27,41,56,8,25,43,62,18,39,61,20,44 }; static const int keccak_piln[24] = { 10,7,11,17,18,3,5,16,8,21,24,4,15,23,19,13,12,2,20,14,22,9,6,1 }; static inline void sha3_do_chunk(uint64_t state[25], uint64_t buf[], int bufsz) { int i, j, r; uint64_t tmp, bc[5]; /* merge buf with state */ for (i = 0; i < bufsz; i++) state[i] ^= le64_to_cpu(buf[i]); /* run keccak rounds */ for (r = 0; r < KECCAK_NB_ROUNDS; r++) { /* compute the parity of each columns */ for (i = 0; i < 5; i++) bc[i] = state[i] ^ state[i+5] ^ state[i+10] ^ state[i+15] ^ state[i+20]; for (i = 0; i < 5; i++) { tmp = bc[(i + 4) % 5] ^ rol64(bc[(i + 1) % 5], 1); for (j = 0; j < 25; j += 5) state[j + i] ^= tmp; } /* rho pi */ tmp = state[1]; for (i = 0; i < 24; i++) { j = keccak_piln[i]; bc[0] = state[j]; state[j] = rol64(tmp, keccak_rotc[i]); tmp = bc[0]; } /* bitwise combine along rows using a = a xor (not b and c) */ for (j = 0; j < 25; j += 5) { for (i = 0; i < 5; i++) bc[i] = state[j + i]; #define andn(b,c) (~(b) & (c)) state[j + 0] ^= andn(bc[1], bc[2]); state[j + 1] ^= andn(bc[2], bc[3]); state[j + 2] ^= andn(bc[3], bc[4]); state[j + 3] ^= andn(bc[4], bc[0]); state[j + 4] ^= andn(bc[0], bc[1]); #undef andn } /* xor the round constant */ state[0] ^= keccak_rndc[r]; } } /* * Initialize a SHA-3 / SHAKE context: hashlen is the security level (and * half the capacity) in bits */ void cryptonite_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen) { /* assert(hashlen >= SHA3_BITSIZE_MIN && hashlen <= SHA3_BITSIZE_MAX) */ int bufsz = SHA3_BUF_SIZE(hashlen); memset(ctx, 0, sizeof(*ctx) + bufsz); ctx->bufsz = bufsz; } /* Update a SHA-3 / SHAKE context */ void cryptonite_sha3_update(struct sha3_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t to_fill; to_fill = ctx->bufsz - ctx->bufindex; if (ctx->bufindex == ctx->bufsz) { sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); ctx->bufindex = 0; } /* process partial buffer if there's enough data to make a block */ if (ctx->bufindex && len >= to_fill) { memcpy(ctx->buf + ctx->bufindex, data, to_fill); sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); len -= to_fill; data += to_fill; ctx->bufindex = 0; } if (need_alignment(data, 8)) { uint64_t tramp[SHA3_BUF_SIZE_MAX/8]; ASSERT_ALIGNMENT(tramp, 8); for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz) { memcpy(tramp, data, ctx->bufsz / 8); sha3_do_chunk(ctx->state, (uint64_t *) data, ctx->bufsz / 8); } } else { /* process as much ctx->bufsz-block */ for (; len >= ctx->bufsz; len -= ctx->bufsz, data += ctx->bufsz) sha3_do_chunk(ctx->state, (uint64_t *) data, ctx->bufsz / 8); } /* append data into buf */ if (len) { memcpy(ctx->buf + ctx->bufindex, data, len); ctx->bufindex += len; } } void cryptonite_sha3_finalize_with_pad_byte(struct sha3_ctx *ctx, uint8_t pad_byte) { /* process full buffer if needed */ if (ctx->bufindex == ctx->bufsz) { sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); ctx->bufindex = 0; } /* add the 10*1 padding */ ctx->buf[ctx->bufindex++] = pad_byte; memset(ctx->buf + ctx->bufindex, 0, ctx->bufsz - ctx->bufindex); ctx->buf[ctx->bufsz - 1] |= 0x80; /* process */ sha3_do_chunk(ctx->state, (uint64_t *) ctx->buf, ctx->bufsz / 8); ctx->bufindex = 0; } /* * Extract some bytes from a finalized SHA-3 / SHAKE context. * May be called multiple times. */ void cryptonite_sha3_output(struct sha3_ctx *ctx, uint8_t *out, uint32_t len) { uint64_t w[25]; uint8_t *wptr = (uint8_t *) w; uint32_t still_avail; still_avail = ctx->bufsz - ctx->bufindex; if (ctx->bufindex == ctx->bufsz) { /* squeeze the sponge again, without any input */ sha3_do_chunk(ctx->state, NULL, 0); ctx->bufindex = 0; } /* use bytes already available if this block is fully consumed */ if (ctx->bufindex && len >= still_avail) { cpu_to_le64_array(w, ctx->state, 25); memcpy(out, wptr + ctx->bufindex, still_avail); sha3_do_chunk(ctx->state, NULL, 0); len -= still_avail; out += still_avail; ctx->bufindex = 0; } /* output as much ctx->bufsz-block */ for (; len > ctx->bufsz; len -= ctx->bufsz, out += ctx->bufsz) { cpu_to_le64_array(w, ctx->state, 25); memcpy(out, w, ctx->bufsz); sha3_do_chunk(ctx->state, NULL, 0); } /* output from partial buffer */ if (len) { cpu_to_le64_array(w, ctx->state, 25); memcpy(out, wptr + ctx->bufindex, len); ctx->bufindex += len; } } /* Finalize a SHA-3 context and return the digest value */ void cryptonite_sha3_finalize(struct sha3_ctx *ctx, uint32_t hashlen, uint8_t *out) { cryptonite_sha3_finalize_with_pad_byte(ctx, 0x06); cryptonite_sha3_output(ctx, out, hashlen / 8); } /* Finalize a SHAKE context. Output is read using cryptonite_sha3_output. */ void cryptonite_sha3_finalize_shake(struct sha3_ctx *ctx) { cryptonite_sha3_finalize_with_pad_byte(ctx, 0x1F); } void cryptonite_keccak_init(struct sha3_ctx *ctx, uint32_t hashlen) { cryptonite_sha3_init(ctx, hashlen); } void cryptonite_keccak_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len) { cryptonite_sha3_update(ctx, data, len); } void cryptonite_keccak_finalize(struct sha3_ctx *ctx, uint32_t hashlen, uint8_t *out) { cryptonite_sha3_finalize_with_pad_byte(ctx, 1); cryptonite_sha3_output(ctx, out, hashlen / 8); } cryptonite-0.23/cbits/cryptonite_md2.c0000644000000000000000000001174612514540320016243 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "cryptonite_bitfn.h" #include "cryptonite_md2.h" void cryptonite_md2_init(struct md2_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->sz = 0ULL; } static uint8_t S_table[] = { 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 }; #define UBYTES(s) ((uint8_t *) s) static uint8_t *padding_table[] = { UBYTES(""), UBYTES("\x1"), UBYTES("\x2\x2"), UBYTES("\x3\x3\x3"), UBYTES("\x4\x4\x4\x4"), UBYTES("\x5\x5\x5\x5\x5"), UBYTES("\x6\x6\x6\x6\x6\x6"), UBYTES("\x7\x7\x7\x7\x7\x7\x7"), UBYTES("\x8\x8\x8\x8\x8\x8\x8\x8"), UBYTES("\x9\x9\x9\x9\x9\x9\x9\x9\x9"), UBYTES("\xa\xa\xa\xa\xa\xa\xa\xa\xa\xa"), UBYTES("\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb\xb"), UBYTES("\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc\xc"), UBYTES("\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd\xd"), UBYTES("\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe\xe"), UBYTES("\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf\xf"), UBYTES("\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10") }; static void md2_do_chunk(struct md2_ctx *ctx, const uint8_t *buf) { uint8_t i, j, t; uint8_t x[48]; memcpy(x, ctx->h, 16); memcpy(x+16, buf, 16); for (i = 0; i < 16; i++) x[i+32] = ctx->h[i] ^ buf[i]; for (t = i = 0; i < 18; i++) { for (j = 0; j < 48; j++) t = x[j] ^= S_table[t]; t = (t + i) & 0xff; } memcpy(ctx->h, x, 16); t = ctx->cksum[15]; for (i = 0; i < 16; i++) t = ctx->cksum[i] ^= S_table[buf[i] ^ t]; } void cryptonite_md2_update(struct md2_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t index, to_fill; index = (uint32_t) (ctx->sz & 0xf); to_fill = 16 - index; ctx->sz += len; if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); md2_do_chunk(ctx, ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 16-block as possible */ for (; len >= 16; len -= 16, data += 16) md2_do_chunk(ctx, data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_md2_finalize(struct md2_ctx *ctx, uint8_t *out) { uint32_t index, padlen; index = ctx->sz & 0xf; padlen = 16 - index; cryptonite_md2_update(ctx, padding_table[padlen], padlen); cryptonite_md2_update(ctx, ctx->cksum, 16); memcpy(out, ctx->h, 16); } cryptonite-0.23/cbits/cryptonite_md4.c0000644000000000000000000001132512514540320016236 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "cryptonite_bitfn.h" #include "cryptonite_md4.h" void cryptonite_md4_init(struct md4_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->sz = 0ULL; ctx->h[0] = 0x67452301; ctx->h[1] = 0xefcdab89; ctx->h[2] = 0x98badcfe; ctx->h[3] = 0x10325476; } #define f1(x, y, z) ((x & y) | ((~x) & z)) #define f2(x, y, z) ((x & y) | (x & z) | (y & z)) #define f3(x, y, z) (x ^ y ^ z) #define K1 0x00000000 #define K2 0x5A827999 #define K3 0x6ED9EBA1 #define R(a,b,c,d,f,k,s,i) (a = rol32(a + f(b,c,d) + w[i] + k, s)) static void md4_do_chunk(struct md4_ctx *ctx, uint32_t *buf) { uint32_t a, b, c, d; #ifdef ARCH_IS_BIG_ENDIAN uint32_t w[16]; cpu_to_le32_array(w, (uint32_t *) buf, 16); #else uint32_t *w = buf; #endif a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; R(a, b, c, d, f1, K1, 3, 0); R(d, a, b, c, f1, K1, 7, 1); R(c, d, a, b, f1, K1, 11, 2); R(b, c, d, a, f1, K1, 19, 3); R(a, b, c, d, f1, K1, 3, 4); R(d, a, b, c, f1, K1, 7, 5); R(c, d, a, b, f1, K1, 11, 6); R(b, c, d, a, f1, K1, 19, 7); R(a, b, c, d, f1, K1, 3, 8); R(d, a, b, c, f1, K1, 7, 9); R(c, d, a, b, f1, K1, 11, 10); R(b, c, d, a, f1, K1, 19, 11); R(a, b, c, d, f1, K1, 3, 12); R(d, a, b, c, f1, K1, 7, 13); R(c, d, a, b, f1, K1, 11, 14); R(b, c, d, a, f1, K1, 19, 15); R(a, b, c, d, f2, K2, 3, 0); R(d, a, b, c, f2, K2, 5, 4); R(c, d, a, b, f2, K2, 9, 8); R(b, c, d, a, f2, K2, 13, 12); R(a, b, c, d, f2, K2, 3, 1); R(d, a, b, c, f2, K2, 5, 5); R(c, d, a, b, f2, K2, 9, 9); R(b, c, d, a, f2, K2, 13, 13); R(a, b, c, d, f2, K2, 3, 2); R(d, a, b, c, f2, K2, 5, 6); R(c, d, a, b, f2, K2, 9, 10); R(b, c, d, a, f2, K2, 13, 14); R(a, b, c, d, f2, K2, 3, 3); R(d, a, b, c, f2, K2, 5, 7); R(c, d, a, b, f2, K2, 9, 11); R(b, c, d, a, f2, K2, 13, 15); R(a, b, c, d, f3, K3, 3, 0); R(d, a, b, c, f3, K3, 9, 8); R(c, d, a, b, f3, K3, 11, 4); R(b, c, d, a, f3, K3, 15, 12); R(a, b, c, d, f3, K3, 3, 2); R(d, a, b, c, f3, K3, 9, 10); R(c, d, a, b, f3, K3, 11, 6); R(b, c, d, a, f3, K3, 15, 14); R(a, b, c, d, f3, K3, 3, 1); R(d, a, b, c, f3, K3, 9, 9); R(c, d, a, b, f3, K3, 11, 5); R(b, c, d, a, f3, K3, 15, 13); R(a, b, c, d, f3, K3, 3, 3); R(d, a, b, c, f3, K3, 9, 11); R(c, d, a, b, f3, K3, 11, 7); R(b, c, d, a, f3, K3, 15, 15); ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; } void cryptonite_md4_update(struct md4_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t index, to_fill; index = (uint32_t) (ctx->sz & 0x3f); to_fill = 64 - index; ctx->sz += len; if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); md4_do_chunk(ctx, (uint32_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 64-block as possible */ for (; len >= 64; len -= 64, data += 64) md4_do_chunk(ctx, (uint32_t *) data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_md4_finalize(struct md4_ctx *ctx, uint8_t *out) { static uint8_t padding[64] = { 0x80, }; uint64_t bits; uint32_t index, padlen; /* add padding and update data with it */ bits = cpu_to_le64(ctx->sz << 3); /* pad out to 56 */ index = (uint32_t) (ctx->sz & 0x3f); padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); cryptonite_md4_update(ctx, padding, padlen); /* append length */ cryptonite_md4_update(ctx, (uint8_t *) &bits, sizeof(bits)); /* output hash */ le32_to_cpu_array((uint32_t *) out, ctx->h, 4); } cryptonite-0.23/cbits/cryptonite_md5.c0000644000000000000000000001342113022544154016242 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "cryptonite_bitfn.h" #include "cryptonite_md5.h" void cryptonite_md5_init(struct md5_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->sz = 0ULL; ctx->h[0] = 0x67452301; ctx->h[1] = 0xefcdab89; ctx->h[2] = 0x98badcfe; ctx->h[3] = 0x10325476; } #define f1(x, y, z) (z ^ (x & (y ^ z))) #define f2(x, y, z) f1(z, x, y) #define f3(x, y, z) (x ^ y ^ z) #define f4(x, y, z) (y ^ (x | ~z)) #define R(f, a, b, c, d, i, k, s) a += f(b, c, d) + w[i] + k; a = rol32(a, s); a += b static void md5_do_chunk(struct md5_ctx *ctx, uint32_t *buf) { uint32_t a, b, c, d; #ifdef ARCH_IS_BIG_ENDIAN uint32_t w[16]; cpu_to_le32_array(w, buf, 16); #else uint32_t *w = buf; #endif a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; d = ctx->h[3]; R(f1, a, b, c, d, 0, 0xd76aa478, 7); R(f1, d, a, b, c, 1, 0xe8c7b756, 12); R(f1, c, d, a, b, 2, 0x242070db, 17); R(f1, b, c, d, a, 3, 0xc1bdceee, 22); R(f1, a, b, c, d, 4, 0xf57c0faf, 7); R(f1, d, a, b, c, 5, 0x4787c62a, 12); R(f1, c, d, a, b, 6, 0xa8304613, 17); R(f1, b, c, d, a, 7, 0xfd469501, 22); R(f1, a, b, c, d, 8, 0x698098d8, 7); R(f1, d, a, b, c, 9, 0x8b44f7af, 12); R(f1, c, d, a, b, 10, 0xffff5bb1, 17); R(f1, b, c, d, a, 11, 0x895cd7be, 22); R(f1, a, b, c, d, 12, 0x6b901122, 7); R(f1, d, a, b, c, 13, 0xfd987193, 12); R(f1, c, d, a, b, 14, 0xa679438e, 17); R(f1, b, c, d, a, 15, 0x49b40821, 22); R(f2, a, b, c, d, 1, 0xf61e2562, 5); R(f2, d, a, b, c, 6, 0xc040b340, 9); R(f2, c, d, a, b, 11, 0x265e5a51, 14); R(f2, b, c, d, a, 0, 0xe9b6c7aa, 20); R(f2, a, b, c, d, 5, 0xd62f105d, 5); R(f2, d, a, b, c, 10, 0x02441453, 9); R(f2, c, d, a, b, 15, 0xd8a1e681, 14); R(f2, b, c, d, a, 4, 0xe7d3fbc8, 20); R(f2, a, b, c, d, 9, 0x21e1cde6, 5); R(f2, d, a, b, c, 14, 0xc33707d6, 9); R(f2, c, d, a, b, 3, 0xf4d50d87, 14); R(f2, b, c, d, a, 8, 0x455a14ed, 20); R(f2, a, b, c, d, 13, 0xa9e3e905, 5); R(f2, d, a, b, c, 2, 0xfcefa3f8, 9); R(f2, c, d, a, b, 7, 0x676f02d9, 14); R(f2, b, c, d, a, 12, 0x8d2a4c8a, 20); R(f3, a, b, c, d, 5, 0xfffa3942, 4); R(f3, d, a, b, c, 8, 0x8771f681, 11); R(f3, c, d, a, b, 11, 0x6d9d6122, 16); R(f3, b, c, d, a, 14, 0xfde5380c, 23); R(f3, a, b, c, d, 1, 0xa4beea44, 4); R(f3, d, a, b, c, 4, 0x4bdecfa9, 11); R(f3, c, d, a, b, 7, 0xf6bb4b60, 16); R(f3, b, c, d, a, 10, 0xbebfbc70, 23); R(f3, a, b, c, d, 13, 0x289b7ec6, 4); R(f3, d, a, b, c, 0, 0xeaa127fa, 11); R(f3, c, d, a, b, 3, 0xd4ef3085, 16); R(f3, b, c, d, a, 6, 0x04881d05, 23); R(f3, a, b, c, d, 9, 0xd9d4d039, 4); R(f3, d, a, b, c, 12, 0xe6db99e5, 11); R(f3, c, d, a, b, 15, 0x1fa27cf8, 16); R(f3, b, c, d, a, 2, 0xc4ac5665, 23); R(f4, a, b, c, d, 0, 0xf4292244, 6); R(f4, d, a, b, c, 7, 0x432aff97, 10); R(f4, c, d, a, b, 14, 0xab9423a7, 15); R(f4, b, c, d, a, 5, 0xfc93a039, 21); R(f4, a, b, c, d, 12, 0x655b59c3, 6); R(f4, d, a, b, c, 3, 0x8f0ccc92, 10); R(f4, c, d, a, b, 10, 0xffeff47d, 15); R(f4, b, c, d, a, 1, 0x85845dd1, 21); R(f4, a, b, c, d, 8, 0x6fa87e4f, 6); R(f4, d, a, b, c, 15, 0xfe2ce6e0, 10); R(f4, c, d, a, b, 6, 0xa3014314, 15); R(f4, b, c, d, a, 13, 0x4e0811a1, 21); R(f4, a, b, c, d, 4, 0xf7537e82, 6); R(f4, d, a, b, c, 11, 0xbd3af235, 10); R(f4, c, d, a, b, 2, 0x2ad7d2bb, 15); R(f4, b, c, d, a, 9, 0xeb86d391, 21); ctx->h[0] += a; ctx->h[1] += b; ctx->h[2] += c; ctx->h[3] += d; } void cryptonite_md5_update(struct md5_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t index, to_fill; index = (uint32_t) (ctx->sz & 0x3f); to_fill = 64 - index; ctx->sz += len; if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); md5_do_chunk(ctx, (uint32_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 64-block as possible */ for (; len >= 64; len -= 64, data += 64) md5_do_chunk(ctx, (uint32_t *) data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_md5_finalize(struct md5_ctx *ctx, uint8_t *out) { static uint8_t padding[64] = { 0x80, }; uint64_t bits; uint32_t index, padlen; uint32_t *p = (uint32_t *) out; /* add padding and update data with it */ bits = cpu_to_le64(ctx->sz << 3); /* pad out to 56 */ index = (uint32_t) (ctx->sz & 0x3f); padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); cryptonite_md5_update(ctx, padding, padlen); /* append length */ cryptonite_md5_update(ctx, (uint8_t *) &bits, sizeof(bits)); /* output hash */ p[0] = cpu_to_le32(ctx->h[0]); p[1] = cpu_to_le32(ctx->h[1]); p[2] = cpu_to_le32(ctx->h[2]); p[3] = cpu_to_le32(ctx->h[3]); } cryptonite-0.23/cbits/cryptonite_ripemd.c0000644000000000000000000002400312514540320017027 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "cryptonite_ripemd.h" #include "cryptonite_bitfn.h" #include void cryptonite_ripemd160_init(struct ripemd160_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0x67452301; ctx->h[1] = 0xefcdab89; ctx->h[2] = 0x98badcfe; ctx->h[3] = 0x10325476; ctx->h[4] = 0xc3d2e1f0; } #define K1 0x00000000 #define K2 0x5a827999 #define K3 0x6ed9eba1 #define K4 0x8f1bbcdc #define K5 0xa953fd4e #define K6 0x50a28be6 #define K7 0x5c4dd124 #define K8 0x6d703ef3 #define K9 0x7a6d76e9 #define f1(x, y, z) (x ^ y ^ z) #define f2(x, y, z) (z ^ (x & (y ^ z))) #define f3(x, y, z) ((x | ~y) ^ z) #define f4(x, y, z) (y ^ (z & (x ^ y))) #define f5(x, y, z) (x ^ (y | ~z)) #define R(a, b, c, d, e, f, k, i, s) \ a += f(b, c, d) + w[i] + k; a = rol32(a, s) + e; c = rol32(c, 10) static void ripemd160_do_chunk(struct ripemd160_ctx *ctx, uint32_t *buf) { uint32_t a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; #ifdef ARCH_IS_BIG_ENDIAN uint32_t w[16]; cpu_to_le32_array(w, buf, 16); #else uint32_t *w = buf; #endif a1 = ctx->h[0]; b1 = ctx->h[1]; c1 = ctx->h[2]; d1 = ctx->h[3]; e1 = ctx->h[4]; a2 = ctx->h[0]; b2 = ctx->h[1]; c2 = ctx->h[2]; d2 = ctx->h[3]; e2 = ctx->h[4]; /* 5 passes on first state copy */ R(a1, b1, c1, d1, e1, f1, K1, 0, 11); R(e1, a1, b1, c1, d1, f1, K1, 1, 14); R(d1, e1, a1, b1, c1, f1, K1, 2, 15); R(c1, d1, e1, a1, b1, f1, K1, 3, 12); R(b1, c1, d1, e1, a1, f1, K1, 4, 5); R(a1, b1, c1, d1, e1, f1, K1, 5, 8); R(e1, a1, b1, c1, d1, f1, K1, 6, 7); R(d1, e1, a1, b1, c1, f1, K1, 7, 9); R(c1, d1, e1, a1, b1, f1, K1, 8, 11); R(b1, c1, d1, e1, a1, f1, K1, 9, 13); R(a1, b1, c1, d1, e1, f1, K1, 10, 14); R(e1, a1, b1, c1, d1, f1, K1, 11, 15); R(d1, e1, a1, b1, c1, f1, K1, 12, 6); R(c1, d1, e1, a1, b1, f1, K1, 13, 7); R(b1, c1, d1, e1, a1, f1, K1, 14, 9); R(a1, b1, c1, d1, e1, f1, K1, 15, 8); R(e1, a1, b1, c1, d1, f2, K2, 7, 7); R(d1, e1, a1, b1, c1, f2, K2, 4, 6); R(c1, d1, e1, a1, b1, f2, K2, 13, 8); R(b1, c1, d1, e1, a1, f2, K2, 1, 13); R(a1, b1, c1, d1, e1, f2, K2, 10, 11); R(e1, a1, b1, c1, d1, f2, K2, 6, 9); R(d1, e1, a1, b1, c1, f2, K2, 15, 7); R(c1, d1, e1, a1, b1, f2, K2, 3, 15); R(b1, c1, d1, e1, a1, f2, K2, 12, 7); R(a1, b1, c1, d1, e1, f2, K2, 0, 12); R(e1, a1, b1, c1, d1, f2, K2, 9, 15); R(d1, e1, a1, b1, c1, f2, K2, 5, 9); R(c1, d1, e1, a1, b1, f2, K2, 2, 11); R(b1, c1, d1, e1, a1, f2, K2, 14, 7); R(a1, b1, c1, d1, e1, f2, K2, 11, 13); R(e1, a1, b1, c1, d1, f2, K2, 8, 12); R(d1, e1, a1, b1, c1, f3, K3, 3, 11); R(c1, d1, e1, a1, b1, f3, K3, 10, 13); R(b1, c1, d1, e1, a1, f3, K3, 14, 6); R(a1, b1, c1, d1, e1, f3, K3, 4, 7); R(e1, a1, b1, c1, d1, f3, K3, 9, 14); R(d1, e1, a1, b1, c1, f3, K3, 15, 9); R(c1, d1, e1, a1, b1, f3, K3, 8, 13); R(b1, c1, d1, e1, a1, f3, K3, 1, 15); R(a1, b1, c1, d1, e1, f3, K3, 2, 14); R(e1, a1, b1, c1, d1, f3, K3, 7, 8); R(d1, e1, a1, b1, c1, f3, K3, 0, 13); R(c1, d1, e1, a1, b1, f3, K3, 6, 6); R(b1, c1, d1, e1, a1, f3, K3, 13, 5); R(a1, b1, c1, d1, e1, f3, K3, 11, 12); R(e1, a1, b1, c1, d1, f3, K3, 5, 7); R(d1, e1, a1, b1, c1, f3, K3, 12, 5); R(c1, d1, e1, a1, b1, f4, K4, 1, 11); R(b1, c1, d1, e1, a1, f4, K4, 9, 12); R(a1, b1, c1, d1, e1, f4, K4, 11, 14); R(e1, a1, b1, c1, d1, f4, K4, 10, 15); R(d1, e1, a1, b1, c1, f4, K4, 0, 14); R(c1, d1, e1, a1, b1, f4, K4, 8, 15); R(b1, c1, d1, e1, a1, f4, K4, 12, 9); R(a1, b1, c1, d1, e1, f4, K4, 4, 8); R(e1, a1, b1, c1, d1, f4, K4, 13, 9); R(d1, e1, a1, b1, c1, f4, K4, 3, 14); R(c1, d1, e1, a1, b1, f4, K4, 7, 5); R(b1, c1, d1, e1, a1, f4, K4, 15, 6); R(a1, b1, c1, d1, e1, f4, K4, 14, 8); R(e1, a1, b1, c1, d1, f4, K4, 5, 6); R(d1, e1, a1, b1, c1, f4, K4, 6, 5); R(c1, d1, e1, a1, b1, f4, K4, 2, 12); R(b1, c1, d1, e1, a1, f5, K5, 4, 9); R(a1, b1, c1, d1, e1, f5, K5, 0, 15); R(e1, a1, b1, c1, d1, f5, K5, 5, 5); R(d1, e1, a1, b1, c1, f5, K5, 9, 11); R(c1, d1, e1, a1, b1, f5, K5, 7, 6); R(b1, c1, d1, e1, a1, f5, K5, 12, 8); R(a1, b1, c1, d1, e1, f5, K5, 2, 13); R(e1, a1, b1, c1, d1, f5, K5, 10, 12); R(d1, e1, a1, b1, c1, f5, K5, 14, 5); R(c1, d1, e1, a1, b1, f5, K5, 1, 12); R(b1, c1, d1, e1, a1, f5, K5, 3, 13); R(a1, b1, c1, d1, e1, f5, K5, 8, 14); R(e1, a1, b1, c1, d1, f5, K5, 11, 11); R(d1, e1, a1, b1, c1, f5, K5, 6, 8); R(c1, d1, e1, a1, b1, f5, K5, 15, 5); R(b1, c1, d1, e1, a1, f5, K5, 13, 6); /* 5 passes on second state copy */ R(a2, b2, c2, d2, e2, f5, K6, 5, 8); R(e2, a2, b2, c2, d2, f5, K6, 14, 9); R(d2, e2, a2, b2, c2, f5, K6, 7, 9); R(c2, d2, e2, a2, b2, f5, K6, 0, 11); R(b2, c2, d2, e2, a2, f5, K6, 9, 13); R(a2, b2, c2, d2, e2, f5, K6, 2, 15); R(e2, a2, b2, c2, d2, f5, K6, 11, 15); R(d2, e2, a2, b2, c2, f5, K6, 4, 5); R(c2, d2, e2, a2, b2, f5, K6, 13, 7); R(b2, c2, d2, e2, a2, f5, K6, 6, 7); R(a2, b2, c2, d2, e2, f5, K6, 15, 8); R(e2, a2, b2, c2, d2, f5, K6, 8, 11); R(d2, e2, a2, b2, c2, f5, K6, 1, 14); R(c2, d2, e2, a2, b2, f5, K6, 10, 14); R(b2, c2, d2, e2, a2, f5, K6, 3, 12); R(a2, b2, c2, d2, e2, f5, K6, 12, 6); R(e2, a2, b2, c2, d2, f4, K7, 6, 9); R(d2, e2, a2, b2, c2, f4, K7, 11, 13); R(c2, d2, e2, a2, b2, f4, K7, 3, 15); R(b2, c2, d2, e2, a2, f4, K7, 7, 7); R(a2, b2, c2, d2, e2, f4, K7, 0, 12); R(e2, a2, b2, c2, d2, f4, K7, 13, 8); R(d2, e2, a2, b2, c2, f4, K7, 5, 9); R(c2, d2, e2, a2, b2, f4, K7, 10, 11); R(b2, c2, d2, e2, a2, f4, K7, 14, 7); R(a2, b2, c2, d2, e2, f4, K7, 15, 7); R(e2, a2, b2, c2, d2, f4, K7, 8, 12); R(d2, e2, a2, b2, c2, f4, K7, 12, 7); R(c2, d2, e2, a2, b2, f4, K7, 4, 6); R(b2, c2, d2, e2, a2, f4, K7, 9, 15); R(a2, b2, c2, d2, e2, f4, K7, 1, 13); R(e2, a2, b2, c2, d2, f4, K7, 2, 11); R(d2, e2, a2, b2, c2, f3, K8, 15, 9); R(c2, d2, e2, a2, b2, f3, K8, 5, 7); R(b2, c2, d2, e2, a2, f3, K8, 1, 15); R(a2, b2, c2, d2, e2, f3, K8, 3, 11); R(e2, a2, b2, c2, d2, f3, K8, 7, 8); R(d2, e2, a2, b2, c2, f3, K8, 14, 6); R(c2, d2, e2, a2, b2, f3, K8, 6, 6); R(b2, c2, d2, e2, a2, f3, K8, 9, 14); R(a2, b2, c2, d2, e2, f3, K8, 11, 12); R(e2, a2, b2, c2, d2, f3, K8, 8, 13); R(d2, e2, a2, b2, c2, f3, K8, 12, 5); R(c2, d2, e2, a2, b2, f3, K8, 2, 14); R(b2, c2, d2, e2, a2, f3, K8, 10, 13); R(a2, b2, c2, d2, e2, f3, K8, 0, 13); R(e2, a2, b2, c2, d2, f3, K8, 4, 7); R(d2, e2, a2, b2, c2, f3, K8, 13, 5); R(c2, d2, e2, a2, b2, f2, K9, 8, 15); R(b2, c2, d2, e2, a2, f2, K9, 6, 5); R(a2, b2, c2, d2, e2, f2, K9, 4, 8); R(e2, a2, b2, c2, d2, f2, K9, 1, 11); R(d2, e2, a2, b2, c2, f2, K9, 3, 14); R(c2, d2, e2, a2, b2, f2, K9, 11, 14); R(b2, c2, d2, e2, a2, f2, K9, 15, 6); R(a2, b2, c2, d2, e2, f2, K9, 0, 14); R(e2, a2, b2, c2, d2, f2, K9, 5, 6); R(d2, e2, a2, b2, c2, f2, K9, 12, 9); R(c2, d2, e2, a2, b2, f2, K9, 2, 12); R(b2, c2, d2, e2, a2, f2, K9, 13, 9); R(a2, b2, c2, d2, e2, f2, K9, 9, 12); R(e2, a2, b2, c2, d2, f2, K9, 7, 5); R(d2, e2, a2, b2, c2, f2, K9, 10, 15); R(c2, d2, e2, a2, b2, f2, K9, 14, 8); R(b2, c2, d2, e2, a2, f1, K1, 12, 8); R(a2, b2, c2, d2, e2, f1, K1, 15, 5); R(e2, a2, b2, c2, d2, f1, K1, 10, 12); R(d2, e2, a2, b2, c2, f1, K1, 4, 9); R(c2, d2, e2, a2, b2, f1, K1, 1, 12); R(b2, c2, d2, e2, a2, f1, K1, 5, 5); R(a2, b2, c2, d2, e2, f1, K1, 8, 14); R(e2, a2, b2, c2, d2, f1, K1, 7, 6); R(d2, e2, a2, b2, c2, f1, K1, 6, 8); R(c2, d2, e2, a2, b2, f1, K1, 2, 13); R(b2, c2, d2, e2, a2, f1, K1, 13, 6); R(a2, b2, c2, d2, e2, f1, K1, 14, 5); R(e2, a2, b2, c2, d2, f1, K1, 0, 15); R(d2, e2, a2, b2, c2, f1, K1, 3, 13); R(c2, d2, e2, a2, b2, f1, K1, 9, 11); R(b2, c2, d2, e2, a2, f1, K1, 11, 11); d2 += c1 + ctx->h[1]; ctx->h[1] = ctx->h[2] + d1 + e2; ctx->h[2] = ctx->h[3] + e1 + a2; ctx->h[3] = ctx->h[4] + a1 + b2; ctx->h[4] = ctx->h[0] + b1 + c2; ctx->h[0] = d2; } void cryptonite_ripemd160_update(struct ripemd160_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t index, to_fill; index = (uint32_t) (ctx->sz & 0x3f); to_fill = 64 - index; ctx->sz += len; if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); ripemd160_do_chunk(ctx, (uint32_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } for (; len >= 64; len -= 64, data += 64) ripemd160_do_chunk(ctx, (uint32_t *) data); if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_ripemd160_finalize(struct ripemd160_ctx *ctx, uint8_t *out) { static uint8_t padding[64] = { 0x80, }; uint64_t bits; uint32_t index, padlen; uint32_t *p = (uint32_t *) out; /* add padding and update data with it */ bits = cpu_to_le64(ctx->sz << 3); /* pad out to 56 */ index = (uint32_t) (ctx->sz & 0x3f); padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); cryptonite_ripemd160_update(ctx, padding, padlen); /* append length */ cryptonite_ripemd160_update(ctx, (uint8_t *) &bits, sizeof(bits)); /* output digest */ p[0] = cpu_to_le32(ctx->h[0]); p[1] = cpu_to_le32(ctx->h[1]); p[2] = cpu_to_le32(ctx->h[2]); p[3] = cpu_to_le32(ctx->h[3]); p[4] = cpu_to_le32(ctx->h[4]); } cryptonite-0.23/cbits/cryptonite_skein256.c0000644000000000000000000001325712673727640017150 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "cryptonite_skein.h" #include "cryptonite_skein256.h" #include "cryptonite_bitfn.h" static const uint8_t K256_0[2] = { 14, 16, }; static const uint8_t K256_1[2] = { 52, 57, }; static const uint8_t K256_2[2] = { 23, 40, }; static const uint8_t K256_3[2] = { 5, 37, }; static const uint8_t K256_4[2] = { 25, 33, }; static const uint8_t K256_5[2] = { 46, 12, }; static const uint8_t K256_6[2] = { 58, 22, }; static const uint8_t K256_7[2] = { 32, 32, }; static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, uint32_t len) { uint64_t x[4]; uint64_t ts[3]; uint64_t ks[4+1]; ks[4] = 0x1bd11bdaa9fc1a22ULL; ks[0] = ctx->h[0]; ks[4] ^= ctx->h[0]; ks[1] = ctx->h[1]; ks[4] ^= ctx->h[1]; ks[2] = ctx->h[2]; ks[4] ^= ctx->h[2]; ks[3] = ctx->h[3]; ks[4] ^= ctx->h[3]; ts[0] = ctx->t0; ts[1] = ctx->t1; ts[0] += len; ts[2] = ts[0] ^ ts[1]; #define INJECTKEY(r) \ x[0] += ks[((r)+0) % (4+1)]; \ x[1] += ks[((r)+1) % (4+1)] + ts[((r)+0) % 3]; \ x[2] += ks[((r)+2) % (4+1)] + ts[((r)+1) % 3]; \ x[3] += ks[((r)+3) % (4+1)] + (r) #define ROUND(a,b,c,d,k) \ x[a] += x[b]; x[b] = rol64(x[b],k[0]); x[b] ^= x[a]; \ x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c]; #define PASS(i) \ ROUND(0,1,2,3,K256_0); \ ROUND(0,3,2,1,K256_1); \ ROUND(0,1,2,3,K256_2); \ ROUND(0,3,2,1,K256_3); \ INJECTKEY((i*2) + 1); \ ROUND(0,1,2,3,K256_4); \ ROUND(0,3,2,1,K256_5); \ ROUND(0,1,2,3,K256_6); \ ROUND(0,3,2,1,K256_7); \ INJECTKEY((i*2) + 2) x[0] = le64_to_cpu(buf[0]) + ks[0]; x[1] = le64_to_cpu(buf[1]) + ks[1] + ts[0]; x[2] = le64_to_cpu(buf[2]) + ks[2] + ts[1]; x[3] = le64_to_cpu(buf[3]) + ks[3]; /* 9 pass of 8 rounds = 72 rounds */ PASS(0); PASS(1); PASS(2); PASS(3); PASS(4); PASS(5); PASS(6); PASS(7); PASS(8); ts[1] &= ~FLAG_FIRST; ctx->t0 = ts[0]; ctx->t1 = ts[1]; ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]); ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]); ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]); ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]); } void cryptonite_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen) { uint64_t buf[4]; memset(ctx, 0, sizeof(*ctx)); SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG)); memset(buf, '\0', sizeof(buf)); buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING); buf[1] = cpu_to_le64(hashlen); buf[2] = 0; /* tree info, not implemented */ skein256_do_chunk(ctx, buf, 4*8); SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG)); } void cryptonite_skein256_update(struct skein256_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t to_fill; if (!len) return; to_fill = 32 - ctx->bufindex; if (ctx->bufindex == 32) { skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32); ctx->bufindex = 0; } /* process partial buffer if there's enough data to make a block * and there's without doubt further blocks */ if (ctx->bufindex && len > to_fill) { memcpy(ctx->buf + ctx->bufindex, data, to_fill); skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32); len -= to_fill; data += to_fill; ctx->bufindex = 0; } /* process as much 32-block as possible except the last one in case we finalize */ for (; len > 32; len -= 32, data += 32) skein256_do_chunk(ctx, (uint64_t *) data, 32); /* append data into buf */ if (len) { memcpy(ctx->buf + ctx->bufindex, data, len); ctx->bufindex += len; } } void cryptonite_skein256_finalize(struct skein256_ctx *ctx, uint32_t hashlen, uint8_t *out) { uint32_t outsize; uint64_t *p = (uint64_t *) out; uint64_t x[4]; int i, j, n; ctx->t1 |= FLAG_FINAL; /* if buf is not complete pad with 0 bytes */ if (ctx->bufindex < 32) memset(ctx->buf + ctx->bufindex, '\0', 32 - ctx->bufindex); skein256_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex); memset(ctx->buf, '\0', 32); /* make sure we have a 8 bit up rounded value */ outsize = (hashlen + 7) >> 3; /* backup h[0--4] */ for (j = 0; j < 4; j++) x[j] = ctx->h[j]; /* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */ for (i = 0; i*32 < outsize; i++) { uint64_t w[4]; *((uint64_t *) ctx->buf) = cpu_to_le64(i); SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT)); skein256_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t)); n = outsize - i * 32; if (n >= 32) n = 32; cpu_to_le64_array(w, ctx->h, 4); memcpy(out + i*32, w, n); /* restore h[0--4] */ for (j = 0; j < 4; j++) ctx->h[j] = x[j]; } } cryptonite-0.23/cbits/cryptonite_skein512.c0000644000000000000000000001514012673727640017134 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "cryptonite_skein.h" #include "cryptonite_skein512.h" #include "cryptonite_bitfn.h" static const uint8_t K512_0[4] = { 46, 36, 19, 37, }; static const uint8_t K512_1[4] = { 33, 27, 14, 42, }; static const uint8_t K512_2[4] = { 17, 49, 36, 39, }; static const uint8_t K512_3[4] = { 44, 9, 54, 56, }; static const uint8_t K512_4[4] = { 39, 30, 34, 24, }; static const uint8_t K512_5[4] = { 13, 50, 10, 17, }; static const uint8_t K512_6[4] = { 25, 29, 39, 43, }; static const uint8_t K512_7[4] = { 8, 35, 56, 22, }; static inline void skein512_do_chunk(struct skein512_ctx *ctx, uint64_t *buf, uint32_t len) { uint64_t x[8]; uint64_t ts[3]; uint64_t ks[8+1]; ks[8] = 0x1bd11bdaa9fc1a22ULL; ks[0] = ctx->h[0]; ks[8] ^= ctx->h[0]; ks[1] = ctx->h[1]; ks[8] ^= ctx->h[1]; ks[2] = ctx->h[2]; ks[8] ^= ctx->h[2]; ks[3] = ctx->h[3]; ks[8] ^= ctx->h[3]; ks[4] = ctx->h[4]; ks[8] ^= ctx->h[4]; ks[5] = ctx->h[5]; ks[8] ^= ctx->h[5]; ks[6] = ctx->h[6]; ks[8] ^= ctx->h[6]; ks[7] = ctx->h[7]; ks[8] ^= ctx->h[7]; ts[0] = ctx->t0; ts[1] = ctx->t1; ts[0] += len; ts[2] = ts[0] ^ ts[1]; #define INJECTKEY(r) \ x[0] += ks[((r)+0) % (8+1)]; \ x[1] += ks[((r)+1) % (8+1)]; \ x[2] += ks[((r)+2) % (8+1)]; \ x[3] += ks[((r)+3) % (8+1)]; \ x[4] += ks[((r)+4) % (8+1)]; \ x[5] += ks[((r)+5) % (8+1)] + ts[((r)+0) % 3]; \ x[6] += ks[((r)+6) % (8+1)] + ts[((r)+1) % 3]; \ x[7] += ks[((r)+7) % (8+1)] + (r) #define ROUND(a,b,c,d,e,f,g,h,k) \ x[a] += x[b]; x[b] = rol64(x[b],k[0]); x[b] ^= x[a]; \ x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c]; \ x[e] += x[f]; x[f] = rol64(x[f],k[2]); x[f] ^= x[e]; \ x[g] += x[h]; x[h] = rol64(x[h],k[3]); x[h] ^= x[g]; #define PASS(i) \ ROUND(0,1,2,3,4,5,6,7,K512_0); \ ROUND(2,1,4,7,6,5,0,3,K512_1); \ ROUND(4,1,6,3,0,5,2,7,K512_2); \ ROUND(6,1,0,7,2,5,4,3,K512_3); \ INJECTKEY((i*2) + 1); \ ROUND(0,1,2,3,4,5,6,7,K512_4); \ ROUND(2,1,4,7,6,5,0,3,K512_5); \ ROUND(4,1,6,3,0,5,2,7,K512_6); \ ROUND(6,1,0,7,2,5,4,3,K512_7); \ INJECTKEY((i*2) + 2) x[0] = le64_to_cpu(buf[0]) + ks[0]; x[1] = le64_to_cpu(buf[1]) + ks[1]; x[2] = le64_to_cpu(buf[2]) + ks[2]; x[3] = le64_to_cpu(buf[3]) + ks[3]; x[4] = le64_to_cpu(buf[4]) + ks[4]; x[5] = le64_to_cpu(buf[5]) + ks[5] + ts[0]; x[6] = le64_to_cpu(buf[6]) + ks[6] + ts[1]; x[7] = le64_to_cpu(buf[7]) + ks[7]; /* 9 pass of 8 rounds = 72 rounds */ PASS(0); PASS(1); PASS(2); PASS(3); PASS(4); PASS(5); PASS(6); PASS(7); PASS(8); ts[1] &= ~FLAG_FIRST; ctx->t0 = ts[0]; ctx->t1 = ts[1]; ctx->h[0] = x[0] ^ cpu_to_le64(buf[0]); ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]); ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]); ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]); ctx->h[4] = x[4] ^ cpu_to_le64(buf[4]); ctx->h[5] = x[5] ^ cpu_to_le64(buf[5]); ctx->h[6] = x[6] ^ cpu_to_le64(buf[6]); ctx->h[7] = x[7] ^ cpu_to_le64(buf[7]); } void cryptonite_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen) { uint64_t buf[8]; memset(ctx, 0, sizeof(*ctx)); SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_CFG)); memset(buf, '\0', sizeof(buf)); buf[0] = cpu_to_le64((SKEIN_VERSION << 32) | SKEIN_IDSTRING); buf[1] = cpu_to_le64(hashlen); buf[2] = 0; /* tree info, not implemented */ skein512_do_chunk(ctx, buf, 4*8); SET_TYPE(ctx, FLAG_FIRST | FLAG_TYPE(TYPE_MSG)); } void cryptonite_skein512_update(struct skein512_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t to_fill; if (!len) return; to_fill = 64 - ctx->bufindex; if (ctx->bufindex == 64) { skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64); ctx->bufindex = 0; } /* process partial buffer if there's enough data to make a block * and there's without doubt further blocks */ if (ctx->bufindex && len > to_fill) { memcpy(ctx->buf + ctx->bufindex, data, to_fill); skein512_do_chunk(ctx, (uint64_t *) ctx->buf, 64); len -= to_fill; data += to_fill; ctx->bufindex = 0; } /* process as much 64-block as possible except the last one in case we finalize */ for (; len > 64; len -= 64, data += 64) skein512_do_chunk(ctx, (uint64_t *) data, 64); /* append data into buf */ if (len) { memcpy(ctx->buf + ctx->bufindex, data, len); ctx->bufindex += len; } } void cryptonite_skein512_finalize(struct skein512_ctx *ctx, uint32_t hashlen, uint8_t *out) { uint32_t outsize; uint64_t *p = (uint64_t *) out; uint64_t x[8]; int i, j, n; ctx->t1 |= FLAG_FINAL; /* if buf is not complete pad with 0 bytes */ if (ctx->bufindex < 64) memset(ctx->buf + ctx->bufindex, '\0', 64 - ctx->bufindex); skein512_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex); memset(ctx->buf, '\0', 64); /* make sure we have a 8 bit rounded value */ outsize = (hashlen + 7) >> 3; /* backup h[0--7] */ for (j = 0; j < 8; j++) x[j] = ctx->h[j]; /* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */ for (i = 0; i*64 < outsize; i++) { uint64_t w[8]; *((uint64_t *) ctx->buf) = cpu_to_le64(i); SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT)); skein512_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t)); n = outsize - i * 64; if (n >= 64) n = 64; cpu_to_le64_array(w, ctx->h, 8); memcpy(out + i*64, w, n); /* restore h[0--7] */ for (j = 0; j < 8; j++) ctx->h[j] = x[j]; } } cryptonite-0.23/cbits/cryptonite_tiger.c0000644000000000000000000006641112514540320016672 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "cryptonite_tiger.h" #include "cryptonite_bitfn.h" static const uint64_t t1[256] = { 0x02aab17cf7e90c5eULL,0xac424b03e243a8ecULL,0x72cd5be30dd5fcd3ULL,0x6d019b93f6f97f3aULL, 0xcd9978ffd21f9193ULL,0x7573a1c9708029e2ULL,0xb164326b922a83c3ULL,0x46883eee04915870ULL, 0xeaace3057103ece6ULL,0xc54169b808a3535cULL,0x4ce754918ddec47cULL,0x0aa2f4dfdc0df40cULL, 0x10b76f18a74dbefaULL,0xc6ccb6235ad1ab6aULL,0x13726121572fe2ffULL,0x1a488c6f199d921eULL, 0x4bc9f9f4da0007caULL,0x26f5e6f6e85241c7ULL,0x859079dbea5947b6ULL,0x4f1885c5c99e8c92ULL, 0xd78e761ea96f864bULL,0x8e36428c52b5c17dULL,0x69cf6827373063c1ULL,0xb607c93d9bb4c56eULL, 0x7d820e760e76b5eaULL,0x645c9cc6f07fdc42ULL,0xbf38a078243342e0ULL,0x5f6b343c9d2e7d04ULL, 0xf2c28aeb600b0ec6ULL,0x6c0ed85f7254bcacULL,0x71592281a4db4fe5ULL,0x1967fa69ce0fed9fULL, 0xfd5293f8b96545dbULL,0xc879e9d7f2a7600bULL,0x860248920193194eULL,0xa4f9533b2d9cc0b3ULL, 0x9053836c15957613ULL,0xdb6dcf8afc357bf1ULL,0x18beea7a7a370f57ULL,0x037117ca50b99066ULL, 0x6ab30a9774424a35ULL,0xf4e92f02e325249bULL,0x7739db07061ccae1ULL,0xd8f3b49ceca42a05ULL, 0xbd56be3f51382f73ULL,0x45faed5843b0bb28ULL,0x1c813d5c11bf1f83ULL,0x8af0e4b6d75fa169ULL, 0x33ee18a487ad9999ULL,0x3c26e8eab1c94410ULL,0xb510102bc0a822f9ULL,0x141eef310ce6123bULL, 0xfc65b90059ddb154ULL,0xe0158640c5e0e607ULL,0x884e079826c3a3cfULL,0x930d0d9523c535fdULL, 0x35638d754e9a2b00ULL,0x4085fccf40469dd5ULL,0xc4b17ad28be23a4cULL,0xcab2f0fc6a3e6a2eULL, 0x2860971a6b943fcdULL,0x3dde6ee212e30446ULL,0x6222f32ae01765aeULL,0x5d550bb5478308feULL, 0xa9efa98da0eda22aULL,0xc351a71686c40da7ULL,0x1105586d9c867c84ULL,0xdcffee85fda22853ULL, 0xccfbd0262c5eef76ULL,0xbaf294cb8990d201ULL,0xe69464f52afad975ULL,0x94b013afdf133e14ULL, 0x06a7d1a32823c958ULL,0x6f95fe5130f61119ULL,0xd92ab34e462c06c0ULL,0xed7bde33887c71d2ULL, 0x79746d6e6518393eULL,0x5ba419385d713329ULL,0x7c1ba6b948a97564ULL,0x31987c197bfdac67ULL, 0xde6c23c44b053d02ULL,0x581c49fed002d64dULL,0xdd474d6338261571ULL,0xaa4546c3e473d062ULL, 0x928fce349455f860ULL,0x48161bbacaab94d9ULL,0x63912430770e6f68ULL,0x6ec8a5e602c6641cULL, 0x87282515337ddd2bULL,0x2cda6b42034b701bULL,0xb03d37c181cb096dULL,0xe108438266c71c6fULL, 0x2b3180c7eb51b255ULL,0xdf92b82f96c08bbcULL,0x5c68c8c0a632f3baULL,0x5504cc861c3d0556ULL, 0xabbfa4e55fb26b8fULL,0x41848b0ab3baceb4ULL,0xb334a273aa445d32ULL,0xbca696f0a85ad881ULL, 0x24f6ec65b528d56cULL,0x0ce1512e90f4524aULL,0x4e9dd79d5506d35aULL,0x258905fac6ce9779ULL, 0x2019295b3e109b33ULL,0xf8a9478b73a054ccULL,0x2924f2f934417eb0ULL,0x3993357d536d1bc4ULL, 0x38a81ac21db6ff8bULL,0x47c4fbf17d6016bfULL,0x1e0faadd7667e3f5ULL,0x7abcff62938beb96ULL, 0xa78dad948fc179c9ULL,0x8f1f98b72911e50dULL,0x61e48eae27121a91ULL,0x4d62f7ad31859808ULL, 0xeceba345ef5ceaebULL,0xf5ceb25ebc9684ceULL,0xf633e20cb7f76221ULL,0xa32cdf06ab8293e4ULL, 0x985a202ca5ee2ca4ULL,0xcf0b8447cc8a8fb1ULL,0x9f765244979859a3ULL,0xa8d516b1a1240017ULL, 0x0bd7ba3ebb5dc726ULL,0xe54bca55b86adb39ULL,0x1d7a3afd6c478063ULL,0x519ec608e7669eddULL, 0x0e5715a2d149aa23ULL,0x177d4571848ff194ULL,0xeeb55f3241014c22ULL,0x0f5e5ca13a6e2ec2ULL, 0x8029927b75f5c361ULL,0xad139fabc3d6e436ULL,0x0d5df1a94ccf402fULL,0x3e8bd948bea5dfc8ULL, 0xa5a0d357bd3ff77eULL,0xa2d12e251f74f645ULL,0x66fd9e525e81a082ULL,0x2e0c90ce7f687a49ULL, 0xc2e8bcbeba973bc5ULL,0x000001bce509745fULL,0x423777bbe6dab3d6ULL,0xd1661c7eaef06eb5ULL, 0xa1781f354daacfd8ULL,0x2d11284a2b16affcULL,0xf1fc4f67fa891d1fULL,0x73ecc25dcb920adaULL, 0xae610c22c2a12651ULL,0x96e0a810d356b78aULL,0x5a9a381f2fe7870fULL,0xd5ad62ede94e5530ULL, 0xd225e5e8368d1427ULL,0x65977b70c7af4631ULL,0x99f889b2de39d74fULL,0x233f30bf54e1d143ULL, 0x9a9675d3d9a63c97ULL,0x5470554ff334f9a8ULL,0x166acb744a4f5688ULL,0x70c74caab2e4aeadULL, 0xf0d091646f294d12ULL,0x57b82a89684031d1ULL,0xefd95a5a61be0b6bULL,0x2fbd12e969f2f29aULL, 0x9bd37013feff9fe8ULL,0x3f9b0404d6085a06ULL,0x4940c1f3166cfe15ULL,0x09542c4dcdf3defbULL, 0xb4c5218385cd5ce3ULL,0xc935b7dc4462a641ULL,0x3417f8a68ed3b63fULL,0xb80959295b215b40ULL, 0xf99cdaef3b8c8572ULL,0x018c0614f8fcb95dULL,0x1b14accd1a3acdf3ULL,0x84d471f200bb732dULL, 0xc1a3110e95e8da16ULL,0x430a7220bf1a82b8ULL,0xb77e090d39df210eULL,0x5ef4bd9f3cd05e9dULL, 0x9d4ff6da7e57a444ULL,0xda1d60e183d4a5f8ULL,0xb287c38417998e47ULL,0xfe3edc121bb31886ULL, 0xc7fe3ccc980ccbefULL,0xe46fb590189bfd03ULL,0x3732fd469a4c57dcULL,0x7ef700a07cf1ad65ULL, 0x59c64468a31d8859ULL,0x762fb0b4d45b61f6ULL,0x155baed099047718ULL,0x68755e4c3d50baa6ULL, 0xe9214e7f22d8b4dfULL,0x2addbf532eac95f4ULL,0x32ae3909b4bd0109ULL,0x834df537b08e3450ULL, 0xfa209da84220728dULL,0x9e691d9b9efe23f7ULL,0x0446d288c4ae8d7fULL,0x7b4cc524e169785bULL, 0x21d87f0135ca1385ULL,0xcebb400f137b8aa5ULL,0x272e2b66580796beULL,0x3612264125c2b0deULL, 0x057702bdad1efbb2ULL,0xd4babb8eacf84be9ULL,0x91583139641bc67bULL,0x8bdc2de08036e024ULL, 0x603c8156f49f68edULL,0xf7d236f7dbef5111ULL,0x9727c4598ad21e80ULL,0xa08a0896670a5fd7ULL, 0xcb4a8f4309eba9cbULL,0x81af564b0f7036a1ULL,0xc0b99aa778199abdULL,0x959f1ec83fc8e952ULL, 0x8c505077794a81b9ULL,0x3acaaf8f056338f0ULL,0x07b43f50627a6778ULL,0x4a44ab49f5eccc77ULL, 0x3bc3d6e4b679ee98ULL,0x9cc0d4d1cf14108cULL,0x4406c00b206bc8a0ULL,0x82a18854c8d72d89ULL, 0x67e366b35c3c432cULL,0xb923dd61102b37f2ULL,0x56ab2779d884271dULL,0xbe83e1b0ff1525afULL, 0xfb7c65d4217e49a9ULL,0x6bdbe0e76d48e7d4ULL,0x08df828745d9179eULL,0x22ea6a9add53bd34ULL, 0xe36e141c5622200aULL,0x7f805d1b8cb750eeULL,0xafe5c7a59f58e837ULL,0xe27f996a4fb1c23cULL, 0xd3867dfb0775f0d0ULL,0xd0e673de6e88891aULL,0x123aeb9eafb86c25ULL,0x30f1d5d5c145b895ULL, 0xbb434a2dee7269e7ULL,0x78cb67ecf931fa38ULL,0xf33b0372323bbf9cULL,0x52d66336fb279c74ULL, 0x505f33ac0afb4eaaULL,0xe8a5cd99a2cce187ULL,0x534974801e2d30bbULL,0x8d2d5711d5876d90ULL, 0x1f1a412891bc038eULL,0xd6e2e71d82e56648ULL,0x74036c3a497732b7ULL,0x89b67ed96361f5abULL, 0xffed95d8f1ea02a2ULL,0xe72b3bd61464d43dULL,0xa6300f170bdc4820ULL,0xebc18760ed78a77aULL, }; static const uint64_t t2[256] = { 0xe6a6be5a05a12138ULL,0xb5a122a5b4f87c98ULL,0x563c6089140b6990ULL,0x4c46cb2e391f5dd5ULL, 0xd932addbc9b79434ULL,0x08ea70e42015aff5ULL,0xd765a6673e478cf1ULL,0xc4fb757eab278d99ULL, 0xdf11c6862d6e0692ULL,0xddeb84f10d7f3b16ULL,0x6f2ef604a665ea04ULL,0x4a8e0f0ff0e0dfb3ULL, 0xa5edeef83dbcba51ULL,0xfc4f0a2a0ea4371eULL,0xe83e1da85cb38429ULL,0xdc8ff882ba1b1ce2ULL, 0xcd45505e8353e80dULL,0x18d19a00d4db0717ULL,0x34a0cfeda5f38101ULL,0x0be77e518887caf2ULL, 0x1e341438b3c45136ULL,0xe05797f49089ccf9ULL,0xffd23f9df2591d14ULL,0x543dda228595c5cdULL, 0x661f81fd99052a33ULL,0x8736e641db0f7b76ULL,0x15227725418e5307ULL,0xe25f7f46162eb2faULL, 0x48a8b2126c13d9feULL,0xafdc541792e76eeaULL,0x03d912bfc6d1898fULL,0x31b1aafa1b83f51bULL, 0xf1ac2796e42ab7d9ULL,0x40a3a7d7fcd2ebacULL,0x1056136d0afbbcc5ULL,0x7889e1dd9a6d0c85ULL, 0xd33525782a7974aaULL,0xa7e25d09078ac09bULL,0xbd4138b3eac6edd0ULL,0x920abfbe71eb9e70ULL, 0xa2a5d0f54fc2625cULL,0xc054e36b0b1290a3ULL,0xf6dd59ff62fe932bULL,0x3537354511a8ac7dULL, 0xca845e9172fadcd4ULL,0x84f82b60329d20dcULL,0x79c62ce1cd672f18ULL,0x8b09a2add124642cULL, 0xd0c1e96a19d9e726ULL,0x5a786a9b4ba9500cULL,0x0e020336634c43f3ULL,0xc17b474aeb66d822ULL, 0x6a731ae3ec9baac2ULL,0x8226667ae0840258ULL,0x67d4567691caeca5ULL,0x1d94155c4875adb5ULL, 0x6d00fd985b813fdfULL,0x51286efcb774cd06ULL,0x5e8834471fa744afULL,0xf72ca0aee761ae2eULL, 0xbe40e4cdaee8e09aULL,0xe9970bbb5118f665ULL,0x726e4beb33df1964ULL,0x703b000729199762ULL, 0x4631d816f5ef30a7ULL,0xb880b5b51504a6beULL,0x641793c37ed84b6cULL,0x7b21ed77f6e97d96ULL, 0x776306312ef96b73ULL,0xae528948e86ff3f4ULL,0x53dbd7f286a3f8f8ULL,0x16cadce74cfc1063ULL, 0x005c19bdfa52c6ddULL,0x68868f5d64d46ad3ULL,0x3a9d512ccf1e186aULL,0x367e62c2385660aeULL, 0xe359e7ea77dcb1d7ULL,0x526c0773749abe6eULL,0x735ae5f9d09f734bULL,0x493fc7cc8a558ba8ULL, 0xb0b9c1533041ab45ULL,0x321958ba470a59bdULL,0x852db00b5f46c393ULL,0x91209b2bd336b0e5ULL, 0x6e604f7d659ef19fULL,0xb99a8ae2782ccb24ULL,0xccf52ab6c814c4c7ULL,0x4727d9afbe11727bULL, 0x7e950d0c0121b34dULL,0x756f435670ad471fULL,0xf5add442615a6849ULL,0x4e87e09980b9957aULL, 0x2acfa1df50aee355ULL,0xd898263afd2fd556ULL,0xc8f4924dd80c8fd6ULL,0xcf99ca3d754a173aULL, 0xfe477bacaf91bf3cULL,0xed5371f6d690c12dULL,0x831a5c285e687094ULL,0xc5d3c90a3708a0a4ULL, 0x0f7f903717d06580ULL,0x19f9bb13b8fdf27fULL,0xb1bd6f1b4d502843ULL,0x1c761ba38fff4012ULL, 0x0d1530c4e2e21f3bULL,0x8943ce69a7372c8aULL,0xe5184e11feb5ce66ULL,0x618bdb80bd736621ULL, 0x7d29bad68b574d0bULL,0x81bb613e25e6fe5bULL,0x071c9c10bc07913fULL,0xc7beeb7909ac2d97ULL, 0xc3e58d353bc5d757ULL,0xeb017892f38f61e8ULL,0xd4effb9c9b1cc21aULL,0x99727d26f494f7abULL, 0xa3e063a2956b3e03ULL,0x9d4a8b9a4aa09c30ULL,0x3f6ab7d500090fb4ULL,0x9cc0f2a057268ac0ULL, 0x3dee9d2dedbf42d1ULL,0x330f49c87960a972ULL,0xc6b2720287421b41ULL,0x0ac59ec07c00369cULL, 0xef4eac49cb353425ULL,0xf450244eef0129d8ULL,0x8acc46e5caf4deb6ULL,0x2ffeab63989263f7ULL, 0x8f7cb9fe5d7a4578ULL,0x5bd8f7644e634635ULL,0x427a7315bf2dc900ULL,0x17d0c4aa2125261cULL, 0x3992486c93518e50ULL,0xb4cbfee0a2d7d4c3ULL,0x7c75d6202c5ddd8dULL,0xdbc295d8e35b6c61ULL, 0x60b369d302032b19ULL,0xce42685fdce44132ULL,0x06f3ddb9ddf65610ULL,0x8ea4d21db5e148f0ULL, 0x20b0fce62fcd496fULL,0x2c1b912358b0ee31ULL,0xb28317b818f5a308ULL,0xa89c1e189ca6d2cfULL, 0x0c6b18576aaadbc8ULL,0xb65deaa91299fae3ULL,0xfb2b794b7f1027e7ULL,0x04e4317f443b5bebULL, 0x4b852d325939d0a6ULL,0xd5ae6beefb207ffcULL,0x309682b281c7d374ULL,0xbae309a194c3b475ULL, 0x8cc3f97b13b49f05ULL,0x98a9422ff8293967ULL,0x244b16b01076ff7cULL,0xf8bf571c663d67eeULL, 0x1f0d6758eee30da1ULL,0xc9b611d97adeb9b7ULL,0xb7afd5887b6c57a2ULL,0x6290ae846b984fe1ULL, 0x94df4cdeacc1a5fdULL,0x058a5bd1c5483affULL,0x63166cc142ba3c37ULL,0x8db8526eb2f76f40ULL, 0xe10880036f0d6d4eULL,0x9e0523c9971d311dULL,0x45ec2824cc7cd691ULL,0x575b8359e62382c9ULL, 0xfa9e400dc4889995ULL,0xd1823ecb45721568ULL,0xdafd983b8206082fULL,0xaa7d29082386a8cbULL, 0x269fcd4403b87588ULL,0x1b91f5f728bdd1e0ULL,0xe4669f39040201f6ULL,0x7a1d7c218cf04adeULL, 0x65623c29d79ce5ceULL,0x2368449096c00bb1ULL,0xab9bf1879da503baULL,0xbc23ecb1a458058eULL, 0x9a58df01bb401eccULL,0xa070e868a85f143dULL,0x4ff188307df2239eULL,0x14d565b41a641183ULL, 0xee13337452701602ULL,0x950e3dcf3f285e09ULL,0x59930254b9c80953ULL,0x3bf299408930da6dULL, 0xa955943f53691387ULL,0xa15edecaa9cb8784ULL,0x29142127352be9a0ULL,0x76f0371fff4e7afbULL, 0x0239f450274f2228ULL,0xbb073af01d5e868bULL,0xbfc80571c10e96c1ULL,0xd267088568222e23ULL, 0x9671a3d48e80b5b0ULL,0x55b5d38ae193bb81ULL,0x693ae2d0a18b04b8ULL,0x5c48b4ecadd5335fULL, 0xfd743b194916a1caULL,0x2577018134be98c4ULL,0xe77987e83c54a4adULL,0x28e11014da33e1b9ULL, 0x270cc59e226aa213ULL,0x71495f756d1a5f60ULL,0x9be853fb60afef77ULL,0xadc786a7f7443dbfULL, 0x0904456173b29a82ULL,0x58bc7a66c232bd5eULL,0xf306558c673ac8b2ULL,0x41f639c6b6c9772aULL, 0x216defe99fda35daULL,0x11640cc71c7be615ULL,0x93c43694565c5527ULL,0xea038e6246777839ULL, 0xf9abf3ce5a3e2469ULL,0x741e768d0fd312d2ULL,0x0144b883ced652c6ULL,0xc20b5a5ba33f8552ULL, 0x1ae69633c3435a9dULL,0x97a28ca4088cfdecULL,0x8824a43c1e96f420ULL,0x37612fa66eeea746ULL, 0x6b4cb165f9cf0e5aULL,0x43aa1c06a0abfb4aULL,0x7f4dc26ff162796bULL,0x6cbacc8e54ed9b0fULL, 0xa6b7ffefd2bb253eULL,0x2e25bc95b0a29d4fULL,0x86d6a58bdef1388cULL,0xded74ac576b6f054ULL, 0x8030bdbc2b45805dULL,0x3c81af70e94d9289ULL,0x3eff6dda9e3100dbULL,0xb38dc39fdfcc8847ULL, 0x123885528d17b87eULL,0xf2da0ed240b1b642ULL,0x44cefadcd54bf9a9ULL,0x1312200e433c7ee6ULL, 0x9ffcc84f3a78c748ULL,0xf0cd1f72248576bbULL,0xec6974053638cfe4ULL,0x2ba7b67c0cec4e4cULL, 0xac2f4df3e5ce32edULL,0xcb33d14326ea4c11ULL,0xa4e9044cc77e58bcULL,0x5f513293d934fcefULL, 0x5dc9645506e55444ULL,0x50de418f317de40aULL,0x388cb31a69dde259ULL,0x2db4a83455820a86ULL, 0x9010a91e84711ae9ULL,0x4df7f0b7b1498371ULL,0xd62a2eabc0977179ULL,0x22fac097aa8d5c0eULL, }; static const uint64_t t3[256]= { 0xf49fcc2ff1daf39bULL,0x487fd5c66ff29281ULL,0xe8a30667fcdca83fULL,0x2c9b4be3d2fcce63ULL, 0xda3ff74b93fbbbc2ULL,0x2fa165d2fe70ba66ULL,0xa103e279970e93d4ULL,0xbecdec77b0e45e71ULL, 0xcfb41e723985e497ULL,0xb70aaa025ef75017ULL,0xd42309f03840b8e0ULL,0x8efc1ad035898579ULL, 0x96c6920be2b2abc5ULL,0x66af4163375a9172ULL,0x2174abdcca7127fbULL,0xb33ccea64a72ff41ULL, 0xf04a4933083066a5ULL,0x8d970acdd7289af5ULL,0x8f96e8e031c8c25eULL,0xf3fec02276875d47ULL, 0xec7bf310056190ddULL,0xf5adb0aebb0f1491ULL,0x9b50f8850fd58892ULL,0x4975488358b74de8ULL, 0xa3354ff691531c61ULL,0x0702bbe481d2c6eeULL,0x89fb24057deded98ULL,0xac3075138596e902ULL, 0x1d2d3580172772edULL,0xeb738fc28e6bc30dULL,0x5854ef8f63044326ULL,0x9e5c52325add3bbeULL, 0x90aa53cf325c4623ULL,0xc1d24d51349dd067ULL,0x2051cfeea69ea624ULL,0x13220f0a862e7e4fULL, 0xce39399404e04864ULL,0xd9c42ca47086fcb7ULL,0x685ad2238a03e7ccULL,0x066484b2ab2ff1dbULL, 0xfe9d5d70efbf79ecULL,0x5b13b9dd9c481854ULL,0x15f0d475ed1509adULL,0x0bebcd060ec79851ULL, 0xd58c6791183ab7f8ULL,0xd1187c5052f3eee4ULL,0xc95d1192e54e82ffULL,0x86eea14cb9ac6ca2ULL, 0x3485beb153677d5dULL,0xdd191d781f8c492aULL,0xf60866baa784ebf9ULL,0x518f643ba2d08c74ULL, 0x8852e956e1087c22ULL,0xa768cb8dc410ae8dULL,0x38047726bfec8e1aULL,0xa67738b4cd3b45aaULL, 0xad16691cec0dde19ULL,0xc6d4319380462e07ULL,0xc5a5876d0ba61938ULL,0x16b9fa1fa58fd840ULL, 0x188ab1173ca74f18ULL,0xabda2f98c99c021fULL,0x3e0580ab134ae816ULL,0x5f3b05b773645abbULL, 0x2501a2be5575f2f6ULL,0x1b2f74004e7e8ba9ULL,0x1cd7580371e8d953ULL,0x7f6ed89562764e30ULL, 0xb15926ff596f003dULL,0x9f65293da8c5d6b9ULL,0x6ecef04dd690f84cULL,0x4782275fff33af88ULL, 0xe41433083f820801ULL,0xfd0dfe409a1af9b5ULL,0x4325a3342cdb396bULL,0x8ae77e62b301b252ULL, 0xc36f9e9f6655615aULL,0x85455a2d92d32c09ULL,0xf2c7dea949477485ULL,0x63cfb4c133a39ebaULL, 0x83b040cc6ebc5462ULL,0x3b9454c8fdb326b0ULL,0x56f56a9e87ffd78cULL,0x2dc2940d99f42bc6ULL, 0x98f7df096b096e2dULL,0x19a6e01e3ad852bfULL,0x42a99ccbdbd4b40bULL,0xa59998af45e9c559ULL, 0x366295e807d93186ULL,0x6b48181bfaa1f773ULL,0x1fec57e2157a0a1dULL,0x4667446af6201ad5ULL, 0xe615ebcacfb0f075ULL,0xb8f31f4f68290778ULL,0x22713ed6ce22d11eULL,0x3057c1a72ec3c93bULL, 0xcb46acc37c3f1f2fULL,0xdbb893fd02aaf50eULL,0x331fd92e600b9fcfULL,0xa498f96148ea3ad6ULL, 0xa8d8426e8b6a83eaULL,0xa089b274b7735cdcULL,0x87f6b3731e524a11ULL,0x118808e5cbc96749ULL, 0x9906e4c7b19bd394ULL,0xafed7f7e9b24a20cULL,0x6509eadeeb3644a7ULL,0x6c1ef1d3e8ef0edeULL, 0xb9c97d43e9798fb4ULL,0xa2f2d784740c28a3ULL,0x7b8496476197566fULL,0x7a5be3e6b65f069dULL, 0xf96330ed78be6f10ULL,0xeee60de77a076a15ULL,0x2b4bee4aa08b9bd0ULL,0x6a56a63ec7b8894eULL, 0x02121359ba34fef4ULL,0x4cbf99f8283703fcULL,0x398071350caf30c8ULL,0xd0a77a89f017687aULL, 0xf1c1a9eb9e423569ULL,0x8c7976282dee8199ULL,0x5d1737a5dd1f7abdULL,0x4f53433c09a9fa80ULL, 0xfa8b0c53df7ca1d9ULL,0x3fd9dcbc886ccb77ULL,0xc040917ca91b4720ULL,0x7dd00142f9d1dcdfULL, 0x8476fc1d4f387b58ULL,0x23f8e7c5f3316503ULL,0x032a2244e7e37339ULL,0x5c87a5d750f5a74bULL, 0x082b4cc43698992eULL,0xdf917becb858f63cULL,0x3270b8fc5bf86ddaULL,0x10ae72bb29b5dd76ULL, 0x576ac94e7700362bULL,0x1ad112dac61efb8fULL,0x691bc30ec5faa427ULL,0xff246311cc327143ULL, 0x3142368e30e53206ULL,0x71380e31e02ca396ULL,0x958d5c960aad76f1ULL,0xf8d6f430c16da536ULL, 0xc8ffd13f1be7e1d2ULL,0x7578ae66004ddbe1ULL,0x05833f01067be646ULL,0xbb34b5ad3bfe586dULL, 0x095f34c9a12b97f0ULL,0x247ab64525d60ca8ULL,0xdcdbc6f3017477d1ULL,0x4a2e14d4decad24dULL, 0xbdb5e6d9be0a1eebULL,0x2a7e70f7794301abULL,0xdef42d8a270540fdULL,0x01078ec0a34c22c1ULL, 0xe5de511af4c16387ULL,0x7ebb3a52bd9a330aULL,0x77697857aa7d6435ULL,0x004e831603ae4c32ULL, 0xe7a21020ad78e312ULL,0x9d41a70c6ab420f2ULL,0x28e06c18ea1141e6ULL,0xd2b28cbd984f6b28ULL, 0x26b75f6c446e9d83ULL,0xba47568c4d418d7fULL,0xd80badbfe6183d8eULL,0x0e206d7f5f166044ULL, 0xe258a43911cbca3eULL,0x723a1746b21dc0bcULL,0xc7caa854f5d7cdd3ULL,0x7cac32883d261d9cULL, 0x7690c26423ba942cULL,0x17e55524478042b8ULL,0xe0be477656a2389fULL,0x4d289b5e67ab2da0ULL, 0x44862b9c8fbbfd31ULL,0xb47cc8049d141365ULL,0x822c1b362b91c793ULL,0x4eb14655fb13dfd8ULL, 0x1ecbba0714e2a97bULL,0x6143459d5cde5f14ULL,0x53a8fbf1d5f0ac89ULL,0x97ea04d81c5e5b00ULL, 0x622181a8d4fdb3f3ULL,0xe9bcd341572a1208ULL,0x1411258643cce58aULL,0x9144c5fea4c6e0a4ULL, 0x0d33d06565cf620fULL,0x54a48d489f219ca1ULL,0xc43e5eac6d63c821ULL,0xa9728b3a72770dafULL, 0xd7934e7b20df87efULL,0xe35503b61a3e86e5ULL,0xcae321fbc819d504ULL,0x129a50b3ac60bfa6ULL, 0xcd5e68ea7e9fb6c3ULL,0xb01c90199483b1c7ULL,0x3de93cd5c295376cULL,0xaed52edf2ab9ad13ULL, 0x2e60f512c0a07884ULL,0xbc3d86a3e36210c9ULL,0x35269d9b163951ceULL,0x0c7d6e2ad0cdb5faULL, 0x59e86297d87f5733ULL,0x298ef221898db0e7ULL,0x55000029d1a5aa7eULL,0x8bc08ae1b5061b45ULL, 0xc2c31c2b6c92703aULL,0x94cc596baf25ef42ULL,0x0a1d73db22540456ULL,0x04b6a0f9d9c4179aULL, 0xeffdafa2ae3d3c60ULL,0xf7c8075bb49496c4ULL,0x9cc5c7141d1cd4e3ULL,0x78bd1638218e5534ULL, 0xb2f11568f850246aULL,0xedfabcfa9502bc29ULL,0x796ce5f2da23051bULL,0xaae128b0dc93537cULL, 0x3a493da0ee4b29aeULL,0xb5df6b2c416895d7ULL,0xfcabbd25122d7f37ULL,0x70810b58105dc4b1ULL, 0xe10fdd37f7882a90ULL,0x524dcab5518a3f5cULL,0x3c9e85878451255bULL,0x4029828119bd34e2ULL, 0x74a05b6f5d3ceccbULL,0xb610021542e13ecaULL,0x0ff979d12f59e2acULL,0x6037da27e4f9cc50ULL, 0x5e92975a0df1847dULL,0xd66de190d3e623feULL,0x5032d6b87b568048ULL,0x9a36b7ce8235216eULL, 0x80272a7a24f64b4aULL,0x93efed8b8c6916f7ULL,0x37ddbff44cce1555ULL,0x4b95db5d4b99bd25ULL, 0x92d3fda169812fc0ULL,0xfb1a4a9a90660bb6ULL,0x730c196946a4b9b2ULL,0x81e289aa7f49da68ULL, 0x64669a0f83b1a05fULL,0x27b3ff7d9644f48bULL,0xcc6b615c8db675b3ULL,0x674f20b9bcebbe95ULL, 0x6f31238275655982ULL,0x5ae488713e45cf05ULL,0xbf619f9954c21157ULL,0xeabac46040a8eae9ULL, 0x454c6fe9f2c0c1cdULL,0x419cf6496412691cULL,0xd3dc3bef265b0f70ULL,0x6d0e60f5c3578a9eULL, }; static const uint64_t t4[256]= { 0x5b0e608526323c55ULL,0x1a46c1a9fa1b59f5ULL, 0xa9e245a17c4c8ffaULL,0x65ca5159db2955d7ULL, 0x05db0a76ce35afc2ULL,0x81eac77ea9113d45ULL, 0x528ef88ab6ac0a0dULL,0xa09ea253597be3ffULL, 0x430ddfb3ac48cd56ULL,0xc4b3a67af45ce46fULL, 0x4ececfd8fbe2d05eULL,0x3ef56f10b39935f0ULL, 0x0b22d6829cd619c6ULL,0x17fd460a74df2069ULL, 0x6cf8cc8e8510ed40ULL,0xd6c824bf3a6ecaa7ULL, 0x61243d581a817049ULL,0x048bacb6bbc163a2ULL, 0xd9a38ac27d44cc32ULL,0x7fddff5baaf410abULL, 0xad6d495aa804824bULL,0xe1a6a74f2d8c9f94ULL, 0xd4f7851235dee8e3ULL,0xfd4b7f886540d893ULL, 0x247c20042aa4bfdaULL,0x096ea1c517d1327cULL, 0xd56966b4361a6685ULL,0x277da5c31221057dULL, 0x94d59893a43acff7ULL,0x64f0c51ccdc02281ULL, 0x3d33bcc4ff6189dbULL,0xe005cb184ce66af1ULL, 0xff5ccd1d1db99beaULL,0xb0b854a7fe42980fULL, 0x7bd46a6a718d4b9fULL,0xd10fa8cc22a5fd8cULL, 0xd31484952be4bd31ULL,0xc7fa975fcb243847ULL, 0x4886ed1e5846c407ULL,0x28cddb791eb70b04ULL, 0xc2b00be2f573417fULL,0x5c9590452180f877ULL, 0x7a6bddfff370eb00ULL,0xce509e38d6d9d6a4ULL, 0xebeb0f00647fa702ULL,0x1dcc06cf76606f06ULL, 0xe4d9f28ba286ff0aULL,0xd85a305dc918c262ULL, 0x475b1d8732225f54ULL,0x2d4fb51668ccb5feULL, 0xa679b9d9d72bba20ULL,0x53841c0d912d43a5ULL, 0x3b7eaa48bf12a4e8ULL,0x781e0e47f22f1ddfULL, 0xeff20ce60ab50973ULL,0x20d261d19dffb742ULL, 0x16a12b03062a2e39ULL,0x1960eb2239650495ULL, 0x251c16fed50eb8b8ULL,0x9ac0c330f826016eULL, 0xed152665953e7671ULL,0x02d63194a6369570ULL, 0x5074f08394b1c987ULL,0x70ba598c90b25ce1ULL, 0x794a15810b9742f6ULL,0x0d5925e9fcaf8c6cULL, 0x3067716cd868744eULL,0x910ab077e8d7731bULL, 0x6a61bbdb5ac42f61ULL,0x93513efbf0851567ULL, 0xf494724b9e83e9d5ULL,0xe887e1985c09648dULL, 0x34b1d3c675370cfdULL,0xdc35e433bc0d255dULL, 0xd0aab84234131be0ULL,0x08042a50b48b7eafULL, 0x9997c4ee44a3ab35ULL,0x829a7b49201799d0ULL, 0x263b8307b7c54441ULL,0x752f95f4fd6a6ca6ULL, 0x927217402c08c6e5ULL,0x2a8ab754a795d9eeULL, 0xa442f7552f72943dULL,0x2c31334e19781208ULL, 0x4fa98d7ceaee6291ULL,0x55c3862f665db309ULL, 0xbd0610175d53b1f3ULL,0x46fe6cb840413f27ULL, 0x3fe03792df0cfa59ULL,0xcfe700372eb85e8fULL, 0xa7be29e7adbce118ULL,0xe544ee5cde8431ddULL, 0x8a781b1b41f1873eULL,0xa5c94c78a0d2f0e7ULL, 0x39412e2877b60728ULL,0xa1265ef3afc9a62cULL, 0xbcc2770c6a2506c5ULL,0x3ab66dd5dce1ce12ULL, 0xe65499d04a675b37ULL,0x7d8f523481bfd216ULL, 0x0f6f64fcec15f389ULL,0x74efbe618b5b13c8ULL, 0xacdc82b714273e1dULL,0xdd40bfe003199d17ULL, 0x37e99257e7e061f8ULL,0xfa52626904775aaaULL, 0x8bbbf63a463d56f9ULL,0xf0013f1543a26e64ULL, 0xa8307e9f879ec898ULL,0xcc4c27a4150177ccULL, 0x1b432f2cca1d3348ULL,0xde1d1f8f9f6fa013ULL, 0x606602a047a7ddd6ULL,0xd237ab64cc1cb2c7ULL, 0x9b938e7225fcd1d3ULL,0xec4e03708e0ff476ULL, 0xfeb2fbda3d03c12dULL,0xae0bced2ee43889aULL, 0x22cb8923ebfb4f43ULL,0x69360d013cf7396dULL, 0x855e3602d2d4e022ULL,0x073805bad01f784cULL, 0x33e17a133852f546ULL,0xdf4874058ac7b638ULL, 0xba92b29c678aa14aULL,0x0ce89fc76cfaadcdULL, 0x5f9d4e0908339e34ULL,0xf1afe9291f5923b9ULL, 0x6e3480f60f4a265fULL,0xeebf3a2ab29b841cULL, 0xe21938a88f91b4adULL,0x57dfeff845c6d3c3ULL, 0x2f006b0bf62caaf2ULL,0x62f479ef6f75ee78ULL, 0x11a55ad41c8916a9ULL,0xf229d29084fed453ULL, 0x42f1c27b16b000e6ULL,0x2b1f76749823c074ULL, 0x4b76eca3c2745360ULL,0x8c98f463b91691bdULL, 0x14bcc93cf1ade66aULL,0x8885213e6d458397ULL, 0x8e177df0274d4711ULL,0xb49b73b5503f2951ULL, 0x10168168c3f96b6bULL,0x0e3d963b63cab0aeULL, 0x8dfc4b5655a1db14ULL,0xf789f1356e14de5cULL, 0x683e68af4e51dac1ULL,0xc9a84f9d8d4b0fd9ULL, 0x3691e03f52a0f9d1ULL,0x5ed86e46e1878e80ULL, 0x3c711a0e99d07150ULL,0x5a0865b20c4e9310ULL, 0x56fbfc1fe4f0682eULL,0xea8d5de3105edf9bULL, 0x71abfdb12379187aULL,0x2eb99de1bee77b9cULL, 0x21ecc0ea33cf4523ULL,0x59a4d7521805c7a1ULL, 0x3896f5eb56ae7c72ULL,0xaa638f3db18f75dcULL, 0x9f39358dabe9808eULL,0xb7defa91c00b72acULL, 0x6b5541fd62492d92ULL,0x6dc6dee8f92e4d5bULL, 0x353f57abc4beea7eULL,0x735769d6da5690ceULL, 0x0a234aa642391484ULL,0xf6f9508028f80d9dULL, 0xb8e319a27ab3f215ULL,0x31ad9c1151341a4dULL, 0x773c22a57bef5805ULL,0x45c7561a07968633ULL, 0xf913da9e249dbe36ULL,0xda652d9b78a64c68ULL, 0x4c27a97f3bc334efULL,0x76621220e66b17f4ULL, 0x967743899acd7d0bULL,0xf3ee5bcae0ed6782ULL, 0x409f753600c879fcULL,0x06d09a39b5926db6ULL, 0x6f83aeb0317ac588ULL,0x01e6ca4a86381f21ULL, 0x66ff3462d19f3025ULL,0x72207c24ddfd3bfbULL, 0x4af6b6d3e2ece2ebULL,0x9c994dbec7ea08deULL, 0x49ace597b09a8bc4ULL,0xb38c4766cf0797baULL, 0x131b9373c57c2a75ULL,0xb1822cce61931e58ULL, 0x9d7555b909ba1c0cULL,0x127fafdd937d11d2ULL, 0x29da3badc66d92e4ULL,0xa2c1d57154c2ecbcULL, 0x58c5134d82f6fe24ULL,0x1c3ae3515b62274fULL, 0xe907c82e01cb8126ULL,0xf8ed091913e37fcbULL, 0x3249d8f9c80046c9ULL,0x80cf9bede388fb63ULL, 0x1881539a116cf19eULL,0x5103f3f76bd52457ULL, 0x15b7e6f5ae47f7a8ULL,0xdbd7c6ded47e9ccfULL, 0x44e55c410228bb1aULL,0xb647d4255edb4e99ULL, 0x5d11882bb8aafc30ULL,0xf5098bbb29d3212aULL, 0x8fb5ea14e90296b3ULL,0x677b942157dd025aULL, 0xfb58e7c0a390acb5ULL,0x89d3674c83bd4a01ULL, 0x9e2da4df4bf3b93bULL,0xfcc41e328cab4829ULL, 0x03f38c96ba582c52ULL,0xcad1bdbd7fd85db2ULL, 0xbbb442c16082ae83ULL,0xb95fe86ba5da9ab0ULL, 0xb22e04673771a93fULL,0x845358c9493152d8ULL, 0xbe2a488697b4541eULL,0x95a2dc2dd38e6966ULL, 0xc02c11ac923c852bULL,0x2388b1990df2a87bULL, 0x7c8008fa1b4f37beULL,0x1f70d0c84d54e503ULL, 0x5490adec7ece57d4ULL,0x002b3c27d9063a3aULL, 0x7eaea3848030a2bfULL,0xc602326ded2003c0ULL, 0x83a7287d69a94086ULL,0xc57a5fcb30f57a8aULL, 0xb56844e479ebe779ULL,0xa373b40f05dcbce9ULL, 0xd71a786e88570ee2ULL,0x879cbacdbde8f6a0ULL, 0x976ad1bcc164a32fULL,0xab21e25e9666d78bULL, 0x901063aae5e5c33cULL,0x9818b34448698d90ULL, 0xe36487ae3e1e8abbULL,0xafbdf931893bdcb4ULL, 0x6345a0dc5fbbd519ULL,0x8628fe269b9465caULL, 0x1e5d01603f9c51ecULL,0x4de44006a15049b7ULL, 0xbf6c70e5f776cbb1ULL,0x411218f2ef552bedULL, 0xcb0c0708705a36a3ULL,0xe74d14754f986044ULL, 0xcd56d9430ea8280eULL,0xc12591d7535f5065ULL, 0xc83223f1720aef96ULL,0xc3a0396f7363a51fULL, }; void cryptonite_tiger_init(struct tiger_ctx *ctx) { memset(ctx, 0, sizeof(*ctx)); ctx->h[0] = 0x0123456789abcdefULL; ctx->h[1] = 0xfedcba9876543210ULL; ctx->h[2] = 0xf096a5b4c3b2e187ULL; } static inline void tiger_do_chunk(struct tiger_ctx *ctx, uint64_t *buf) { uint64_t x0, x1, x2, x3, x4, x5, x6, x7; uint64_t a,b,c; a = ctx->h[0]; b = ctx->h[1]; c = ctx->h[2]; x0 = cpu_to_le64(buf[0]); x1 = cpu_to_le64(buf[1]); x2 = cpu_to_le64(buf[2]); x3 = cpu_to_le64(buf[3]); x4 = cpu_to_le64(buf[4]); x5 = cpu_to_le64(buf[5]); x6 = cpu_to_le64(buf[6]); x7 = cpu_to_le64(buf[7]); #define BYTEOF(c, n) ((uint8_t) (c >> ((n * 8)))) #define ROUND(a,b,c,x,mul) \ c ^= x; \ a -= t1[BYTEOF(c,0)] ^ t2[BYTEOF(c,2)] ^ t3[BYTEOF(c,4)] ^ t4[BYTEOF(c,6)]; \ b += t4[BYTEOF(c,1)] ^ t3[BYTEOF(c,3)] ^ t2[BYTEOF(c,5)] ^ t1[BYTEOF(c,7)]; \ b *= mul; #define PASS(a,b,c,mul) \ ROUND(a,b,c,x0,mul); \ ROUND(b,c,a,x1,mul); \ ROUND(c,a,b,x2,mul); \ ROUND(a,b,c,x3,mul); \ ROUND(b,c,a,x4,mul); \ ROUND(c,a,b,x5,mul); \ ROUND(a,b,c,x6,mul); \ ROUND(b,c,a,x7,mul) #define SCHEDULE() \ x0 -= x7 ^ 0xa5a5a5a5a5a5a5a5ULL; \ x1 ^= x0; \ x2 += x1; \ x3 -= x2 ^ ((~x1)<<19); \ x4 ^= x3; \ x5 += x4; \ x6 -= x5 ^ ((~x4)>>23); \ x7 ^= x6; \ x0 += x7; \ x1 -= x0 ^ ((~x7)<<19); \ x2 ^= x1; \ x3 += x2; \ x4 -= x3 ^ ((~x2)>>23); \ x5 ^= x4; \ x6 += x5; \ x7 -= x6 ^ 0x0123456789abcdefULL PASS(a,b,c,5); SCHEDULE(); PASS(c,a,b,7); SCHEDULE(); PASS(b,c,a,9); ctx->h[0] ^= a; ctx->h[1] = b - ctx->h[1]; ctx->h[2] += c; } void cryptonite_tiger_update(struct tiger_ctx *ctx, const uint8_t *data, uint32_t len) { uint32_t index, to_fill; index = (uint32_t) (ctx->sz & 0x3f); to_fill = 64 - index; ctx->sz += len; /* process partial buffer if there's enough data to make a block */ if (index && len >= to_fill) { memcpy(ctx->buf + index, data, to_fill); tiger_do_chunk(ctx, (uint64_t *) ctx->buf); len -= to_fill; data += to_fill; index = 0; } /* process as much 64-block as possible */ for (; len >= 64; len -= 64, data += 64) tiger_do_chunk(ctx, (uint64_t *) data); /* append data into buf */ if (len) memcpy(ctx->buf + index, data, len); } void cryptonite_tiger_finalize(struct tiger_ctx *ctx, uint8_t *out) { static uint8_t padding[64] = { 0x01, }; uint64_t bits; uint32_t index, padlen; uint64_t *p = (uint64_t *) out; /* add padding and update data with it */ bits = cpu_to_le64(ctx->sz << 3); /* pad out to 56 */ index = (uint32_t) (ctx->sz & 0x3f); padlen = (index < 56) ? (56 - index) : ((64 + 56) - index); cryptonite_tiger_update(ctx, padding, padlen); /* append length */ cryptonite_tiger_update(ctx, (uint8_t *) &bits, sizeof(bits)); /* output hash */ p[0] = cpu_to_le64(ctx->h[0]); p[1] = cpu_to_le64(ctx->h[1]); p[2] = cpu_to_le64(ctx->h[2]); } cryptonite-0.23/cbits/cryptonite_whirlpool.c0000644000000000000000000016726312365237076017625 0ustar0000000000000000/** * The Whirlpool hashing function. * *

* References * *

* The Whirlpool algorithm was developed by * Paulo S. L. M. Barreto and * Vincent Rijmen. * * See * P.S.L.M. Barreto, V. Rijmen, * ``The Whirlpool hashing function,'' * NESSIE submission, 2000 (tweaked version, 2001), * * * @author Paulo S.L.M. Barreto * @author Vincent Rijmen. * * @version 3.0 (2003.03.12) * * ============================================================================= * * Differences from version 2.1: * * - Suboptimal diffusion matrix replaced by cir(1, 1, 4, 1, 8, 5, 2, 9). * * ============================================================================= * * Differences from version 2.0: * * - Generation of ISO/IEC 10118-3 test vectors. * - Bug fix: nonzero carry was ignored when tallying the data length * (this bug apparently only manifested itself when feeding data * in pieces rather than in a single chunk at once). * - Support for MS Visual C++ 64-bit integer arithmetic. * * Differences from version 1.0: * * - Original S-box replaced by the tweaked, hardware-efficient version. * * ============================================================================= * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ /* Modified by Stijn van Drongelen for use in the cryptohash library. */ #include #include #include "cryptonite_bitfn.h" #include "cryptonite_whirlpool.h" /* #define TRACE_INTERMEDIATE_VALUES */ /* * The number of rounds of the internal dedicated block cipher. */ #define R 10 /* * Though Whirlpool is endianness-neutral, the encryption tables are listed * in BIG-ENDIAN format, which is adopted throughout this implementation * (but little-endian notation would be equally suitable if consistently * employed). */ static const uint64_t C0[256] = { 0x18186018c07830d8ULL, 0x23238c2305af4626ULL, 0xc6c63fc67ef991b8ULL, 0xe8e887e8136fcdfbULL, 0x878726874ca113cbULL, 0xb8b8dab8a9626d11ULL, 0x0101040108050209ULL, 0x4f4f214f426e9e0dULL, 0x3636d836adee6c9bULL, 0xa6a6a2a6590451ffULL, 0xd2d26fd2debdb90cULL, 0xf5f5f3f5fb06f70eULL, 0x7979f979ef80f296ULL, 0x6f6fa16f5fcede30ULL, 0x91917e91fcef3f6dULL, 0x52525552aa07a4f8ULL, 0x60609d6027fdc047ULL, 0xbcbccabc89766535ULL, 0x9b9b569baccd2b37ULL, 0x8e8e028e048c018aULL, 0xa3a3b6a371155bd2ULL, 0x0c0c300c603c186cULL, 0x7b7bf17bff8af684ULL, 0x3535d435b5e16a80ULL, 0x1d1d741de8693af5ULL, 0xe0e0a7e05347ddb3ULL, 0xd7d77bd7f6acb321ULL, 0xc2c22fc25eed999cULL, 0x2e2eb82e6d965c43ULL, 0x4b4b314b627a9629ULL, 0xfefedffea321e15dULL, 0x575741578216aed5ULL, 0x15155415a8412abdULL, 0x7777c1779fb6eee8ULL, 0x3737dc37a5eb6e92ULL, 0xe5e5b3e57b56d79eULL, 0x9f9f469f8cd92313ULL, 0xf0f0e7f0d317fd23ULL, 0x4a4a354a6a7f9420ULL, 0xdada4fda9e95a944ULL, 0x58587d58fa25b0a2ULL, 0xc9c903c906ca8fcfULL, 0x2929a429558d527cULL, 0x0a0a280a5022145aULL, 0xb1b1feb1e14f7f50ULL, 0xa0a0baa0691a5dc9ULL, 0x6b6bb16b7fdad614ULL, 0x85852e855cab17d9ULL, 0xbdbdcebd8173673cULL, 0x5d5d695dd234ba8fULL, 0x1010401080502090ULL, 0xf4f4f7f4f303f507ULL, 0xcbcb0bcb16c08bddULL, 0x3e3ef83eedc67cd3ULL, 0x0505140528110a2dULL, 0x676781671fe6ce78ULL, 0xe4e4b7e47353d597ULL, 0x27279c2725bb4e02ULL, 0x4141194132588273ULL, 0x8b8b168b2c9d0ba7ULL, 0xa7a7a6a7510153f6ULL, 0x7d7de97dcf94fab2ULL, 0x95956e95dcfb3749ULL, 0xd8d847d88e9fad56ULL, 0xfbfbcbfb8b30eb70ULL, 0xeeee9fee2371c1cdULL, 0x7c7ced7cc791f8bbULL, 0x6666856617e3cc71ULL, 0xdddd53dda68ea77bULL, 0x17175c17b84b2eafULL, 0x4747014702468e45ULL, 0x9e9e429e84dc211aULL, 0xcaca0fca1ec589d4ULL, 0x2d2db42d75995a58ULL, 0xbfbfc6bf9179632eULL, 0x07071c07381b0e3fULL, 0xadad8ead012347acULL, 0x5a5a755aea2fb4b0ULL, 0x838336836cb51befULL, 0x3333cc3385ff66b6ULL, 0x636391633ff2c65cULL, 0x02020802100a0412ULL, 0xaaaa92aa39384993ULL, 0x7171d971afa8e2deULL, 0xc8c807c80ecf8dc6ULL, 0x19196419c87d32d1ULL, 0x494939497270923bULL, 0xd9d943d9869aaf5fULL, 0xf2f2eff2c31df931ULL, 0xe3e3abe34b48dba8ULL, 0x5b5b715be22ab6b9ULL, 0x88881a8834920dbcULL, 0x9a9a529aa4c8293eULL, 0x262698262dbe4c0bULL, 0x3232c8328dfa64bfULL, 0xb0b0fab0e94a7d59ULL, 0xe9e983e91b6acff2ULL, 0x0f0f3c0f78331e77ULL, 0xd5d573d5e6a6b733ULL, 0x80803a8074ba1df4ULL, 0xbebec2be997c6127ULL, 0xcdcd13cd26de87ebULL, 0x3434d034bde46889ULL, 0x48483d487a759032ULL, 0xffffdbffab24e354ULL, 0x7a7af57af78ff48dULL, 0x90907a90f4ea3d64ULL, 0x5f5f615fc23ebe9dULL, 0x202080201da0403dULL, 0x6868bd6867d5d00fULL, 0x1a1a681ad07234caULL, 0xaeae82ae192c41b7ULL, 0xb4b4eab4c95e757dULL, 0x54544d549a19a8ceULL, 0x93937693ece53b7fULL, 0x222288220daa442fULL, 0x64648d6407e9c863ULL, 0xf1f1e3f1db12ff2aULL, 0x7373d173bfa2e6ccULL, 0x12124812905a2482ULL, 0x40401d403a5d807aULL, 0x0808200840281048ULL, 0xc3c32bc356e89b95ULL, 0xecec97ec337bc5dfULL, 0xdbdb4bdb9690ab4dULL, 0xa1a1bea1611f5fc0ULL, 0x8d8d0e8d1c830791ULL, 0x3d3df43df5c97ac8ULL, 0x97976697ccf1335bULL, 0x0000000000000000ULL, 0xcfcf1bcf36d483f9ULL, 0x2b2bac2b4587566eULL, 0x7676c57697b3ece1ULL, 0x8282328264b019e6ULL, 0xd6d67fd6fea9b128ULL, 0x1b1b6c1bd87736c3ULL, 0xb5b5eeb5c15b7774ULL, 0xafaf86af112943beULL, 0x6a6ab56a77dfd41dULL, 0x50505d50ba0da0eaULL, 0x45450945124c8a57ULL, 0xf3f3ebf3cb18fb38ULL, 0x3030c0309df060adULL, 0xefef9bef2b74c3c4ULL, 0x3f3ffc3fe5c37edaULL, 0x55554955921caac7ULL, 0xa2a2b2a2791059dbULL, 0xeaea8fea0365c9e9ULL, 0x656589650fecca6aULL, 0xbabad2bab9686903ULL, 0x2f2fbc2f65935e4aULL, 0xc0c027c04ee79d8eULL, 0xdede5fdebe81a160ULL, 0x1c1c701ce06c38fcULL, 0xfdfdd3fdbb2ee746ULL, 0x4d4d294d52649a1fULL, 0x92927292e4e03976ULL, 0x7575c9758fbceafaULL, 0x06061806301e0c36ULL, 0x8a8a128a249809aeULL, 0xb2b2f2b2f940794bULL, 0xe6e6bfe66359d185ULL, 0x0e0e380e70361c7eULL, 0x1f1f7c1ff8633ee7ULL, 0x6262956237f7c455ULL, 0xd4d477d4eea3b53aULL, 0xa8a89aa829324d81ULL, 0x96966296c4f43152ULL, 0xf9f9c3f99b3aef62ULL, 0xc5c533c566f697a3ULL, 0x2525942535b14a10ULL, 0x59597959f220b2abULL, 0x84842a8454ae15d0ULL, 0x7272d572b7a7e4c5ULL, 0x3939e439d5dd72ecULL, 0x4c4c2d4c5a619816ULL, 0x5e5e655eca3bbc94ULL, 0x7878fd78e785f09fULL, 0x3838e038ddd870e5ULL, 0x8c8c0a8c14860598ULL, 0xd1d163d1c6b2bf17ULL, 0xa5a5aea5410b57e4ULL, 0xe2e2afe2434dd9a1ULL, 0x616199612ff8c24eULL, 0xb3b3f6b3f1457b42ULL, 0x2121842115a54234ULL, 0x9c9c4a9c94d62508ULL, 0x1e1e781ef0663ceeULL, 0x4343114322528661ULL, 0xc7c73bc776fc93b1ULL, 0xfcfcd7fcb32be54fULL, 0x0404100420140824ULL, 0x51515951b208a2e3ULL, 0x99995e99bcc72f25ULL, 0x6d6da96d4fc4da22ULL, 0x0d0d340d68391a65ULL, 0xfafacffa8335e979ULL, 0xdfdf5bdfb684a369ULL, 0x7e7ee57ed79bfca9ULL, 0x242490243db44819ULL, 0x3b3bec3bc5d776feULL, 0xabab96ab313d4b9aULL, 0xcece1fce3ed181f0ULL, 0x1111441188552299ULL, 0x8f8f068f0c890383ULL, 0x4e4e254e4a6b9c04ULL, 0xb7b7e6b7d1517366ULL, 0xebeb8beb0b60cbe0ULL, 0x3c3cf03cfdcc78c1ULL, 0x81813e817cbf1ffdULL, 0x94946a94d4fe3540ULL, 0xf7f7fbf7eb0cf31cULL, 0xb9b9deb9a1676f18ULL, 0x13134c13985f268bULL, 0x2c2cb02c7d9c5851ULL, 0xd3d36bd3d6b8bb05ULL, 0xe7e7bbe76b5cd38cULL, 0x6e6ea56e57cbdc39ULL, 0xc4c437c46ef395aaULL, 0x03030c03180f061bULL, 0x565645568a13acdcULL, 0x44440d441a49885eULL, 0x7f7fe17fdf9efea0ULL, 0xa9a99ea921374f88ULL, 0x2a2aa82a4d825467ULL, 0xbbbbd6bbb16d6b0aULL, 0xc1c123c146e29f87ULL, 0x53535153a202a6f1ULL, 0xdcdc57dcae8ba572ULL, 0x0b0b2c0b58271653ULL, 0x9d9d4e9d9cd32701ULL, 0x6c6cad6c47c1d82bULL, 0x3131c43195f562a4ULL, 0x7474cd7487b9e8f3ULL, 0xf6f6fff6e309f115ULL, 0x464605460a438c4cULL, 0xacac8aac092645a5ULL, 0x89891e893c970fb5ULL, 0x14145014a04428b4ULL, 0xe1e1a3e15b42dfbaULL, 0x16165816b04e2ca6ULL, 0x3a3ae83acdd274f7ULL, 0x6969b9696fd0d206ULL, 0x09092409482d1241ULL, 0x7070dd70a7ade0d7ULL, 0xb6b6e2b6d954716fULL, 0xd0d067d0ceb7bd1eULL, 0xeded93ed3b7ec7d6ULL, 0xcccc17cc2edb85e2ULL, 0x424215422a578468ULL, 0x98985a98b4c22d2cULL, 0xa4a4aaa4490e55edULL, 0x2828a0285d885075ULL, 0x5c5c6d5cda31b886ULL, 0xf8f8c7f8933fed6bULL, 0x8686228644a411c2ULL, }; static const uint64_t C1[256] = { 0xd818186018c07830ULL, 0x2623238c2305af46ULL, 0xb8c6c63fc67ef991ULL, 0xfbe8e887e8136fcdULL, 0xcb878726874ca113ULL, 0x11b8b8dab8a9626dULL, 0x0901010401080502ULL, 0x0d4f4f214f426e9eULL, 0x9b3636d836adee6cULL, 0xffa6a6a2a6590451ULL, 0x0cd2d26fd2debdb9ULL, 0x0ef5f5f3f5fb06f7ULL, 0x967979f979ef80f2ULL, 0x306f6fa16f5fcedeULL, 0x6d91917e91fcef3fULL, 0xf852525552aa07a4ULL, 0x4760609d6027fdc0ULL, 0x35bcbccabc897665ULL, 0x379b9b569baccd2bULL, 0x8a8e8e028e048c01ULL, 0xd2a3a3b6a371155bULL, 0x6c0c0c300c603c18ULL, 0x847b7bf17bff8af6ULL, 0x803535d435b5e16aULL, 0xf51d1d741de8693aULL, 0xb3e0e0a7e05347ddULL, 0x21d7d77bd7f6acb3ULL, 0x9cc2c22fc25eed99ULL, 0x432e2eb82e6d965cULL, 0x294b4b314b627a96ULL, 0x5dfefedffea321e1ULL, 0xd5575741578216aeULL, 0xbd15155415a8412aULL, 0xe87777c1779fb6eeULL, 0x923737dc37a5eb6eULL, 0x9ee5e5b3e57b56d7ULL, 0x139f9f469f8cd923ULL, 0x23f0f0e7f0d317fdULL, 0x204a4a354a6a7f94ULL, 0x44dada4fda9e95a9ULL, 0xa258587d58fa25b0ULL, 0xcfc9c903c906ca8fULL, 0x7c2929a429558d52ULL, 0x5a0a0a280a502214ULL, 0x50b1b1feb1e14f7fULL, 0xc9a0a0baa0691a5dULL, 0x146b6bb16b7fdad6ULL, 0xd985852e855cab17ULL, 0x3cbdbdcebd817367ULL, 0x8f5d5d695dd234baULL, 0x9010104010805020ULL, 0x07f4f4f7f4f303f5ULL, 0xddcbcb0bcb16c08bULL, 0xd33e3ef83eedc67cULL, 0x2d0505140528110aULL, 0x78676781671fe6ceULL, 0x97e4e4b7e47353d5ULL, 0x0227279c2725bb4eULL, 0x7341411941325882ULL, 0xa78b8b168b2c9d0bULL, 0xf6a7a7a6a7510153ULL, 0xb27d7de97dcf94faULL, 0x4995956e95dcfb37ULL, 0x56d8d847d88e9fadULL, 0x70fbfbcbfb8b30ebULL, 0xcdeeee9fee2371c1ULL, 0xbb7c7ced7cc791f8ULL, 0x716666856617e3ccULL, 0x7bdddd53dda68ea7ULL, 0xaf17175c17b84b2eULL, 0x454747014702468eULL, 0x1a9e9e429e84dc21ULL, 0xd4caca0fca1ec589ULL, 0x582d2db42d75995aULL, 0x2ebfbfc6bf917963ULL, 0x3f07071c07381b0eULL, 0xacadad8ead012347ULL, 0xb05a5a755aea2fb4ULL, 0xef838336836cb51bULL, 0xb63333cc3385ff66ULL, 0x5c636391633ff2c6ULL, 0x1202020802100a04ULL, 0x93aaaa92aa393849ULL, 0xde7171d971afa8e2ULL, 0xc6c8c807c80ecf8dULL, 0xd119196419c87d32ULL, 0x3b49493949727092ULL, 0x5fd9d943d9869aafULL, 0x31f2f2eff2c31df9ULL, 0xa8e3e3abe34b48dbULL, 0xb95b5b715be22ab6ULL, 0xbc88881a8834920dULL, 0x3e9a9a529aa4c829ULL, 0x0b262698262dbe4cULL, 0xbf3232c8328dfa64ULL, 0x59b0b0fab0e94a7dULL, 0xf2e9e983e91b6acfULL, 0x770f0f3c0f78331eULL, 0x33d5d573d5e6a6b7ULL, 0xf480803a8074ba1dULL, 0x27bebec2be997c61ULL, 0xebcdcd13cd26de87ULL, 0x893434d034bde468ULL, 0x3248483d487a7590ULL, 0x54ffffdbffab24e3ULL, 0x8d7a7af57af78ff4ULL, 0x6490907a90f4ea3dULL, 0x9d5f5f615fc23ebeULL, 0x3d202080201da040ULL, 0x0f6868bd6867d5d0ULL, 0xca1a1a681ad07234ULL, 0xb7aeae82ae192c41ULL, 0x7db4b4eab4c95e75ULL, 0xce54544d549a19a8ULL, 0x7f93937693ece53bULL, 0x2f222288220daa44ULL, 0x6364648d6407e9c8ULL, 0x2af1f1e3f1db12ffULL, 0xcc7373d173bfa2e6ULL, 0x8212124812905a24ULL, 0x7a40401d403a5d80ULL, 0x4808082008402810ULL, 0x95c3c32bc356e89bULL, 0xdfecec97ec337bc5ULL, 0x4ddbdb4bdb9690abULL, 0xc0a1a1bea1611f5fULL, 0x918d8d0e8d1c8307ULL, 0xc83d3df43df5c97aULL, 0x5b97976697ccf133ULL, 0x0000000000000000ULL, 0xf9cfcf1bcf36d483ULL, 0x6e2b2bac2b458756ULL, 0xe17676c57697b3ecULL, 0xe68282328264b019ULL, 0x28d6d67fd6fea9b1ULL, 0xc31b1b6c1bd87736ULL, 0x74b5b5eeb5c15b77ULL, 0xbeafaf86af112943ULL, 0x1d6a6ab56a77dfd4ULL, 0xea50505d50ba0da0ULL, 0x5745450945124c8aULL, 0x38f3f3ebf3cb18fbULL, 0xad3030c0309df060ULL, 0xc4efef9bef2b74c3ULL, 0xda3f3ffc3fe5c37eULL, 0xc755554955921caaULL, 0xdba2a2b2a2791059ULL, 0xe9eaea8fea0365c9ULL, 0x6a656589650feccaULL, 0x03babad2bab96869ULL, 0x4a2f2fbc2f65935eULL, 0x8ec0c027c04ee79dULL, 0x60dede5fdebe81a1ULL, 0xfc1c1c701ce06c38ULL, 0x46fdfdd3fdbb2ee7ULL, 0x1f4d4d294d52649aULL, 0x7692927292e4e039ULL, 0xfa7575c9758fbceaULL, 0x3606061806301e0cULL, 0xae8a8a128a249809ULL, 0x4bb2b2f2b2f94079ULL, 0x85e6e6bfe66359d1ULL, 0x7e0e0e380e70361cULL, 0xe71f1f7c1ff8633eULL, 0x556262956237f7c4ULL, 0x3ad4d477d4eea3b5ULL, 0x81a8a89aa829324dULL, 0x5296966296c4f431ULL, 0x62f9f9c3f99b3aefULL, 0xa3c5c533c566f697ULL, 0x102525942535b14aULL, 0xab59597959f220b2ULL, 0xd084842a8454ae15ULL, 0xc57272d572b7a7e4ULL, 0xec3939e439d5dd72ULL, 0x164c4c2d4c5a6198ULL, 0x945e5e655eca3bbcULL, 0x9f7878fd78e785f0ULL, 0xe53838e038ddd870ULL, 0x988c8c0a8c148605ULL, 0x17d1d163d1c6b2bfULL, 0xe4a5a5aea5410b57ULL, 0xa1e2e2afe2434dd9ULL, 0x4e616199612ff8c2ULL, 0x42b3b3f6b3f1457bULL, 0x342121842115a542ULL, 0x089c9c4a9c94d625ULL, 0xee1e1e781ef0663cULL, 0x6143431143225286ULL, 0xb1c7c73bc776fc93ULL, 0x4ffcfcd7fcb32be5ULL, 0x2404041004201408ULL, 0xe351515951b208a2ULL, 0x2599995e99bcc72fULL, 0x226d6da96d4fc4daULL, 0x650d0d340d68391aULL, 0x79fafacffa8335e9ULL, 0x69dfdf5bdfb684a3ULL, 0xa97e7ee57ed79bfcULL, 0x19242490243db448ULL, 0xfe3b3bec3bc5d776ULL, 0x9aabab96ab313d4bULL, 0xf0cece1fce3ed181ULL, 0x9911114411885522ULL, 0x838f8f068f0c8903ULL, 0x044e4e254e4a6b9cULL, 0x66b7b7e6b7d15173ULL, 0xe0ebeb8beb0b60cbULL, 0xc13c3cf03cfdcc78ULL, 0xfd81813e817cbf1fULL, 0x4094946a94d4fe35ULL, 0x1cf7f7fbf7eb0cf3ULL, 0x18b9b9deb9a1676fULL, 0x8b13134c13985f26ULL, 0x512c2cb02c7d9c58ULL, 0x05d3d36bd3d6b8bbULL, 0x8ce7e7bbe76b5cd3ULL, 0x396e6ea56e57cbdcULL, 0xaac4c437c46ef395ULL, 0x1b03030c03180f06ULL, 0xdc565645568a13acULL, 0x5e44440d441a4988ULL, 0xa07f7fe17fdf9efeULL, 0x88a9a99ea921374fULL, 0x672a2aa82a4d8254ULL, 0x0abbbbd6bbb16d6bULL, 0x87c1c123c146e29fULL, 0xf153535153a202a6ULL, 0x72dcdc57dcae8ba5ULL, 0x530b0b2c0b582716ULL, 0x019d9d4e9d9cd327ULL, 0x2b6c6cad6c47c1d8ULL, 0xa43131c43195f562ULL, 0xf37474cd7487b9e8ULL, 0x15f6f6fff6e309f1ULL, 0x4c464605460a438cULL, 0xa5acac8aac092645ULL, 0xb589891e893c970fULL, 0xb414145014a04428ULL, 0xbae1e1a3e15b42dfULL, 0xa616165816b04e2cULL, 0xf73a3ae83acdd274ULL, 0x066969b9696fd0d2ULL, 0x4109092409482d12ULL, 0xd77070dd70a7ade0ULL, 0x6fb6b6e2b6d95471ULL, 0x1ed0d067d0ceb7bdULL, 0xd6eded93ed3b7ec7ULL, 0xe2cccc17cc2edb85ULL, 0x68424215422a5784ULL, 0x2c98985a98b4c22dULL, 0xeda4a4aaa4490e55ULL, 0x752828a0285d8850ULL, 0x865c5c6d5cda31b8ULL, 0x6bf8f8c7f8933fedULL, 0xc28686228644a411ULL, }; static const uint64_t C2[256] = { 0x30d818186018c078ULL, 0x462623238c2305afULL, 0x91b8c6c63fc67ef9ULL, 0xcdfbe8e887e8136fULL, 0x13cb878726874ca1ULL, 0x6d11b8b8dab8a962ULL, 0x0209010104010805ULL, 0x9e0d4f4f214f426eULL, 0x6c9b3636d836adeeULL, 0x51ffa6a6a2a65904ULL, 0xb90cd2d26fd2debdULL, 0xf70ef5f5f3f5fb06ULL, 0xf2967979f979ef80ULL, 0xde306f6fa16f5fceULL, 0x3f6d91917e91fcefULL, 0xa4f852525552aa07ULL, 0xc04760609d6027fdULL, 0x6535bcbccabc8976ULL, 0x2b379b9b569baccdULL, 0x018a8e8e028e048cULL, 0x5bd2a3a3b6a37115ULL, 0x186c0c0c300c603cULL, 0xf6847b7bf17bff8aULL, 0x6a803535d435b5e1ULL, 0x3af51d1d741de869ULL, 0xddb3e0e0a7e05347ULL, 0xb321d7d77bd7f6acULL, 0x999cc2c22fc25eedULL, 0x5c432e2eb82e6d96ULL, 0x96294b4b314b627aULL, 0xe15dfefedffea321ULL, 0xaed5575741578216ULL, 0x2abd15155415a841ULL, 0xeee87777c1779fb6ULL, 0x6e923737dc37a5ebULL, 0xd79ee5e5b3e57b56ULL, 0x23139f9f469f8cd9ULL, 0xfd23f0f0e7f0d317ULL, 0x94204a4a354a6a7fULL, 0xa944dada4fda9e95ULL, 0xb0a258587d58fa25ULL, 0x8fcfc9c903c906caULL, 0x527c2929a429558dULL, 0x145a0a0a280a5022ULL, 0x7f50b1b1feb1e14fULL, 0x5dc9a0a0baa0691aULL, 0xd6146b6bb16b7fdaULL, 0x17d985852e855cabULL, 0x673cbdbdcebd8173ULL, 0xba8f5d5d695dd234ULL, 0x2090101040108050ULL, 0xf507f4f4f7f4f303ULL, 0x8bddcbcb0bcb16c0ULL, 0x7cd33e3ef83eedc6ULL, 0x0a2d050514052811ULL, 0xce78676781671fe6ULL, 0xd597e4e4b7e47353ULL, 0x4e0227279c2725bbULL, 0x8273414119413258ULL, 0x0ba78b8b168b2c9dULL, 0x53f6a7a7a6a75101ULL, 0xfab27d7de97dcf94ULL, 0x374995956e95dcfbULL, 0xad56d8d847d88e9fULL, 0xeb70fbfbcbfb8b30ULL, 0xc1cdeeee9fee2371ULL, 0xf8bb7c7ced7cc791ULL, 0xcc716666856617e3ULL, 0xa77bdddd53dda68eULL, 0x2eaf17175c17b84bULL, 0x8e45474701470246ULL, 0x211a9e9e429e84dcULL, 0x89d4caca0fca1ec5ULL, 0x5a582d2db42d7599ULL, 0x632ebfbfc6bf9179ULL, 0x0e3f07071c07381bULL, 0x47acadad8ead0123ULL, 0xb4b05a5a755aea2fULL, 0x1bef838336836cb5ULL, 0x66b63333cc3385ffULL, 0xc65c636391633ff2ULL, 0x041202020802100aULL, 0x4993aaaa92aa3938ULL, 0xe2de7171d971afa8ULL, 0x8dc6c8c807c80ecfULL, 0x32d119196419c87dULL, 0x923b494939497270ULL, 0xaf5fd9d943d9869aULL, 0xf931f2f2eff2c31dULL, 0xdba8e3e3abe34b48ULL, 0xb6b95b5b715be22aULL, 0x0dbc88881a883492ULL, 0x293e9a9a529aa4c8ULL, 0x4c0b262698262dbeULL, 0x64bf3232c8328dfaULL, 0x7d59b0b0fab0e94aULL, 0xcff2e9e983e91b6aULL, 0x1e770f0f3c0f7833ULL, 0xb733d5d573d5e6a6ULL, 0x1df480803a8074baULL, 0x6127bebec2be997cULL, 0x87ebcdcd13cd26deULL, 0x68893434d034bde4ULL, 0x903248483d487a75ULL, 0xe354ffffdbffab24ULL, 0xf48d7a7af57af78fULL, 0x3d6490907a90f4eaULL, 0xbe9d5f5f615fc23eULL, 0x403d202080201da0ULL, 0xd00f6868bd6867d5ULL, 0x34ca1a1a681ad072ULL, 0x41b7aeae82ae192cULL, 0x757db4b4eab4c95eULL, 0xa8ce54544d549a19ULL, 0x3b7f93937693ece5ULL, 0x442f222288220daaULL, 0xc86364648d6407e9ULL, 0xff2af1f1e3f1db12ULL, 0xe6cc7373d173bfa2ULL, 0x248212124812905aULL, 0x807a40401d403a5dULL, 0x1048080820084028ULL, 0x9b95c3c32bc356e8ULL, 0xc5dfecec97ec337bULL, 0xab4ddbdb4bdb9690ULL, 0x5fc0a1a1bea1611fULL, 0x07918d8d0e8d1c83ULL, 0x7ac83d3df43df5c9ULL, 0x335b97976697ccf1ULL, 0x0000000000000000ULL, 0x83f9cfcf1bcf36d4ULL, 0x566e2b2bac2b4587ULL, 0xece17676c57697b3ULL, 0x19e68282328264b0ULL, 0xb128d6d67fd6fea9ULL, 0x36c31b1b6c1bd877ULL, 0x7774b5b5eeb5c15bULL, 0x43beafaf86af1129ULL, 0xd41d6a6ab56a77dfULL, 0xa0ea50505d50ba0dULL, 0x8a5745450945124cULL, 0xfb38f3f3ebf3cb18ULL, 0x60ad3030c0309df0ULL, 0xc3c4efef9bef2b74ULL, 0x7eda3f3ffc3fe5c3ULL, 0xaac755554955921cULL, 0x59dba2a2b2a27910ULL, 0xc9e9eaea8fea0365ULL, 0xca6a656589650fecULL, 0x6903babad2bab968ULL, 0x5e4a2f2fbc2f6593ULL, 0x9d8ec0c027c04ee7ULL, 0xa160dede5fdebe81ULL, 0x38fc1c1c701ce06cULL, 0xe746fdfdd3fdbb2eULL, 0x9a1f4d4d294d5264ULL, 0x397692927292e4e0ULL, 0xeafa7575c9758fbcULL, 0x0c3606061806301eULL, 0x09ae8a8a128a2498ULL, 0x794bb2b2f2b2f940ULL, 0xd185e6e6bfe66359ULL, 0x1c7e0e0e380e7036ULL, 0x3ee71f1f7c1ff863ULL, 0xc4556262956237f7ULL, 0xb53ad4d477d4eea3ULL, 0x4d81a8a89aa82932ULL, 0x315296966296c4f4ULL, 0xef62f9f9c3f99b3aULL, 0x97a3c5c533c566f6ULL, 0x4a102525942535b1ULL, 0xb2ab59597959f220ULL, 0x15d084842a8454aeULL, 0xe4c57272d572b7a7ULL, 0x72ec3939e439d5ddULL, 0x98164c4c2d4c5a61ULL, 0xbc945e5e655eca3bULL, 0xf09f7878fd78e785ULL, 0x70e53838e038ddd8ULL, 0x05988c8c0a8c1486ULL, 0xbf17d1d163d1c6b2ULL, 0x57e4a5a5aea5410bULL, 0xd9a1e2e2afe2434dULL, 0xc24e616199612ff8ULL, 0x7b42b3b3f6b3f145ULL, 0x42342121842115a5ULL, 0x25089c9c4a9c94d6ULL, 0x3cee1e1e781ef066ULL, 0x8661434311432252ULL, 0x93b1c7c73bc776fcULL, 0xe54ffcfcd7fcb32bULL, 0x0824040410042014ULL, 0xa2e351515951b208ULL, 0x2f2599995e99bcc7ULL, 0xda226d6da96d4fc4ULL, 0x1a650d0d340d6839ULL, 0xe979fafacffa8335ULL, 0xa369dfdf5bdfb684ULL, 0xfca97e7ee57ed79bULL, 0x4819242490243db4ULL, 0x76fe3b3bec3bc5d7ULL, 0x4b9aabab96ab313dULL, 0x81f0cece1fce3ed1ULL, 0x2299111144118855ULL, 0x03838f8f068f0c89ULL, 0x9c044e4e254e4a6bULL, 0x7366b7b7e6b7d151ULL, 0xcbe0ebeb8beb0b60ULL, 0x78c13c3cf03cfdccULL, 0x1ffd81813e817cbfULL, 0x354094946a94d4feULL, 0xf31cf7f7fbf7eb0cULL, 0x6f18b9b9deb9a167ULL, 0x268b13134c13985fULL, 0x58512c2cb02c7d9cULL, 0xbb05d3d36bd3d6b8ULL, 0xd38ce7e7bbe76b5cULL, 0xdc396e6ea56e57cbULL, 0x95aac4c437c46ef3ULL, 0x061b03030c03180fULL, 0xacdc565645568a13ULL, 0x885e44440d441a49ULL, 0xfea07f7fe17fdf9eULL, 0x4f88a9a99ea92137ULL, 0x54672a2aa82a4d82ULL, 0x6b0abbbbd6bbb16dULL, 0x9f87c1c123c146e2ULL, 0xa6f153535153a202ULL, 0xa572dcdc57dcae8bULL, 0x16530b0b2c0b5827ULL, 0x27019d9d4e9d9cd3ULL, 0xd82b6c6cad6c47c1ULL, 0x62a43131c43195f5ULL, 0xe8f37474cd7487b9ULL, 0xf115f6f6fff6e309ULL, 0x8c4c464605460a43ULL, 0x45a5acac8aac0926ULL, 0x0fb589891e893c97ULL, 0x28b414145014a044ULL, 0xdfbae1e1a3e15b42ULL, 0x2ca616165816b04eULL, 0x74f73a3ae83acdd2ULL, 0xd2066969b9696fd0ULL, 0x124109092409482dULL, 0xe0d77070dd70a7adULL, 0x716fb6b6e2b6d954ULL, 0xbd1ed0d067d0ceb7ULL, 0xc7d6eded93ed3b7eULL, 0x85e2cccc17cc2edbULL, 0x8468424215422a57ULL, 0x2d2c98985a98b4c2ULL, 0x55eda4a4aaa4490eULL, 0x50752828a0285d88ULL, 0xb8865c5c6d5cda31ULL, 0xed6bf8f8c7f8933fULL, 0x11c28686228644a4ULL, }; static const uint64_t C3[256] = { 0x7830d818186018c0ULL, 0xaf462623238c2305ULL, 0xf991b8c6c63fc67eULL, 0x6fcdfbe8e887e813ULL, 0xa113cb878726874cULL, 0x626d11b8b8dab8a9ULL, 0x0502090101040108ULL, 0x6e9e0d4f4f214f42ULL, 0xee6c9b3636d836adULL, 0x0451ffa6a6a2a659ULL, 0xbdb90cd2d26fd2deULL, 0x06f70ef5f5f3f5fbULL, 0x80f2967979f979efULL, 0xcede306f6fa16f5fULL, 0xef3f6d91917e91fcULL, 0x07a4f852525552aaULL, 0xfdc04760609d6027ULL, 0x766535bcbccabc89ULL, 0xcd2b379b9b569bacULL, 0x8c018a8e8e028e04ULL, 0x155bd2a3a3b6a371ULL, 0x3c186c0c0c300c60ULL, 0x8af6847b7bf17bffULL, 0xe16a803535d435b5ULL, 0x693af51d1d741de8ULL, 0x47ddb3e0e0a7e053ULL, 0xacb321d7d77bd7f6ULL, 0xed999cc2c22fc25eULL, 0x965c432e2eb82e6dULL, 0x7a96294b4b314b62ULL, 0x21e15dfefedffea3ULL, 0x16aed55757415782ULL, 0x412abd15155415a8ULL, 0xb6eee87777c1779fULL, 0xeb6e923737dc37a5ULL, 0x56d79ee5e5b3e57bULL, 0xd923139f9f469f8cULL, 0x17fd23f0f0e7f0d3ULL, 0x7f94204a4a354a6aULL, 0x95a944dada4fda9eULL, 0x25b0a258587d58faULL, 0xca8fcfc9c903c906ULL, 0x8d527c2929a42955ULL, 0x22145a0a0a280a50ULL, 0x4f7f50b1b1feb1e1ULL, 0x1a5dc9a0a0baa069ULL, 0xdad6146b6bb16b7fULL, 0xab17d985852e855cULL, 0x73673cbdbdcebd81ULL, 0x34ba8f5d5d695dd2ULL, 0x5020901010401080ULL, 0x03f507f4f4f7f4f3ULL, 0xc08bddcbcb0bcb16ULL, 0xc67cd33e3ef83eedULL, 0x110a2d0505140528ULL, 0xe6ce78676781671fULL, 0x53d597e4e4b7e473ULL, 0xbb4e0227279c2725ULL, 0x5882734141194132ULL, 0x9d0ba78b8b168b2cULL, 0x0153f6a7a7a6a751ULL, 0x94fab27d7de97dcfULL, 0xfb374995956e95dcULL, 0x9fad56d8d847d88eULL, 0x30eb70fbfbcbfb8bULL, 0x71c1cdeeee9fee23ULL, 0x91f8bb7c7ced7cc7ULL, 0xe3cc716666856617ULL, 0x8ea77bdddd53dda6ULL, 0x4b2eaf17175c17b8ULL, 0x468e454747014702ULL, 0xdc211a9e9e429e84ULL, 0xc589d4caca0fca1eULL, 0x995a582d2db42d75ULL, 0x79632ebfbfc6bf91ULL, 0x1b0e3f07071c0738ULL, 0x2347acadad8ead01ULL, 0x2fb4b05a5a755aeaULL, 0xb51bef838336836cULL, 0xff66b63333cc3385ULL, 0xf2c65c636391633fULL, 0x0a04120202080210ULL, 0x384993aaaa92aa39ULL, 0xa8e2de7171d971afULL, 0xcf8dc6c8c807c80eULL, 0x7d32d119196419c8ULL, 0x70923b4949394972ULL, 0x9aaf5fd9d943d986ULL, 0x1df931f2f2eff2c3ULL, 0x48dba8e3e3abe34bULL, 0x2ab6b95b5b715be2ULL, 0x920dbc88881a8834ULL, 0xc8293e9a9a529aa4ULL, 0xbe4c0b262698262dULL, 0xfa64bf3232c8328dULL, 0x4a7d59b0b0fab0e9ULL, 0x6acff2e9e983e91bULL, 0x331e770f0f3c0f78ULL, 0xa6b733d5d573d5e6ULL, 0xba1df480803a8074ULL, 0x7c6127bebec2be99ULL, 0xde87ebcdcd13cd26ULL, 0xe468893434d034bdULL, 0x75903248483d487aULL, 0x24e354ffffdbffabULL, 0x8ff48d7a7af57af7ULL, 0xea3d6490907a90f4ULL, 0x3ebe9d5f5f615fc2ULL, 0xa0403d202080201dULL, 0xd5d00f6868bd6867ULL, 0x7234ca1a1a681ad0ULL, 0x2c41b7aeae82ae19ULL, 0x5e757db4b4eab4c9ULL, 0x19a8ce54544d549aULL, 0xe53b7f93937693ecULL, 0xaa442f222288220dULL, 0xe9c86364648d6407ULL, 0x12ff2af1f1e3f1dbULL, 0xa2e6cc7373d173bfULL, 0x5a24821212481290ULL, 0x5d807a40401d403aULL, 0x2810480808200840ULL, 0xe89b95c3c32bc356ULL, 0x7bc5dfecec97ec33ULL, 0x90ab4ddbdb4bdb96ULL, 0x1f5fc0a1a1bea161ULL, 0x8307918d8d0e8d1cULL, 0xc97ac83d3df43df5ULL, 0xf1335b97976697ccULL, 0x0000000000000000ULL, 0xd483f9cfcf1bcf36ULL, 0x87566e2b2bac2b45ULL, 0xb3ece17676c57697ULL, 0xb019e68282328264ULL, 0xa9b128d6d67fd6feULL, 0x7736c31b1b6c1bd8ULL, 0x5b7774b5b5eeb5c1ULL, 0x2943beafaf86af11ULL, 0xdfd41d6a6ab56a77ULL, 0x0da0ea50505d50baULL, 0x4c8a574545094512ULL, 0x18fb38f3f3ebf3cbULL, 0xf060ad3030c0309dULL, 0x74c3c4efef9bef2bULL, 0xc37eda3f3ffc3fe5ULL, 0x1caac75555495592ULL, 0x1059dba2a2b2a279ULL, 0x65c9e9eaea8fea03ULL, 0xecca6a656589650fULL, 0x686903babad2bab9ULL, 0x935e4a2f2fbc2f65ULL, 0xe79d8ec0c027c04eULL, 0x81a160dede5fdebeULL, 0x6c38fc1c1c701ce0ULL, 0x2ee746fdfdd3fdbbULL, 0x649a1f4d4d294d52ULL, 0xe0397692927292e4ULL, 0xbceafa7575c9758fULL, 0x1e0c360606180630ULL, 0x9809ae8a8a128a24ULL, 0x40794bb2b2f2b2f9ULL, 0x59d185e6e6bfe663ULL, 0x361c7e0e0e380e70ULL, 0x633ee71f1f7c1ff8ULL, 0xf7c4556262956237ULL, 0xa3b53ad4d477d4eeULL, 0x324d81a8a89aa829ULL, 0xf4315296966296c4ULL, 0x3aef62f9f9c3f99bULL, 0xf697a3c5c533c566ULL, 0xb14a102525942535ULL, 0x20b2ab59597959f2ULL, 0xae15d084842a8454ULL, 0xa7e4c57272d572b7ULL, 0xdd72ec3939e439d5ULL, 0x6198164c4c2d4c5aULL, 0x3bbc945e5e655ecaULL, 0x85f09f7878fd78e7ULL, 0xd870e53838e038ddULL, 0x8605988c8c0a8c14ULL, 0xb2bf17d1d163d1c6ULL, 0x0b57e4a5a5aea541ULL, 0x4dd9a1e2e2afe243ULL, 0xf8c24e616199612fULL, 0x457b42b3b3f6b3f1ULL, 0xa542342121842115ULL, 0xd625089c9c4a9c94ULL, 0x663cee1e1e781ef0ULL, 0x5286614343114322ULL, 0xfc93b1c7c73bc776ULL, 0x2be54ffcfcd7fcb3ULL, 0x1408240404100420ULL, 0x08a2e351515951b2ULL, 0xc72f2599995e99bcULL, 0xc4da226d6da96d4fULL, 0x391a650d0d340d68ULL, 0x35e979fafacffa83ULL, 0x84a369dfdf5bdfb6ULL, 0x9bfca97e7ee57ed7ULL, 0xb44819242490243dULL, 0xd776fe3b3bec3bc5ULL, 0x3d4b9aabab96ab31ULL, 0xd181f0cece1fce3eULL, 0x5522991111441188ULL, 0x8903838f8f068f0cULL, 0x6b9c044e4e254e4aULL, 0x517366b7b7e6b7d1ULL, 0x60cbe0ebeb8beb0bULL, 0xcc78c13c3cf03cfdULL, 0xbf1ffd81813e817cULL, 0xfe354094946a94d4ULL, 0x0cf31cf7f7fbf7ebULL, 0x676f18b9b9deb9a1ULL, 0x5f268b13134c1398ULL, 0x9c58512c2cb02c7dULL, 0xb8bb05d3d36bd3d6ULL, 0x5cd38ce7e7bbe76bULL, 0xcbdc396e6ea56e57ULL, 0xf395aac4c437c46eULL, 0x0f061b03030c0318ULL, 0x13acdc565645568aULL, 0x49885e44440d441aULL, 0x9efea07f7fe17fdfULL, 0x374f88a9a99ea921ULL, 0x8254672a2aa82a4dULL, 0x6d6b0abbbbd6bbb1ULL, 0xe29f87c1c123c146ULL, 0x02a6f153535153a2ULL, 0x8ba572dcdc57dcaeULL, 0x2716530b0b2c0b58ULL, 0xd327019d9d4e9d9cULL, 0xc1d82b6c6cad6c47ULL, 0xf562a43131c43195ULL, 0xb9e8f37474cd7487ULL, 0x09f115f6f6fff6e3ULL, 0x438c4c464605460aULL, 0x2645a5acac8aac09ULL, 0x970fb589891e893cULL, 0x4428b414145014a0ULL, 0x42dfbae1e1a3e15bULL, 0x4e2ca616165816b0ULL, 0xd274f73a3ae83acdULL, 0xd0d2066969b9696fULL, 0x2d12410909240948ULL, 0xade0d77070dd70a7ULL, 0x54716fb6b6e2b6d9ULL, 0xb7bd1ed0d067d0ceULL, 0x7ec7d6eded93ed3bULL, 0xdb85e2cccc17cc2eULL, 0x578468424215422aULL, 0xc22d2c98985a98b4ULL, 0x0e55eda4a4aaa449ULL, 0x8850752828a0285dULL, 0x31b8865c5c6d5cdaULL, 0x3fed6bf8f8c7f893ULL, 0xa411c28686228644ULL, }; static const uint64_t C4[256] = { 0xc07830d818186018ULL, 0x05af462623238c23ULL, 0x7ef991b8c6c63fc6ULL, 0x136fcdfbe8e887e8ULL, 0x4ca113cb87872687ULL, 0xa9626d11b8b8dab8ULL, 0x0805020901010401ULL, 0x426e9e0d4f4f214fULL, 0xadee6c9b3636d836ULL, 0x590451ffa6a6a2a6ULL, 0xdebdb90cd2d26fd2ULL, 0xfb06f70ef5f5f3f5ULL, 0xef80f2967979f979ULL, 0x5fcede306f6fa16fULL, 0xfcef3f6d91917e91ULL, 0xaa07a4f852525552ULL, 0x27fdc04760609d60ULL, 0x89766535bcbccabcULL, 0xaccd2b379b9b569bULL, 0x048c018a8e8e028eULL, 0x71155bd2a3a3b6a3ULL, 0x603c186c0c0c300cULL, 0xff8af6847b7bf17bULL, 0xb5e16a803535d435ULL, 0xe8693af51d1d741dULL, 0x5347ddb3e0e0a7e0ULL, 0xf6acb321d7d77bd7ULL, 0x5eed999cc2c22fc2ULL, 0x6d965c432e2eb82eULL, 0x627a96294b4b314bULL, 0xa321e15dfefedffeULL, 0x8216aed557574157ULL, 0xa8412abd15155415ULL, 0x9fb6eee87777c177ULL, 0xa5eb6e923737dc37ULL, 0x7b56d79ee5e5b3e5ULL, 0x8cd923139f9f469fULL, 0xd317fd23f0f0e7f0ULL, 0x6a7f94204a4a354aULL, 0x9e95a944dada4fdaULL, 0xfa25b0a258587d58ULL, 0x06ca8fcfc9c903c9ULL, 0x558d527c2929a429ULL, 0x5022145a0a0a280aULL, 0xe14f7f50b1b1feb1ULL, 0x691a5dc9a0a0baa0ULL, 0x7fdad6146b6bb16bULL, 0x5cab17d985852e85ULL, 0x8173673cbdbdcebdULL, 0xd234ba8f5d5d695dULL, 0x8050209010104010ULL, 0xf303f507f4f4f7f4ULL, 0x16c08bddcbcb0bcbULL, 0xedc67cd33e3ef83eULL, 0x28110a2d05051405ULL, 0x1fe6ce7867678167ULL, 0x7353d597e4e4b7e4ULL, 0x25bb4e0227279c27ULL, 0x3258827341411941ULL, 0x2c9d0ba78b8b168bULL, 0x510153f6a7a7a6a7ULL, 0xcf94fab27d7de97dULL, 0xdcfb374995956e95ULL, 0x8e9fad56d8d847d8ULL, 0x8b30eb70fbfbcbfbULL, 0x2371c1cdeeee9feeULL, 0xc791f8bb7c7ced7cULL, 0x17e3cc7166668566ULL, 0xa68ea77bdddd53ddULL, 0xb84b2eaf17175c17ULL, 0x02468e4547470147ULL, 0x84dc211a9e9e429eULL, 0x1ec589d4caca0fcaULL, 0x75995a582d2db42dULL, 0x9179632ebfbfc6bfULL, 0x381b0e3f07071c07ULL, 0x012347acadad8eadULL, 0xea2fb4b05a5a755aULL, 0x6cb51bef83833683ULL, 0x85ff66b63333cc33ULL, 0x3ff2c65c63639163ULL, 0x100a041202020802ULL, 0x39384993aaaa92aaULL, 0xafa8e2de7171d971ULL, 0x0ecf8dc6c8c807c8ULL, 0xc87d32d119196419ULL, 0x7270923b49493949ULL, 0x869aaf5fd9d943d9ULL, 0xc31df931f2f2eff2ULL, 0x4b48dba8e3e3abe3ULL, 0xe22ab6b95b5b715bULL, 0x34920dbc88881a88ULL, 0xa4c8293e9a9a529aULL, 0x2dbe4c0b26269826ULL, 0x8dfa64bf3232c832ULL, 0xe94a7d59b0b0fab0ULL, 0x1b6acff2e9e983e9ULL, 0x78331e770f0f3c0fULL, 0xe6a6b733d5d573d5ULL, 0x74ba1df480803a80ULL, 0x997c6127bebec2beULL, 0x26de87ebcdcd13cdULL, 0xbde468893434d034ULL, 0x7a75903248483d48ULL, 0xab24e354ffffdbffULL, 0xf78ff48d7a7af57aULL, 0xf4ea3d6490907a90ULL, 0xc23ebe9d5f5f615fULL, 0x1da0403d20208020ULL, 0x67d5d00f6868bd68ULL, 0xd07234ca1a1a681aULL, 0x192c41b7aeae82aeULL, 0xc95e757db4b4eab4ULL, 0x9a19a8ce54544d54ULL, 0xece53b7f93937693ULL, 0x0daa442f22228822ULL, 0x07e9c86364648d64ULL, 0xdb12ff2af1f1e3f1ULL, 0xbfa2e6cc7373d173ULL, 0x905a248212124812ULL, 0x3a5d807a40401d40ULL, 0x4028104808082008ULL, 0x56e89b95c3c32bc3ULL, 0x337bc5dfecec97ecULL, 0x9690ab4ddbdb4bdbULL, 0x611f5fc0a1a1bea1ULL, 0x1c8307918d8d0e8dULL, 0xf5c97ac83d3df43dULL, 0xccf1335b97976697ULL, 0x0000000000000000ULL, 0x36d483f9cfcf1bcfULL, 0x4587566e2b2bac2bULL, 0x97b3ece17676c576ULL, 0x64b019e682823282ULL, 0xfea9b128d6d67fd6ULL, 0xd87736c31b1b6c1bULL, 0xc15b7774b5b5eeb5ULL, 0x112943beafaf86afULL, 0x77dfd41d6a6ab56aULL, 0xba0da0ea50505d50ULL, 0x124c8a5745450945ULL, 0xcb18fb38f3f3ebf3ULL, 0x9df060ad3030c030ULL, 0x2b74c3c4efef9befULL, 0xe5c37eda3f3ffc3fULL, 0x921caac755554955ULL, 0x791059dba2a2b2a2ULL, 0x0365c9e9eaea8feaULL, 0x0fecca6a65658965ULL, 0xb9686903babad2baULL, 0x65935e4a2f2fbc2fULL, 0x4ee79d8ec0c027c0ULL, 0xbe81a160dede5fdeULL, 0xe06c38fc1c1c701cULL, 0xbb2ee746fdfdd3fdULL, 0x52649a1f4d4d294dULL, 0xe4e0397692927292ULL, 0x8fbceafa7575c975ULL, 0x301e0c3606061806ULL, 0x249809ae8a8a128aULL, 0xf940794bb2b2f2b2ULL, 0x6359d185e6e6bfe6ULL, 0x70361c7e0e0e380eULL, 0xf8633ee71f1f7c1fULL, 0x37f7c45562629562ULL, 0xeea3b53ad4d477d4ULL, 0x29324d81a8a89aa8ULL, 0xc4f4315296966296ULL, 0x9b3aef62f9f9c3f9ULL, 0x66f697a3c5c533c5ULL, 0x35b14a1025259425ULL, 0xf220b2ab59597959ULL, 0x54ae15d084842a84ULL, 0xb7a7e4c57272d572ULL, 0xd5dd72ec3939e439ULL, 0x5a6198164c4c2d4cULL, 0xca3bbc945e5e655eULL, 0xe785f09f7878fd78ULL, 0xddd870e53838e038ULL, 0x148605988c8c0a8cULL, 0xc6b2bf17d1d163d1ULL, 0x410b57e4a5a5aea5ULL, 0x434dd9a1e2e2afe2ULL, 0x2ff8c24e61619961ULL, 0xf1457b42b3b3f6b3ULL, 0x15a5423421218421ULL, 0x94d625089c9c4a9cULL, 0xf0663cee1e1e781eULL, 0x2252866143431143ULL, 0x76fc93b1c7c73bc7ULL, 0xb32be54ffcfcd7fcULL, 0x2014082404041004ULL, 0xb208a2e351515951ULL, 0xbcc72f2599995e99ULL, 0x4fc4da226d6da96dULL, 0x68391a650d0d340dULL, 0x8335e979fafacffaULL, 0xb684a369dfdf5bdfULL, 0xd79bfca97e7ee57eULL, 0x3db4481924249024ULL, 0xc5d776fe3b3bec3bULL, 0x313d4b9aabab96abULL, 0x3ed181f0cece1fceULL, 0x8855229911114411ULL, 0x0c8903838f8f068fULL, 0x4a6b9c044e4e254eULL, 0xd1517366b7b7e6b7ULL, 0x0b60cbe0ebeb8bebULL, 0xfdcc78c13c3cf03cULL, 0x7cbf1ffd81813e81ULL, 0xd4fe354094946a94ULL, 0xeb0cf31cf7f7fbf7ULL, 0xa1676f18b9b9deb9ULL, 0x985f268b13134c13ULL, 0x7d9c58512c2cb02cULL, 0xd6b8bb05d3d36bd3ULL, 0x6b5cd38ce7e7bbe7ULL, 0x57cbdc396e6ea56eULL, 0x6ef395aac4c437c4ULL, 0x180f061b03030c03ULL, 0x8a13acdc56564556ULL, 0x1a49885e44440d44ULL, 0xdf9efea07f7fe17fULL, 0x21374f88a9a99ea9ULL, 0x4d8254672a2aa82aULL, 0xb16d6b0abbbbd6bbULL, 0x46e29f87c1c123c1ULL, 0xa202a6f153535153ULL, 0xae8ba572dcdc57dcULL, 0x582716530b0b2c0bULL, 0x9cd327019d9d4e9dULL, 0x47c1d82b6c6cad6cULL, 0x95f562a43131c431ULL, 0x87b9e8f37474cd74ULL, 0xe309f115f6f6fff6ULL, 0x0a438c4c46460546ULL, 0x092645a5acac8aacULL, 0x3c970fb589891e89ULL, 0xa04428b414145014ULL, 0x5b42dfbae1e1a3e1ULL, 0xb04e2ca616165816ULL, 0xcdd274f73a3ae83aULL, 0x6fd0d2066969b969ULL, 0x482d124109092409ULL, 0xa7ade0d77070dd70ULL, 0xd954716fb6b6e2b6ULL, 0xceb7bd1ed0d067d0ULL, 0x3b7ec7d6eded93edULL, 0x2edb85e2cccc17ccULL, 0x2a57846842421542ULL, 0xb4c22d2c98985a98ULL, 0x490e55eda4a4aaa4ULL, 0x5d8850752828a028ULL, 0xda31b8865c5c6d5cULL, 0x933fed6bf8f8c7f8ULL, 0x44a411c286862286ULL, }; static const uint64_t C5[256] = { 0x18c07830d8181860ULL, 0x2305af462623238cULL, 0xc67ef991b8c6c63fULL, 0xe8136fcdfbe8e887ULL, 0x874ca113cb878726ULL, 0xb8a9626d11b8b8daULL, 0x0108050209010104ULL, 0x4f426e9e0d4f4f21ULL, 0x36adee6c9b3636d8ULL, 0xa6590451ffa6a6a2ULL, 0xd2debdb90cd2d26fULL, 0xf5fb06f70ef5f5f3ULL, 0x79ef80f2967979f9ULL, 0x6f5fcede306f6fa1ULL, 0x91fcef3f6d91917eULL, 0x52aa07a4f8525255ULL, 0x6027fdc04760609dULL, 0xbc89766535bcbccaULL, 0x9baccd2b379b9b56ULL, 0x8e048c018a8e8e02ULL, 0xa371155bd2a3a3b6ULL, 0x0c603c186c0c0c30ULL, 0x7bff8af6847b7bf1ULL, 0x35b5e16a803535d4ULL, 0x1de8693af51d1d74ULL, 0xe05347ddb3e0e0a7ULL, 0xd7f6acb321d7d77bULL, 0xc25eed999cc2c22fULL, 0x2e6d965c432e2eb8ULL, 0x4b627a96294b4b31ULL, 0xfea321e15dfefedfULL, 0x578216aed5575741ULL, 0x15a8412abd151554ULL, 0x779fb6eee87777c1ULL, 0x37a5eb6e923737dcULL, 0xe57b56d79ee5e5b3ULL, 0x9f8cd923139f9f46ULL, 0xf0d317fd23f0f0e7ULL, 0x4a6a7f94204a4a35ULL, 0xda9e95a944dada4fULL, 0x58fa25b0a258587dULL, 0xc906ca8fcfc9c903ULL, 0x29558d527c2929a4ULL, 0x0a5022145a0a0a28ULL, 0xb1e14f7f50b1b1feULL, 0xa0691a5dc9a0a0baULL, 0x6b7fdad6146b6bb1ULL, 0x855cab17d985852eULL, 0xbd8173673cbdbdceULL, 0x5dd234ba8f5d5d69ULL, 0x1080502090101040ULL, 0xf4f303f507f4f4f7ULL, 0xcb16c08bddcbcb0bULL, 0x3eedc67cd33e3ef8ULL, 0x0528110a2d050514ULL, 0x671fe6ce78676781ULL, 0xe47353d597e4e4b7ULL, 0x2725bb4e0227279cULL, 0x4132588273414119ULL, 0x8b2c9d0ba78b8b16ULL, 0xa7510153f6a7a7a6ULL, 0x7dcf94fab27d7de9ULL, 0x95dcfb374995956eULL, 0xd88e9fad56d8d847ULL, 0xfb8b30eb70fbfbcbULL, 0xee2371c1cdeeee9fULL, 0x7cc791f8bb7c7cedULL, 0x6617e3cc71666685ULL, 0xdda68ea77bdddd53ULL, 0x17b84b2eaf17175cULL, 0x4702468e45474701ULL, 0x9e84dc211a9e9e42ULL, 0xca1ec589d4caca0fULL, 0x2d75995a582d2db4ULL, 0xbf9179632ebfbfc6ULL, 0x07381b0e3f07071cULL, 0xad012347acadad8eULL, 0x5aea2fb4b05a5a75ULL, 0x836cb51bef838336ULL, 0x3385ff66b63333ccULL, 0x633ff2c65c636391ULL, 0x02100a0412020208ULL, 0xaa39384993aaaa92ULL, 0x71afa8e2de7171d9ULL, 0xc80ecf8dc6c8c807ULL, 0x19c87d32d1191964ULL, 0x497270923b494939ULL, 0xd9869aaf5fd9d943ULL, 0xf2c31df931f2f2efULL, 0xe34b48dba8e3e3abULL, 0x5be22ab6b95b5b71ULL, 0x8834920dbc88881aULL, 0x9aa4c8293e9a9a52ULL, 0x262dbe4c0b262698ULL, 0x328dfa64bf3232c8ULL, 0xb0e94a7d59b0b0faULL, 0xe91b6acff2e9e983ULL, 0x0f78331e770f0f3cULL, 0xd5e6a6b733d5d573ULL, 0x8074ba1df480803aULL, 0xbe997c6127bebec2ULL, 0xcd26de87ebcdcd13ULL, 0x34bde468893434d0ULL, 0x487a75903248483dULL, 0xffab24e354ffffdbULL, 0x7af78ff48d7a7af5ULL, 0x90f4ea3d6490907aULL, 0x5fc23ebe9d5f5f61ULL, 0x201da0403d202080ULL, 0x6867d5d00f6868bdULL, 0x1ad07234ca1a1a68ULL, 0xae192c41b7aeae82ULL, 0xb4c95e757db4b4eaULL, 0x549a19a8ce54544dULL, 0x93ece53b7f939376ULL, 0x220daa442f222288ULL, 0x6407e9c86364648dULL, 0xf1db12ff2af1f1e3ULL, 0x73bfa2e6cc7373d1ULL, 0x12905a2482121248ULL, 0x403a5d807a40401dULL, 0x0840281048080820ULL, 0xc356e89b95c3c32bULL, 0xec337bc5dfecec97ULL, 0xdb9690ab4ddbdb4bULL, 0xa1611f5fc0a1a1beULL, 0x8d1c8307918d8d0eULL, 0x3df5c97ac83d3df4ULL, 0x97ccf1335b979766ULL, 0x0000000000000000ULL, 0xcf36d483f9cfcf1bULL, 0x2b4587566e2b2bacULL, 0x7697b3ece17676c5ULL, 0x8264b019e6828232ULL, 0xd6fea9b128d6d67fULL, 0x1bd87736c31b1b6cULL, 0xb5c15b7774b5b5eeULL, 0xaf112943beafaf86ULL, 0x6a77dfd41d6a6ab5ULL, 0x50ba0da0ea50505dULL, 0x45124c8a57454509ULL, 0xf3cb18fb38f3f3ebULL, 0x309df060ad3030c0ULL, 0xef2b74c3c4efef9bULL, 0x3fe5c37eda3f3ffcULL, 0x55921caac7555549ULL, 0xa2791059dba2a2b2ULL, 0xea0365c9e9eaea8fULL, 0x650fecca6a656589ULL, 0xbab9686903babad2ULL, 0x2f65935e4a2f2fbcULL, 0xc04ee79d8ec0c027ULL, 0xdebe81a160dede5fULL, 0x1ce06c38fc1c1c70ULL, 0xfdbb2ee746fdfdd3ULL, 0x4d52649a1f4d4d29ULL, 0x92e4e03976929272ULL, 0x758fbceafa7575c9ULL, 0x06301e0c36060618ULL, 0x8a249809ae8a8a12ULL, 0xb2f940794bb2b2f2ULL, 0xe66359d185e6e6bfULL, 0x0e70361c7e0e0e38ULL, 0x1ff8633ee71f1f7cULL, 0x6237f7c455626295ULL, 0xd4eea3b53ad4d477ULL, 0xa829324d81a8a89aULL, 0x96c4f43152969662ULL, 0xf99b3aef62f9f9c3ULL, 0xc566f697a3c5c533ULL, 0x2535b14a10252594ULL, 0x59f220b2ab595979ULL, 0x8454ae15d084842aULL, 0x72b7a7e4c57272d5ULL, 0x39d5dd72ec3939e4ULL, 0x4c5a6198164c4c2dULL, 0x5eca3bbc945e5e65ULL, 0x78e785f09f7878fdULL, 0x38ddd870e53838e0ULL, 0x8c148605988c8c0aULL, 0xd1c6b2bf17d1d163ULL, 0xa5410b57e4a5a5aeULL, 0xe2434dd9a1e2e2afULL, 0x612ff8c24e616199ULL, 0xb3f1457b42b3b3f6ULL, 0x2115a54234212184ULL, 0x9c94d625089c9c4aULL, 0x1ef0663cee1e1e78ULL, 0x4322528661434311ULL, 0xc776fc93b1c7c73bULL, 0xfcb32be54ffcfcd7ULL, 0x0420140824040410ULL, 0x51b208a2e3515159ULL, 0x99bcc72f2599995eULL, 0x6d4fc4da226d6da9ULL, 0x0d68391a650d0d34ULL, 0xfa8335e979fafacfULL, 0xdfb684a369dfdf5bULL, 0x7ed79bfca97e7ee5ULL, 0x243db44819242490ULL, 0x3bc5d776fe3b3becULL, 0xab313d4b9aabab96ULL, 0xce3ed181f0cece1fULL, 0x1188552299111144ULL, 0x8f0c8903838f8f06ULL, 0x4e4a6b9c044e4e25ULL, 0xb7d1517366b7b7e6ULL, 0xeb0b60cbe0ebeb8bULL, 0x3cfdcc78c13c3cf0ULL, 0x817cbf1ffd81813eULL, 0x94d4fe354094946aULL, 0xf7eb0cf31cf7f7fbULL, 0xb9a1676f18b9b9deULL, 0x13985f268b13134cULL, 0x2c7d9c58512c2cb0ULL, 0xd3d6b8bb05d3d36bULL, 0xe76b5cd38ce7e7bbULL, 0x6e57cbdc396e6ea5ULL, 0xc46ef395aac4c437ULL, 0x03180f061b03030cULL, 0x568a13acdc565645ULL, 0x441a49885e44440dULL, 0x7fdf9efea07f7fe1ULL, 0xa921374f88a9a99eULL, 0x2a4d8254672a2aa8ULL, 0xbbb16d6b0abbbbd6ULL, 0xc146e29f87c1c123ULL, 0x53a202a6f1535351ULL, 0xdcae8ba572dcdc57ULL, 0x0b582716530b0b2cULL, 0x9d9cd327019d9d4eULL, 0x6c47c1d82b6c6cadULL, 0x3195f562a43131c4ULL, 0x7487b9e8f37474cdULL, 0xf6e309f115f6f6ffULL, 0x460a438c4c464605ULL, 0xac092645a5acac8aULL, 0x893c970fb589891eULL, 0x14a04428b4141450ULL, 0xe15b42dfbae1e1a3ULL, 0x16b04e2ca6161658ULL, 0x3acdd274f73a3ae8ULL, 0x696fd0d2066969b9ULL, 0x09482d1241090924ULL, 0x70a7ade0d77070ddULL, 0xb6d954716fb6b6e2ULL, 0xd0ceb7bd1ed0d067ULL, 0xed3b7ec7d6eded93ULL, 0xcc2edb85e2cccc17ULL, 0x422a578468424215ULL, 0x98b4c22d2c98985aULL, 0xa4490e55eda4a4aaULL, 0x285d8850752828a0ULL, 0x5cda31b8865c5c6dULL, 0xf8933fed6bf8f8c7ULL, 0x8644a411c2868622ULL, }; static const uint64_t C6[256] = { 0x6018c07830d81818ULL, 0x8c2305af46262323ULL, 0x3fc67ef991b8c6c6ULL, 0x87e8136fcdfbe8e8ULL, 0x26874ca113cb8787ULL, 0xdab8a9626d11b8b8ULL, 0x0401080502090101ULL, 0x214f426e9e0d4f4fULL, 0xd836adee6c9b3636ULL, 0xa2a6590451ffa6a6ULL, 0x6fd2debdb90cd2d2ULL, 0xf3f5fb06f70ef5f5ULL, 0xf979ef80f2967979ULL, 0xa16f5fcede306f6fULL, 0x7e91fcef3f6d9191ULL, 0x5552aa07a4f85252ULL, 0x9d6027fdc0476060ULL, 0xcabc89766535bcbcULL, 0x569baccd2b379b9bULL, 0x028e048c018a8e8eULL, 0xb6a371155bd2a3a3ULL, 0x300c603c186c0c0cULL, 0xf17bff8af6847b7bULL, 0xd435b5e16a803535ULL, 0x741de8693af51d1dULL, 0xa7e05347ddb3e0e0ULL, 0x7bd7f6acb321d7d7ULL, 0x2fc25eed999cc2c2ULL, 0xb82e6d965c432e2eULL, 0x314b627a96294b4bULL, 0xdffea321e15dfefeULL, 0x41578216aed55757ULL, 0x5415a8412abd1515ULL, 0xc1779fb6eee87777ULL, 0xdc37a5eb6e923737ULL, 0xb3e57b56d79ee5e5ULL, 0x469f8cd923139f9fULL, 0xe7f0d317fd23f0f0ULL, 0x354a6a7f94204a4aULL, 0x4fda9e95a944dadaULL, 0x7d58fa25b0a25858ULL, 0x03c906ca8fcfc9c9ULL, 0xa429558d527c2929ULL, 0x280a5022145a0a0aULL, 0xfeb1e14f7f50b1b1ULL, 0xbaa0691a5dc9a0a0ULL, 0xb16b7fdad6146b6bULL, 0x2e855cab17d98585ULL, 0xcebd8173673cbdbdULL, 0x695dd234ba8f5d5dULL, 0x4010805020901010ULL, 0xf7f4f303f507f4f4ULL, 0x0bcb16c08bddcbcbULL, 0xf83eedc67cd33e3eULL, 0x140528110a2d0505ULL, 0x81671fe6ce786767ULL, 0xb7e47353d597e4e4ULL, 0x9c2725bb4e022727ULL, 0x1941325882734141ULL, 0x168b2c9d0ba78b8bULL, 0xa6a7510153f6a7a7ULL, 0xe97dcf94fab27d7dULL, 0x6e95dcfb37499595ULL, 0x47d88e9fad56d8d8ULL, 0xcbfb8b30eb70fbfbULL, 0x9fee2371c1cdeeeeULL, 0xed7cc791f8bb7c7cULL, 0x856617e3cc716666ULL, 0x53dda68ea77bddddULL, 0x5c17b84b2eaf1717ULL, 0x014702468e454747ULL, 0x429e84dc211a9e9eULL, 0x0fca1ec589d4cacaULL, 0xb42d75995a582d2dULL, 0xc6bf9179632ebfbfULL, 0x1c07381b0e3f0707ULL, 0x8ead012347acadadULL, 0x755aea2fb4b05a5aULL, 0x36836cb51bef8383ULL, 0xcc3385ff66b63333ULL, 0x91633ff2c65c6363ULL, 0x0802100a04120202ULL, 0x92aa39384993aaaaULL, 0xd971afa8e2de7171ULL, 0x07c80ecf8dc6c8c8ULL, 0x6419c87d32d11919ULL, 0x39497270923b4949ULL, 0x43d9869aaf5fd9d9ULL, 0xeff2c31df931f2f2ULL, 0xabe34b48dba8e3e3ULL, 0x715be22ab6b95b5bULL, 0x1a8834920dbc8888ULL, 0x529aa4c8293e9a9aULL, 0x98262dbe4c0b2626ULL, 0xc8328dfa64bf3232ULL, 0xfab0e94a7d59b0b0ULL, 0x83e91b6acff2e9e9ULL, 0x3c0f78331e770f0fULL, 0x73d5e6a6b733d5d5ULL, 0x3a8074ba1df48080ULL, 0xc2be997c6127bebeULL, 0x13cd26de87ebcdcdULL, 0xd034bde468893434ULL, 0x3d487a7590324848ULL, 0xdbffab24e354ffffULL, 0xf57af78ff48d7a7aULL, 0x7a90f4ea3d649090ULL, 0x615fc23ebe9d5f5fULL, 0x80201da0403d2020ULL, 0xbd6867d5d00f6868ULL, 0x681ad07234ca1a1aULL, 0x82ae192c41b7aeaeULL, 0xeab4c95e757db4b4ULL, 0x4d549a19a8ce5454ULL, 0x7693ece53b7f9393ULL, 0x88220daa442f2222ULL, 0x8d6407e9c8636464ULL, 0xe3f1db12ff2af1f1ULL, 0xd173bfa2e6cc7373ULL, 0x4812905a24821212ULL, 0x1d403a5d807a4040ULL, 0x2008402810480808ULL, 0x2bc356e89b95c3c3ULL, 0x97ec337bc5dfececULL, 0x4bdb9690ab4ddbdbULL, 0xbea1611f5fc0a1a1ULL, 0x0e8d1c8307918d8dULL, 0xf43df5c97ac83d3dULL, 0x6697ccf1335b9797ULL, 0x0000000000000000ULL, 0x1bcf36d483f9cfcfULL, 0xac2b4587566e2b2bULL, 0xc57697b3ece17676ULL, 0x328264b019e68282ULL, 0x7fd6fea9b128d6d6ULL, 0x6c1bd87736c31b1bULL, 0xeeb5c15b7774b5b5ULL, 0x86af112943beafafULL, 0xb56a77dfd41d6a6aULL, 0x5d50ba0da0ea5050ULL, 0x0945124c8a574545ULL, 0xebf3cb18fb38f3f3ULL, 0xc0309df060ad3030ULL, 0x9bef2b74c3c4efefULL, 0xfc3fe5c37eda3f3fULL, 0x4955921caac75555ULL, 0xb2a2791059dba2a2ULL, 0x8fea0365c9e9eaeaULL, 0x89650fecca6a6565ULL, 0xd2bab9686903babaULL, 0xbc2f65935e4a2f2fULL, 0x27c04ee79d8ec0c0ULL, 0x5fdebe81a160dedeULL, 0x701ce06c38fc1c1cULL, 0xd3fdbb2ee746fdfdULL, 0x294d52649a1f4d4dULL, 0x7292e4e039769292ULL, 0xc9758fbceafa7575ULL, 0x1806301e0c360606ULL, 0x128a249809ae8a8aULL, 0xf2b2f940794bb2b2ULL, 0xbfe66359d185e6e6ULL, 0x380e70361c7e0e0eULL, 0x7c1ff8633ee71f1fULL, 0x956237f7c4556262ULL, 0x77d4eea3b53ad4d4ULL, 0x9aa829324d81a8a8ULL, 0x6296c4f431529696ULL, 0xc3f99b3aef62f9f9ULL, 0x33c566f697a3c5c5ULL, 0x942535b14a102525ULL, 0x7959f220b2ab5959ULL, 0x2a8454ae15d08484ULL, 0xd572b7a7e4c57272ULL, 0xe439d5dd72ec3939ULL, 0x2d4c5a6198164c4cULL, 0x655eca3bbc945e5eULL, 0xfd78e785f09f7878ULL, 0xe038ddd870e53838ULL, 0x0a8c148605988c8cULL, 0x63d1c6b2bf17d1d1ULL, 0xaea5410b57e4a5a5ULL, 0xafe2434dd9a1e2e2ULL, 0x99612ff8c24e6161ULL, 0xf6b3f1457b42b3b3ULL, 0x842115a542342121ULL, 0x4a9c94d625089c9cULL, 0x781ef0663cee1e1eULL, 0x1143225286614343ULL, 0x3bc776fc93b1c7c7ULL, 0xd7fcb32be54ffcfcULL, 0x1004201408240404ULL, 0x5951b208a2e35151ULL, 0x5e99bcc72f259999ULL, 0xa96d4fc4da226d6dULL, 0x340d68391a650d0dULL, 0xcffa8335e979fafaULL, 0x5bdfb684a369dfdfULL, 0xe57ed79bfca97e7eULL, 0x90243db448192424ULL, 0xec3bc5d776fe3b3bULL, 0x96ab313d4b9aababULL, 0x1fce3ed181f0ceceULL, 0x4411885522991111ULL, 0x068f0c8903838f8fULL, 0x254e4a6b9c044e4eULL, 0xe6b7d1517366b7b7ULL, 0x8beb0b60cbe0ebebULL, 0xf03cfdcc78c13c3cULL, 0x3e817cbf1ffd8181ULL, 0x6a94d4fe35409494ULL, 0xfbf7eb0cf31cf7f7ULL, 0xdeb9a1676f18b9b9ULL, 0x4c13985f268b1313ULL, 0xb02c7d9c58512c2cULL, 0x6bd3d6b8bb05d3d3ULL, 0xbbe76b5cd38ce7e7ULL, 0xa56e57cbdc396e6eULL, 0x37c46ef395aac4c4ULL, 0x0c03180f061b0303ULL, 0x45568a13acdc5656ULL, 0x0d441a49885e4444ULL, 0xe17fdf9efea07f7fULL, 0x9ea921374f88a9a9ULL, 0xa82a4d8254672a2aULL, 0xd6bbb16d6b0abbbbULL, 0x23c146e29f87c1c1ULL, 0x5153a202a6f15353ULL, 0x57dcae8ba572dcdcULL, 0x2c0b582716530b0bULL, 0x4e9d9cd327019d9dULL, 0xad6c47c1d82b6c6cULL, 0xc43195f562a43131ULL, 0xcd7487b9e8f37474ULL, 0xfff6e309f115f6f6ULL, 0x05460a438c4c4646ULL, 0x8aac092645a5acacULL, 0x1e893c970fb58989ULL, 0x5014a04428b41414ULL, 0xa3e15b42dfbae1e1ULL, 0x5816b04e2ca61616ULL, 0xe83acdd274f73a3aULL, 0xb9696fd0d2066969ULL, 0x2409482d12410909ULL, 0xdd70a7ade0d77070ULL, 0xe2b6d954716fb6b6ULL, 0x67d0ceb7bd1ed0d0ULL, 0x93ed3b7ec7d6ededULL, 0x17cc2edb85e2ccccULL, 0x15422a5784684242ULL, 0x5a98b4c22d2c9898ULL, 0xaaa4490e55eda4a4ULL, 0xa0285d8850752828ULL, 0x6d5cda31b8865c5cULL, 0xc7f8933fed6bf8f8ULL, 0x228644a411c28686ULL, }; static const uint64_t C7[256] = { 0x186018c07830d818ULL, 0x238c2305af462623ULL, 0xc63fc67ef991b8c6ULL, 0xe887e8136fcdfbe8ULL, 0x8726874ca113cb87ULL, 0xb8dab8a9626d11b8ULL, 0x0104010805020901ULL, 0x4f214f426e9e0d4fULL, 0x36d836adee6c9b36ULL, 0xa6a2a6590451ffa6ULL, 0xd26fd2debdb90cd2ULL, 0xf5f3f5fb06f70ef5ULL, 0x79f979ef80f29679ULL, 0x6fa16f5fcede306fULL, 0x917e91fcef3f6d91ULL, 0x525552aa07a4f852ULL, 0x609d6027fdc04760ULL, 0xbccabc89766535bcULL, 0x9b569baccd2b379bULL, 0x8e028e048c018a8eULL, 0xa3b6a371155bd2a3ULL, 0x0c300c603c186c0cULL, 0x7bf17bff8af6847bULL, 0x35d435b5e16a8035ULL, 0x1d741de8693af51dULL, 0xe0a7e05347ddb3e0ULL, 0xd77bd7f6acb321d7ULL, 0xc22fc25eed999cc2ULL, 0x2eb82e6d965c432eULL, 0x4b314b627a96294bULL, 0xfedffea321e15dfeULL, 0x5741578216aed557ULL, 0x155415a8412abd15ULL, 0x77c1779fb6eee877ULL, 0x37dc37a5eb6e9237ULL, 0xe5b3e57b56d79ee5ULL, 0x9f469f8cd923139fULL, 0xf0e7f0d317fd23f0ULL, 0x4a354a6a7f94204aULL, 0xda4fda9e95a944daULL, 0x587d58fa25b0a258ULL, 0xc903c906ca8fcfc9ULL, 0x29a429558d527c29ULL, 0x0a280a5022145a0aULL, 0xb1feb1e14f7f50b1ULL, 0xa0baa0691a5dc9a0ULL, 0x6bb16b7fdad6146bULL, 0x852e855cab17d985ULL, 0xbdcebd8173673cbdULL, 0x5d695dd234ba8f5dULL, 0x1040108050209010ULL, 0xf4f7f4f303f507f4ULL, 0xcb0bcb16c08bddcbULL, 0x3ef83eedc67cd33eULL, 0x05140528110a2d05ULL, 0x6781671fe6ce7867ULL, 0xe4b7e47353d597e4ULL, 0x279c2725bb4e0227ULL, 0x4119413258827341ULL, 0x8b168b2c9d0ba78bULL, 0xa7a6a7510153f6a7ULL, 0x7de97dcf94fab27dULL, 0x956e95dcfb374995ULL, 0xd847d88e9fad56d8ULL, 0xfbcbfb8b30eb70fbULL, 0xee9fee2371c1cdeeULL, 0x7ced7cc791f8bb7cULL, 0x66856617e3cc7166ULL, 0xdd53dda68ea77bddULL, 0x175c17b84b2eaf17ULL, 0x47014702468e4547ULL, 0x9e429e84dc211a9eULL, 0xca0fca1ec589d4caULL, 0x2db42d75995a582dULL, 0xbfc6bf9179632ebfULL, 0x071c07381b0e3f07ULL, 0xad8ead012347acadULL, 0x5a755aea2fb4b05aULL, 0x8336836cb51bef83ULL, 0x33cc3385ff66b633ULL, 0x6391633ff2c65c63ULL, 0x020802100a041202ULL, 0xaa92aa39384993aaULL, 0x71d971afa8e2de71ULL, 0xc807c80ecf8dc6c8ULL, 0x196419c87d32d119ULL, 0x4939497270923b49ULL, 0xd943d9869aaf5fd9ULL, 0xf2eff2c31df931f2ULL, 0xe3abe34b48dba8e3ULL, 0x5b715be22ab6b95bULL, 0x881a8834920dbc88ULL, 0x9a529aa4c8293e9aULL, 0x2698262dbe4c0b26ULL, 0x32c8328dfa64bf32ULL, 0xb0fab0e94a7d59b0ULL, 0xe983e91b6acff2e9ULL, 0x0f3c0f78331e770fULL, 0xd573d5e6a6b733d5ULL, 0x803a8074ba1df480ULL, 0xbec2be997c6127beULL, 0xcd13cd26de87ebcdULL, 0x34d034bde4688934ULL, 0x483d487a75903248ULL, 0xffdbffab24e354ffULL, 0x7af57af78ff48d7aULL, 0x907a90f4ea3d6490ULL, 0x5f615fc23ebe9d5fULL, 0x2080201da0403d20ULL, 0x68bd6867d5d00f68ULL, 0x1a681ad07234ca1aULL, 0xae82ae192c41b7aeULL, 0xb4eab4c95e757db4ULL, 0x544d549a19a8ce54ULL, 0x937693ece53b7f93ULL, 0x2288220daa442f22ULL, 0x648d6407e9c86364ULL, 0xf1e3f1db12ff2af1ULL, 0x73d173bfa2e6cc73ULL, 0x124812905a248212ULL, 0x401d403a5d807a40ULL, 0x0820084028104808ULL, 0xc32bc356e89b95c3ULL, 0xec97ec337bc5dfecULL, 0xdb4bdb9690ab4ddbULL, 0xa1bea1611f5fc0a1ULL, 0x8d0e8d1c8307918dULL, 0x3df43df5c97ac83dULL, 0x976697ccf1335b97ULL, 0x0000000000000000ULL, 0xcf1bcf36d483f9cfULL, 0x2bac2b4587566e2bULL, 0x76c57697b3ece176ULL, 0x82328264b019e682ULL, 0xd67fd6fea9b128d6ULL, 0x1b6c1bd87736c31bULL, 0xb5eeb5c15b7774b5ULL, 0xaf86af112943beafULL, 0x6ab56a77dfd41d6aULL, 0x505d50ba0da0ea50ULL, 0x450945124c8a5745ULL, 0xf3ebf3cb18fb38f3ULL, 0x30c0309df060ad30ULL, 0xef9bef2b74c3c4efULL, 0x3ffc3fe5c37eda3fULL, 0x554955921caac755ULL, 0xa2b2a2791059dba2ULL, 0xea8fea0365c9e9eaULL, 0x6589650fecca6a65ULL, 0xbad2bab9686903baULL, 0x2fbc2f65935e4a2fULL, 0xc027c04ee79d8ec0ULL, 0xde5fdebe81a160deULL, 0x1c701ce06c38fc1cULL, 0xfdd3fdbb2ee746fdULL, 0x4d294d52649a1f4dULL, 0x927292e4e0397692ULL, 0x75c9758fbceafa75ULL, 0x061806301e0c3606ULL, 0x8a128a249809ae8aULL, 0xb2f2b2f940794bb2ULL, 0xe6bfe66359d185e6ULL, 0x0e380e70361c7e0eULL, 0x1f7c1ff8633ee71fULL, 0x62956237f7c45562ULL, 0xd477d4eea3b53ad4ULL, 0xa89aa829324d81a8ULL, 0x966296c4f4315296ULL, 0xf9c3f99b3aef62f9ULL, 0xc533c566f697a3c5ULL, 0x25942535b14a1025ULL, 0x597959f220b2ab59ULL, 0x842a8454ae15d084ULL, 0x72d572b7a7e4c572ULL, 0x39e439d5dd72ec39ULL, 0x4c2d4c5a6198164cULL, 0x5e655eca3bbc945eULL, 0x78fd78e785f09f78ULL, 0x38e038ddd870e538ULL, 0x8c0a8c148605988cULL, 0xd163d1c6b2bf17d1ULL, 0xa5aea5410b57e4a5ULL, 0xe2afe2434dd9a1e2ULL, 0x6199612ff8c24e61ULL, 0xb3f6b3f1457b42b3ULL, 0x21842115a5423421ULL, 0x9c4a9c94d625089cULL, 0x1e781ef0663cee1eULL, 0x4311432252866143ULL, 0xc73bc776fc93b1c7ULL, 0xfcd7fcb32be54ffcULL, 0x0410042014082404ULL, 0x515951b208a2e351ULL, 0x995e99bcc72f2599ULL, 0x6da96d4fc4da226dULL, 0x0d340d68391a650dULL, 0xfacffa8335e979faULL, 0xdf5bdfb684a369dfULL, 0x7ee57ed79bfca97eULL, 0x2490243db4481924ULL, 0x3bec3bc5d776fe3bULL, 0xab96ab313d4b9aabULL, 0xce1fce3ed181f0ceULL, 0x1144118855229911ULL, 0x8f068f0c8903838fULL, 0x4e254e4a6b9c044eULL, 0xb7e6b7d1517366b7ULL, 0xeb8beb0b60cbe0ebULL, 0x3cf03cfdcc78c13cULL, 0x813e817cbf1ffd81ULL, 0x946a94d4fe354094ULL, 0xf7fbf7eb0cf31cf7ULL, 0xb9deb9a1676f18b9ULL, 0x134c13985f268b13ULL, 0x2cb02c7d9c58512cULL, 0xd36bd3d6b8bb05d3ULL, 0xe7bbe76b5cd38ce7ULL, 0x6ea56e57cbdc396eULL, 0xc437c46ef395aac4ULL, 0x030c03180f061b03ULL, 0x5645568a13acdc56ULL, 0x440d441a49885e44ULL, 0x7fe17fdf9efea07fULL, 0xa99ea921374f88a9ULL, 0x2aa82a4d8254672aULL, 0xbbd6bbb16d6b0abbULL, 0xc123c146e29f87c1ULL, 0x535153a202a6f153ULL, 0xdc57dcae8ba572dcULL, 0x0b2c0b582716530bULL, 0x9d4e9d9cd327019dULL, 0x6cad6c47c1d82b6cULL, 0x31c43195f562a431ULL, 0x74cd7487b9e8f374ULL, 0xf6fff6e309f115f6ULL, 0x4605460a438c4c46ULL, 0xac8aac092645a5acULL, 0x891e893c970fb589ULL, 0x145014a04428b414ULL, 0xe1a3e15b42dfbae1ULL, 0x165816b04e2ca616ULL, 0x3ae83acdd274f73aULL, 0x69b9696fd0d20669ULL, 0x092409482d124109ULL, 0x70dd70a7ade0d770ULL, 0xb6e2b6d954716fb6ULL, 0xd067d0ceb7bd1ed0ULL, 0xed93ed3b7ec7d6edULL, 0xcc17cc2edb85e2ccULL, 0x4215422a57846842ULL, 0x985a98b4c22d2c98ULL, 0xa4aaa4490e55eda4ULL, 0x28a0285d88507528ULL, 0x5c6d5cda31b8865cULL, 0xf8c7f8933fed6bf8ULL, 0x86228644a411c286ULL, }; static const uint64_t rc[R + 1] = { 0x0000000000000000ULL, 0x1823c6e887b8014fULL, 0x36a6d2f5796f9152ULL, 0x60bc9b8ea30c7b35ULL, 0x1de0d7c22e4bfe57ULL, 0x157737e59ff04adaULL, 0x58c9290ab1a06b85ULL, 0xbd5d10f4cb3e0567ULL, 0xe427418ba77d95d8ULL, 0xfbee7c66dd17479eULL, 0xca2dbf07ad5a8333ULL, }; /* This might not be true for all platforms and compilers. */ #define SANE_ARRAY_PACKING 1 #if defined(SANE_ARRAY_PACKING) && (defined(ARCH_IS_LITTLE_ENDIAN) || defined(ARCH_IS_BIG_ENDIAN)) #if defined(ARCH_IS_LITTLE_ENDIAN) #define LB(n) do { L[n] = C0[mu[((n+0)%8) * 8 + 7]] \ ^ C1[mu[((n+7)%8) * 8 + 6]] \ ^ C2[mu[((n+6)%8) * 8 + 5]] \ ^ C3[mu[((n+5)%8) * 8 + 4]] \ ^ C4[mu[((n+4)%8) * 8 + 3]] \ ^ C5[mu[((n+3)%8) * 8 + 2]] \ ^ C6[mu[((n+2)%8) * 8 + 1]] \ ^ C7[mu[((n+1)%8) * 8 + 0]] \ ; } while (0) #else #define LB(n) do { L[n] = C0[mu[((n+0)%8) * 8 + 0]] \ ^ C1[mu[((n+7)%8) * 8 + 1]] \ ^ C2[mu[((n+6)%8) * 8 + 2]] \ ^ C3[mu[((n+5)%8) * 8 + 3]] \ ^ C4[mu[((n+4)%8) * 8 + 4]] \ ^ C5[mu[((n+3)%8) * 8 + 5]] \ ^ C6[mu[((n+2)%8) * 8 + 6]] \ ^ C7[mu[((n+1)%8) * 8 + 7]] \ ; } while (0) #endif static void transformMatrix(uint64_t m[8]) { uint64_t L[8]; uint8_t *mu = (uint8_t*)m; LB(0); LB(1); LB(2); LB(3); LB(4); LB(5); LB(6); LB(7); array_copy64(m, L, 8); } #else static void transformMatrix(uint64_t m[8]) { uint64_t L[8]; L[0] = C0[(int)(m[0] >> 56) ] ^ C1[(int)(m[7] >> 48) & 0xff] ^ C2[(int)(m[6] >> 40) & 0xff] ^ C3[(int)(m[5] >> 32) & 0xff] ^ C4[(int)(m[4] >> 24) & 0xff] ^ C5[(int)(m[3] >> 16) & 0xff] ^ C6[(int)(m[2] >> 8) & 0xff] ^ C7[(int)(m[1] ) & 0xff]; L[1] = C0[(int)(m[1] >> 56) ] ^ C1[(int)(m[0] >> 48) & 0xff] ^ C2[(int)(m[7] >> 40) & 0xff] ^ C3[(int)(m[6] >> 32) & 0xff] ^ C4[(int)(m[5] >> 24) & 0xff] ^ C5[(int)(m[4] >> 16) & 0xff] ^ C6[(int)(m[3] >> 8) & 0xff] ^ C7[(int)(m[2] ) & 0xff]; L[2] = C0[(int)(m[2] >> 56) ] ^ C1[(int)(m[1] >> 48) & 0xff] ^ C2[(int)(m[0] >> 40) & 0xff] ^ C3[(int)(m[7] >> 32) & 0xff] ^ C4[(int)(m[6] >> 24) & 0xff] ^ C5[(int)(m[5] >> 16) & 0xff] ^ C6[(int)(m[4] >> 8) & 0xff] ^ C7[(int)(m[3] ) & 0xff]; L[3] = C0[(int)(m[3] >> 56) ] ^ C1[(int)(m[2] >> 48) & 0xff] ^ C2[(int)(m[1] >> 40) & 0xff] ^ C3[(int)(m[0] >> 32) & 0xff] ^ C4[(int)(m[7] >> 24) & 0xff] ^ C5[(int)(m[6] >> 16) & 0xff] ^ C6[(int)(m[5] >> 8) & 0xff] ^ C7[(int)(m[4] ) & 0xff]; L[4] = C0[(int)(m[4] >> 56) ] ^ C1[(int)(m[3] >> 48) & 0xff] ^ C2[(int)(m[2] >> 40) & 0xff] ^ C3[(int)(m[1] >> 32) & 0xff] ^ C4[(int)(m[0] >> 24) & 0xff] ^ C5[(int)(m[7] >> 16) & 0xff] ^ C6[(int)(m[6] >> 8) & 0xff] ^ C7[(int)(m[5] ) & 0xff]; L[5] = C0[(int)(m[5] >> 56) ] ^ C1[(int)(m[4] >> 48) & 0xff] ^ C2[(int)(m[3] >> 40) & 0xff] ^ C3[(int)(m[2] >> 32) & 0xff] ^ C4[(int)(m[1] >> 24) & 0xff] ^ C5[(int)(m[0] >> 16) & 0xff] ^ C6[(int)(m[7] >> 8) & 0xff] ^ C7[(int)(m[6] ) & 0xff]; L[6] = C0[(int)(m[6] >> 56) ] ^ C1[(int)(m[5] >> 48) & 0xff] ^ C2[(int)(m[4] >> 40) & 0xff] ^ C3[(int)(m[3] >> 32) & 0xff] ^ C4[(int)(m[2] >> 24) & 0xff] ^ C5[(int)(m[1] >> 16) & 0xff] ^ C6[(int)(m[0] >> 8) & 0xff] ^ C7[(int)(m[7] ) & 0xff]; L[7] = C0[(int)(m[7] >> 56) ] ^ C1[(int)(m[6] >> 48) & 0xff] ^ C2[(int)(m[5] >> 40) & 0xff] ^ C3[(int)(m[4] >> 32) & 0xff] ^ C4[(int)(m[3] >> 24) & 0xff] ^ C5[(int)(m[2] >> 16) & 0xff] ^ C6[(int)(m[1] >> 8) & 0xff] ^ C7[(int)(m[0] ) & 0xff]; array_copy64(m, L, 8); } #endif static void inplaceXor(uint64_t dst[8], uint64_t src[8]) { dst[0] ^= src[0]; dst[1] ^= src[1]; dst[2] ^= src[2]; dst[3] ^= src[3]; dst[4] ^= src[4]; dst[5] ^= src[5]; dst[6] ^= src[6]; dst[7] ^= src[7]; } /** * The core Whirlpool transform. */ static void processBuffer(whirlpool_ctx * const ctx) { int i, r; uint64_t K[8]; /* the round key */ uint64_t block[8]; /* mu(buffer) */ uint64_t state[8]; /* the cipher state */ uint64_t L[8]; uint8_t *buffer = ctx->buffer; /* * map the buffer to a block: */ for (i = 0; i < 8; i++, buffer += 8) { block[i] = (((uint64_t)buffer[0] ) << 56) ^ (((uint64_t)buffer[1] & 0xffL) << 48) ^ (((uint64_t)buffer[2] & 0xffL) << 40) ^ (((uint64_t)buffer[3] & 0xffL) << 32) ^ (((uint64_t)buffer[4] & 0xffL) << 24) ^ (((uint64_t)buffer[5] & 0xffL) << 16) ^ (((uint64_t)buffer[6] & 0xffL) << 8) ^ (((uint64_t)buffer[7] & 0xffL) ); } /* * compute and apply K^0 to the cipher state: */ array_copy64(K, ctx->hash, 8); array_copy64(state, block, 8); inplaceXor(state, K); /* * iterate over all rounds: */ for (r = 1; r <= R; r++) { /* * compute K^r from K^{r-1}: */ transformMatrix(K); K[0] ^= rc[r]; /* * apply the r-th round transformation: */ transformMatrix(state); inplaceXor(state, K); } /* * apply the Miyaguchi-Preneel compression function: */ inplaceXor(ctx->hash, state); inplaceXor(ctx->hash, block); } /** * Initialize the hashing state. */ void cryptonite_whirlpool_init(struct whirlpool_ctx * const ctx) { int i; memset(ctx->bitLength, 0, 32); ctx->bufferBits = ctx->bufferPos = 0; ctx->buffer[0] = 0; /* it's only necessary to cleanup buffer[bufferPos] */ for (i = 0; i < 8; i++) { ctx->hash[i] = 0L; /* initial value */ } } /** * Delivers input data to the hashing algorithm. * * @param source plaintext data to hash. * @param sourceBits how many bits of plaintext to process. * * This method maintains the invariant: bufferBits < DIGESTBITS */ void cryptonite_whirlpool_update(struct whirlpool_ctx * const ctx, const uint8_t * const source, uint32_t sourceBytes) { /* sourcePos | +-------+-------+------- ||||||||||||||||||||| source +-------+-------+------- +-------+-------+-------+-------+-------+------- |||||||||||||||||||||| buffer +-------+-------+-------+-------+-------+------- | bufferPos */ int sourceBits = sourceBytes * 8; int sourcePos = 0; /* index of leftmost source uint8_t containing data (1 to 8 bits). */ int sourceGap = (8 - ((int)sourceBits & 7)) & 7; /* space on source[sourcePos]. */ int bufferRem = ctx->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */ int i; uint32_t b, carry; uint8_t *buffer = ctx->buffer; uint8_t *bitLength = ctx->bitLength; int bufferBits = ctx->bufferBits; int bufferPos = ctx->bufferPos; /* * tally the length of the added data: */ uint64_t value = sourceBits; for (i = 31, carry = 0; i >= 0 && (carry != 0 || value != 0ULL); i--) { carry += bitLength[i] + ((uint32_t)value & 0xff); bitLength[i] = (uint8_t)carry; carry >>= 8; value >>= 8; } /* * process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks): */ while (sourceBits > 8) { /* N.B. at least source[sourcePos] and source[sourcePos+1] contain data. */ /* * take a byte from the source: */ b = ((source[sourcePos] << sourceGap) & 0xff) | ((source[sourcePos + 1] & 0xff) >> (8 - sourceGap)); /* * process this byte: */ buffer[bufferPos++] |= (uint8_t)(b >> bufferRem); bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */ if (bufferBits == DIGESTBITS) { /* * process data block: */ processBuffer(ctx); /* * reset buffer: */ bufferBits = bufferPos = 0; } buffer[bufferPos] = b << (8 - bufferRem); bufferBits += bufferRem; /* * proceed to remaining data: */ sourceBits -= 8; sourcePos++; } /* now 0 <= sourceBits <= 8; * furthermore, all data (if any is left) is in source[sourcePos]. */ if (sourceBits > 0) { b = (source[sourcePos] << sourceGap) & 0xff; /* bits are left-justified on b. */ /* * process the remaining bits: */ buffer[bufferPos] |= b >> bufferRem; } else { b = 0; } if (bufferRem + sourceBits < 8) { /* * all remaining data fits on buffer[bufferPos], * and there still remains some space. */ bufferBits += sourceBits; } else { /* * buffer[bufferPos] is full: */ bufferPos++; bufferBits += 8 - bufferRem; /* bufferBits = 8*bufferPos; */ sourceBits -= 8 - bufferRem; /* now 0 <= sourceBits < 8; * furthermore, all data (if any is left) is in source[sourcePos]. */ if (bufferBits == DIGESTBITS) { /* * process data block: */ processBuffer(ctx); /* * reset buffer: */ bufferBits = bufferPos = 0; } buffer[bufferPos] = b << (8 - bufferRem); bufferBits += (int)sourceBits; } ctx->bufferBits = bufferBits; ctx->bufferPos = bufferPos; } /** * Get the hash value from the hashing state. * * This method uses the invariant: bufferBits < DIGESTBITS */ void cryptonite_whirlpool_finalize(struct whirlpool_ctx * const ctx, uint8_t * const result) { int i; uint8_t *buffer = ctx->buffer; uint8_t *bitLength = ctx->bitLength; int bufferBits = ctx->bufferBits; int bufferPos = ctx->bufferPos; uint8_t *digest = result; /* * append a '1'-bit: */ buffer[bufferPos] |= 0x80U >> (bufferBits & 7); bufferPos++; /* all remaining bits on the current uint8_t are set to zero. */ /* * pad with zero bits to complete (N*WBLOCKBITS - LENGTHBITS) bits: */ if (bufferPos > WBLOCKBYTES - LENGTHBYTES) { if (bufferPos < WBLOCKBYTES) { memset(&buffer[bufferPos], 0, WBLOCKBYTES - bufferPos); } /* * process data block: */ processBuffer(ctx); /* * reset buffer: */ bufferPos = 0; } if (bufferPos < WBLOCKBYTES - LENGTHBYTES) { memset(&buffer[bufferPos], 0, (WBLOCKBYTES - LENGTHBYTES) - bufferPos); } bufferPos = WBLOCKBYTES - LENGTHBYTES; /* * append bit length of hashed data: */ memcpy(&buffer[WBLOCKBYTES - LENGTHBYTES], bitLength, LENGTHBYTES); /* * process data block: */ processBuffer(ctx); /* * return the completed message digest: */ for (i = 0; i < DIGESTBYTES/8; i++) { digest[0] = (uint8_t)(ctx->hash[i] >> 56); digest[1] = (uint8_t)(ctx->hash[i] >> 48); digest[2] = (uint8_t)(ctx->hash[i] >> 40); digest[3] = (uint8_t)(ctx->hash[i] >> 32); digest[4] = (uint8_t)(ctx->hash[i] >> 24); digest[5] = (uint8_t)(ctx->hash[i] >> 16); digest[6] = (uint8_t)(ctx->hash[i] >> 8); digest[7] = (uint8_t)(ctx->hash[i] ); digest += 8; } ctx->bufferBits = bufferBits; ctx->bufferPos = bufferPos; } cryptonite-0.23/cbits/cryptonite_scrypt.c0000644000000000000000000000560312567623176017123 0ustar0000000000000000/* * Copyright (C) 2014 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Based on scrypt from Colin Percival's paper */ #include #include #include "cryptonite_bitfn.h" #include "cryptonite_salsa.h" static void blockmix_salsa8(uint32_t *in, uint32_t *out, uint32_t *X, const uint32_t r) { int i; array_copy32(X, &in[(2 * r - 1) * 16], 16); for (i = 0; i < 2 * r; i += 2) { cryptonite_salsa_core_xor(8, (block *) X, (block *) &in[i*16]); array_copy32(&out[i * 8], X, 16); cryptonite_salsa_core_xor(8, (block *) X, (block *) &in[i*16+16]); array_copy32(&out[i * 8 + r * 16], X, 16); } } static inline uint64_t integerify(uint32_t *B, const uint32_t r) { return B[(2*r-1) * 16] | (uint64_t)B[(2*r-1) * 16 + 1] << 32; } static inline uint32_t load32(const uint8_t *p) { return le32_to_cpu(*((uint32_t *) p)); } static inline void store32(const uint8_t *p, uint32_t val) { *((uint32_t *) p) = cpu_to_le32(val); } void cryptonite_scrypt_smix(uint8_t *B, const uint32_t r, const uint64_t N, uint32_t *V, uint32_t *XY) { uint32_t *X = XY; uint32_t *Y = &XY[32 * r]; uint32_t *Z = &XY[64 * r]; uint64_t i, j; int k; const int r32 = 32*r; for (k = 0; k < r32; k++) X[k] = load32(&B[4 * k]); for (i = 0; i < N; i += 2) { array_copy32(&V[i * r32], X, r32); blockmix_salsa8(X, Y, Z, r); array_copy32(&V[(i + 1) * r32], Y, r32); blockmix_salsa8(Y, X, Z, r); } for (i = 0; i < N; i += 2) { j = integerify(X, r) & (N - 1); array_xor32(X, &V[j * r32], r32); blockmix_salsa8(X, Y, Z, r); j = integerify(Y, r) & (N - 1); array_xor32(Y, &V[j * r32], r32); blockmix_salsa8(Y, X, Z, r); } for (k = 0; k < r32; k++) store32(&B[4*k], X[k]); } cryptonite-0.23/cbits/cryptonite_pbkdf2.c0000644000000000000000000004422513052512456016736 0ustar0000000000000000/* * fast-pbkdf2 - Optimal PBKDF2-HMAC calculation * Written in 2015 by Joseph Birr-Pixton * Ported to cryptonite in 2017 by Nicolas Di Prima * * To the extent possible under law, the author(s) have dedicated all * copyright and related and neighboring rights to this software to the * public domain worldwide. This software is distributed without any * warranty. * * You should have received a copy of the CC0 Public Domain Dedication * along with this software. If not, see * . */ #include #include #include "cryptonite_pbkdf2.h" #include "cryptonite_bitfn.h" #include "cryptonite_align.h" #include "cryptonite_sha1.h" #include "cryptonite_sha256.h" #include "cryptonite_sha512.h" /* --- MSVC doesn't support C99 --- */ #ifdef _MSC_VER #define restrict #define _Pragma __pragma #endif /* --- Common useful things --- */ #define MIN(a, b) ((a) > (b)) ? (b) : (a) /* Prepare block (of blocksz bytes) to contain md padding denoting a msg-size * message (in bytes). block has a prefix of used bytes. * * Message length is expressed in 32 bits (so suitable for sha1, sha256, sha512). */ static inline void md_pad(uint8_t *block, size_t blocksz, size_t used, size_t msg) { memset(block + used, 0, blocksz - used - 4); block[used] = 0x80; block += blocksz - 4; store_be32(block, (uint32_t) (msg * 8)); } /* Internal function/type names for hash-specific things. */ #define HMAC_CTX(_name) HMAC_ ## _name ## _ctx #define HMAC_INIT(_name) HMAC_ ## _name ## _init #define HMAC_UPDATE(_name) HMAC_ ## _name ## _update #define HMAC_FINAL(_name) HMAC_ ## _name ## _final #define PBKDF2_F(_name) pbkdf2_f_ ## _name #define PBKDF2(_name) pbkdf2_ ## _name /* This macro expands to decls for the whole implementation for a given * hash function. Arguments are: * * _name like 'sha1', added to symbol names * _blocksz block size, in bytes * _hashsz digest output, in bytes * _ctx hash context type * _init hash context initialisation function * args: (_ctx *c) * _update hash context update function * args: (_ctx *c, const void *data, size_t ndata) * _final hash context finish function * args: (void *out, _ctx *c) * _xform hash context raw block update function * args: (_ctx *c, const void *data) * _xcpy hash context raw copy function (only need copy hash state) * args: (_ctx * restrict out, const _ctx *restrict in) * _xtract hash context state extraction * args: args (_ctx *restrict c, uint8_t *restrict out) * _xxor hash context xor function (only need xor hash state) * args: (_ctx *restrict out, const _ctx *restrict in) * * The resulting function is named PBKDF2(_name). */ #define DECL_PBKDF2(_name, _blocksz, _hashsz, _ctx, \ _init, _update, _xform, _final, _xcpy, _xtract, _xxor) \ typedef struct { \ _ctx inner; \ _ctx outer; \ } HMAC_CTX(_name); \ \ static inline void HMAC_INIT(_name)(HMAC_CTX(_name) *ctx, \ const uint8_t *key, size_t nkey) \ { \ /* Prepare key: */ \ uint8_t k[_blocksz]; \ \ /* Shorten long keys. */ \ if (nkey > _blocksz) \ { \ _init(&ctx->inner); \ _update(&ctx->inner, key, nkey); \ _final(&ctx->inner, k); \ \ key = k; \ nkey = _hashsz; \ } \ \ /* Standard doesn't cover case where blocksz < hashsz. */ \ assert(nkey <= _blocksz); \ \ /* Right zero-pad short keys. */ \ if (k != key) \ memcpy(k, key, nkey); \ if (_blocksz > nkey) \ memset(k + nkey, 0, _blocksz - nkey); \ \ /* Start inner hash computation */ \ uint8_t blk_inner[_blocksz]; \ uint8_t blk_outer[_blocksz]; \ \ for (size_t i = 0; i < _blocksz; i++) \ { \ blk_inner[i] = 0x36 ^ k[i]; \ blk_outer[i] = 0x5c ^ k[i]; \ } \ \ _init(&ctx->inner); \ _update(&ctx->inner, blk_inner, sizeof blk_inner); \ \ /* And outer. */ \ _init(&ctx->outer); \ _update(&ctx->outer, blk_outer, sizeof blk_outer); \ } \ \ static inline void HMAC_UPDATE(_name)(HMAC_CTX(_name) *ctx, \ const void *data, size_t ndata) \ { \ _update(&ctx->inner, data, ndata); \ } \ \ static inline void HMAC_FINAL(_name)(HMAC_CTX(_name) *ctx, \ uint8_t out[_hashsz]) \ { \ _final(&ctx->inner, out); \ _update(&ctx->outer, out, _hashsz); \ _final(&ctx->outer, out); \ } \ \ \ /* --- PBKDF2 --- */ \ static inline void PBKDF2_F(_name)(const HMAC_CTX(_name) *startctx, \ uint32_t counter, \ const uint8_t *salt, size_t nsalt, \ uint32_t iterations, \ uint8_t *out) \ { \ uint8_t countbuf[4]; \ store_be32(countbuf, counter); \ \ /* Prepare loop-invariant padding block. */ \ uint8_t Ublock[_blocksz]; \ md_pad(Ublock, _blocksz, _hashsz, _blocksz + _hashsz); \ \ /* First iteration: \ * U_1 = PRF(P, S || INT_32_BE(i)) \ */ \ HMAC_CTX(_name) ctx = *startctx; \ HMAC_UPDATE(_name)(&ctx, salt, nsalt); \ HMAC_UPDATE(_name)(&ctx, countbuf, sizeof countbuf); \ HMAC_FINAL(_name)(&ctx, Ublock); \ _ctx result = ctx.outer; \ \ /* Subsequent iterations: \ * U_c = PRF(P, U_{c-1}) \ */ \ for (uint32_t i = 1; i < iterations; i++) \ { \ /* Complete inner hash with previous U */ \ _xcpy(&ctx.inner, &startctx->inner); \ _xform(&ctx.inner, Ublock); \ _xtract(&ctx.inner, Ublock); \ /* Complete outer hash with inner output */ \ _xcpy(&ctx.outer, &startctx->outer); \ _xform(&ctx.outer, Ublock); \ _xtract(&ctx.outer, Ublock); \ _xxor(&result, &ctx.outer); \ } \ \ /* Reform result into output buffer. */ \ _xtract(&result, out); \ } \ \ static inline void PBKDF2(_name)(const uint8_t *pw, size_t npw, \ const uint8_t *salt, size_t nsalt, \ uint32_t iterations, \ uint8_t *out, size_t nout) \ { \ assert(iterations); \ assert(out && nout); \ \ /* Starting point for inner loop. */ \ HMAC_CTX(_name) ctx; \ HMAC_INIT(_name)(&ctx, pw, npw); \ \ /* How many blocks do we need? */ \ uint32_t blocks_needed = (uint32_t)(nout + _hashsz - 1) / _hashsz; \ \ for (uint32_t counter = 1; counter <= blocks_needed; counter++) \ { \ uint8_t block[_hashsz]; \ PBKDF2_F(_name)(&ctx, counter, salt, nsalt, iterations, block); \ \ size_t offset = (counter - 1) * _hashsz; \ size_t taken = MIN(nout - offset, _hashsz); \ memcpy(out + offset, block, taken); \ } \ } static inline void sha1_extract(struct sha1_ctx *restrict ctx, uint8_t *restrict out) { store_be32(out , ctx->h[0]); store_be32(out+4 , ctx->h[1]); store_be32(out+8 , ctx->h[2]); store_be32(out+12, ctx->h[3]); store_be32(out+16, ctx->h[4]); } static inline void sha1_cpy(struct sha1_ctx *restrict out, const struct sha1_ctx *restrict in) { out->h[0] = in->h[0]; out->h[1] = in->h[1]; out->h[2] = in->h[2]; out->h[3] = in->h[3]; out->h[4] = in->h[4]; } static inline void sha1_xor(struct sha1_ctx *restrict out, const struct sha1_ctx *restrict in) { out->h[0] ^= in->h[0]; out->h[1] ^= in->h[1]; out->h[2] ^= in->h[2]; out->h[3] ^= in->h[3]; out->h[4] ^= in->h[4]; } void cryptonite_sha1_transform(struct sha1_ctx* ctx, uint8_t block[SHA1_BLOCK_SIZE]) { cryptonite_sha1_update(ctx, block, SHA1_BLOCK_SIZE); } DECL_PBKDF2(sha1, SHA1_BLOCK_SIZE, SHA1_DIGEST_SIZE, struct sha1_ctx, cryptonite_sha1_init, cryptonite_sha1_update, cryptonite_sha1_transform, cryptonite_sha1_finalize, sha1_cpy, sha1_extract, sha1_xor); static inline void sha256_extract(struct sha256_ctx *restrict ctx, uint8_t *restrict out) { store_be32(out , ctx->h[0]); store_be32(out+4 , ctx->h[1]); store_be32(out+8 , ctx->h[2]); store_be32(out+12, ctx->h[3]); store_be32(out+16, ctx->h[4]); store_be32(out+20, ctx->h[5]); store_be32(out+24, ctx->h[6]); store_be32(out+28, ctx->h[7]); } static inline void sha256_cpy(struct sha256_ctx *restrict out, const struct sha256_ctx *restrict in) { out->h[0] = in->h[0]; out->h[1] = in->h[1]; out->h[2] = in->h[2]; out->h[3] = in->h[3]; out->h[4] = in->h[4]; out->h[5] = in->h[5]; out->h[6] = in->h[6]; out->h[7] = in->h[7]; } static inline void sha256_xor(struct sha256_ctx *restrict out, const struct sha256_ctx *restrict in) { out->h[0] ^= in->h[0]; out->h[1] ^= in->h[1]; out->h[2] ^= in->h[2]; out->h[3] ^= in->h[3]; out->h[4] ^= in->h[4]; out->h[5] ^= in->h[5]; out->h[6] ^= in->h[6]; out->h[7] ^= in->h[7]; } void cryptonite_sha256_transform(struct sha256_ctx* ctx, uint8_t block[SHA256_BLOCK_SIZE]) { cryptonite_sha256_update(ctx, block, SHA256_BLOCK_SIZE); } DECL_PBKDF2(sha256, SHA256_BLOCK_SIZE, SHA256_DIGEST_SIZE, struct sha256_ctx, cryptonite_sha256_init, cryptonite_sha256_update, cryptonite_sha256_transform, cryptonite_sha256_finalize, sha256_cpy, sha256_extract, sha256_xor); static inline void sha512_extract(struct sha512_ctx *restrict ctx, uint8_t *restrict out) { store_be64(out , ctx->h[0]); store_be64(out+8 , ctx->h[1]); store_be64(out+16, ctx->h[2]); store_be64(out+24, ctx->h[3]); store_be64(out+32, ctx->h[4]); store_be64(out+40, ctx->h[5]); store_be64(out+48, ctx->h[6]); store_be64(out+56, ctx->h[7]); } static inline void sha512_cpy(struct sha512_ctx *restrict out, const struct sha512_ctx *restrict in) { out->h[0] = in->h[0]; out->h[1] = in->h[1]; out->h[2] = in->h[2]; out->h[3] = in->h[3]; out->h[4] = in->h[4]; out->h[5] = in->h[5]; out->h[6] = in->h[6]; out->h[7] = in->h[7]; } static inline void sha512_xor(struct sha512_ctx *restrict out, const struct sha512_ctx *restrict in) { out->h[0] ^= in->h[0]; out->h[1] ^= in->h[1]; out->h[2] ^= in->h[2]; out->h[3] ^= in->h[3]; out->h[4] ^= in->h[4]; out->h[5] ^= in->h[5]; out->h[6] ^= in->h[6]; out->h[7] ^= in->h[7]; } void cryptonite_sha512_transform(struct sha512_ctx* ctx, uint8_t block[SHA512_BLOCK_SIZE]) { cryptonite_sha512_update(ctx, block, SHA512_BLOCK_SIZE); } DECL_PBKDF2(sha512, SHA512_BLOCK_SIZE, SHA512_DIGEST_SIZE, struct sha512_ctx, cryptonite_sha512_init, cryptonite_sha512_update, cryptonite_sha512_transform, cryptonite_sha512_finalize, sha512_cpy, sha512_extract, sha512_xor); void cryptonite_fastpbkdf2_hmac_sha1( const uint8_t *pw, size_t npw , const uint8_t *salt, size_t nsalt , uint32_t iterations , uint8_t *out, size_t nout ) { PBKDF2(sha1)(pw, npw, salt, nsalt, iterations, out, nout); } void cryptonite_fastpbkdf2_hmac_sha256( const uint8_t *pw, size_t npw , const uint8_t *salt, size_t nsalt , uint32_t iterations , uint8_t *out, size_t nout ) { PBKDF2(sha256)(pw, npw, salt, nsalt, iterations, out, nout); } void cryptonite_fastpbkdf2_hmac_sha512( const uint8_t *pw, size_t npw , const uint8_t *salt, size_t nsalt , uint32_t iterations , uint8_t *out, size_t nout ) { PBKDF2(sha512)(pw, npw, salt, nsalt, iterations, out, nout); } cryptonite-0.23/cbits/argon2/argon2.c0000644000000000000000000000772313054050744015667 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #include #include #include #include "argon2.h" #include "core.c" int cryptonite_argon2_ctx(argon2_context *context, argon2_type type) { /* 1. Validate all inputs */ int result = validate_inputs(context); uint32_t memory_blocks, segment_length; argon2_instance_t instance; if (ARGON2_OK != result) { return result; } if (Argon2_d != type && Argon2_i != type && Argon2_id != type) { return ARGON2_INCORRECT_TYPE; } /* 2. Align memory size */ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ memory_blocks = context->m_cost; if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; } segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); /* Ensure that all segments have equal length */ memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); instance.version = context->version; instance.memory = NULL; instance.passes = context->t_cost; instance.memory_blocks = memory_blocks; instance.segment_length = segment_length; instance.lane_length = segment_length * ARGON2_SYNC_POINTS; instance.lanes = context->lanes; instance.threads = context->threads; instance.type = type; /* 3. Initialization: Hashing inputs, allocating memory, filling first * blocks */ result = initialize(&instance, context); if (ARGON2_OK != result) { return result; } /* 4. Filling memory */ result = fill_memory_blocks(&instance); if (ARGON2_OK != result) { return result; } /* 5. Finalization */ finalize(context, &instance); return ARGON2_OK; } int cryptonite_argon2_hash(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, const size_t saltlen, void *hash, const size_t hashlen, argon2_type type, const uint32_t version){ argon2_context context; int result; uint8_t *out; if (hashlen > ARGON2_MAX_OUTLEN) { return ARGON2_OUTPUT_TOO_LONG; } if (hashlen < ARGON2_MIN_OUTLEN) { return ARGON2_OUTPUT_TOO_SHORT; } out = malloc(hashlen); if (!out) { return ARGON2_MEMORY_ALLOCATION_ERROR; } context.out = (uint8_t *)out; context.outlen = (uint32_t)hashlen; context.pwd = CONST_CAST(uint8_t *)pwd; context.pwdlen = (uint32_t)pwdlen; context.salt = CONST_CAST(uint8_t *)salt; context.saltlen = (uint32_t)saltlen; context.secret = NULL; context.secretlen = 0; context.ad = NULL; context.adlen = 0; context.t_cost = t_cost; context.m_cost = m_cost; context.lanes = parallelism; context.threads = parallelism; context.allocate_cbk = NULL; context.free_cbk = NULL; context.flags = ARGON2_DEFAULT_FLAGS; context.version = version; result = cryptonite_argon2_ctx(&context, type); if (result != ARGON2_OK) { clear_internal_memory(out, hashlen); free(out); return result; } /* if raw hash requested, write it */ if (hash) { memcpy(hash, out, hashlen); } clear_internal_memory(out, hashlen); free(out); return ARGON2_OK; } cryptonite-0.23/cbits/curve25519/curve25519-donna-c64.c0000644000000000000000000003227112723504474020264 0ustar0000000000000000/* Copyright 2008, Google Inc. * All rights reserved. * * Code released into the public domain. * * curve25519-donna: Curve25519 elliptic curve, public key function * * http://code.google.com/p/curve25519-donna/ * * Adam Langley * * Derived from public domain C code by Daniel J. Bernstein * * More information about curve25519 can be found here * http://cr.yp.to/ecdh.html * * djb's sample implementation of curve25519 is written in a special assembly * language called qhasm and uses the floating point registers. * * This is, almost, a clean room reimplementation from the curve25519 paper. It * uses many of the tricks described therein. Only the crecip function is taken * from the sample implementation. */ #include #include typedef uint8_t u8; typedef uint64_t limb; typedef limb felem[5]; // This is a special gcc mode for 128-bit integers. It's implemented on 64-bit // platforms only as far as I know. typedef unsigned uint128_t __attribute__((mode(TI))); #undef force_inline #define force_inline __attribute__((always_inline)) /* Sum two numbers: output += in */ static inline void force_inline fsum(limb *output, const limb *in) { output[0] += in[0]; output[1] += in[1]; output[2] += in[2]; output[3] += in[3]; output[4] += in[4]; } /* Find the difference of two numbers: output = in - output * (note the order of the arguments!) * * Assumes that out[i] < 2**52 * On return, out[i] < 2**55 */ static inline void force_inline fdifference_backwards(felem out, const felem in) { /* 152 is 19 << 3 */ static const limb two54m152 = (((limb)1) << 54) - 152; static const limb two54m8 = (((limb)1) << 54) - 8; out[0] = in[0] + two54m152 - out[0]; out[1] = in[1] + two54m8 - out[1]; out[2] = in[2] + two54m8 - out[2]; out[3] = in[3] + two54m8 - out[3]; out[4] = in[4] + two54m8 - out[4]; } /* Multiply a number by a scalar: output = in * scalar */ static inline void force_inline fscalar_product(felem output, const felem in, const limb scalar) { uint128_t a; a = ((uint128_t) in[0]) * scalar; output[0] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[1]) * scalar + ((limb) (a >> 51)); output[1] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[2]) * scalar + ((limb) (a >> 51)); output[2] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[3]) * scalar + ((limb) (a >> 51)); output[3] = ((limb)a) & 0x7ffffffffffff; a = ((uint128_t) in[4]) * scalar + ((limb) (a >> 51)); output[4] = ((limb)a) & 0x7ffffffffffff; output[0] += (a >> 51) * 19; } /* Multiply two numbers: output = in2 * in * * output must be distinct to both inputs. The inputs are reduced coefficient * form, the output is not. * * Assumes that in[i] < 2**55 and likewise for in2. * On return, output[i] < 2**52 */ static inline void force_inline fmul(felem output, const felem in2, const felem in) { uint128_t t[5]; limb r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; s0 = in2[0]; s1 = in2[1]; s2 = in2[2]; s3 = in2[3]; s4 = in2[4]; t[0] = ((uint128_t) r0) * s0; t[1] = ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0; t[2] = ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * s1; t[3] = ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * s2 + ((uint128_t) r2) * s1; t[4] = ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2; r4 *= 19; r1 *= 19; r2 *= 19; r3 *= 19; t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * s3 + ((uint128_t) r3) * s2; t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * s3; t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4; t[3] += ((uint128_t) r4) * s4; r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51); t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51); t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51); t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51); t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51); r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff; r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffff; r2 += c; output[0] = r0; output[1] = r1; output[2] = r2; output[3] = r3; output[4] = r4; } static inline void force_inline fsquare_times(felem output, const felem in, limb count) { uint128_t t[5]; limb r0,r1,r2,r3,r4,c; limb d0,d1,d2,d4,d419; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; do { d0 = r0 * 2; d1 = r1 * 2; d2 = r2 * 2 * 19; d419 = r4 * 19; d4 = d419 * 2; t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 )); t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19)); t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 )); t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 )); t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 )); r0 = (limb)t[0] & 0x7ffffffffffff; c = (limb)(t[0] >> 51); t[1] += c; r1 = (limb)t[1] & 0x7ffffffffffff; c = (limb)(t[1] >> 51); t[2] += c; r2 = (limb)t[2] & 0x7ffffffffffff; c = (limb)(t[2] >> 51); t[3] += c; r3 = (limb)t[3] & 0x7ffffffffffff; c = (limb)(t[3] >> 51); t[4] += c; r4 = (limb)t[4] & 0x7ffffffffffff; c = (limb)(t[4] >> 51); r0 += c * 19; c = r0 >> 51; r0 = r0 & 0x7ffffffffffff; r1 += c; c = r1 >> 51; r1 = r1 & 0x7ffffffffffff; r2 += c; } while(--count); output[0] = r0; output[1] = r1; output[2] = r2; output[3] = r3; output[4] = r4; } /* Load a little-endian 64-bit number */ static limb load_limb(const u8 *in) { return ((limb)in[0]) | (((limb)in[1]) << 8) | (((limb)in[2]) << 16) | (((limb)in[3]) << 24) | (((limb)in[4]) << 32) | (((limb)in[5]) << 40) | (((limb)in[6]) << 48) | (((limb)in[7]) << 56); } static void store_limb(u8 *out, limb in) { out[0] = in & 0xff; out[1] = (in >> 8) & 0xff; out[2] = (in >> 16) & 0xff; out[3] = (in >> 24) & 0xff; out[4] = (in >> 32) & 0xff; out[5] = (in >> 40) & 0xff; out[6] = (in >> 48) & 0xff; out[7] = (in >> 56) & 0xff; } /* Take a little-endian, 32-byte number and expand it into polynomial form */ static void fexpand(limb *output, const u8 *in) { output[0] = load_limb(in) & 0x7ffffffffffff; output[1] = (load_limb(in+6) >> 3) & 0x7ffffffffffff; output[2] = (load_limb(in+12) >> 6) & 0x7ffffffffffff; output[3] = (load_limb(in+19) >> 1) & 0x7ffffffffffff; output[4] = (load_limb(in+24) >> 12) & 0x7ffffffffffff; } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array */ static void fcontract(u8 *output, const felem input) { uint128_t t[5]; t[0] = input[0]; t[1] = input[1]; t[2] = input[2]; t[3] = input[3]; t[4] = input[4]; t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff; t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff; /* now t is between 0 and 2^255-1, properly carried. */ /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ t[0] += 19; t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[0] += 19 * (t[4] >> 51); t[4] &= 0x7ffffffffffff; /* now between 19 and 2^255-1 in both cases, and offset by 19. */ t[0] += 0x8000000000000 - 19; t[1] += 0x8000000000000 - 1; t[2] += 0x8000000000000 - 1; t[3] += 0x8000000000000 - 1; t[4] += 0x8000000000000 - 1; /* now between 2^255 and 2^256-20, and offset by 2^255. */ t[1] += t[0] >> 51; t[0] &= 0x7ffffffffffff; t[2] += t[1] >> 51; t[1] &= 0x7ffffffffffff; t[3] += t[2] >> 51; t[2] &= 0x7ffffffffffff; t[4] += t[3] >> 51; t[3] &= 0x7ffffffffffff; t[4] &= 0x7ffffffffffff; store_limb(output, t[0] | (t[1] << 51)); store_limb(output+8, (t[1] >> 13) | (t[2] << 38)); store_limb(output+16, (t[2] >> 26) | (t[3] << 25)); store_limb(output+24, (t[3] >> 39) | (t[4] << 12)); } /* Input: Q, Q', Q-Q' * Output: 2Q, Q+Q' * * x2 z3: long form * x3 z3: long form * x z: short form, destroyed * xprime zprime: short form, destroyed * qmqp: short form, preserved */ static void fmonty(limb *x2, limb *z2, /* output 2Q */ limb *x3, limb *z3, /* output Q + Q' */ limb *x, limb *z, /* input Q */ limb *xprime, limb *zprime, /* input Q' */ const limb *qmqp /* input Q - Q' */) { limb origx[5], origxprime[5], zzz[5], xx[5], zz[5], xxprime[5], zzprime[5], zzzprime[5]; memcpy(origx, x, 5 * sizeof(limb)); fsum(x, z); fdifference_backwards(z, origx); // does x - z memcpy(origxprime, xprime, sizeof(limb) * 5); fsum(xprime, zprime); fdifference_backwards(zprime, origxprime); fmul(xxprime, xprime, z); fmul(zzprime, x, zprime); memcpy(origxprime, xxprime, sizeof(limb) * 5); fsum(xxprime, zzprime); fdifference_backwards(zzprime, origxprime); fsquare_times(x3, xxprime, 1); fsquare_times(zzzprime, zzprime, 1); fmul(z3, zzzprime, qmqp); fsquare_times(xx, x, 1); fsquare_times(zz, z, 1); fmul(x2, xx, zz); fdifference_backwards(zz, xx); // does zz = xx - zz fscalar_product(zzz, zz, 121665); fsum(zzz, xx); fmul(z2, zz, zzz); } // ----------------------------------------------------------------------------- // Maybe swap the contents of two limb arrays (@a and @b), each @len elements // long. Perform the swap iff @swap is non-zero. // // This function performs the swap without leaking any side-channel // information. // ----------------------------------------------------------------------------- static void swap_conditional(limb a[5], limb b[5], limb iswap) { unsigned i; const limb swap = -iswap; for (i = 0; i < 5; ++i) { const limb x = swap & (a[i] ^ b[i]); a[i] ^= x; b[i] ^= x; } } /* Calculates nQ where Q is the x-coordinate of a point on the curve * * resultx/resultz: the x coordinate of the resulting curve point (short form) * n: a little endian, 32-byte number * q: a point of the curve (short form) */ static void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) { limb a[5] = {0}, b[5] = {1}, c[5] = {1}, d[5] = {0}; limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; limb e[5] = {0}, f[5] = {1}, g[5] = {0}, h[5] = {1}; limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; unsigned i, j; memcpy(nqpqx, q, sizeof(limb) * 5); for (i = 0; i < 32; ++i) { u8 byte = n[31 - i]; for (j = 0; j < 8; ++j) { const limb bit = byte >> 7; swap_conditional(nqx, nqpqx, bit); swap_conditional(nqz, nqpqz, bit); fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q); swap_conditional(nqx2, nqpqx2, bit); swap_conditional(nqz2, nqpqz2, bit); t = nqx; nqx = nqx2; nqx2 = t; t = nqz; nqz = nqz2; nqz2 = t; t = nqpqx; nqpqx = nqpqx2; nqpqx2 = t; t = nqpqz; nqpqz = nqpqz2; nqpqz2 = t; byte <<= 1; } } memcpy(resultx, nqx, sizeof(limb) * 5); memcpy(resultz, nqz, sizeof(limb) * 5); } // ----------------------------------------------------------------------------- // Shamelessly copied from djb's code, tightened a little // ----------------------------------------------------------------------------- static void crecip(felem out, const felem z) { felem a,t0,b,c; /* 2 */ fsquare_times(a, z, 1); // a = 2 /* 8 */ fsquare_times(t0, a, 2); /* 9 */ fmul(b, t0, z); // b = 9 /* 11 */ fmul(a, b, a); // a = 11 /* 22 */ fsquare_times(t0, a, 1); /* 2^5 - 2^0 = 31 */ fmul(b, t0, b); /* 2^10 - 2^5 */ fsquare_times(t0, b, 5); /* 2^10 - 2^0 */ fmul(b, t0, b); /* 2^20 - 2^10 */ fsquare_times(t0, b, 10); /* 2^20 - 2^0 */ fmul(c, t0, b); /* 2^40 - 2^20 */ fsquare_times(t0, c, 20); /* 2^40 - 2^0 */ fmul(t0, t0, c); /* 2^50 - 2^10 */ fsquare_times(t0, t0, 10); /* 2^50 - 2^0 */ fmul(b, t0, b); /* 2^100 - 2^50 */ fsquare_times(t0, b, 50); /* 2^100 - 2^0 */ fmul(c, t0, b); /* 2^200 - 2^100 */ fsquare_times(t0, c, 100); /* 2^200 - 2^0 */ fmul(t0, t0, c); /* 2^250 - 2^50 */ fsquare_times(t0, t0, 50); /* 2^250 - 2^0 */ fmul(t0, t0, b); /* 2^255 - 2^5 */ fsquare_times(t0, t0, 5); /* 2^255 - 21 */ fmul(out, t0, a); } int cryptonite_curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { limb bp[5], x[5], z[5], zmone[5]; uint8_t e[32]; int i; for (i = 0;i < 32;++i) e[i] = secret[i]; e[0] &= 248; e[31] &= 127; e[31] |= 64; fexpand(bp, basepoint); cmult(x, z, e, bp); crecip(zmone, z); fmul(z, x, zmone); fcontract(mypublic, z); return 0; } cryptonite-0.23/cbits/curve25519/curve25519-donna.c0000644000000000000000000007573612462144657017712 0ustar0000000000000000/* Copyright 2008, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * curve25519-donna: Curve25519 elliptic curve, public key function * * http://code.google.com/p/curve25519-donna/ * * Adam Langley * * Derived from public domain C code by Daniel J. Bernstein * * More information about curve25519 can be found here * http://cr.yp.to/ecdh.html * * djb's sample implementation of curve25519 is written in a special assembly * language called qhasm and uses the floating point registers. * * This is, almost, a clean room reimplementation from the curve25519 paper. It * uses many of the tricks described therein. Only the crecip function is taken * from the sample implementation. */ #include #include #ifdef _MSC_VER #define inline __inline #endif typedef uint8_t u8; typedef int32_t s32; typedef int64_t limb; /* Field element representation: * * Field elements are written as an array of signed, 64-bit limbs, least * significant first. The value of the field element is: * x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ... * * i.e. the limbs are 26, 25, 26, 25, ... bits wide. */ /* Sum two numbers: output += in */ static void fsum(limb *output, const limb *in) { unsigned i; for (i = 0; i < 10; i += 2) { output[0+i] = output[0+i] + in[0+i]; output[1+i] = output[1+i] + in[1+i]; } } /* Find the difference of two numbers: output = in - output * (note the order of the arguments!). */ static void fdifference(limb *output, const limb *in) { unsigned i; for (i = 0; i < 10; ++i) { output[i] = in[i] - output[i]; } } /* Multiply a number by a scalar: output = in * scalar */ static void fscalar_product(limb *output, const limb *in, const limb scalar) { unsigned i; for (i = 0; i < 10; ++i) { output[i] = in[i] * scalar; } } /* Multiply two numbers: output = in2 * in * * output must be distinct to both inputs. The inputs are reduced coefficient * form, the output is not. * * output[x] <= 14 * the largest product of the input limbs. */ static void fproduct(limb *output, const limb *in2, const limb *in) { output[0] = ((limb) ((s32) in2[0])) * ((s32) in[0]); output[1] = ((limb) ((s32) in2[0])) * ((s32) in[1]) + ((limb) ((s32) in2[1])) * ((s32) in[0]); output[2] = 2 * ((limb) ((s32) in2[1])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[2]) + ((limb) ((s32) in2[2])) * ((s32) in[0]); output[3] = ((limb) ((s32) in2[1])) * ((s32) in[2]) + ((limb) ((s32) in2[2])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[3]) + ((limb) ((s32) in2[3])) * ((s32) in[0]); output[4] = ((limb) ((s32) in2[2])) * ((s32) in[2]) + 2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) + ((limb) ((s32) in2[3])) * ((s32) in[1])) + ((limb) ((s32) in2[0])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[0]); output[5] = ((limb) ((s32) in2[2])) * ((s32) in[3]) + ((limb) ((s32) in2[3])) * ((s32) in[2]) + ((limb) ((s32) in2[1])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[0]); output[6] = 2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) + ((limb) ((s32) in2[1])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[1])) + ((limb) ((s32) in2[2])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[2]) + ((limb) ((s32) in2[0])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[0]); output[7] = ((limb) ((s32) in2[3])) * ((s32) in[4]) + ((limb) ((s32) in2[4])) * ((s32) in[3]) + ((limb) ((s32) in2[2])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[2]) + ((limb) ((s32) in2[1])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[0]); output[8] = ((limb) ((s32) in2[4])) * ((s32) in[4]) + 2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[3]) + ((limb) ((s32) in2[1])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[1])) + ((limb) ((s32) in2[2])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[2]) + ((limb) ((s32) in2[0])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[0]); output[9] = ((limb) ((s32) in2[4])) * ((s32) in[5]) + ((limb) ((s32) in2[5])) * ((s32) in[4]) + ((limb) ((s32) in2[3])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[3]) + ((limb) ((s32) in2[2])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[2]) + ((limb) ((s32) in2[1])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[1]) + ((limb) ((s32) in2[0])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[0]); output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) + ((limb) ((s32) in2[3])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[3]) + ((limb) ((s32) in2[1])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[1])) + ((limb) ((s32) in2[4])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[4]) + ((limb) ((s32) in2[2])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[2]); output[11] = ((limb) ((s32) in2[5])) * ((s32) in[6]) + ((limb) ((s32) in2[6])) * ((s32) in[5]) + ((limb) ((s32) in2[4])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[4]) + ((limb) ((s32) in2[3])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[3]) + ((limb) ((s32) in2[2])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[2]); output[12] = ((limb) ((s32) in2[6])) * ((s32) in[6]) + 2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[5]) + ((limb) ((s32) in2[3])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[3])) + ((limb) ((s32) in2[4])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[4]); output[13] = ((limb) ((s32) in2[6])) * ((s32) in[7]) + ((limb) ((s32) in2[7])) * ((s32) in[6]) + ((limb) ((s32) in2[5])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[5]) + ((limb) ((s32) in2[4])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[4]); output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) + ((limb) ((s32) in2[5])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[5])) + ((limb) ((s32) in2[6])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[6]); output[15] = ((limb) ((s32) in2[7])) * ((s32) in[8]) + ((limb) ((s32) in2[8])) * ((s32) in[7]) + ((limb) ((s32) in2[6])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[6]); output[16] = ((limb) ((s32) in2[8])) * ((s32) in[8]) + 2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[7])); output[17] = ((limb) ((s32) in2[8])) * ((s32) in[9]) + ((limb) ((s32) in2[9])) * ((s32) in[8]); output[18] = 2 * ((limb) ((s32) in2[9])) * ((s32) in[9]); } /* Reduce a long form to a short form by taking the input mod 2^255 - 19. * * On entry: |output[i]| < 14*2^54 * On exit: |output[0..8]| < 280*2^54 */ static void freduce_degree(limb *output) { /* Each of these shifts and adds ends up multiplying the value by 19. * * For output[0..8], the absolute entry value is < 14*2^54 and we add, at * most, 19*14*2^54 thus, on exit, |output[0..8]| < 280*2^54. */ output[8] += output[18] << 4; output[8] += output[18] << 1; output[8] += output[18]; output[7] += output[17] << 4; output[7] += output[17] << 1; output[7] += output[17]; output[6] += output[16] << 4; output[6] += output[16] << 1; output[6] += output[16]; output[5] += output[15] << 4; output[5] += output[15] << 1; output[5] += output[15]; output[4] += output[14] << 4; output[4] += output[14] << 1; output[4] += output[14]; output[3] += output[13] << 4; output[3] += output[13] << 1; output[3] += output[13]; output[2] += output[12] << 4; output[2] += output[12] << 1; output[2] += output[12]; output[1] += output[11] << 4; output[1] += output[11] << 1; output[1] += output[11]; output[0] += output[10] << 4; output[0] += output[10] << 1; output[0] += output[10]; } #if (-1 & 3) != 3 #error "This code only works on a two's complement system" #endif /* return v / 2^26, using only shifts and adds. * * On entry: v can take any value. */ static inline limb div_by_2_26(const limb v) { /* High word of v; no shift needed. */ const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); /* Set to all 1s if v was negative; else set to 0s. */ const int32_t sign = ((int32_t) highword) >> 31; /* Set to 0x3ffffff if v was negative; else set to 0. */ const int32_t roundoff = ((uint32_t) sign) >> 6; /* Should return v / (1<<26) */ return (v + roundoff) >> 26; } /* return v / (2^25), using only shifts and adds. * * On entry: v can take any value. */ static inline limb div_by_2_25(const limb v) { /* High word of v; no shift needed*/ const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32); /* Set to all 1s if v was negative; else set to 0s. */ const int32_t sign = ((int32_t) highword) >> 31; /* Set to 0x1ffffff if v was negative; else set to 0. */ const int32_t roundoff = ((uint32_t) sign) >> 7; /* Should return v / (1<<25) */ return (v + roundoff) >> 25; } /* Reduce all coefficients of the short form input so that |x| < 2^26. * * On entry: |output[i]| < 280*2^54 */ static void freduce_coefficients(limb *output) { unsigned i; output[10] = 0; for (i = 0; i < 10; i += 2) { limb over = div_by_2_26(output[i]); /* The entry condition (that |output[i]| < 280*2^54) means that over is, at * most, 280*2^28 in the first iteration of this loop. This is added to the * next limb and we can approximate the resulting bound of that limb by * 281*2^54. */ output[i] -= over << 26; output[i+1] += over; /* For the first iteration, |output[i+1]| < 281*2^54, thus |over| < * 281*2^29. When this is added to the next limb, the resulting bound can * be approximated as 281*2^54. * * For subsequent iterations of the loop, 281*2^54 remains a conservative * bound and no overflow occurs. */ over = div_by_2_25(output[i+1]); output[i+1] -= over << 25; output[i+2] += over; } /* Now |output[10]| < 281*2^29 and all other coefficients are reduced. */ output[0] += output[10] << 4; output[0] += output[10] << 1; output[0] += output[10]; output[10] = 0; /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19*281*2^29 * So |over| will be no more than 2^16. */ { limb over = div_by_2_26(output[0]); output[0] -= over << 26; output[1] += over; } /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 2^16 < 2^26. The * bound on |output[1]| is sufficient to meet our needs. */ } /* A helpful wrapper around fproduct: output = in * in2. * * On entry: |in[i]| < 2^27 and |in2[i]| < 2^27. * * output must be distinct to both inputs. The output is reduced degree * (indeed, one need only provide storage for 10 limbs) and |output[i]| < 2^26. */ static void fmul(limb *output, const limb *in, const limb *in2) { limb t[19]; fproduct(t, in, in2); /* |t[i]| < 14*2^54 */ freduce_degree(t); freduce_coefficients(t); /* |t[i]| < 2^26 */ memcpy(output, t, sizeof(limb) * 10); } /* Square a number: output = in**2 * * output must be distinct from the input. The inputs are reduced coefficient * form, the output is not. * * output[x] <= 14 * the largest product of the input limbs. */ static void fsquare_inner(limb *output, const limb *in) { output[0] = ((limb) ((s32) in[0])) * ((s32) in[0]); output[1] = 2 * ((limb) ((s32) in[0])) * ((s32) in[1]); output[2] = 2 * (((limb) ((s32) in[1])) * ((s32) in[1]) + ((limb) ((s32) in[0])) * ((s32) in[2])); output[3] = 2 * (((limb) ((s32) in[1])) * ((s32) in[2]) + ((limb) ((s32) in[0])) * ((s32) in[3])); output[4] = ((limb) ((s32) in[2])) * ((s32) in[2]) + 4 * ((limb) ((s32) in[1])) * ((s32) in[3]) + 2 * ((limb) ((s32) in[0])) * ((s32) in[4]); output[5] = 2 * (((limb) ((s32) in[2])) * ((s32) in[3]) + ((limb) ((s32) in[1])) * ((s32) in[4]) + ((limb) ((s32) in[0])) * ((s32) in[5])); output[6] = 2 * (((limb) ((s32) in[3])) * ((s32) in[3]) + ((limb) ((s32) in[2])) * ((s32) in[4]) + ((limb) ((s32) in[0])) * ((s32) in[6]) + 2 * ((limb) ((s32) in[1])) * ((s32) in[5])); output[7] = 2 * (((limb) ((s32) in[3])) * ((s32) in[4]) + ((limb) ((s32) in[2])) * ((s32) in[5]) + ((limb) ((s32) in[1])) * ((s32) in[6]) + ((limb) ((s32) in[0])) * ((s32) in[7])); output[8] = ((limb) ((s32) in[4])) * ((s32) in[4]) + 2 * (((limb) ((s32) in[2])) * ((s32) in[6]) + ((limb) ((s32) in[0])) * ((s32) in[8]) + 2 * (((limb) ((s32) in[1])) * ((s32) in[7]) + ((limb) ((s32) in[3])) * ((s32) in[5]))); output[9] = 2 * (((limb) ((s32) in[4])) * ((s32) in[5]) + ((limb) ((s32) in[3])) * ((s32) in[6]) + ((limb) ((s32) in[2])) * ((s32) in[7]) + ((limb) ((s32) in[1])) * ((s32) in[8]) + ((limb) ((s32) in[0])) * ((s32) in[9])); output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) + ((limb) ((s32) in[4])) * ((s32) in[6]) + ((limb) ((s32) in[2])) * ((s32) in[8]) + 2 * (((limb) ((s32) in[3])) * ((s32) in[7]) + ((limb) ((s32) in[1])) * ((s32) in[9]))); output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) + ((limb) ((s32) in[4])) * ((s32) in[7]) + ((limb) ((s32) in[3])) * ((s32) in[8]) + ((limb) ((s32) in[2])) * ((s32) in[9])); output[12] = ((limb) ((s32) in[6])) * ((s32) in[6]) + 2 * (((limb) ((s32) in[4])) * ((s32) in[8]) + 2 * (((limb) ((s32) in[5])) * ((s32) in[7]) + ((limb) ((s32) in[3])) * ((s32) in[9]))); output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) + ((limb) ((s32) in[5])) * ((s32) in[8]) + ((limb) ((s32) in[4])) * ((s32) in[9])); output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) + ((limb) ((s32) in[6])) * ((s32) in[8]) + 2 * ((limb) ((s32) in[5])) * ((s32) in[9])); output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) + ((limb) ((s32) in[6])) * ((s32) in[9])); output[16] = ((limb) ((s32) in[8])) * ((s32) in[8]) + 4 * ((limb) ((s32) in[7])) * ((s32) in[9]); output[17] = 2 * ((limb) ((s32) in[8])) * ((s32) in[9]); output[18] = 2 * ((limb) ((s32) in[9])) * ((s32) in[9]); } /* fsquare sets output = in^2. * * On entry: The |in| argument is in reduced coefficients form and |in[i]| < * 2^27. * * On exit: The |output| argument is in reduced coefficients form (indeed, one * need only provide storage for 10 limbs) and |out[i]| < 2^26. */ static void fsquare(limb *output, const limb *in) { limb t[19]; fsquare_inner(t, in); /* |t[i]| < 14*2^54 because the largest product of two limbs will be < * 2^(27+27) and fsquare_inner adds together, at most, 14 of those * products. */ freduce_degree(t); freduce_coefficients(t); /* |t[i]| < 2^26 */ memcpy(output, t, sizeof(limb) * 10); } /* Take a little-endian, 32-byte number and expand it into polynomial form */ static void fexpand(limb *output, const u8 *input) { #define F(n,start,shift,mask) \ output[n] = ((((limb) input[start + 0]) | \ ((limb) input[start + 1]) << 8 | \ ((limb) input[start + 2]) << 16 | \ ((limb) input[start + 3]) << 24) >> shift) & mask; F(0, 0, 0, 0x3ffffff); F(1, 3, 2, 0x1ffffff); F(2, 6, 3, 0x3ffffff); F(3, 9, 5, 0x1ffffff); F(4, 12, 6, 0x3ffffff); F(5, 16, 0, 0x1ffffff); F(6, 19, 1, 0x3ffffff); F(7, 22, 3, 0x1ffffff); F(8, 25, 4, 0x3ffffff); F(9, 28, 6, 0x1ffffff); #undef F } #if (-32 >> 1) != -16 #error "This code only works when >> does sign-extension on negative numbers" #endif /* s32_eq returns 0xffffffff iff a == b and zero otherwise. */ static s32 s32_eq(s32 a, s32 b) { a = ~(a ^ b); a &= a << 16; a &= a << 8; a &= a << 4; a &= a << 2; a &= a << 1; return a >> 31; } /* s32_gte returns 0xffffffff if a >= b and zero otherwise, where a and b are * both non-negative. */ static s32 s32_gte(s32 a, s32 b) { a -= b; /* a >= 0 iff a >= b. */ return ~(a >> 31); } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array. * * On entry: |input_limbs[i]| < 2^26 */ static void fcontract(u8 *output, limb *input_limbs) { int i; int j; s32 input[10]; s32 mask; /* |input_limbs[i]| < 2^26, so it's valid to convert to an s32. */ for (i = 0; i < 10; i++) { input[i] = input_limbs[i]; } for (j = 0; j < 2; ++j) { for (i = 0; i < 9; ++i) { if ((i & 1) == 1) { /* This calculation is a time-invariant way to make input[i] * non-negative by borrowing from the next-larger limb. */ const s32 mask = input[i] >> 31; const s32 carry = -((input[i] & mask) >> 25); input[i] = input[i] + (carry << 25); input[i+1] = input[i+1] - carry; } else { const s32 mask = input[i] >> 31; const s32 carry = -((input[i] & mask) >> 26); input[i] = input[i] + (carry << 26); input[i+1] = input[i+1] - carry; } } /* There's no greater limb for input[9] to borrow from, but we can multiply * by 19 and borrow from input[0], which is valid mod 2^255-19. */ { const s32 mask = input[9] >> 31; const s32 carry = -((input[9] & mask) >> 25); input[9] = input[9] + (carry << 25); input[0] = input[0] - (carry * 19); } /* After the first iteration, input[1..9] are non-negative and fit within * 25 or 26 bits, depending on position. However, input[0] may be * negative. */ } /* The first borrow-propagation pass above ended with every limb except (possibly) input[0] non-negative. If input[0] was negative after the first pass, then it was because of a carry from input[9]. On entry, input[9] < 2^26 so the carry was, at most, one, since (2**26-1) >> 25 = 1. Thus input[0] >= -19. In the second pass, each limb is decreased by at most one. Thus the second borrow-propagation pass could only have wrapped around to decrease input[0] again if the first pass left input[0] negative *and* input[1] through input[9] were all zero. In that case, input[1] is now 2^25 - 1, and this last borrow-propagation step will leave input[1] non-negative. */ { const s32 mask = input[0] >> 31; const s32 carry = -((input[0] & mask) >> 26); input[0] = input[0] + (carry << 26); input[1] = input[1] - carry; } /* All input[i] are now non-negative. However, there might be values between * 2^25 and 2^26 in a limb which is, nominally, 25 bits wide. */ for (j = 0; j < 2; j++) { for (i = 0; i < 9; i++) { if ((i & 1) == 1) { const s32 carry = input[i] >> 25; input[i] &= 0x1ffffff; input[i+1] += carry; } else { const s32 carry = input[i] >> 26; input[i] &= 0x3ffffff; input[i+1] += carry; } } { const s32 carry = input[9] >> 25; input[9] &= 0x1ffffff; input[0] += 19*carry; } } /* If the first carry-chain pass, just above, ended up with a carry from * input[9], and that caused input[0] to be out-of-bounds, then input[0] was * < 2^26 + 2*19, because the carry was, at most, two. * * If the second pass carried from input[9] again then input[0] is < 2*19 and * the input[9] -> input[0] carry didn't push input[0] out of bounds. */ /* It still remains the case that input might be between 2^255-19 and 2^255. * In this case, input[1..9] must take their maximum value and input[0] must * be >= (2^255-19) & 0x3ffffff, which is 0x3ffffed. */ mask = s32_gte(input[0], 0x3ffffed); for (i = 1; i < 10; i++) { if ((i & 1) == 1) { mask &= s32_eq(input[i], 0x1ffffff); } else { mask &= s32_eq(input[i], 0x3ffffff); } } /* mask is either 0xffffffff (if input >= 2^255-19) and zero otherwise. Thus * this conditionally subtracts 2^255-19. */ input[0] -= mask & 0x3ffffed; for (i = 1; i < 10; i++) { if ((i & 1) == 1) { input[i] -= mask & 0x1ffffff; } else { input[i] -= mask & 0x3ffffff; } } input[1] <<= 2; input[2] <<= 3; input[3] <<= 5; input[4] <<= 6; input[6] <<= 1; input[7] <<= 3; input[8] <<= 4; input[9] <<= 6; #define F(i, s) \ output[s+0] |= input[i] & 0xff; \ output[s+1] = (input[i] >> 8) & 0xff; \ output[s+2] = (input[i] >> 16) & 0xff; \ output[s+3] = (input[i] >> 24) & 0xff; output[0] = 0; output[16] = 0; F(0,0); F(1,3); F(2,6); F(3,9); F(4,12); F(5,16); F(6,19); F(7,22); F(8,25); F(9,28); #undef F } /* Input: Q, Q', Q-Q' * Output: 2Q, Q+Q' * * x2 z3: long form * x3 z3: long form * x z: short form, destroyed * xprime zprime: short form, destroyed * qmqp: short form, preserved * * On entry and exit, the absolute value of the limbs of all inputs and outputs * are < 2^26. */ static void fmonty(limb *x2, limb *z2, /* output 2Q */ limb *x3, limb *z3, /* output Q + Q' */ limb *x, limb *z, /* input Q */ limb *xprime, limb *zprime, /* input Q' */ const limb *qmqp /* input Q - Q' */) { limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19], zzprime[19], zzzprime[19], xxxprime[19]; memcpy(origx, x, 10 * sizeof(limb)); fsum(x, z); /* |x[i]| < 2^27 */ fdifference(z, origx); /* does x - z */ /* |z[i]| < 2^27 */ memcpy(origxprime, xprime, sizeof(limb) * 10); fsum(xprime, zprime); /* |xprime[i]| < 2^27 */ fdifference(zprime, origxprime); /* |zprime[i]| < 2^27 */ fproduct(xxprime, xprime, z); /* |xxprime[i]| < 14*2^54: the largest product of two limbs will be < * 2^(27+27) and fproduct adds together, at most, 14 of those products. * (Approximating that to 2^58 doesn't work out.) */ fproduct(zzprime, x, zprime); /* |zzprime[i]| < 14*2^54 */ freduce_degree(xxprime); freduce_coefficients(xxprime); /* |xxprime[i]| < 2^26 */ freduce_degree(zzprime); freduce_coefficients(zzprime); /* |zzprime[i]| < 2^26 */ memcpy(origxprime, xxprime, sizeof(limb) * 10); fsum(xxprime, zzprime); /* |xxprime[i]| < 2^27 */ fdifference(zzprime, origxprime); /* |zzprime[i]| < 2^27 */ fsquare(xxxprime, xxprime); /* |xxxprime[i]| < 2^26 */ fsquare(zzzprime, zzprime); /* |zzzprime[i]| < 2^26 */ fproduct(zzprime, zzzprime, qmqp); /* |zzprime[i]| < 14*2^52 */ freduce_degree(zzprime); freduce_coefficients(zzprime); /* |zzprime[i]| < 2^26 */ memcpy(x3, xxxprime, sizeof(limb) * 10); memcpy(z3, zzprime, sizeof(limb) * 10); fsquare(xx, x); /* |xx[i]| < 2^26 */ fsquare(zz, z); /* |zz[i]| < 2^26 */ fproduct(x2, xx, zz); /* |x2[i]| < 14*2^52 */ freduce_degree(x2); freduce_coefficients(x2); /* |x2[i]| < 2^26 */ fdifference(zz, xx); // does zz = xx - zz /* |zz[i]| < 2^27 */ memset(zzz + 10, 0, sizeof(limb) * 9); fscalar_product(zzz, zz, 121665); /* |zzz[i]| < 2^(27+17) */ /* No need to call freduce_degree here: fscalar_product doesn't increase the degree of its input. */ freduce_coefficients(zzz); /* |zzz[i]| < 2^26 */ fsum(zzz, xx); /* |zzz[i]| < 2^27 */ fproduct(z2, zz, zzz); /* |z2[i]| < 14*2^(26+27) */ freduce_degree(z2); freduce_coefficients(z2); /* |z2|i| < 2^26 */ } /* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave * them unchanged if 'iswap' is 0. Runs in data-invariant time to avoid * side-channel attacks. * * NOTE that this function requires that 'iswap' be 1 or 0; other values give * wrong results. Also, the two limb arrays must be in reduced-coefficient, * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped, * and all all values in a[0..9],b[0..9] must have magnitude less than * INT32_MAX. */ static void swap_conditional(limb a[19], limb b[19], limb iswap) { unsigned i; const s32 swap = (s32) -iswap; for (i = 0; i < 10; ++i) { const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) ); a[i] = ((s32)a[i]) ^ x; b[i] = ((s32)b[i]) ^ x; } } /* Calculates nQ where Q is the x-coordinate of a point on the curve * * resultx/resultz: the x coordinate of the resulting curve point (short form) * n: a little endian, 32-byte number * q: a point of the curve (short form) */ static void cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) { limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0}; limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t; limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1}; limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h; unsigned i, j; memcpy(nqpqx, q, sizeof(limb) * 10); for (i = 0; i < 32; ++i) { u8 byte = n[31 - i]; for (j = 0; j < 8; ++j) { const limb bit = byte >> 7; swap_conditional(nqx, nqpqx, bit); swap_conditional(nqz, nqpqz, bit); fmonty(nqx2, nqz2, nqpqx2, nqpqz2, nqx, nqz, nqpqx, nqpqz, q); swap_conditional(nqx2, nqpqx2, bit); swap_conditional(nqz2, nqpqz2, bit); t = nqx; nqx = nqx2; nqx2 = t; t = nqz; nqz = nqz2; nqz2 = t; t = nqpqx; nqpqx = nqpqx2; nqpqx2 = t; t = nqpqz; nqpqz = nqpqz2; nqpqz2 = t; byte <<= 1; } } memcpy(resultx, nqx, sizeof(limb) * 10); memcpy(resultz, nqz, sizeof(limb) * 10); } // ----------------------------------------------------------------------------- // Shamelessly copied from djb's code // ----------------------------------------------------------------------------- static void crecip(limb *out, const limb *z) { limb z2[10]; limb z9[10]; limb z11[10]; limb z2_5_0[10]; limb z2_10_0[10]; limb z2_20_0[10]; limb z2_50_0[10]; limb z2_100_0[10]; limb t0[10]; limb t1[10]; int i; /* 2 */ fsquare(z2,z); /* 4 */ fsquare(t1,z2); /* 8 */ fsquare(t0,t1); /* 9 */ fmul(z9,t0,z); /* 11 */ fmul(z11,z9,z2); /* 22 */ fsquare(t0,z11); /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9); /* 2^6 - 2^1 */ fsquare(t0,z2_5_0); /* 2^7 - 2^2 */ fsquare(t1,t0); /* 2^8 - 2^3 */ fsquare(t0,t1); /* 2^9 - 2^4 */ fsquare(t1,t0); /* 2^10 - 2^5 */ fsquare(t0,t1); /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0); /* 2^11 - 2^1 */ fsquare(t0,z2_10_0); /* 2^12 - 2^2 */ fsquare(t1,t0); /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0); /* 2^21 - 2^1 */ fsquare(t0,z2_20_0); /* 2^22 - 2^2 */ fsquare(t1,t0); /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0); /* 2^41 - 2^1 */ fsquare(t1,t0); /* 2^42 - 2^2 */ fsquare(t0,t1); /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0); /* 2^51 - 2^1 */ fsquare(t0,z2_50_0); /* 2^52 - 2^2 */ fsquare(t1,t0); /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0); /* 2^101 - 2^1 */ fsquare(t1,z2_100_0); /* 2^102 - 2^2 */ fsquare(t0,t1); /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); } /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0); /* 2^201 - 2^1 */ fsquare(t0,t1); /* 2^202 - 2^2 */ fsquare(t1,t0); /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); } /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0); /* 2^251 - 2^1 */ fsquare(t1,t0); /* 2^252 - 2^2 */ fsquare(t0,t1); /* 2^253 - 2^3 */ fsquare(t1,t0); /* 2^254 - 2^4 */ fsquare(t0,t1); /* 2^255 - 2^5 */ fsquare(t1,t0); /* 2^255 - 21 */ fmul(out,t1,z11); } int cryptonite_curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { limb bp[10], x[10], z[11], zmone[10]; uint8_t e[32]; int i; for (i = 0; i < 32; ++i) e[i] = secret[i]; e[0] &= 248; e[31] &= 127; e[31] |= 64; fexpand(bp, basepoint); cmult(x, z, e, bp); crecip(zmone, z); fmul(z, x, zmone); fcontract(mypublic, z); return 0; } cryptonite-0.23/cbits/cryptonite_rdrand.c0000644000000000000000000000771712740632655017054 0ustar0000000000000000/* * Copyright (C) Thomas DuBuisson * Copyright (C) 2013 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include int cryptonite_cpu_has_rdrand() { uint32_t ax,bx,cx,dx,func=1; #if defined(__PIC__) && defined(__i386__) __asm__ volatile ("mov %%ebx, %%edi;" "cpuid;" "xchgl %%ebx, %%edi;" : "=a" (ax), "=D" (bx), "=c" (cx), "=d" (dx) : "a" (func)); #else __asm__ volatile ("cpuid": "=a" (ax), "=b" (bx), "=c" (cx), "=d" (dx) : "a" (func)); #endif return (cx & 0x40000000); } /* inline encoding of 'rdrand %rax' to cover old binutils * - no inputs * - 'cc' to the clobber list as we modify condition code. * - output of rdrand in rax and have a 8 bit error condition */ #define inline_rdrand_rax(val, err) \ asm(".byte 0x48,0x0f,0xc7,0xf0; setc %1" \ : "=a" (val), "=q" (err) \ : \ : "cc") /* inline encoding of 'rdrand %eax' to cover old binutils * - no inputs * - 'cc' to the clobber list as we modify condition code. * - output of rdrand in eax and have a 8 bit error condition */ #define inline_rdrand_eax(val, err) \ asm(".byte 0x0f,0xc7,0xf0; setc %1" \ : "=a" (val), "=q" (err) \ : \ : "cc") #ifdef __x86_64__ # define RDRAND_SZ 8 # define RDRAND_T uint64_t #define inline_rdrand(val, err) err = cryptonite_rdrand_step(&val) #else # define RDRAND_SZ 4 # define RDRAND_T uint32_t #define inline_rdrand(val, err) err = cryptonite_rdrand_step(&val) #endif /* sadly many people are still using an old binutils, * leading to report that instruction is not recognized. */ #if 1 /* Returns 1 on success */ static inline int cryptonite_rdrand_step(RDRAND_T *buffer) { unsigned char err; asm volatile ("rdrand %0; setc %1" : "=r" (*buffer), "=qm" (err)); return (int) err; } #endif /* Returns the number of bytes succesfully generated */ int cryptonite_get_rand_bytes(uint8_t *buffer, size_t len) { RDRAND_T tmp; int aligned = (intptr_t) buffer % RDRAND_SZ; int orig_len = len; int to_alignment = RDRAND_SZ - aligned; uint8_t ok; if (aligned != 0) { inline_rdrand(tmp, ok); if (!ok) return 0; memcpy(buffer, (uint8_t *) &tmp, to_alignment); buffer += to_alignment; len -= to_alignment; } for (; len >= RDRAND_SZ; buffer += RDRAND_SZ, len -= RDRAND_SZ) { inline_rdrand(tmp, ok); if (!ok) return (orig_len - len); *((RDRAND_T *) buffer) = tmp; } if (len > 0) { inline_rdrand(tmp, ok); if (!ok) return (orig_len - len); memcpy(buffer, (uint8_t *) &tmp, len); } return orig_len; } cryptonite-0.23/cbits/aes/x86ni.c0000644000000000000000000002577313054074213015035 0ustar0000000000000000/* * Copyright (c) 2012-2013 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifdef WITH_AESNI #include #include #include #include #include #include #include #ifdef ARCH_X86 #define ALIGN_UP(addr, size) (((addr) + ((size) - 1)) & (~((size) - 1))) #define ALIGNMENT(n) __attribute__((aligned(n))) /* old GCC version doesn't cope with the shuffle parameters, that can take 2 values (0xff and 0xaa) * in our case, passed as argument despite being a immediate 8 bits constant anyway. * un-factorise aes_128_key_expansion into 2 version that have the shuffle parameter explicitly set */ static __m128i aes_128_key_expansion_ff(__m128i key, __m128i keygened) { keygened = _mm_shuffle_epi32(keygened, 0xff); key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); return _mm_xor_si128(key, keygened); } static __m128i aes_128_key_expansion_aa(__m128i key, __m128i keygened) { keygened = _mm_shuffle_epi32(keygened, 0xaa); key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); return _mm_xor_si128(key, keygened); } void cryptonite_aesni_init(aes_key *key, uint8_t *ikey, uint8_t size) { __m128i k[28]; uint64_t *out = (uint64_t *) key->data; int i; switch (size) { case 16: k[0] = _mm_loadu_si128((const __m128i*) ikey); #define AES_128_key_exp(K, RCON) aes_128_key_expansion_ff(K, _mm_aeskeygenassist_si128(K, RCON)) k[1] = AES_128_key_exp(k[0], 0x01); k[2] = AES_128_key_exp(k[1], 0x02); k[3] = AES_128_key_exp(k[2], 0x04); k[4] = AES_128_key_exp(k[3], 0x08); k[5] = AES_128_key_exp(k[4], 0x10); k[6] = AES_128_key_exp(k[5], 0x20); k[7] = AES_128_key_exp(k[6], 0x40); k[8] = AES_128_key_exp(k[7], 0x80); k[9] = AES_128_key_exp(k[8], 0x1B); k[10] = AES_128_key_exp(k[9], 0x36); /* generate decryption keys in reverse order. * k[10] is shared by last encryption and first decryption rounds * k[20] is shared by first encryption round (and is the original user key) */ k[11] = _mm_aesimc_si128(k[9]); k[12] = _mm_aesimc_si128(k[8]); k[13] = _mm_aesimc_si128(k[7]); k[14] = _mm_aesimc_si128(k[6]); k[15] = _mm_aesimc_si128(k[5]); k[16] = _mm_aesimc_si128(k[4]); k[17] = _mm_aesimc_si128(k[3]); k[18] = _mm_aesimc_si128(k[2]); k[19] = _mm_aesimc_si128(k[1]); for (i = 0; i < 20; i++) _mm_storeu_si128(((__m128i *) out) + i, k[i]); break; case 32: #define AES_256_key_exp_1(K1, K2, RCON) aes_128_key_expansion_ff(K1, _mm_aeskeygenassist_si128(K2, RCON)) #define AES_256_key_exp_2(K1, K2) aes_128_key_expansion_aa(K1, _mm_aeskeygenassist_si128(K2, 0x00)) k[0] = _mm_loadu_si128((const __m128i*) ikey); k[1] = _mm_loadu_si128((const __m128i*) (ikey+16)); k[2] = AES_256_key_exp_1(k[0], k[1], 0x01); k[3] = AES_256_key_exp_2(k[1], k[2]); k[4] = AES_256_key_exp_1(k[2], k[3], 0x02); k[5] = AES_256_key_exp_2(k[3], k[4]); k[6] = AES_256_key_exp_1(k[4], k[5], 0x04); k[7] = AES_256_key_exp_2(k[5], k[6]); k[8] = AES_256_key_exp_1(k[6], k[7], 0x08); k[9] = AES_256_key_exp_2(k[7], k[8]); k[10] = AES_256_key_exp_1(k[8], k[9], 0x10); k[11] = AES_256_key_exp_2(k[9], k[10]); k[12] = AES_256_key_exp_1(k[10], k[11], 0x20); k[13] = AES_256_key_exp_2(k[11], k[12]); k[14] = AES_256_key_exp_1(k[12], k[13], 0x40); k[15] = _mm_aesimc_si128(k[13]); k[16] = _mm_aesimc_si128(k[12]); k[17] = _mm_aesimc_si128(k[11]); k[18] = _mm_aesimc_si128(k[10]); k[19] = _mm_aesimc_si128(k[9]); k[20] = _mm_aesimc_si128(k[8]); k[21] = _mm_aesimc_si128(k[7]); k[22] = _mm_aesimc_si128(k[6]); k[23] = _mm_aesimc_si128(k[5]); k[24] = _mm_aesimc_si128(k[4]); k[25] = _mm_aesimc_si128(k[3]); k[26] = _mm_aesimc_si128(k[2]); k[27] = _mm_aesimc_si128(k[1]); for (i = 0; i < 28; i++) _mm_storeu_si128(((__m128i *) out) + i, k[i]); break; default: break; } } /* TO OPTIMISE: use pcmulqdq... or some faster code. * this is the lamest way of doing it, but i'm out of time. * this is basically a copy of gf_mulx in gf.c */ static __m128i gfmulx(__m128i v) { uint64_t v_[2] ALIGNMENT(16); const uint64_t gf_mask = 0x8000000000000000; _mm_store_si128((__m128i *) v_, v); uint64_t r = ((v_[1] & gf_mask) ? 0x87 : 0); v_[1] = (v_[1] << 1) | (v_[0] & gf_mask ? 1 : 0); v_[0] = (v_[0] << 1) ^ r; v = _mm_load_si128((__m128i *) v_); return v; } static void unopt_gf_mul(block128 *a, block128 *b) { uint64_t a0, a1, v0, v1; int i, j; a0 = a1 = 0; v0 = cpu_to_be64(a->q[0]); v1 = cpu_to_be64(a->q[1]); for (i = 0; i < 16; i++) for (j = 0x80; j != 0; j >>= 1) { uint8_t x = b->b[i] & j; a0 ^= x ? v0 : 0; a1 ^= x ? v1 : 0; x = (uint8_t) v1 & 1; v1 = (v1 >> 1) | (v0 << 63); v0 = (v0 >> 1) ^ (x ? (0xe1ULL << 56) : 0); } a->q[0] = cpu_to_be64(a0); a->q[1] = cpu_to_be64(a1); } static __m128i ghash_add(__m128i tag, __m128i h, __m128i m) { aes_block _t, _h; tag = _mm_xor_si128(tag, m); _mm_store_si128((__m128i *) &_t, tag); _mm_store_si128((__m128i *) &_h, h); unopt_gf_mul(&_t, &_h); tag = _mm_load_si128((__m128i *) &_t); return tag; } #define PRELOAD_ENC_KEYS128(k) \ __m128i K0 = _mm_loadu_si128(((__m128i *) k)+0); \ __m128i K1 = _mm_loadu_si128(((__m128i *) k)+1); \ __m128i K2 = _mm_loadu_si128(((__m128i *) k)+2); \ __m128i K3 = _mm_loadu_si128(((__m128i *) k)+3); \ __m128i K4 = _mm_loadu_si128(((__m128i *) k)+4); \ __m128i K5 = _mm_loadu_si128(((__m128i *) k)+5); \ __m128i K6 = _mm_loadu_si128(((__m128i *) k)+6); \ __m128i K7 = _mm_loadu_si128(((__m128i *) k)+7); \ __m128i K8 = _mm_loadu_si128(((__m128i *) k)+8); \ __m128i K9 = _mm_loadu_si128(((__m128i *) k)+9); \ __m128i K10 = _mm_loadu_si128(((__m128i *) k)+10); #define PRELOAD_ENC_KEYS256(k) \ PRELOAD_ENC_KEYS128(k) \ __m128i K11 = _mm_loadu_si128(((__m128i *) k)+11); \ __m128i K12 = _mm_loadu_si128(((__m128i *) k)+12); \ __m128i K13 = _mm_loadu_si128(((__m128i *) k)+13); \ __m128i K14 = _mm_loadu_si128(((__m128i *) k)+14); #define DO_ENC_BLOCK128(m) \ m = _mm_xor_si128(m, K0); \ m = _mm_aesenc_si128(m, K1); \ m = _mm_aesenc_si128(m, K2); \ m = _mm_aesenc_si128(m, K3); \ m = _mm_aesenc_si128(m, K4); \ m = _mm_aesenc_si128(m, K5); \ m = _mm_aesenc_si128(m, K6); \ m = _mm_aesenc_si128(m, K7); \ m = _mm_aesenc_si128(m, K8); \ m = _mm_aesenc_si128(m, K9); \ m = _mm_aesenclast_si128(m, K10); #define DO_ENC_BLOCK256(m) \ m = _mm_xor_si128(m, K0); \ m = _mm_aesenc_si128(m, K1); \ m = _mm_aesenc_si128(m, K2); \ m = _mm_aesenc_si128(m, K3); \ m = _mm_aesenc_si128(m, K4); \ m = _mm_aesenc_si128(m, K5); \ m = _mm_aesenc_si128(m, K6); \ m = _mm_aesenc_si128(m, K7); \ m = _mm_aesenc_si128(m, K8); \ m = _mm_aesenc_si128(m, K9); \ m = _mm_aesenc_si128(m, K10); \ m = _mm_aesenc_si128(m, K11); \ m = _mm_aesenc_si128(m, K12); \ m = _mm_aesenc_si128(m, K13); \ m = _mm_aesenclast_si128(m, K14); /* load K0 at K9 from index 'at' */ #define PRELOAD_DEC_KEYS_AT(k, at) \ __m128i K0 = _mm_loadu_si128(((__m128i *) k)+at+0); \ __m128i K1 = _mm_loadu_si128(((__m128i *) k)+at+1); \ __m128i K2 = _mm_loadu_si128(((__m128i *) k)+at+2); \ __m128i K3 = _mm_loadu_si128(((__m128i *) k)+at+3); \ __m128i K4 = _mm_loadu_si128(((__m128i *) k)+at+4); \ __m128i K5 = _mm_loadu_si128(((__m128i *) k)+at+5); \ __m128i K6 = _mm_loadu_si128(((__m128i *) k)+at+6); \ __m128i K7 = _mm_loadu_si128(((__m128i *) k)+at+7); \ __m128i K8 = _mm_loadu_si128(((__m128i *) k)+at+8); \ __m128i K9 = _mm_loadu_si128(((__m128i *) k)+at+9); \ #define PRELOAD_DEC_KEYS128(k) \ PRELOAD_DEC_KEYS_AT(k, 10) \ __m128i K10 = _mm_loadu_si128(((__m128i *) k)+0); #define PRELOAD_DEC_KEYS256(k) \ PRELOAD_DEC_KEYS_AT(k, 14) \ __m128i K10 = _mm_loadu_si128(((__m128i *) k)+14+10); \ __m128i K11 = _mm_loadu_si128(((__m128i *) k)+14+11); \ __m128i K12 = _mm_loadu_si128(((__m128i *) k)+14+12); \ __m128i K13 = _mm_loadu_si128(((__m128i *) k)+14+13); \ __m128i K14 = _mm_loadu_si128(((__m128i *) k)+0); #define DO_DEC_BLOCK128(m) \ m = _mm_xor_si128(m, K0); \ m = _mm_aesdec_si128(m, K1); \ m = _mm_aesdec_si128(m, K2); \ m = _mm_aesdec_si128(m, K3); \ m = _mm_aesdec_si128(m, K4); \ m = _mm_aesdec_si128(m, K5); \ m = _mm_aesdec_si128(m, K6); \ m = _mm_aesdec_si128(m, K7); \ m = _mm_aesdec_si128(m, K8); \ m = _mm_aesdec_si128(m, K9); \ m = _mm_aesdeclast_si128(m, K10); #define DO_DEC_BLOCK256(m) \ m = _mm_xor_si128(m, K0); \ m = _mm_aesdec_si128(m, K1); \ m = _mm_aesdec_si128(m, K2); \ m = _mm_aesdec_si128(m, K3); \ m = _mm_aesdec_si128(m, K4); \ m = _mm_aesdec_si128(m, K5); \ m = _mm_aesdec_si128(m, K6); \ m = _mm_aesdec_si128(m, K7); \ m = _mm_aesdec_si128(m, K8); \ m = _mm_aesdec_si128(m, K9); \ m = _mm_aesdec_si128(m, K10); \ m = _mm_aesdec_si128(m, K11); \ m = _mm_aesdec_si128(m, K12); \ m = _mm_aesdec_si128(m, K13); \ m = _mm_aesdeclast_si128(m, K14); #define SIZE 128 #define SIZED(m) m##128 #define PRELOAD_ENC PRELOAD_ENC_KEYS128 #define DO_ENC_BLOCK DO_ENC_BLOCK128 #define PRELOAD_DEC PRELOAD_DEC_KEYS128 #define DO_DEC_BLOCK DO_DEC_BLOCK128 #include #undef SIZE #undef SIZED #undef PRELOAD_ENC #undef PRELOAD_DEC #undef DO_ENC_BLOCK #undef DO_DEC_BLOCK #define SIZED(m) m##256 #define SIZE 256 #define PRELOAD_ENC PRELOAD_ENC_KEYS256 #define DO_ENC_BLOCK DO_ENC_BLOCK256 #define PRELOAD_DEC PRELOAD_DEC_KEYS256 #define DO_DEC_BLOCK DO_DEC_BLOCK256 #include #undef SIZE #undef SIZED #undef PRELOAD_ENC #undef PRELOAD_DEC #undef DO_ENC_BLOCK #undef DO_DEC_BLOCK #endif #endif cryptonite-0.23/cbits/aes/generic.c0000644000000000000000000005012412541524734015471 0ustar0000000000000000/* * Copyright (C) 2008 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * AES implementation */ #include #include #include #include static uint8_t sbox[256] = { 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 }; static uint8_t rsbox[256] = { 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 }; static uint8_t Rcon[] = { 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, }; #define G(a,b,c,d,e,f) { a,b,c,d,e,f } static uint8_t gmtab[256][6] = { G(0x00, 0x00, 0x00, 0x00, 0x00, 0x00), G(0x02, 0x03, 0x09, 0x0b, 0x0d, 0x0e), G(0x04, 0x06, 0x12, 0x16, 0x1a, 0x1c), G(0x06, 0x05, 0x1b, 0x1d, 0x17, 0x12), G(0x08, 0x0c, 0x24, 0x2c, 0x34, 0x38), G(0x0a, 0x0f, 0x2d, 0x27, 0x39, 0x36), G(0x0c, 0x0a, 0x36, 0x3a, 0x2e, 0x24), G(0x0e, 0x09, 0x3f, 0x31, 0x23, 0x2a), G(0x10, 0x18, 0x48, 0x58, 0x68, 0x70), G(0x12, 0x1b, 0x41, 0x53, 0x65, 0x7e), G(0x14, 0x1e, 0x5a, 0x4e, 0x72, 0x6c), G(0x16, 0x1d, 0x53, 0x45, 0x7f, 0x62), G(0x18, 0x14, 0x6c, 0x74, 0x5c, 0x48), G(0x1a, 0x17, 0x65, 0x7f, 0x51, 0x46), G(0x1c, 0x12, 0x7e, 0x62, 0x46, 0x54), G(0x1e, 0x11, 0x77, 0x69, 0x4b, 0x5a), G(0x20, 0x30, 0x90, 0xb0, 0xd0, 0xe0), G(0x22, 0x33, 0x99, 0xbb, 0xdd, 0xee), G(0x24, 0x36, 0x82, 0xa6, 0xca, 0xfc), G(0x26, 0x35, 0x8b, 0xad, 0xc7, 0xf2), G(0x28, 0x3c, 0xb4, 0x9c, 0xe4, 0xd8), G(0x2a, 0x3f, 0xbd, 0x97, 0xe9, 0xd6), G(0x2c, 0x3a, 0xa6, 0x8a, 0xfe, 0xc4), G(0x2e, 0x39, 0xaf, 0x81, 0xf3, 0xca), G(0x30, 0x28, 0xd8, 0xe8, 0xb8, 0x90), G(0x32, 0x2b, 0xd1, 0xe3, 0xb5, 0x9e), G(0x34, 0x2e, 0xca, 0xfe, 0xa2, 0x8c), G(0x36, 0x2d, 0xc3, 0xf5, 0xaf, 0x82), G(0x38, 0x24, 0xfc, 0xc4, 0x8c, 0xa8), G(0x3a, 0x27, 0xf5, 0xcf, 0x81, 0xa6), G(0x3c, 0x22, 0xee, 0xd2, 0x96, 0xb4), G(0x3e, 0x21, 0xe7, 0xd9, 0x9b, 0xba), G(0x40, 0x60, 0x3b, 0x7b, 0xbb, 0xdb), G(0x42, 0x63, 0x32, 0x70, 0xb6, 0xd5), G(0x44, 0x66, 0x29, 0x6d, 0xa1, 0xc7), G(0x46, 0x65, 0x20, 0x66, 0xac, 0xc9), G(0x48, 0x6c, 0x1f, 0x57, 0x8f, 0xe3), G(0x4a, 0x6f, 0x16, 0x5c, 0x82, 0xed), G(0x4c, 0x6a, 0x0d, 0x41, 0x95, 0xff), G(0x4e, 0x69, 0x04, 0x4a, 0x98, 0xf1), G(0x50, 0x78, 0x73, 0x23, 0xd3, 0xab), G(0x52, 0x7b, 0x7a, 0x28, 0xde, 0xa5), G(0x54, 0x7e, 0x61, 0x35, 0xc9, 0xb7), G(0x56, 0x7d, 0x68, 0x3e, 0xc4, 0xb9), G(0x58, 0x74, 0x57, 0x0f, 0xe7, 0x93), G(0x5a, 0x77, 0x5e, 0x04, 0xea, 0x9d), G(0x5c, 0x72, 0x45, 0x19, 0xfd, 0x8f), G(0x5e, 0x71, 0x4c, 0x12, 0xf0, 0x81), G(0x60, 0x50, 0xab, 0xcb, 0x6b, 0x3b), G(0x62, 0x53, 0xa2, 0xc0, 0x66, 0x35), G(0x64, 0x56, 0xb9, 0xdd, 0x71, 0x27), G(0x66, 0x55, 0xb0, 0xd6, 0x7c, 0x29), G(0x68, 0x5c, 0x8f, 0xe7, 0x5f, 0x03), G(0x6a, 0x5f, 0x86, 0xec, 0x52, 0x0d), G(0x6c, 0x5a, 0x9d, 0xf1, 0x45, 0x1f), G(0x6e, 0x59, 0x94, 0xfa, 0x48, 0x11), G(0x70, 0x48, 0xe3, 0x93, 0x03, 0x4b), G(0x72, 0x4b, 0xea, 0x98, 0x0e, 0x45), G(0x74, 0x4e, 0xf1, 0x85, 0x19, 0x57), G(0x76, 0x4d, 0xf8, 0x8e, 0x14, 0x59), G(0x78, 0x44, 0xc7, 0xbf, 0x37, 0x73), G(0x7a, 0x47, 0xce, 0xb4, 0x3a, 0x7d), G(0x7c, 0x42, 0xd5, 0xa9, 0x2d, 0x6f), G(0x7e, 0x41, 0xdc, 0xa2, 0x20, 0x61), G(0x80, 0xc0, 0x76, 0xf6, 0x6d, 0xad), G(0x82, 0xc3, 0x7f, 0xfd, 0x60, 0xa3), G(0x84, 0xc6, 0x64, 0xe0, 0x77, 0xb1), G(0x86, 0xc5, 0x6d, 0xeb, 0x7a, 0xbf), G(0x88, 0xcc, 0x52, 0xda, 0x59, 0x95), G(0x8a, 0xcf, 0x5b, 0xd1, 0x54, 0x9b), G(0x8c, 0xca, 0x40, 0xcc, 0x43, 0x89), G(0x8e, 0xc9, 0x49, 0xc7, 0x4e, 0x87), G(0x90, 0xd8, 0x3e, 0xae, 0x05, 0xdd), G(0x92, 0xdb, 0x37, 0xa5, 0x08, 0xd3), G(0x94, 0xde, 0x2c, 0xb8, 0x1f, 0xc1), G(0x96, 0xdd, 0x25, 0xb3, 0x12, 0xcf), G(0x98, 0xd4, 0x1a, 0x82, 0x31, 0xe5), G(0x9a, 0xd7, 0x13, 0x89, 0x3c, 0xeb), G(0x9c, 0xd2, 0x08, 0x94, 0x2b, 0xf9), G(0x9e, 0xd1, 0x01, 0x9f, 0x26, 0xf7), G(0xa0, 0xf0, 0xe6, 0x46, 0xbd, 0x4d), G(0xa2, 0xf3, 0xef, 0x4d, 0xb0, 0x43), G(0xa4, 0xf6, 0xf4, 0x50, 0xa7, 0x51), G(0xa6, 0xf5, 0xfd, 0x5b, 0xaa, 0x5f), G(0xa8, 0xfc, 0xc2, 0x6a, 0x89, 0x75), G(0xaa, 0xff, 0xcb, 0x61, 0x84, 0x7b), G(0xac, 0xfa, 0xd0, 0x7c, 0x93, 0x69), G(0xae, 0xf9, 0xd9, 0x77, 0x9e, 0x67), G(0xb0, 0xe8, 0xae, 0x1e, 0xd5, 0x3d), G(0xb2, 0xeb, 0xa7, 0x15, 0xd8, 0x33), G(0xb4, 0xee, 0xbc, 0x08, 0xcf, 0x21), G(0xb6, 0xed, 0xb5, 0x03, 0xc2, 0x2f), G(0xb8, 0xe4, 0x8a, 0x32, 0xe1, 0x05), G(0xba, 0xe7, 0x83, 0x39, 0xec, 0x0b), G(0xbc, 0xe2, 0x98, 0x24, 0xfb, 0x19), G(0xbe, 0xe1, 0x91, 0x2f, 0xf6, 0x17), G(0xc0, 0xa0, 0x4d, 0x8d, 0xd6, 0x76), G(0xc2, 0xa3, 0x44, 0x86, 0xdb, 0x78), G(0xc4, 0xa6, 0x5f, 0x9b, 0xcc, 0x6a), G(0xc6, 0xa5, 0x56, 0x90, 0xc1, 0x64), G(0xc8, 0xac, 0x69, 0xa1, 0xe2, 0x4e), G(0xca, 0xaf, 0x60, 0xaa, 0xef, 0x40), G(0xcc, 0xaa, 0x7b, 0xb7, 0xf8, 0x52), G(0xce, 0xa9, 0x72, 0xbc, 0xf5, 0x5c), G(0xd0, 0xb8, 0x05, 0xd5, 0xbe, 0x06), G(0xd2, 0xbb, 0x0c, 0xde, 0xb3, 0x08), G(0xd4, 0xbe, 0x17, 0xc3, 0xa4, 0x1a), G(0xd6, 0xbd, 0x1e, 0xc8, 0xa9, 0x14), G(0xd8, 0xb4, 0x21, 0xf9, 0x8a, 0x3e), G(0xda, 0xb7, 0x28, 0xf2, 0x87, 0x30), G(0xdc, 0xb2, 0x33, 0xef, 0x90, 0x22), G(0xde, 0xb1, 0x3a, 0xe4, 0x9d, 0x2c), G(0xe0, 0x90, 0xdd, 0x3d, 0x06, 0x96), G(0xe2, 0x93, 0xd4, 0x36, 0x0b, 0x98), G(0xe4, 0x96, 0xcf, 0x2b, 0x1c, 0x8a), G(0xe6, 0x95, 0xc6, 0x20, 0x11, 0x84), G(0xe8, 0x9c, 0xf9, 0x11, 0x32, 0xae), G(0xea, 0x9f, 0xf0, 0x1a, 0x3f, 0xa0), G(0xec, 0x9a, 0xeb, 0x07, 0x28, 0xb2), G(0xee, 0x99, 0xe2, 0x0c, 0x25, 0xbc), G(0xf0, 0x88, 0x95, 0x65, 0x6e, 0xe6), G(0xf2, 0x8b, 0x9c, 0x6e, 0x63, 0xe8), G(0xf4, 0x8e, 0x87, 0x73, 0x74, 0xfa), G(0xf6, 0x8d, 0x8e, 0x78, 0x79, 0xf4), G(0xf8, 0x84, 0xb1, 0x49, 0x5a, 0xde), G(0xfa, 0x87, 0xb8, 0x42, 0x57, 0xd0), G(0xfc, 0x82, 0xa3, 0x5f, 0x40, 0xc2), G(0xfe, 0x81, 0xaa, 0x54, 0x4d, 0xcc), G(0x1b, 0x9b, 0xec, 0xf7, 0xda, 0x41), G(0x19, 0x98, 0xe5, 0xfc, 0xd7, 0x4f), G(0x1f, 0x9d, 0xfe, 0xe1, 0xc0, 0x5d), G(0x1d, 0x9e, 0xf7, 0xea, 0xcd, 0x53), G(0x13, 0x97, 0xc8, 0xdb, 0xee, 0x79), G(0x11, 0x94, 0xc1, 0xd0, 0xe3, 0x77), G(0x17, 0x91, 0xda, 0xcd, 0xf4, 0x65), G(0x15, 0x92, 0xd3, 0xc6, 0xf9, 0x6b), G(0x0b, 0x83, 0xa4, 0xaf, 0xb2, 0x31), G(0x09, 0x80, 0xad, 0xa4, 0xbf, 0x3f), G(0x0f, 0x85, 0xb6, 0xb9, 0xa8, 0x2d), G(0x0d, 0x86, 0xbf, 0xb2, 0xa5, 0x23), G(0x03, 0x8f, 0x80, 0x83, 0x86, 0x09), G(0x01, 0x8c, 0x89, 0x88, 0x8b, 0x07), G(0x07, 0x89, 0x92, 0x95, 0x9c, 0x15), G(0x05, 0x8a, 0x9b, 0x9e, 0x91, 0x1b), G(0x3b, 0xab, 0x7c, 0x47, 0x0a, 0xa1), G(0x39, 0xa8, 0x75, 0x4c, 0x07, 0xaf), G(0x3f, 0xad, 0x6e, 0x51, 0x10, 0xbd), G(0x3d, 0xae, 0x67, 0x5a, 0x1d, 0xb3), G(0x33, 0xa7, 0x58, 0x6b, 0x3e, 0x99), G(0x31, 0xa4, 0x51, 0x60, 0x33, 0x97), G(0x37, 0xa1, 0x4a, 0x7d, 0x24, 0x85), G(0x35, 0xa2, 0x43, 0x76, 0x29, 0x8b), G(0x2b, 0xb3, 0x34, 0x1f, 0x62, 0xd1), G(0x29, 0xb0, 0x3d, 0x14, 0x6f, 0xdf), G(0x2f, 0xb5, 0x26, 0x09, 0x78, 0xcd), G(0x2d, 0xb6, 0x2f, 0x02, 0x75, 0xc3), G(0x23, 0xbf, 0x10, 0x33, 0x56, 0xe9), G(0x21, 0xbc, 0x19, 0x38, 0x5b, 0xe7), G(0x27, 0xb9, 0x02, 0x25, 0x4c, 0xf5), G(0x25, 0xba, 0x0b, 0x2e, 0x41, 0xfb), G(0x5b, 0xfb, 0xd7, 0x8c, 0x61, 0x9a), G(0x59, 0xf8, 0xde, 0x87, 0x6c, 0x94), G(0x5f, 0xfd, 0xc5, 0x9a, 0x7b, 0x86), G(0x5d, 0xfe, 0xcc, 0x91, 0x76, 0x88), G(0x53, 0xf7, 0xf3, 0xa0, 0x55, 0xa2), G(0x51, 0xf4, 0xfa, 0xab, 0x58, 0xac), G(0x57, 0xf1, 0xe1, 0xb6, 0x4f, 0xbe), G(0x55, 0xf2, 0xe8, 0xbd, 0x42, 0xb0), G(0x4b, 0xe3, 0x9f, 0xd4, 0x09, 0xea), G(0x49, 0xe0, 0x96, 0xdf, 0x04, 0xe4), G(0x4f, 0xe5, 0x8d, 0xc2, 0x13, 0xf6), G(0x4d, 0xe6, 0x84, 0xc9, 0x1e, 0xf8), G(0x43, 0xef, 0xbb, 0xf8, 0x3d, 0xd2), G(0x41, 0xec, 0xb2, 0xf3, 0x30, 0xdc), G(0x47, 0xe9, 0xa9, 0xee, 0x27, 0xce), G(0x45, 0xea, 0xa0, 0xe5, 0x2a, 0xc0), G(0x7b, 0xcb, 0x47, 0x3c, 0xb1, 0x7a), G(0x79, 0xc8, 0x4e, 0x37, 0xbc, 0x74), G(0x7f, 0xcd, 0x55, 0x2a, 0xab, 0x66), G(0x7d, 0xce, 0x5c, 0x21, 0xa6, 0x68), G(0x73, 0xc7, 0x63, 0x10, 0x85, 0x42), G(0x71, 0xc4, 0x6a, 0x1b, 0x88, 0x4c), G(0x77, 0xc1, 0x71, 0x06, 0x9f, 0x5e), G(0x75, 0xc2, 0x78, 0x0d, 0x92, 0x50), G(0x6b, 0xd3, 0x0f, 0x64, 0xd9, 0x0a), G(0x69, 0xd0, 0x06, 0x6f, 0xd4, 0x04), G(0x6f, 0xd5, 0x1d, 0x72, 0xc3, 0x16), G(0x6d, 0xd6, 0x14, 0x79, 0xce, 0x18), G(0x63, 0xdf, 0x2b, 0x48, 0xed, 0x32), G(0x61, 0xdc, 0x22, 0x43, 0xe0, 0x3c), G(0x67, 0xd9, 0x39, 0x5e, 0xf7, 0x2e), G(0x65, 0xda, 0x30, 0x55, 0xfa, 0x20), G(0x9b, 0x5b, 0x9a, 0x01, 0xb7, 0xec), G(0x99, 0x58, 0x93, 0x0a, 0xba, 0xe2), G(0x9f, 0x5d, 0x88, 0x17, 0xad, 0xf0), G(0x9d, 0x5e, 0x81, 0x1c, 0xa0, 0xfe), G(0x93, 0x57, 0xbe, 0x2d, 0x83, 0xd4), G(0x91, 0x54, 0xb7, 0x26, 0x8e, 0xda), G(0x97, 0x51, 0xac, 0x3b, 0x99, 0xc8), G(0x95, 0x52, 0xa5, 0x30, 0x94, 0xc6), G(0x8b, 0x43, 0xd2, 0x59, 0xdf, 0x9c), G(0x89, 0x40, 0xdb, 0x52, 0xd2, 0x92), G(0x8f, 0x45, 0xc0, 0x4f, 0xc5, 0x80), G(0x8d, 0x46, 0xc9, 0x44, 0xc8, 0x8e), G(0x83, 0x4f, 0xf6, 0x75, 0xeb, 0xa4), G(0x81, 0x4c, 0xff, 0x7e, 0xe6, 0xaa), G(0x87, 0x49, 0xe4, 0x63, 0xf1, 0xb8), G(0x85, 0x4a, 0xed, 0x68, 0xfc, 0xb6), G(0xbb, 0x6b, 0x0a, 0xb1, 0x67, 0x0c), G(0xb9, 0x68, 0x03, 0xba, 0x6a, 0x02), G(0xbf, 0x6d, 0x18, 0xa7, 0x7d, 0x10), G(0xbd, 0x6e, 0x11, 0xac, 0x70, 0x1e), G(0xb3, 0x67, 0x2e, 0x9d, 0x53, 0x34), G(0xb1, 0x64, 0x27, 0x96, 0x5e, 0x3a), G(0xb7, 0x61, 0x3c, 0x8b, 0x49, 0x28), G(0xb5, 0x62, 0x35, 0x80, 0x44, 0x26), G(0xab, 0x73, 0x42, 0xe9, 0x0f, 0x7c), G(0xa9, 0x70, 0x4b, 0xe2, 0x02, 0x72), G(0xaf, 0x75, 0x50, 0xff, 0x15, 0x60), G(0xad, 0x76, 0x59, 0xf4, 0x18, 0x6e), G(0xa3, 0x7f, 0x66, 0xc5, 0x3b, 0x44), G(0xa1, 0x7c, 0x6f, 0xce, 0x36, 0x4a), G(0xa7, 0x79, 0x74, 0xd3, 0x21, 0x58), G(0xa5, 0x7a, 0x7d, 0xd8, 0x2c, 0x56), G(0xdb, 0x3b, 0xa1, 0x7a, 0x0c, 0x37), G(0xd9, 0x38, 0xa8, 0x71, 0x01, 0x39), G(0xdf, 0x3d, 0xb3, 0x6c, 0x16, 0x2b), G(0xdd, 0x3e, 0xba, 0x67, 0x1b, 0x25), G(0xd3, 0x37, 0x85, 0x56, 0x38, 0x0f), G(0xd1, 0x34, 0x8c, 0x5d, 0x35, 0x01), G(0xd7, 0x31, 0x97, 0x40, 0x22, 0x13), G(0xd5, 0x32, 0x9e, 0x4b, 0x2f, 0x1d), G(0xcb, 0x23, 0xe9, 0x22, 0x64, 0x47), G(0xc9, 0x20, 0xe0, 0x29, 0x69, 0x49), G(0xcf, 0x25, 0xfb, 0x34, 0x7e, 0x5b), G(0xcd, 0x26, 0xf2, 0x3f, 0x73, 0x55), G(0xc3, 0x2f, 0xcd, 0x0e, 0x50, 0x7f), G(0xc1, 0x2c, 0xc4, 0x05, 0x5d, 0x71), G(0xc7, 0x29, 0xdf, 0x18, 0x4a, 0x63), G(0xc5, 0x2a, 0xd6, 0x13, 0x47, 0x6d), G(0xfb, 0x0b, 0x31, 0xca, 0xdc, 0xd7), G(0xf9, 0x08, 0x38, 0xc1, 0xd1, 0xd9), G(0xff, 0x0d, 0x23, 0xdc, 0xc6, 0xcb), G(0xfd, 0x0e, 0x2a, 0xd7, 0xcb, 0xc5), G(0xf3, 0x07, 0x15, 0xe6, 0xe8, 0xef), G(0xf1, 0x04, 0x1c, 0xed, 0xe5, 0xe1), G(0xf7, 0x01, 0x07, 0xf0, 0xf2, 0xf3), G(0xf5, 0x02, 0x0e, 0xfb, 0xff, 0xfd), G(0xeb, 0x13, 0x79, 0x92, 0xb4, 0xa7), G(0xe9, 0x10, 0x70, 0x99, 0xb9, 0xa9), G(0xef, 0x15, 0x6b, 0x84, 0xae, 0xbb), G(0xed, 0x16, 0x62, 0x8f, 0xa3, 0xb5), G(0xe3, 0x1f, 0x5d, 0xbe, 0x80, 0x9f), G(0xe1, 0x1c, 0x54, 0xb5, 0x8d, 0x91), G(0xe7, 0x19, 0x4f, 0xa8, 0x9a, 0x83), G(0xe5, 0x1a, 0x46, 0xa3, 0x97, 0x8d), }; #undef G static void expand_key(uint8_t *expandedKey, uint8_t *key, int size, size_t expandedKeySize) { int csz; int i; uint8_t t[4] = { 0 }; for (i = 0; i < size; i++) expandedKey[i] = key[i]; csz = size; i = 1; while (csz < expandedKeySize) { t[0] = expandedKey[(csz - 4) + 0]; t[1] = expandedKey[(csz - 4) + 1]; t[2] = expandedKey[(csz - 4) + 2]; t[3] = expandedKey[(csz - 4) + 3]; if (csz % size == 0) { uint8_t tmp; tmp = t[0]; t[0] = sbox[t[1]] ^ Rcon[i++ % sizeof(Rcon)]; t[1] = sbox[t[2]]; t[2] = sbox[t[3]]; t[3] = sbox[tmp]; } if (size == 32 && ((csz % size) == 16)) { t[0] = sbox[t[0]]; t[1] = sbox[t[1]]; t[2] = sbox[t[2]]; t[3] = sbox[t[3]]; } expandedKey[csz] = expandedKey[csz - size] ^ t[0]; csz++; expandedKey[csz] = expandedKey[csz - size] ^ t[1]; csz++; expandedKey[csz] = expandedKey[csz - size] ^ t[2]; csz++; expandedKey[csz] = expandedKey[csz - size] ^ t[3]; csz++; } } static void shift_rows(uint8_t *state) { uint32_t *s32; int i; for (i = 0; i < 16; i++) state[i] = sbox[state[i]]; s32 = (uint32_t *) state; s32[1] = rol32_be(s32[1], 8); s32[2] = rol32_be(s32[2], 16); s32[3] = rol32_be(s32[3], 24); } static void add_round_key(uint8_t *state, uint8_t *rk) { uint32_t *s32, *r32; s32 = (uint32_t *) state; r32 = (uint32_t *) rk; s32[0] ^= r32[0]; s32[1] ^= r32[1]; s32[2] ^= r32[2]; s32[3] ^= r32[3]; } #define gm1(a) (a) #define gm2(a) gmtab[a][0] #define gm3(a) gmtab[a][1] #define gm9(a) gmtab[a][2] #define gm11(a) gmtab[a][3] #define gm13(a) gmtab[a][4] #define gm14(a) gmtab[a][5] static void mix_columns(uint8_t *state) { int i; uint8_t cpy[4]; for (i = 0; i < 4; i++) { cpy[0] = state[0 * 4 + i]; cpy[1] = state[1 * 4 + i]; cpy[2] = state[2 * 4 + i]; cpy[3] = state[3 * 4 + i]; state[i] = gm2(cpy[0]) ^ gm1(cpy[3]) ^ gm1(cpy[2]) ^ gm3(cpy[1]); state[4+i] = gm2(cpy[1]) ^ gm1(cpy[0]) ^ gm1(cpy[3]) ^ gm3(cpy[2]); state[8+i] = gm2(cpy[2]) ^ gm1(cpy[1]) ^ gm1(cpy[0]) ^ gm3(cpy[3]); state[12+i] = gm2(cpy[3]) ^ gm1(cpy[2]) ^ gm1(cpy[1]) ^ gm3(cpy[0]); } } static void create_round_key(uint8_t *expandedKey, uint8_t *rk) { int i,j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) rk[i + j * 4] = expandedKey[i * 4 + j]; } static void aes_main(aes_key *key, uint8_t *state) { int i = 0; uint8_t rk[16]; create_round_key(key->data, rk); add_round_key(state, rk); for (i = 1; i < key->nbr; i++) { create_round_key(key->data + 16 * i, rk); shift_rows(state); mix_columns(state); add_round_key(state, rk); } create_round_key(key->data + 16 * key->nbr, rk); shift_rows(state); add_round_key(state, rk); } static void shift_rows_inv(uint8_t *state) { uint32_t *s32; int i; s32 = (uint32_t *) state; s32[1] = ror32_be(s32[1], 8); s32[2] = ror32_be(s32[2], 16); s32[3] = ror32_be(s32[3], 24); for (i = 0; i < 16; i++) state[i] = rsbox[state[i]]; } static void mix_columns_inv(uint8_t *state) { int i; uint8_t cpy[4]; for (i = 0; i < 4; i++) { cpy[0] = state[0 * 4 + i]; cpy[1] = state[1 * 4 + i]; cpy[2] = state[2 * 4 + i]; cpy[3] = state[3 * 4 + i]; state[i] = gm14(cpy[0]) ^ gm9(cpy[3]) ^ gm13(cpy[2]) ^ gm11(cpy[1]); state[4+i] = gm14(cpy[1]) ^ gm9(cpy[0]) ^ gm13(cpy[3]) ^ gm11(cpy[2]); state[8+i] = gm14(cpy[2]) ^ gm9(cpy[1]) ^ gm13(cpy[0]) ^ gm11(cpy[3]); state[12+i] = gm14(cpy[3]) ^ gm9(cpy[2]) ^ gm13(cpy[1]) ^ gm11(cpy[0]); } } static void aes_main_inv(aes_key *key, uint8_t *state) { int i = 0; uint8_t rk[16]; create_round_key(key->data + 16 * key->nbr, rk); add_round_key(state, rk); for (i = key->nbr - 1; i > 0; i--) { create_round_key(key->data + 16 * i, rk); shift_rows_inv(state); add_round_key(state, rk); mix_columns_inv(state); } create_round_key(key->data, rk); shift_rows_inv(state); add_round_key(state, rk); } /* Set the block values, for the block: * a0,0 a0,1 a0,2 a0,3 * a1,0 a1,1 a1,2 a1,3 -> a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3 * a2,0 a2,1 a2,2 a2,3 * a3,0 a3,1 a3,2 a3,3 */ #define swap_block(t, f) \ t[0] = f[0]; t[4] = f[1]; t[8] = f[2]; t[12] = f[3]; \ t[1] = f[4]; t[5] = f[5]; t[9] = f[6]; t[13] = f[7]; \ t[2] = f[8]; t[6] = f[9]; t[10] = f[10]; t[14] = f[11]; \ t[3] = f[12]; t[7] = f[13]; t[11] = f[14]; t[15] = f[15] void cryptonite_aes_generic_encrypt_block(aes_block *output, aes_key *key, aes_block *input) { uint8_t block[16]; uint8_t *iptr, *optr; iptr = (uint8_t *) input; optr = (uint8_t *) output; swap_block(block, iptr); aes_main(key, block); swap_block(optr, block); } void cryptonite_aes_generic_decrypt_block(aes_block *output, aes_key *key, aes_block *input) { uint8_t block[16]; uint8_t *iptr, *optr; iptr = (uint8_t *) input; optr = (uint8_t *) output; swap_block(block, iptr); aes_main_inv(key, block); swap_block(optr, block); } void cryptonite_aes_generic_init(aes_key *key, uint8_t *origkey, uint8_t size) { int esz; switch (size) { case 16: key->nbr = 10; esz = 176; break; case 24: key->nbr = 12; esz = 208; break; case 32: key->nbr = 14; esz = 240; break; default: return; } expand_key(key->data, origkey, size, esz); return; } cryptonite-0.23/cbits/aes/gf.c0000644000000000000000000000515212643044626014452 0ustar0000000000000000/* * Copyright (c) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include /* this is a really inefficient way to GF multiply. * the alternative without hw accel is building small tables * to speed up the multiplication. * TODO: optimise with tables */ void cryptonite_gf_mul(block128 *a, block128 *b) { uint64_t a0, a1, v0, v1; int i, j; a0 = a1 = 0; v0 = cpu_to_be64(a->q[0]); v1 = cpu_to_be64(a->q[1]); for (i = 0; i < 16; i++) for (j = 0x80; j != 0; j >>= 1) { uint8_t x = b->b[i] & j; a0 ^= x ? v0 : 0; a1 ^= x ? v1 : 0; x = (uint8_t) v1 & 1; v1 = (v1 >> 1) | (v0 << 63); v0 = (v0 >> 1) ^ (x ? (0xe1ULL << 56) : 0); } a->q[0] = cpu_to_be64(a0); a->q[1] = cpu_to_be64(a1); } /* inplace GFMUL for xts mode */ void cryptonite_gf_mulx(block128 *a) { const uint64_t gf_mask = cpu_to_le64(0x8000000000000000ULL); uint64_t r = ((a->q[1] & gf_mask) ? cpu_to_le64(0x87) : 0); a->q[1] = cpu_to_le64((le64_to_cpu(a->q[1]) << 1) | (a->q[0] & gf_mask ? 1 : 0)); a->q[0] = cpu_to_le64(le64_to_cpu(a->q[0]) << 1) ^ r; } cryptonite-0.23/cbits/cryptonite_aes.c0000644000000000000000000006465313054074213016341 0ustar0000000000000000/* * Copyright (c) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include #include #include #include #include void cryptonite_aes_generic_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t length); void cryptonite_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_generic_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_generic_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_generic_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_generic_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length); enum { /* init */ INIT_128, INIT_192, INIT_256, /* single block */ ENCRYPT_BLOCK_128, ENCRYPT_BLOCK_192, ENCRYPT_BLOCK_256, DECRYPT_BLOCK_128, DECRYPT_BLOCK_192, DECRYPT_BLOCK_256, /* ecb */ ENCRYPT_ECB_128, ENCRYPT_ECB_192, ENCRYPT_ECB_256, DECRYPT_ECB_128, DECRYPT_ECB_192, DECRYPT_ECB_256, /* cbc */ ENCRYPT_CBC_128, ENCRYPT_CBC_192, ENCRYPT_CBC_256, DECRYPT_CBC_128, DECRYPT_CBC_192, DECRYPT_CBC_256, /* ctr */ ENCRYPT_CTR_128, ENCRYPT_CTR_192, ENCRYPT_CTR_256, /* xts */ ENCRYPT_XTS_128, ENCRYPT_XTS_192, ENCRYPT_XTS_256, DECRYPT_XTS_128, DECRYPT_XTS_192, DECRYPT_XTS_256, /* gcm */ ENCRYPT_GCM_128, ENCRYPT_GCM_192, ENCRYPT_GCM_256, DECRYPT_GCM_128, DECRYPT_GCM_192, DECRYPT_GCM_256, /* ocb */ ENCRYPT_OCB_128, ENCRYPT_OCB_192, ENCRYPT_OCB_256, DECRYPT_OCB_128, DECRYPT_OCB_192, DECRYPT_OCB_256, }; void *cryptonite_aes_branch_table[] = { /* INIT */ [INIT_128] = cryptonite_aes_generic_init, [INIT_192] = cryptonite_aes_generic_init, [INIT_256] = cryptonite_aes_generic_init, /* BLOCK */ [ENCRYPT_BLOCK_128] = cryptonite_aes_generic_encrypt_block, [ENCRYPT_BLOCK_192] = cryptonite_aes_generic_encrypt_block, [ENCRYPT_BLOCK_256] = cryptonite_aes_generic_encrypt_block, [DECRYPT_BLOCK_128] = cryptonite_aes_generic_decrypt_block, [DECRYPT_BLOCK_192] = cryptonite_aes_generic_decrypt_block, [DECRYPT_BLOCK_256] = cryptonite_aes_generic_decrypt_block, /* ECB */ [ENCRYPT_ECB_128] = cryptonite_aes_generic_encrypt_ecb, [ENCRYPT_ECB_192] = cryptonite_aes_generic_encrypt_ecb, [ENCRYPT_ECB_256] = cryptonite_aes_generic_encrypt_ecb, [DECRYPT_ECB_128] = cryptonite_aes_generic_decrypt_ecb, [DECRYPT_ECB_192] = cryptonite_aes_generic_decrypt_ecb, [DECRYPT_ECB_256] = cryptonite_aes_generic_decrypt_ecb, /* CBC */ [ENCRYPT_CBC_128] = cryptonite_aes_generic_encrypt_cbc, [ENCRYPT_CBC_192] = cryptonite_aes_generic_encrypt_cbc, [ENCRYPT_CBC_256] = cryptonite_aes_generic_encrypt_cbc, [DECRYPT_CBC_128] = cryptonite_aes_generic_decrypt_cbc, [DECRYPT_CBC_192] = cryptonite_aes_generic_decrypt_cbc, [DECRYPT_CBC_256] = cryptonite_aes_generic_decrypt_cbc, /* CTR */ [ENCRYPT_CTR_128] = cryptonite_aes_generic_encrypt_ctr, [ENCRYPT_CTR_192] = cryptonite_aes_generic_encrypt_ctr, [ENCRYPT_CTR_256] = cryptonite_aes_generic_encrypt_ctr, /* XTS */ [ENCRYPT_XTS_128] = cryptonite_aes_generic_encrypt_xts, [ENCRYPT_XTS_192] = cryptonite_aes_generic_encrypt_xts, [ENCRYPT_XTS_256] = cryptonite_aes_generic_encrypt_xts, [DECRYPT_XTS_128] = cryptonite_aes_generic_decrypt_xts, [DECRYPT_XTS_192] = cryptonite_aes_generic_decrypt_xts, [DECRYPT_XTS_256] = cryptonite_aes_generic_decrypt_xts, /* GCM */ [ENCRYPT_GCM_128] = cryptonite_aes_generic_gcm_encrypt, [ENCRYPT_GCM_192] = cryptonite_aes_generic_gcm_encrypt, [ENCRYPT_GCM_256] = cryptonite_aes_generic_gcm_encrypt, [DECRYPT_GCM_128] = cryptonite_aes_generic_gcm_decrypt, [DECRYPT_GCM_192] = cryptonite_aes_generic_gcm_decrypt, [DECRYPT_GCM_256] = cryptonite_aes_generic_gcm_decrypt, /* OCB */ [ENCRYPT_OCB_128] = cryptonite_aes_generic_ocb_encrypt, [ENCRYPT_OCB_192] = cryptonite_aes_generic_ocb_encrypt, [ENCRYPT_OCB_256] = cryptonite_aes_generic_ocb_encrypt, [DECRYPT_OCB_128] = cryptonite_aes_generic_ocb_decrypt, [DECRYPT_OCB_192] = cryptonite_aes_generic_ocb_decrypt, [DECRYPT_OCB_256] = cryptonite_aes_generic_ocb_decrypt, }; typedef void (*init_f)(aes_key *, uint8_t *, uint8_t); typedef void (*ecb_f)(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks); typedef void (*cbc_f)(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks); typedef void (*ctr_f)(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t length); typedef void (*xts_f)(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks); typedef void (*gcm_crypt_f)(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length); typedef void (*ocb_crypt_f)(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length); typedef void (*block_f)(aes_block *output, aes_key *key, aes_block *input); #ifdef WITH_AESNI #define GET_INIT(strength) \ ((init_f) (cryptonite_aes_branch_table[INIT_128 + strength])) #define GET_ECB_ENCRYPT(strength) \ ((ecb_f) (cryptonite_aes_branch_table[ENCRYPT_ECB_128 + strength])) #define GET_ECB_DECRYPT(strength) \ ((ecb_f) (cryptonite_aes_branch_table[DECRYPT_ECB_128 + strength])) #define GET_CBC_ENCRYPT(strength) \ ((cbc_f) (cryptonite_aes_branch_table[ENCRYPT_CBC_128 + strength])) #define GET_CBC_DECRYPT(strength) \ ((cbc_f) (cryptonite_aes_branch_table[DECRYPT_CBC_128 + strength])) #define GET_CTR_ENCRYPT(strength) \ ((ctr_f) (cryptonite_aes_branch_table[ENCRYPT_CTR_128 + strength])) #define GET_XTS_ENCRYPT(strength) \ ((xts_f) (cryptonite_aes_branch_table[ENCRYPT_XTS_128 + strength])) #define GET_XTS_DECRYPT(strength) \ ((xts_f) (cryptonite_aes_branch_table[DECRYPT_XTS_128 + strength])) #define GET_GCM_ENCRYPT(strength) \ ((gcm_crypt_f) (cryptonite_aes_branch_table[ENCRYPT_GCM_128 + strength])) #define GET_GCM_DECRYPT(strength) \ ((gcm_crypt_f) (cryptonite_aes_branch_table[DECRYPT_GCM_128 + strength])) #define GET_OCB_ENCRYPT(strength) \ ((ocb_crypt_f) (cryptonite_aes_branch_table[ENCRYPT_OCB_128 + strength])) #define GET_OCB_DECRYPT(strength) \ ((ocb_crypt_f) (cryptonite_aes_branch_table[DECRYPT_OCB_128 + strength])) #define cryptonite_aes_encrypt_block(o,k,i) \ (((block_f) (cryptonite_aes_branch_table[ENCRYPT_BLOCK_128 + k->strength]))(o,k,i)) #define cryptonite_aes_decrypt_block(o,k,i) \ (((block_f) (cryptonite_aes_branch_table[DECRYPT_BLOCK_128 + k->strength]))(o,k,i)) #else #define GET_INIT(strenght) cryptonite_aes_generic_init #define GET_ECB_ENCRYPT(strength) cryptonite_aes_generic_encrypt_ecb #define GET_ECB_DECRYPT(strength) cryptonite_aes_generic_decrypt_ecb #define GET_CBC_ENCRYPT(strength) cryptonite_aes_generic_encrypt_cbc #define GET_CBC_DECRYPT(strength) cryptonite_aes_generic_decrypt_cbc #define GET_CTR_ENCRYPT(strength) cryptonite_aes_generic_encrypt_ctr #define GET_XTS_ENCRYPT(strength) cryptonite_aes_generic_encrypt_xts #define GET_XTS_DECRYPT(strength) cryptonite_aes_generic_decrypt_xts #define GET_GCM_ENCRYPT(strength) cryptonite_aes_generic_gcm_encrypt #define GET_GCM_DECRYPT(strength) cryptonite_aes_generic_gcm_decrypt #define GET_OCB_ENCRYPT(strength) cryptonite_aes_generic_ocb_encrypt #define GET_OCB_DECRYPT(strength) cryptonite_aes_generic_ocb_decrypt #define cryptonite_aes_encrypt_block(o,k,i) cryptonite_aes_generic_encrypt_block(o,k,i) #define cryptonite_aes_decrypt_block(o,k,i) cryptonite_aes_generic_decrypt_block(o,k,i) #endif #if defined(ARCH_X86) && defined(WITH_AESNI) static void initialize_table_ni(int aesni, int pclmul) { if (!aesni) return; cryptonite_aes_branch_table[INIT_128] = cryptonite_aesni_init; cryptonite_aes_branch_table[INIT_256] = cryptonite_aesni_init; cryptonite_aes_branch_table[ENCRYPT_BLOCK_128] = cryptonite_aesni_encrypt_block128; cryptonite_aes_branch_table[DECRYPT_BLOCK_128] = cryptonite_aesni_decrypt_block128; cryptonite_aes_branch_table[ENCRYPT_BLOCK_256] = cryptonite_aesni_encrypt_block256; cryptonite_aes_branch_table[DECRYPT_BLOCK_256] = cryptonite_aesni_decrypt_block256; /* ECB */ cryptonite_aes_branch_table[ENCRYPT_ECB_128] = cryptonite_aesni_encrypt_ecb128; cryptonite_aes_branch_table[DECRYPT_ECB_128] = cryptonite_aesni_decrypt_ecb128; cryptonite_aes_branch_table[ENCRYPT_ECB_256] = cryptonite_aesni_encrypt_ecb256; cryptonite_aes_branch_table[DECRYPT_ECB_256] = cryptonite_aesni_decrypt_ecb256; /* CBC */ cryptonite_aes_branch_table[ENCRYPT_CBC_128] = cryptonite_aesni_encrypt_cbc128; cryptonite_aes_branch_table[DECRYPT_CBC_128] = cryptonite_aesni_decrypt_cbc128; cryptonite_aes_branch_table[ENCRYPT_CBC_256] = cryptonite_aesni_encrypt_cbc256; cryptonite_aes_branch_table[DECRYPT_CBC_256] = cryptonite_aesni_decrypt_cbc256; /* CTR */ cryptonite_aes_branch_table[ENCRYPT_CTR_128] = cryptonite_aesni_encrypt_ctr128; cryptonite_aes_branch_table[ENCRYPT_CTR_256] = cryptonite_aesni_encrypt_ctr256; /* XTS */ cryptonite_aes_branch_table[ENCRYPT_XTS_128] = cryptonite_aesni_encrypt_xts128; cryptonite_aes_branch_table[ENCRYPT_XTS_256] = cryptonite_aesni_encrypt_xts256; /* GCM */ cryptonite_aes_branch_table[ENCRYPT_GCM_128] = cryptonite_aesni_gcm_encrypt128; cryptonite_aes_branch_table[ENCRYPT_GCM_256] = cryptonite_aesni_gcm_encrypt256; /* OCB */ /* cryptonite_aes_branch_table[ENCRYPT_OCB_128] = cryptonite_aesni_ocb_encrypt128; cryptonite_aes_branch_table[ENCRYPT_OCB_256] = cryptonite_aesni_ocb_encrypt256; */ } #endif void cryptonite_aes_initkey(aes_key *key, uint8_t *origkey, uint8_t size) { switch (size) { case 16: key->nbr = 10; key->strength = 0; break; case 24: key->nbr = 12; key->strength = 1; break; case 32: key->nbr = 14; key->strength = 2; break; } #if defined(ARCH_X86) && defined(WITH_AESNI) cryptonite_aesni_initialize_hw(initialize_table_ni); #endif init_f _init = GET_INIT(key->strength); _init(key, origkey, size); } void cryptonite_aes_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks) { ecb_f e = GET_ECB_ENCRYPT(key->strength); e(output, key, input, nb_blocks); } void cryptonite_aes_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks) { ecb_f d = GET_ECB_DECRYPT(key->strength); d(output, key, input, nb_blocks); } void cryptonite_aes_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks) { cbc_f e = GET_CBC_ENCRYPT(key->strength); e(output, key, iv, input, nb_blocks); } void cryptonite_aes_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks) { cbc_f d = GET_CBC_DECRYPT(key->strength); d(output, key, iv, input, nb_blocks); } void cryptonite_aes_gen_ctr(aes_block *output, aes_key *key, const aes_block *iv, uint32_t nb_blocks) { aes_block block; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; output++, block128_inc_be(&block)) { cryptonite_aes_encrypt_block(output, key, &block); } } void cryptonite_aes_gen_ctr_cont(aes_block *output, aes_key *key, aes_block *iv, uint32_t nb_blocks) { aes_block block; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; output++, block128_inc_be(&block)) { cryptonite_aes_encrypt_block(output, key, &block); } /* copy back the IV */ block128_copy(iv, &block); } void cryptonite_aes_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t len) { ctr_f e = GET_CTR_ENCRYPT(key->strength); e(output, key, iv, input, len); } void cryptonite_aes_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks) { xts_f e = GET_XTS_ENCRYPT(k1->strength); e(output, k1, k2, dataunit, spoint, input, nb_blocks); } void cryptonite_aes_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks) { cryptonite_aes_generic_decrypt_xts(output, k1, k2, dataunit, spoint, input, nb_blocks); } void cryptonite_aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length) { gcm_crypt_f e = GET_GCM_ENCRYPT(key->strength); e(output, gcm, key, input, length); } void cryptonite_aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length) { gcm_crypt_f d = GET_GCM_DECRYPT(key->strength); d(output, gcm, key, input, length); } void cryptonite_aes_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length) { ocb_crypt_f e = GET_OCB_ENCRYPT(key->strength); e(output, ocb, key, input, length); } void cryptonite_aes_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length) { ocb_crypt_f d = GET_OCB_DECRYPT(key->strength); d(output, ocb, key, input, length); } static void gcm_ghash_add(aes_gcm *gcm, block128 *b) { block128_xor(&gcm->tag, b); cryptonite_gf_mul(&gcm->tag, &gcm->h); } void cryptonite_aes_gcm_init(aes_gcm *gcm, aes_key *key, uint8_t *iv, uint32_t len) { gcm->length_aad = 0; gcm->length_input = 0; block128_zero(&gcm->h); block128_zero(&gcm->tag); block128_zero(&gcm->iv); /* prepare H : encrypt_K(0^128) */ cryptonite_aes_encrypt_block(&gcm->h, key, &gcm->h); if (len == 12) { block128_copy_bytes(&gcm->iv, iv, 12); gcm->iv.b[15] = 0x01; } else { uint32_t origlen = len << 3; int i; for (; len >= 16; len -= 16, iv += 16) { block128_xor(&gcm->iv, (block128 *) iv); cryptonite_gf_mul(&gcm->iv, &gcm->h); } if (len > 0) { block128_xor_bytes(&gcm->iv, iv, len); cryptonite_gf_mul(&gcm->iv, &gcm->h); } for (i = 15; origlen; --i, origlen >>= 8) gcm->iv.b[i] ^= (uint8_t) origlen; cryptonite_gf_mul(&gcm->iv, &gcm->h); } block128_copy(&gcm->civ, &gcm->iv); } void cryptonite_aes_gcm_aad(aes_gcm *gcm, uint8_t *input, uint32_t length) { gcm->length_aad += length; for (; length >= 16; input += 16, length -= 16) { gcm_ghash_add(gcm, (block128 *) input); } if (length > 0) { aes_block tmp; block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); gcm_ghash_add(gcm, &tmp); } } void cryptonite_aes_gcm_finish(uint8_t *tag, aes_gcm *gcm, aes_key *key) { aes_block lblock; int i; /* tag = (tag-1 xor (lenbits(a) | lenbits(c)) ) . H */ lblock.q[0] = cpu_to_be64(gcm->length_aad << 3); lblock.q[1] = cpu_to_be64(gcm->length_input << 3); gcm_ghash_add(gcm, &lblock); cryptonite_aes_encrypt_block(&lblock, key, &gcm->iv); block128_xor(&gcm->tag, &lblock); for (i = 0; i < 16; i++) { tag[i] = gcm->tag.b[i]; } } static inline void ocb_block_double(block128 *d, block128 *s) { unsigned int i; uint8_t tmp = s->b[0]; for (i=0; i<15; i++) d->b[i] = (s->b[i] << 1) | (s->b[i+1] >> 7); d->b[15] = (s->b[15] << 1) ^ ((tmp >> 7) * 0x87); } static void ocb_get_L_i(block128 *l, block128 *lis, unsigned int i) { #define L_CACHED 4 i = bitfn_ntz(i); if (i < L_CACHED) { block128_copy(l, &lis[i]); } else { i -= (L_CACHED - 1); block128_copy(l, &lis[L_CACHED - 1]); while (i--) { ocb_block_double(l, l); } } #undef L_CACHED } void cryptonite_aes_ocb_init(aes_ocb *ocb, aes_key *key, uint8_t *iv, uint32_t len) { block128 tmp, nonce, ktop; unsigned char stretch[24]; unsigned bottom, byteshift, bitshift, i; /* we don't accept more than 15 bytes, any bytes higher will be ignored. */ if (len > 15) { len = 15; } /* create L*, and L$,L0,L1,L2,L3 */ block128_zero(&tmp); cryptonite_aes_encrypt_block(&ocb->lstar, key, &tmp); ocb_block_double(&ocb->ldollar, &ocb->lstar); ocb_block_double(&ocb->li[0], &ocb->ldollar); ocb_block_double(&ocb->li[1], &ocb->li[0]); ocb_block_double(&ocb->li[2], &ocb->li[1]); ocb_block_double(&ocb->li[3], &ocb->li[2]); /* create strech from the nonce */ block128_zero(&nonce); memcpy(nonce.b + 4, iv, 12); nonce.b[0] = (unsigned char)(((16 * 8) % 128) << 1); nonce.b[16-12-1] |= 0x01; bottom = nonce.b[15] & 0x3F; nonce.b[15] &= 0xC0; cryptonite_aes_encrypt_block(&ktop, key, &nonce); memcpy(stretch, ktop.b, 16); memcpy(tmp.b, ktop.b + 1, 8); block128_xor(&tmp, &ktop); memcpy(stretch + 16, tmp.b, 8); /* initialize the encryption offset from stretch */ byteshift = bottom / 8; bitshift = bottom % 8; if (bitshift != 0) for (i = 0; i < 16; i++) ocb->offset_enc.b[i] = (stretch[i+byteshift] << bitshift) | (stretch[i+byteshift+1] >> (8-bitshift)); else for (i = 0; i < 16; i++) ocb->offset_enc.b[i] = stretch[i+byteshift]; /* initialize checksum for aad and encryption, and the aad offset */ block128_zero(&ocb->sum_aad); block128_zero(&ocb->sum_enc); block128_zero(&ocb->offset_aad); } void cryptonite_aes_ocb_aad(aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length) { block128 tmp; unsigned int i; for (i=1; i<= length/16; i++, input=input+16) { ocb_get_L_i(&tmp, ocb->li, i); block128_xor(&ocb->offset_aad, &tmp); block128_vxor(&tmp, &ocb->offset_aad, (block128 *) input); cryptonite_aes_encrypt_block(&tmp, key, &tmp); block128_xor(&ocb->sum_aad, &tmp); } length = length % 16; /* Bytes in final block */ if (length > 0) { block128_xor(&ocb->offset_aad, &ocb->lstar); block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); tmp.b[length] = 0x80; block128_xor(&tmp, &ocb->offset_aad); cryptonite_aes_encrypt_block(&tmp, key, &tmp); block128_xor(&ocb->sum_aad, &tmp); } } void cryptonite_aes_ocb_finish(uint8_t *tag, aes_ocb *ocb, aes_key *key) { block128 tmp; block128_vxor(&tmp, &ocb->sum_enc, &ocb->offset_enc); block128_xor(&tmp, &ocb->ldollar); cryptonite_aes_encrypt_block((block128 *) tag, key, &tmp); block128_xor((block128 *) tag, &ocb->sum_aad); } void cryptonite_aes_generic_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks) { for ( ; nb_blocks-- > 0; input++, output++) { cryptonite_aes_generic_encrypt_block(output, key, input); } } void cryptonite_aes_generic_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks) { for ( ; nb_blocks-- > 0; input++, output++) { cryptonite_aes_generic_decrypt_block(output, key, input); } } void cryptonite_aes_generic_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks) { aes_block block; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; input++, output++) { block128_xor(&block, (block128 *) input); cryptonite_aes_generic_encrypt_block(&block, key, &block); block128_copy((block128 *) output, &block); } } void cryptonite_aes_generic_decrypt_cbc(aes_block *output, aes_key *key, aes_block *ivini, aes_block *input, uint32_t nb_blocks) { aes_block block, blocko; aes_block iv; /* preload IV in block */ block128_copy(&iv, ivini); for ( ; nb_blocks-- > 0; input++, output++) { block128_copy(&block, (block128 *) input); cryptonite_aes_generic_decrypt_block(&blocko, key, &block); block128_vxor((block128 *) output, &blocko, &iv); block128_copy(&iv, &block); } } void cryptonite_aes_generic_encrypt_ctr(uint8_t *output, aes_key *key, aes_block *iv, uint8_t *input, uint32_t len) { aes_block block, o; uint32_t nb_blocks = len / 16; int i; /* preload IV in block */ block128_copy(&block, iv); for ( ; nb_blocks-- > 0; block128_inc_be(&block), output += 16, input += 16) { cryptonite_aes_encrypt_block(&o, key, &block); block128_vxor((block128 *) output, &o, (block128 *) input); } if ((len % 16) != 0) { cryptonite_aes_encrypt_block(&o, key, &block); for (i = 0; i < (len % 16); i++) { *output = ((uint8_t *) &o)[i] ^ *input; output++; input++; } } } void cryptonite_aes_generic_encrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks) { aes_block block, tweak; /* load IV and encrypt it using k2 as the tweak */ block128_copy(&tweak, dataunit); cryptonite_aes_encrypt_block(&tweak, k2, &tweak); /* TO OPTIMISE: this is really inefficient way to do that */ while (spoint-- > 0) cryptonite_gf_mulx(&tweak); for ( ; nb_blocks-- > 0; input++, output++, cryptonite_gf_mulx(&tweak)) { block128_vxor(&block, input, &tweak); cryptonite_aes_encrypt_block(&block, k1, &block); block128_vxor(output, &block, &tweak); } } void cryptonite_aes_generic_decrypt_xts(aes_block *output, aes_key *k1, aes_key *k2, aes_block *dataunit, uint32_t spoint, aes_block *input, uint32_t nb_blocks) { aes_block block, tweak; /* load IV and encrypt it using k2 as the tweak */ block128_copy(&tweak, dataunit); cryptonite_aes_encrypt_block(&tweak, k2, &tweak); /* TO OPTIMISE: this is really inefficient way to do that */ while (spoint-- > 0) cryptonite_gf_mulx(&tweak); for ( ; nb_blocks-- > 0; input++, output++, cryptonite_gf_mulx(&tweak)) { block128_vxor(&block, input, &tweak); cryptonite_aes_decrypt_block(&block, k1, &block); block128_vxor(output, &block, &tweak); } } void cryptonite_aes_generic_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length) { aes_block out; gcm->length_input += length; for (; length >= 16; input += 16, output += 16, length -= 16) { block128_inc_be(&gcm->civ); cryptonite_aes_encrypt_block(&out, key, &gcm->civ); block128_xor(&out, (block128 *) input); gcm_ghash_add(gcm, &out); block128_copy((block128 *) output, &out); } if (length > 0) { aes_block tmp; int i; block128_inc_be(&gcm->civ); /* create e(civ) in out */ cryptonite_aes_encrypt_block(&out, key, &gcm->civ); /* initialize a tmp as input and xor it to e(civ) */ block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); block128_xor_bytes(&tmp, out.b, length); gcm_ghash_add(gcm, &tmp); for (i = 0; i < length; i++) { output[i] = tmp.b[i]; } } } void cryptonite_aes_generic_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length) { aes_block out; gcm->length_input += length; for (; length >= 16; input += 16, output += 16, length -= 16) { block128_inc_be(&gcm->civ); cryptonite_aes_encrypt_block(&out, key, &gcm->civ); gcm_ghash_add(gcm, (block128 *) input); block128_xor(&out, (block128 *) input); block128_copy((block128 *) output, &out); } if (length > 0) { aes_block tmp; int i; block128_inc_be(&gcm->civ); block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); gcm_ghash_add(gcm, &tmp); cryptonite_aes_encrypt_block(&out, key, &gcm->civ); block128_xor_bytes(&tmp, out.b, length); for (i = 0; i < length; i++) { output[i] = tmp.b[i]; } } } static void ocb_generic_crypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length, int encrypt) { block128 tmp, pad; unsigned int i; for (i = 1; i <= length/16; i++, input += 16, output += 16) { /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ ocb_get_L_i(&tmp, ocb->li, i); block128_xor(&ocb->offset_enc, &tmp); block128_vxor(&tmp, &ocb->offset_enc, (block128 *) input); if (encrypt) { cryptonite_aes_encrypt_block(&tmp, key, &tmp); block128_vxor((block128 *) output, &ocb->offset_enc, &tmp); block128_xor(&ocb->sum_enc, (block128 *) input); } else { cryptonite_aes_decrypt_block(&tmp, key, &tmp); block128_vxor((block128 *) output, &ocb->offset_enc, &tmp); block128_xor(&ocb->sum_enc, (block128 *) output); } } /* process the last partial block if any */ length = length % 16; if (length > 0) { block128_xor(&ocb->offset_enc, &ocb->lstar); cryptonite_aes_encrypt_block(&pad, key, &ocb->offset_enc); if (encrypt) { block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); tmp.b[length] = 0x80; block128_xor(&ocb->sum_enc, &tmp); block128_xor(&pad, &tmp); memcpy(output, pad.b, length); output += length; } else { block128_copy(&tmp, &pad); block128_copy_bytes(&tmp, input, length); block128_xor(&tmp, &pad); tmp.b[length] = 0x80; memcpy(output, tmp.b, length); block128_xor(&ocb->sum_enc, &tmp); input += length; } } } void cryptonite_aes_generic_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length) { ocb_generic_crypt(output, ocb, key, input, length, 1); } void cryptonite_aes_generic_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length) { ocb_generic_crypt(output, ocb, key, input, length, 0); } cryptonite-0.23/cbits/blake2/sse/blake2s.c0000644000000000000000000002343113054050744016556 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #include "blake2.h" #include "blake2-impl.h" #include "blake2-config.h" #include #if defined(HAVE_SSSE3) #include #endif #if defined(HAVE_SSE41) #include #endif #if defined(HAVE_AVX) #include #endif #if defined(HAVE_XOP) #include #endif #include "blake2s-round.h" static const uint32_t blake2s_IV[8] = { 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }; /* Some helper functions */ static void blake2s_set_lastnode( blake2s_state *S ) { S->f[1] = (uint32_t)-1; } static int blake2s_is_lastblock( const blake2s_state *S ) { return S->f[0] != 0; } static void blake2s_set_lastblock( blake2s_state *S ) { if( S->last_node ) blake2s_set_lastnode( S ); S->f[0] = (uint32_t)-1; } static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) { uint64_t t = ( ( uint64_t )S->t[1] << 32 ) | S->t[0]; t += inc; S->t[0] = ( uint32_t )( t >> 0 ); S->t[1] = ( uint32_t )( t >> 32 ); } /* init2 xors IV with input parameter block */ int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) { size_t i; /*blake2s_init0( S ); */ const uint8_t * v = ( const uint8_t * )( blake2s_IV ); const uint8_t * p = ( const uint8_t * )( P ); uint8_t * h = ( uint8_t * )( S->h ); /* IV XOR ParamBlock */ memset( S, 0, sizeof( blake2s_state ) ); for( i = 0; i < BLAKE2S_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; S->outlen = P->digest_length; return 0; } /* Some sort of default parameter block initialization, for sequential blake2s */ int blake2s_init( blake2s_state *S, size_t outlen ) { blake2s_param P[1]; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = 0; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store16( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; /* memset(P->reserved, 0, sizeof(P->reserved) ); */ memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); } int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) { blake2s_param P[1]; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; if ( ( !key ) || ( !keylen ) || keylen > BLAKE2S_KEYBYTES ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store16( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; /* memset(P->reserved, 0, sizeof(P->reserved) ); */ memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); if( blake2s_init_param( S, P ) < 0 ) return -1; { uint8_t block[BLAKE2S_BLOCKBYTES]; memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } static void blake2s_compress( blake2s_state *S, const uint8_t block[BLAKE2S_BLOCKBYTES] ) { __m128i row1, row2, row3, row4; __m128i buf1, buf2, buf3, buf4; #if defined(HAVE_SSE41) __m128i t0, t1; #if !defined(HAVE_XOP) __m128i t2; #endif #endif __m128i ff0, ff1; #if defined(HAVE_SSSE3) && !defined(HAVE_XOP) const __m128i r8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); const __m128i r16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); #endif #if defined(HAVE_SSE41) const __m128i m0 = LOADU( block + 00 ); const __m128i m1 = LOADU( block + 16 ); const __m128i m2 = LOADU( block + 32 ); const __m128i m3 = LOADU( block + 48 ); #else const uint32_t m0 = load32(block + 0 * sizeof(uint32_t)); const uint32_t m1 = load32(block + 1 * sizeof(uint32_t)); const uint32_t m2 = load32(block + 2 * sizeof(uint32_t)); const uint32_t m3 = load32(block + 3 * sizeof(uint32_t)); const uint32_t m4 = load32(block + 4 * sizeof(uint32_t)); const uint32_t m5 = load32(block + 5 * sizeof(uint32_t)); const uint32_t m6 = load32(block + 6 * sizeof(uint32_t)); const uint32_t m7 = load32(block + 7 * sizeof(uint32_t)); const uint32_t m8 = load32(block + 8 * sizeof(uint32_t)); const uint32_t m9 = load32(block + 9 * sizeof(uint32_t)); const uint32_t m10 = load32(block + 10 * sizeof(uint32_t)); const uint32_t m11 = load32(block + 11 * sizeof(uint32_t)); const uint32_t m12 = load32(block + 12 * sizeof(uint32_t)); const uint32_t m13 = load32(block + 13 * sizeof(uint32_t)); const uint32_t m14 = load32(block + 14 * sizeof(uint32_t)); const uint32_t m15 = load32(block + 15 * sizeof(uint32_t)); #endif row1 = ff0 = LOADU( &S->h[0] ); row2 = ff1 = LOADU( &S->h[4] ); row3 = _mm_loadu_si128( (__m128i const *)&blake2s_IV[0] ); row4 = _mm_xor_si128( _mm_loadu_si128( (__m128i const *)&blake2s_IV[4] ), LOADU( &S->t[0] ) ); ROUND( 0 ); ROUND( 1 ); ROUND( 2 ); ROUND( 3 ); ROUND( 4 ); ROUND( 5 ); ROUND( 6 ); ROUND( 7 ); ROUND( 8 ); ROUND( 9 ); STOREU( &S->h[0], _mm_xor_si128( ff0, _mm_xor_si128( row1, row3 ) ) ); STOREU( &S->h[4], _mm_xor_si128( ff1, _mm_xor_si128( row2, row4 ) ) ); } int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; if( inlen > 0 ) { size_t left = S->buflen; size_t fill = BLAKE2S_BLOCKBYTES - left; if( inlen > fill ) { S->buflen = 0; memcpy( S->buf + left, in, fill ); /* Fill buffer */ blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S->buf ); /* Compress */ in += fill; inlen -= fill; while(inlen > BLAKE2S_BLOCKBYTES) { blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); blake2s_compress( S, in ); in += BLAKE2S_BLOCKBYTES; inlen -= BLAKE2S_BLOCKBYTES; } } memcpy( S->buf + S->buflen, in, inlen ); S->buflen += inlen; } return 0; } int blake2s_final( blake2s_state *S, void *out, size_t outlen ) { uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; size_t i; if( out == NULL || outlen < S->outlen ) return -1; if( blake2s_is_lastblock( S ) ) return -1; blake2s_increment_counter( S, (uint32_t)S->buflen ); blake2s_set_lastblock( S ); memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ blake2s_compress( S, S->buf ); for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); memcpy( out, buffer, S->outlen ); secure_zero_memory( buffer, sizeof(buffer) ); return 0; } /* inlen, at least, should be uint64_t. Others can be size_t. */ int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { blake2s_state S[1]; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if ( NULL == key && keylen > 0) return -1; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; if( keylen > BLAKE2S_KEYBYTES ) return -1; if( keylen > 0 ) { if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; } else { if( blake2s_init( S, outlen ) < 0 ) return -1; } blake2s_update( S, ( const uint8_t * )in, inlen ); blake2s_final( S, out, outlen ); return 0; } #if defined(SUPERCOP) int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) { return blake2s( out, BLAKE2S_OUTBYTES, in, inlen, NULL, 0 ); } #endif #if defined(BLAKE2S_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2S_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2s_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2s_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2s_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/cbits/blake2/sse/blake2sp.c0000644000000000000000000002200313054050744016730 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #if defined(_OPENMP) #include #endif #include "blake2.h" #include "blake2-impl.h" #define PARALLELISM_DEGREE 8 /* blake2sp_init_param defaults to setting the expecting output length from the digest_length parameter block field. In some cases, however, we do not want this, as the output length of these instances is given by inner_length instead. */ static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P ) { int err = blake2s_init_param(S, P); S->outlen = P->inner_length; return err; } static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint64_t offset ) { blake2s_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0; P->node_offset = offset; P->xof_length = 0; P->node_depth = 0; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2sp_init_leaf_param( S, P ); } static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen ) { blake2s_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0; P->node_offset = 0; P->xof_length = 0; P->node_depth = 1; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); } int blake2sp_init( blake2sp_state *S, size_t outlen ) { size_t i; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2sp_init_root( S->R, outlen, 0 ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; return 0; } int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) { size_t i; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2sp_init_root( S->R, outlen, keylen ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; { uint8_t block[BLAKE2S_BLOCKBYTES]; memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; size_t left = S->buflen; size_t fill = sizeof( S->buf ) - left; size_t i; if( left && inlen >= fill ) { memcpy( S->buf + left, in, fill ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); in += fill; inlen -= fill; left = 0; } #if defined(_OPENMP) #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2S_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) { blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; } } in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; if( inlen > 0 ) memcpy( S->buf + left, in, inlen ); S->buflen = left + inlen; return 0; } int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; size_t i; if(out == NULL || outlen < S->outlen) { return -1; } for( i = 0; i < PARALLELISM_DEGREE; ++i ) { if( S->buflen > i * BLAKE2S_BLOCKBYTES ) { size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); } blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); } for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); return blake2s_final( S->R, out, S->outlen ); } int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; blake2s_state S[PARALLELISM_DEGREE][1]; blake2s_state FS[1]; size_t i; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if ( NULL == key && keylen > 0) return -1; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; if( keylen > BLAKE2S_KEYBYTES ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ if( keylen > 0 ) { uint8_t block[BLAKE2S_BLOCKBYTES]; memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2S_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) { blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; } if( inlen__ > i * BLAKE2S_BLOCKBYTES ) { const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES; const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; blake2s_update( S[i], in__, len ); } blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES ); } if( blake2sp_init_root( FS, outlen, keylen ) < 0 ) return -1; FS->last_node = 1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); return blake2s_final( FS, out, outlen ); } #if defined(BLAKE2SP_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2S_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2sp_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2sp_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2sp_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/cbits/blake2/sse/blake2b.c0000644000000000000000000002421713054050744016540 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #include "blake2.h" #include "blake2-impl.h" #include "blake2-config.h" #ifdef _MSC_VER #include /* for _mm_set_epi64x */ #endif #include #if defined(HAVE_SSSE3) #include #endif #if defined(HAVE_SSE41) #include #endif #if defined(HAVE_AVX) #include #endif #if defined(HAVE_XOP) #include #endif #include "blake2b-round.h" static const uint64_t blake2b_IV[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; /* Some helper functions */ static void blake2b_set_lastnode( blake2b_state *S ) { S->f[1] = (uint64_t)-1; } static int blake2b_is_lastblock( const blake2b_state *S ) { return S->f[0] != 0; } static void blake2b_set_lastblock( blake2b_state *S ) { if( S->last_node ) blake2b_set_lastnode( S ); S->f[0] = (uint64_t)-1; } static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) { S->t[0] += inc; S->t[1] += ( S->t[0] < inc ); } /* init xors IV with input parameter block */ int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) { size_t i; /*blake2b_init0( S ); */ const unsigned char * v = ( const unsigned char * )( blake2b_IV ); const unsigned char * p = ( const unsigned char * )( P ); unsigned char * h = ( unsigned char * )( S->h ); /* IV XOR ParamBlock */ memset( S, 0, sizeof( blake2b_state ) ); for( i = 0; i < BLAKE2B_OUTBYTES; ++i ) h[i] = v[i] ^ p[i]; S->outlen = P->digest_length; return 0; } /* Some sort of default parameter block initialization, for sequential blake2b */ int blake2b_init( blake2b_state *S, size_t outlen ) { blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = 0; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store32( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2b_init_param( S, P ); } int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) { blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; if ( ( !keylen ) || keylen > BLAKE2B_KEYBYTES ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store32( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); if( blake2b_init_param( S, P ) < 0 ) return 0; { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) { __m128i row1l, row1h; __m128i row2l, row2h; __m128i row3l, row3h; __m128i row4l, row4h; __m128i b0, b1; __m128i t0, t1; #if defined(HAVE_SSSE3) && !defined(HAVE_XOP) const __m128i r16 = _mm_setr_epi8( 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9 ); const __m128i r24 = _mm_setr_epi8( 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10 ); #endif #if defined(HAVE_SSE41) const __m128i m0 = LOADU( block + 00 ); const __m128i m1 = LOADU( block + 16 ); const __m128i m2 = LOADU( block + 32 ); const __m128i m3 = LOADU( block + 48 ); const __m128i m4 = LOADU( block + 64 ); const __m128i m5 = LOADU( block + 80 ); const __m128i m6 = LOADU( block + 96 ); const __m128i m7 = LOADU( block + 112 ); #else const uint64_t m0 = load64(block + 0 * sizeof(uint64_t)); const uint64_t m1 = load64(block + 1 * sizeof(uint64_t)); const uint64_t m2 = load64(block + 2 * sizeof(uint64_t)); const uint64_t m3 = load64(block + 3 * sizeof(uint64_t)); const uint64_t m4 = load64(block + 4 * sizeof(uint64_t)); const uint64_t m5 = load64(block + 5 * sizeof(uint64_t)); const uint64_t m6 = load64(block + 6 * sizeof(uint64_t)); const uint64_t m7 = load64(block + 7 * sizeof(uint64_t)); const uint64_t m8 = load64(block + 8 * sizeof(uint64_t)); const uint64_t m9 = load64(block + 9 * sizeof(uint64_t)); const uint64_t m10 = load64(block + 10 * sizeof(uint64_t)); const uint64_t m11 = load64(block + 11 * sizeof(uint64_t)); const uint64_t m12 = load64(block + 12 * sizeof(uint64_t)); const uint64_t m13 = load64(block + 13 * sizeof(uint64_t)); const uint64_t m14 = load64(block + 14 * sizeof(uint64_t)); const uint64_t m15 = load64(block + 15 * sizeof(uint64_t)); #endif row1l = LOADU( &S->h[0] ); row1h = LOADU( &S->h[2] ); row2l = LOADU( &S->h[4] ); row2h = LOADU( &S->h[6] ); row3l = LOADU( &blake2b_IV[0] ); row3h = LOADU( &blake2b_IV[2] ); row4l = _mm_xor_si128( LOADU( &blake2b_IV[4] ), LOADU( &S->t[0] ) ); row4h = _mm_xor_si128( LOADU( &blake2b_IV[6] ), LOADU( &S->f[0] ) ); ROUND( 0 ); ROUND( 1 ); ROUND( 2 ); ROUND( 3 ); ROUND( 4 ); ROUND( 5 ); ROUND( 6 ); ROUND( 7 ); ROUND( 8 ); ROUND( 9 ); ROUND( 10 ); ROUND( 11 ); row1l = _mm_xor_si128( row3l, row1l ); row1h = _mm_xor_si128( row3h, row1h ); STOREU( &S->h[0], _mm_xor_si128( LOADU( &S->h[0] ), row1l ) ); STOREU( &S->h[2], _mm_xor_si128( LOADU( &S->h[2] ), row1h ) ); row2l = _mm_xor_si128( row4l, row2l ); row2h = _mm_xor_si128( row4h, row2h ); STOREU( &S->h[4], _mm_xor_si128( LOADU( &S->h[4] ), row2l ) ); STOREU( &S->h[6], _mm_xor_si128( LOADU( &S->h[6] ), row2h ) ); } int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; if( inlen > 0 ) { size_t left = S->buflen; size_t fill = BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) { S->buflen = 0; memcpy( S->buf + left, in, fill ); /* Fill buffer */ blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); /* Compress */ in += fill; inlen -= fill; while(inlen > BLAKE2B_BLOCKBYTES) { blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); blake2b_compress( S, in ); in += BLAKE2B_BLOCKBYTES; inlen -= BLAKE2B_BLOCKBYTES; } } memcpy( S->buf + S->buflen, in, inlen ); S->buflen += inlen; } return 0; } int blake2b_final( blake2b_state *S, void *out, size_t outlen ) { if( out == NULL || outlen < S->outlen ) return -1; if( blake2b_is_lastblock( S ) ) return -1; blake2b_increment_counter( S, S->buflen ); blake2b_set_lastblock( S ); memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ blake2b_compress( S, S->buf ); memcpy( out, &S->h[0], S->outlen ); return 0; } int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { blake2b_state S[1]; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if( NULL == key && keylen > 0 ) return -1; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( keylen > BLAKE2B_KEYBYTES ) return -1; if( keylen ) { if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; } else { if( blake2b_init( S, outlen ) < 0 ) return -1; } blake2b_update( S, ( const uint8_t * )in, inlen ); blake2b_final( S, out, outlen ); return 0; } int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { return blake2b(out, outlen, in, inlen, key, keylen); } #if defined(SUPERCOP) int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) { return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 ); } #endif #if defined(BLAKE2B_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2B_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2b_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2b_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2b_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/cbits/blake2/sse/blake2bp.c0000644000000000000000000002222413054050744016714 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #include #if defined(_OPENMP) #include #endif #include "blake2.h" #include "blake2-impl.h" #define PARALLELISM_DEGREE 4 /* blake2b_init_param defaults to setting the expecting output length from the digest_length parameter block field. In some cases, however, we do not want this, as the output length of these instances is given by inner_length instead. */ static int blake2bp_init_leaf_param( blake2b_state *S, const blake2b_param *P ) { int err = blake2b_init_param(S, P); S->outlen = P->inner_length; return err; } static int blake2bp_init_leaf( blake2b_state *S, size_t outlen, size_t keylen, uint64_t offset ) { blake2b_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0; P->node_offset = offset; P->xof_length = 0; P->node_depth = 0; P->inner_length = BLAKE2B_OUTBYTES; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2bp_init_leaf_param( S, P ); } static int blake2bp_init_root( blake2b_state *S, size_t outlen, size_t keylen ) { blake2b_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; P->leaf_length = 0; P->node_offset = 0; P->xof_length = 0; P->node_depth = 1; P->inner_length = BLAKE2B_OUTBYTES; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2b_init_param( S, P ); } int blake2bp_init( blake2bp_state *S, size_t outlen ) { size_t i; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2bp_init_root( S->R, outlen, 0 ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; return 0; } int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) { size_t i; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2bp_init_root( S->R, outlen, keylen ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } int blake2bp_update( blake2bp_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; size_t left = S->buflen; size_t fill = sizeof( S->buf ) - left; size_t i; if( left && inlen >= fill ) { memcpy( S->buf + left, in, fill ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); in += fill; inlen -= fill; left = 0; } #if defined(_OPENMP) #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S->S[i], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } } in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; if( inlen > 0 ) memcpy( S->buf + left, in, inlen ); S->buflen = left + inlen; return 0; } int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; size_t i; if(out == NULL || outlen < S->outlen) { return -1; } for( i = 0; i < PARALLELISM_DEGREE; ++i ) { if( S->buflen > i * BLAKE2B_BLOCKBYTES ) { size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); } blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); } for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); return blake2b_final( S->R, out, S->outlen ); } int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; blake2b_state S[PARALLELISM_DEGREE][1]; blake2b_state FS[1]; size_t i; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if( NULL == key && keylen > 0 ) return -1; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( keylen > BLAKE2B_KEYBYTES ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ if( keylen > 0 ) { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S[i], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } if( inlen__ > i * BLAKE2B_BLOCKBYTES ) { const size_t left = inlen__ - i * BLAKE2B_BLOCKBYTES; const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; blake2b_update( S[i], in__, len ); } blake2b_final( S[i], hash[i], BLAKE2B_OUTBYTES ); } if( blake2bp_init_root( FS, outlen, keylen ) < 0 ) return -1; FS->last_node = 1; /* Mark as last node */ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); return blake2b_final( FS, out, outlen ); } #if defined(BLAKE2BP_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2B_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2bp( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2bp_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2bp_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2bp_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2bp_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2bp_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/cbits/blake2/ref/blake2s-ref.c0000644000000000000000000002270413054050744017314 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #include "blake2.h" #include "blake2-impl.h" static const uint32_t blake2s_IV[8] = { 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }; static const uint8_t blake2s_sigma[10][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , }; static void blake2s_set_lastnode( blake2s_state *S ) { S->f[1] = (uint32_t)-1; } /* Some helper functions, not necessarily useful */ static int blake2s_is_lastblock( const blake2s_state *S ) { return S->f[0] != 0; } static void blake2s_set_lastblock( blake2s_state *S ) { if( S->last_node ) blake2s_set_lastnode( S ); S->f[0] = (uint32_t)-1; } static void blake2s_increment_counter( blake2s_state *S, const uint32_t inc ) { S->t[0] += inc; S->t[1] += ( S->t[0] < inc ); } static void blake2s_init0( blake2s_state *S ) { size_t i; memset( S, 0, sizeof( blake2s_state ) ); for( i = 0; i < 8; ++i ) S->h[i] = blake2s_IV[i]; } /* init2 xors IV with input parameter block */ int blake2s_init_param( blake2s_state *S, const blake2s_param *P ) { const unsigned char *p = ( const unsigned char * )( P ); size_t i; blake2s_init0( S ); /* IV XOR ParamBlock */ for( i = 0; i < 8; ++i ) S->h[i] ^= load32( &p[i * 4] ); S->outlen = P->digest_length; return 0; } /* Sequential blake2s initialization */ int blake2s_init( blake2s_state *S, size_t outlen ) { blake2s_param P[1]; /* Move interval verification here? */ if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = 0; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store16( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; /* memset(P->reserved, 0, sizeof(P->reserved) ); */ memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); } int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ) { blake2s_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2S_OUTBYTES ) ) return -1; if ( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store16( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; /* memset(P->reserved, 0, sizeof(P->reserved) ); */ memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); if( blake2s_init_param( S, P ) < 0 ) return -1; { uint8_t block[BLAKE2S_BLOCKBYTES]; memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); blake2s_update( S, block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } #define G(r,i,a,b,c,d) \ do { \ a = a + b + m[blake2s_sigma[r][2*i+0]]; \ d = rotr32(d ^ a, 16); \ c = c + d; \ b = rotr32(b ^ c, 12); \ a = a + b + m[blake2s_sigma[r][2*i+1]]; \ d = rotr32(d ^ a, 8); \ c = c + d; \ b = rotr32(b ^ c, 7); \ } while(0) #define ROUND(r) \ do { \ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ G(r,2,v[ 2],v[ 6],v[10],v[14]); \ G(r,3,v[ 3],v[ 7],v[11],v[15]); \ G(r,4,v[ 0],v[ 5],v[10],v[15]); \ G(r,5,v[ 1],v[ 6],v[11],v[12]); \ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ } while(0) static void blake2s_compress( blake2s_state *S, const uint8_t in[BLAKE2S_BLOCKBYTES] ) { uint32_t m[16]; uint32_t v[16]; size_t i; for( i = 0; i < 16; ++i ) { m[i] = load32( in + i * sizeof( m[i] ) ); } for( i = 0; i < 8; ++i ) { v[i] = S->h[i]; } v[ 8] = blake2s_IV[0]; v[ 9] = blake2s_IV[1]; v[10] = blake2s_IV[2]; v[11] = blake2s_IV[3]; v[12] = S->t[0] ^ blake2s_IV[4]; v[13] = S->t[1] ^ blake2s_IV[5]; v[14] = S->f[0] ^ blake2s_IV[6]; v[15] = S->f[1] ^ blake2s_IV[7]; ROUND( 0 ); ROUND( 1 ); ROUND( 2 ); ROUND( 3 ); ROUND( 4 ); ROUND( 5 ); ROUND( 6 ); ROUND( 7 ); ROUND( 8 ); ROUND( 9 ); for( i = 0; i < 8; ++i ) { S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; } } #undef G #undef ROUND int blake2s_update( blake2s_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; if( inlen > 0 ) { size_t left = S->buflen; size_t fill = BLAKE2S_BLOCKBYTES - left; if( inlen > fill ) { S->buflen = 0; memcpy( S->buf + left, in, fill ); /* Fill buffer */ blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); blake2s_compress( S, S->buf ); /* Compress */ in += fill; inlen -= fill; while(inlen > BLAKE2S_BLOCKBYTES) { blake2s_increment_counter(S, BLAKE2S_BLOCKBYTES); blake2s_compress( S, in ); in += BLAKE2S_BLOCKBYTES; inlen -= BLAKE2S_BLOCKBYTES; } } memcpy( S->buf + S->buflen, in, inlen ); S->buflen += inlen; } return 0; } int blake2s_final( blake2s_state *S, void *out, size_t outlen ) { uint8_t buffer[BLAKE2S_OUTBYTES] = {0}; size_t i; if( out == NULL || outlen < S->outlen ) return -1; if( blake2s_is_lastblock( S ) ) return -1; blake2s_increment_counter( S, ( uint32_t )S->buflen ); blake2s_set_lastblock( S ); memset( S->buf + S->buflen, 0, BLAKE2S_BLOCKBYTES - S->buflen ); /* Padding */ blake2s_compress( S, S->buf ); for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store32( buffer + sizeof( S->h[i] ) * i, S->h[i] ); memcpy( out, buffer, outlen ); secure_zero_memory(buffer, sizeof(buffer)); return 0; } int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { blake2s_state S[1]; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if ( NULL == key && keylen > 0) return -1; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; if( keylen > BLAKE2S_KEYBYTES ) return -1; if( keylen > 0 ) { if( blake2s_init_key( S, outlen, key, keylen ) < 0 ) return -1; } else { if( blake2s_init( S, outlen ) < 0 ) return -1; } blake2s_update( S, ( const uint8_t * )in, inlen ); blake2s_final( S, out, outlen ); return 0; } #if defined(SUPERCOP) int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) { return blake2s( out, BLAKE2S_OUTBYTES in, inlen, NULL, 0 ); } #endif #if defined(BLAKE2S_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2S_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2s( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); if( 0 != memcmp( hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2s_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2s_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2s_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2s_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2s_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2s_keyed_kat[i], BLAKE2S_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/cbits/blake2/ref/blake2sp-ref.c0000644000000000000000000002210613054050744017470 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #if defined(_OPENMP) #include #endif #include "blake2.h" #include "blake2-impl.h" #define PARALLELISM_DEGREE 8 /* blake2sp_init_param defaults to setting the expecting output length from the digest_length parameter block field. In some cases, however, we do not want this, as the output length of these instances is given by inner_length instead. */ static int blake2sp_init_leaf_param( blake2s_state *S, const blake2s_param *P ) { int err = blake2s_init_param(S, P); S->outlen = P->inner_length; return err; } static int blake2sp_init_leaf( blake2s_state *S, size_t outlen, size_t keylen, uint64_t offset ) { blake2s_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; store32( &P->leaf_length, 0 ); store32( &P->node_offset, offset ); store16( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2sp_init_leaf_param( S, P ); } static int blake2sp_init_root( blake2s_state *S, size_t outlen, size_t keylen ) { blake2s_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store16( &P->xof_length, 0 ); P->node_depth = 1; P->inner_length = BLAKE2S_OUTBYTES; memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2s_init_param( S, P ); } int blake2sp_init( blake2sp_state *S, size_t outlen ) { size_t i; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2sp_init_root( S->R, outlen, 0 ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; return 0; } int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ) { size_t i; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; if( !key || !keylen || keylen > BLAKE2S_KEYBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2sp_init_root( S->R, outlen, keylen ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; { uint8_t block[BLAKE2S_BLOCKBYTES]; memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->S[i], block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } int blake2sp_update( blake2sp_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; size_t left = S->buflen; size_t fill = sizeof( S->buf ) - left; size_t i; if( left && inlen >= fill ) { memcpy( S->buf + left, in, fill ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, BLAKE2S_BLOCKBYTES ); in += fill; inlen -= fill; left = 0; } #if defined(_OPENMP) #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2S_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) { blake2s_update( S->S[i], in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; } } in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ); inlen %= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; if( inlen > 0 ) memcpy( S->buf + left, in, inlen ); S->buflen = left + inlen; return 0; } int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; size_t i; if(out == NULL || outlen < S->outlen) { return -1; } for( i = 0; i < PARALLELISM_DEGREE; ++i ) { if( S->buflen > i * BLAKE2S_BLOCKBYTES ) { size_t left = S->buflen - i * BLAKE2S_BLOCKBYTES; if( left > BLAKE2S_BLOCKBYTES ) left = BLAKE2S_BLOCKBYTES; blake2s_update( S->S[i], S->buf + i * BLAKE2S_BLOCKBYTES, left ); } blake2s_final( S->S[i], hash[i], BLAKE2S_OUTBYTES ); } for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S->R, hash[i], BLAKE2S_OUTBYTES ); return blake2s_final( S->R, out, S->outlen ); } int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2S_OUTBYTES]; blake2s_state S[PARALLELISM_DEGREE][1]; blake2s_state FS[1]; size_t i; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if ( NULL == key && keylen > 0) return -1; if( !outlen || outlen > BLAKE2S_OUTBYTES ) return -1; if( keylen > BLAKE2S_KEYBYTES ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2sp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ if( keylen > 0 ) { uint8_t block[BLAKE2S_BLOCKBYTES]; memset( block, 0, BLAKE2S_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( S[i], block, BLAKE2S_BLOCKBYTES ); secure_zero_memory( block, BLAKE2S_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2S_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES ) { blake2s_update( S[i], in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; } if( inlen__ > i * BLAKE2S_BLOCKBYTES ) { const size_t left = inlen__ - i * BLAKE2S_BLOCKBYTES; const size_t len = left <= BLAKE2S_BLOCKBYTES ? left : BLAKE2S_BLOCKBYTES; blake2s_update( S[i], in__, len ); } blake2s_final( S[i], hash[i], BLAKE2S_OUTBYTES ); } if( blake2sp_init_root( FS, outlen, keylen ) < 0 ) return -1; FS->last_node = 1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_update( FS, hash[i], BLAKE2S_OUTBYTES ); return blake2s_final( FS, out, outlen ); } #if defined(BLAKE2SP_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2S_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2S_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2sp( hash, BLAKE2S_OUTBYTES, buf, i, key, BLAKE2S_KEYBYTES ); if( 0 != memcmp( hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2S_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2S_OUTBYTES]; blake2sp_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2sp_init_key(&S, BLAKE2S_OUTBYTES, key, BLAKE2S_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2sp_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2sp_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2sp_final(&S, hash, BLAKE2S_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2sp_keyed_kat[i], BLAKE2S_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/cbits/blake2/ref/blake2b-ref.c0000644000000000000000000002351113054050744017270 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #include "blake2.h" #include "blake2-impl.h" static const uint64_t blake2b_IV[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; static const uint8_t blake2b_sigma[12][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } }; static void blake2b_set_lastnode( blake2b_state *S ) { S->f[1] = (uint64_t)-1; } /* Some helper functions, not necessarily useful */ static int blake2b_is_lastblock( const blake2b_state *S ) { return S->f[0] != 0; } static void blake2b_set_lastblock( blake2b_state *S ) { if( S->last_node ) blake2b_set_lastnode( S ); S->f[0] = (uint64_t)-1; } static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc ) { S->t[0] += inc; S->t[1] += ( S->t[0] < inc ); } static void blake2b_init0( blake2b_state *S ) { size_t i; memset( S, 0, sizeof( blake2b_state ) ); for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i]; } /* init xors IV with input parameter block */ int blake2b_init_param( blake2b_state *S, const blake2b_param *P ) { const uint8_t *p = ( const uint8_t * )( P ); size_t i; blake2b_init0( S ); /* IV XOR ParamBlock */ for( i = 0; i < 8; ++i ) S->h[i] ^= load64( p + sizeof( S->h[i] ) * i ); S->outlen = P->digest_length; return 0; } int blake2b_init( blake2b_state *S, size_t outlen ) { blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = 0; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store32( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2b_init_param( S, P ); } int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ) { blake2b_param P[1]; if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1; if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = 1; P->depth = 1; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store32( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = 0; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); if( blake2b_init_param( S, P ) < 0 ) return -1; { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); blake2b_update( S, block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } #define G(r,i,a,b,c,d) \ do { \ a = a + b + m[blake2b_sigma[r][2*i+0]]; \ d = rotr64(d ^ a, 32); \ c = c + d; \ b = rotr64(b ^ c, 24); \ a = a + b + m[blake2b_sigma[r][2*i+1]]; \ d = rotr64(d ^ a, 16); \ c = c + d; \ b = rotr64(b ^ c, 63); \ } while(0) #define ROUND(r) \ do { \ G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \ G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \ G(r,2,v[ 2],v[ 6],v[10],v[14]); \ G(r,3,v[ 3],v[ 7],v[11],v[15]); \ G(r,4,v[ 0],v[ 5],v[10],v[15]); \ G(r,5,v[ 1],v[ 6],v[11],v[12]); \ G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \ G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \ } while(0) static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] ) { uint64_t m[16]; uint64_t v[16]; size_t i; for( i = 0; i < 16; ++i ) { m[i] = load64( block + i * sizeof( m[i] ) ); } for( i = 0; i < 8; ++i ) { v[i] = S->h[i]; } v[ 8] = blake2b_IV[0]; v[ 9] = blake2b_IV[1]; v[10] = blake2b_IV[2]; v[11] = blake2b_IV[3]; v[12] = blake2b_IV[4] ^ S->t[0]; v[13] = blake2b_IV[5] ^ S->t[1]; v[14] = blake2b_IV[6] ^ S->f[0]; v[15] = blake2b_IV[7] ^ S->f[1]; ROUND( 0 ); ROUND( 1 ); ROUND( 2 ); ROUND( 3 ); ROUND( 4 ); ROUND( 5 ); ROUND( 6 ); ROUND( 7 ); ROUND( 8 ); ROUND( 9 ); ROUND( 10 ); ROUND( 11 ); for( i = 0; i < 8; ++i ) { S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; } } #undef G #undef ROUND int blake2b_update( blake2b_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; if( inlen > 0 ) { size_t left = S->buflen; size_t fill = BLAKE2B_BLOCKBYTES - left; if( inlen > fill ) { S->buflen = 0; memcpy( S->buf + left, in, fill ); /* Fill buffer */ blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES ); blake2b_compress( S, S->buf ); /* Compress */ in += fill; inlen -= fill; while(inlen > BLAKE2B_BLOCKBYTES) { blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); blake2b_compress( S, in ); in += BLAKE2B_BLOCKBYTES; inlen -= BLAKE2B_BLOCKBYTES; } } memcpy( S->buf + S->buflen, in, inlen ); S->buflen += inlen; } return 0; } int blake2b_final( blake2b_state *S, void *out, size_t outlen ) { uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; size_t i; if( out == NULL || outlen < S->outlen ) return -1; if( blake2b_is_lastblock( S ) ) return -1; blake2b_increment_counter( S, S->buflen ); blake2b_set_lastblock( S ); memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */ blake2b_compress( S, S->buf ); for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */ store64( buffer + sizeof( S->h[i] ) * i, S->h[i] ); memcpy( out, buffer, S->outlen ); secure_zero_memory(buffer, sizeof(buffer)); return 0; } /* inlen, at least, should be uint64_t. Others can be size_t. */ int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { blake2b_state S[1]; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if( NULL == key && keylen > 0 ) return -1; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( keylen > BLAKE2B_KEYBYTES ) return -1; if( keylen > 0 ) { if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1; } else { if( blake2b_init( S, outlen ) < 0 ) return -1; } blake2b_update( S, ( const uint8_t * )in, inlen ); blake2b_final( S, out, outlen ); return 0; } int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { return blake2b(out, outlen, in, inlen, key, keylen); } #if defined(SUPERCOP) int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen ) { return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 ); } #endif #if defined(BLAKE2B_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2B_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2b_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2b_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2b_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/cbits/blake2/ref/blake2bp-ref.c0000644000000000000000000002232513054050744017452 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #include #include #include #include #if defined(_OPENMP) #include #endif #include "blake2.h" #include "blake2-impl.h" #define PARALLELISM_DEGREE 4 /* blake2b_init_param defaults to setting the expecting output length from the digest_length parameter block field. In some cases, however, we do not want this, as the output length of these instances is given by inner_length instead. */ static int blake2bp_init_leaf_param( blake2b_state *S, const blake2b_param *P ) { int err = blake2b_init_param(S, P); S->outlen = P->inner_length; return err; } static int blake2bp_init_leaf( blake2b_state *S, size_t outlen, size_t keylen, uint64_t offset ) { blake2b_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; store32( &P->leaf_length, 0 ); store32( &P->node_offset, offset ); store32( &P->xof_length, 0 ); P->node_depth = 0; P->inner_length = BLAKE2B_OUTBYTES; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2bp_init_leaf_param( S, P ); } static int blake2bp_init_root( blake2b_state *S, size_t outlen, size_t keylen ) { blake2b_param P[1]; P->digest_length = (uint8_t)outlen; P->key_length = (uint8_t)keylen; P->fanout = PARALLELISM_DEGREE; P->depth = 2; store32( &P->leaf_length, 0 ); store32( &P->node_offset, 0 ); store32( &P->xof_length, 0 ); P->node_depth = 1; P->inner_length = BLAKE2B_OUTBYTES; memset( P->reserved, 0, sizeof( P->reserved ) ); memset( P->salt, 0, sizeof( P->salt ) ); memset( P->personal, 0, sizeof( P->personal ) ); return blake2b_init_param( S, P ); } int blake2bp_init( blake2bp_state *S, size_t outlen ) { size_t i; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2bp_init_root( S->R, outlen, 0 ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S->S[i], outlen, 0, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; return 0; } int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ) { size_t i; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1; memset( S->buf, 0, sizeof( S->buf ) ); S->buflen = 0; S->outlen = outlen; if( blake2bp_init_root( S->R, outlen, keylen ) < 0 ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S->S[i], outlen, keylen, i ) < 0 ) return -1; S->R->last_node = 1; S->S[PARALLELISM_DEGREE - 1]->last_node = 1; { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } return 0; } int blake2bp_update( blake2bp_state *S, const void *pin, size_t inlen ) { const unsigned char * in = (const unsigned char *)pin; size_t left = S->buflen; size_t fill = sizeof( S->buf ) - left; size_t i; if( left && inlen >= fill ) { memcpy( S->buf + left, in, fill ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, BLAKE2B_BLOCKBYTES ); in += fill; inlen -= fill; left = 0; } #if defined(_OPENMP) #pragma omp parallel shared(S), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S->S[i], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } } in += inlen - inlen % ( PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ); inlen %= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; if( inlen > 0 ) memcpy( S->buf + left, in, inlen ); S->buflen = left + inlen; return 0; } int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; size_t i; if(out == NULL || outlen < S->outlen) { return -1; } for( i = 0; i < PARALLELISM_DEGREE; ++i ) { if( S->buflen > i * BLAKE2B_BLOCKBYTES ) { size_t left = S->buflen - i * BLAKE2B_BLOCKBYTES; if( left > BLAKE2B_BLOCKBYTES ) left = BLAKE2B_BLOCKBYTES; blake2b_update( S->S[i], S->buf + i * BLAKE2B_BLOCKBYTES, left ); } blake2b_final( S->S[i], hash[i], BLAKE2B_OUTBYTES ); } for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S->R, hash[i], BLAKE2B_OUTBYTES ); return blake2b_final( S->R, out, S->outlen ); } int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) { uint8_t hash[PARALLELISM_DEGREE][BLAKE2B_OUTBYTES]; blake2b_state S[PARALLELISM_DEGREE][1]; blake2b_state FS[1]; size_t i; /* Verify parameters */ if ( NULL == in && inlen > 0 ) return -1; if ( NULL == out ) return -1; if( NULL == key && keylen > 0 ) return -1; if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1; if( keylen > BLAKE2B_KEYBYTES ) return -1; for( i = 0; i < PARALLELISM_DEGREE; ++i ) if( blake2bp_init_leaf( S[i], outlen, keylen, i ) < 0 ) return -1; S[PARALLELISM_DEGREE - 1]->last_node = 1; /* mark last node */ if( keylen > 0 ) { uint8_t block[BLAKE2B_BLOCKBYTES]; memset( block, 0, BLAKE2B_BLOCKBYTES ); memcpy( block, key, keylen ); for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( S[i], block, BLAKE2B_BLOCKBYTES ); secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */ } #if defined(_OPENMP) #pragma omp parallel shared(S,hash), num_threads(PARALLELISM_DEGREE) #else for( i = 0; i < PARALLELISM_DEGREE; ++i ) #endif { #if defined(_OPENMP) size_t i = omp_get_thread_num(); #endif size_t inlen__ = inlen; const unsigned char *in__ = ( const unsigned char * )in; in__ += i * BLAKE2B_BLOCKBYTES; while( inlen__ >= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES ) { blake2b_update( S[i], in__, BLAKE2B_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2B_BLOCKBYTES; } if( inlen__ > i * BLAKE2B_BLOCKBYTES ) { const size_t left = inlen__ - i * BLAKE2B_BLOCKBYTES; const size_t len = left <= BLAKE2B_BLOCKBYTES ? left : BLAKE2B_BLOCKBYTES; blake2b_update( S[i], in__, len ); } blake2b_final( S[i], hash[i], BLAKE2B_OUTBYTES ); } if( blake2bp_init_root( FS, outlen, keylen ) < 0 ) return -1; FS->last_node = 1; /* Mark as last node */ for( i = 0; i < PARALLELISM_DEGREE; ++i ) blake2b_update( FS, hash[i], BLAKE2B_OUTBYTES ); return blake2b_final( FS, out, outlen );; } #if defined(BLAKE2BP_SELFTEST) #include #include "blake2-kat.h" int main( void ) { uint8_t key[BLAKE2B_KEYBYTES]; uint8_t buf[BLAKE2_KAT_LENGTH]; size_t i, step; for( i = 0; i < BLAKE2B_KEYBYTES; ++i ) key[i] = ( uint8_t )i; for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) buf[i] = ( uint8_t )i; /* Test simple API */ for( i = 0; i < BLAKE2_KAT_LENGTH; ++i ) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2bp( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES ); if( 0 != memcmp( hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES ) ) { goto fail; } } /* Test streaming API */ for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { uint8_t hash[BLAKE2B_OUTBYTES]; blake2bp_state S; uint8_t * p = buf; size_t mlen = i; int err = 0; if( (err = blake2bp_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) { goto fail; } while (mlen >= step) { if ( (err = blake2bp_update(&S, p, step)) < 0 ) { goto fail; } mlen -= step; p += step; } if ( (err = blake2bp_update(&S, p, mlen)) < 0) { goto fail; } if ( (err = blake2bp_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { goto fail; } if (0 != memcmp(hash, blake2bp_keyed_kat[i], BLAKE2B_OUTBYTES)) { goto fail; } } } puts( "ok" ); return 0; fail: puts("error"); return -1; } #endif cryptonite-0.23/tests/Tests.hs0000644000000000000000000000366113075454604014642 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Main where import Imports import qualified Number import qualified Number.F2m import qualified BCrypt import qualified Hash import qualified Poly1305 import qualified Salsa import qualified XSalsa import qualified ChaCha import qualified ChaChaPoly1305 import qualified KAT_MiyaguchiPreneel import qualified KAT_CMAC import qualified KAT_HMAC import qualified KAT_HKDF import qualified KAT_Argon2 import qualified KAT_PBKDF2 import qualified KAT_Curve25519 import qualified KAT_Curve448 import qualified KAT_Ed25519 import qualified KAT_OTP import qualified KAT_PubKey import qualified KAT_Scrypt -- symmetric cipher -------------------- import qualified KAT_AES import qualified KAT_Blowfish import qualified KAT_Camellia import qualified KAT_DES import qualified KAT_RC4 import qualified KAT_TripleDES import qualified KAT_Twofish -- misc -------------------------------- import qualified KAT_AFIS import qualified Padding tests = testGroup "cryptonite" [ Number.tests , Number.F2m.tests , Hash.tests , Padding.tests , testGroup "ConstructHash" [ KAT_MiyaguchiPreneel.tests ] , testGroup "MAC" [ Poly1305.tests , KAT_CMAC.tests , KAT_HMAC.tests ] , KAT_Curve25519.tests , KAT_Curve448.tests , KAT_Ed25519.tests , KAT_PubKey.tests , KAT_OTP.tests , testGroup "KDF" [ KAT_PBKDF2.tests , KAT_Scrypt.tests , BCrypt.tests , KAT_HKDF.tests , KAT_Argon2.tests ] , testGroup "block-cipher" [ KAT_AES.tests , KAT_Blowfish.tests , KAT_Camellia.tests , KAT_DES.tests , KAT_TripleDES.tests , KAT_Twofish.tests ] , testGroup "stream-cipher" [ KAT_RC4.tests , ChaCha.tests , ChaChaPoly1305.tests , Salsa.tests , XSalsa.tests ] , KAT_AFIS.tests ] main = defaultMain tests cryptonite-0.23/tests/BlockCipher.hs0000644000000000000000000004502012535566225015723 0ustar0000000000000000{-# LANGUAGE ViewPatterns #-} module BlockCipher ( KAT_ECB(..) , KAT_CBC(..) , KAT_CFB(..) , KAT_CTR(..) , KAT_XTS(..) , KAT_AEAD(..) , KATs(..) , defaultKATs , testBlockCipher , CipherInfo ) where import Imports import Data.Maybe import Crypto.Error import Crypto.Cipher.Types import Data.ByteArray as B hiding (pack, null) import qualified Data.ByteString as B ------------------------------------------------------------------------ -- KAT ------------------------------------------------------------------------ type BlockSize = Int type KeySize = Int type CipherInfo a = (BlockSize, KeySize, ByteString -> a) instance Show (IV c) where show _ = "IV" -- | ECB KAT data KAT_ECB = KAT_ECB { ecbKey :: ByteString -- ^ Key , ecbPlaintext :: ByteString -- ^ Plaintext , ecbCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | CBC KAT data KAT_CBC = KAT_CBC { cbcKey :: ByteString -- ^ Key , cbcIV :: ByteString -- ^ IV , cbcPlaintext :: ByteString -- ^ Plaintext , cbcCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | CFB KAT data KAT_CFB = KAT_CFB { cfbKey :: ByteString -- ^ Key , cfbIV :: ByteString -- ^ IV , cfbPlaintext :: ByteString -- ^ Plaintext , cfbCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | CTR KAT data KAT_CTR = KAT_CTR { ctrKey :: ByteString -- ^ Key , ctrIV :: ByteString -- ^ IV (usually represented as a 128 bits integer) , ctrPlaintext :: ByteString -- ^ Plaintext , ctrCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | XTS KAT data KAT_XTS = KAT_XTS { xtsKey1 :: ByteString -- ^ 1st XTS key , xtsKey2 :: ByteString -- ^ 2nd XTS key , xtsIV :: ByteString -- ^ XTS IV , xtsPlaintext :: ByteString -- ^ plaintext , xtsCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | AEAD KAT data KAT_AEAD = KAT_AEAD { aeadMode :: AEADMode , aeadKey :: ByteString -- ^ Key , aeadIV :: ByteString -- ^ IV for initialization , aeadHeader :: ByteString -- ^ Authenticated Header , aeadPlaintext :: ByteString -- ^ Plaintext , aeadCiphertext :: ByteString -- ^ Ciphertext , aeadTaglen :: Int -- ^ aead tag len , aeadTag :: ByteString -- ^ expected tag } deriving (Show,Eq) -- | all the KATs. use defaultKATs to prevent compilation error -- from future expansion of this data structure data KATs = KATs { kat_ECB :: [KAT_ECB] , kat_CBC :: [KAT_CBC] , kat_CFB :: [KAT_CFB] , kat_CTR :: [KAT_CTR] , kat_XTS :: [KAT_XTS] , kat_AEAD :: [KAT_AEAD] } deriving (Show,Eq) defaultKATs = KATs [] [] [] [] [] [] {- testECB (_, _, cipherInit) ecbEncrypt ecbDecrypt kats = testGroup "ECB" (concatMap katTest (zip is kats) {- ++ propTests-}) where katTest (i,d) = [ testCase ("E" ++ show i) (ecbEncrypt ctx (ecbPlaintext d) @?= ecbCiphertext d) , testCase ("D" ++ show i) (ecbDecrypt ctx (ecbCiphertext d) @?= ecbPlaintext d) ] where ctx = cipherInit (ecbKey d) --propTest = testProperty "decrypt.encrypt" (ECBUnit key plaintext) = --testProperty_ECB (ECBUnit (cipherInit -> ctx) (toBytes -> plaintext)) = -- plaintext `assertEq` ecbDecrypt ctx (ecbEncrypt ctx plaintext) testKatCBC cbcInit cbcEncrypt cbcDecrypt (i,d) = [ testCase ("E" ++ show i) (cbcEncrypt ctx iv (cbcPlaintext d) @?= cbcCiphertext d) , testCase ("D" ++ show i) (cbcDecrypt ctx iv (cbcCiphertext d) @?= cbcPlaintext d) ] where ctx = cbcInit $ cbcKey d iv = cbcIV d testKatCFB cfbInit cfbEncrypt cfbDecrypt (i,d) = [ testCase ("E" ++ show i) (cfbEncrypt ctx iv (cfbPlaintext d) @?= cfbCiphertext d) , testCase ("D" ++ show i) (cfbDecrypt ctx iv (cfbCiphertext d) @?= cfbPlaintext d) ] where ctx = cfbInit $ cfbKey d iv = cfbIV d testKatCTR ctrInit ctrCombine (i,d) = [ testCase ("E" ++ i) (ctrCombine ctx iv (ctrPlaintext d) @?= ctrCiphertext d) , testCase ("D" ++ i) (ctrCombine ctx iv (ctrCiphertext d) @?= ctrPlaintext d) ] where ctx = ctrInit $ ctrKey d iv = ctrIV d testKatXTS xtsInit xtsEncrypt xtsDecrypt (i,d) = [ testCase ("E" ++ i) (xtsEncrypt ctx iv 0 (xtsPlaintext d) @?= xtsCiphertext d) , testCase ("D" ++ i) (xtsDecrypt ctx iv 0 (xtsCiphertext d) @?= xtsPlaintext d) ] where ctx = xtsInit (xtsKey1 d, xtsKey2 d) iv = xtsIV d testKatAEAD cipherInit aeadInit aeadAppendHeader aeadEncrypt aeadDecrypt aeadFinalize (i,d) = [ testCase ("AE" ++ i) (etag @?= aeadTag d) , testCase ("AD" ++ i) (dtag @?= aeadTag d) , testCase ("E" ++ i) (ebs @?= aeadCiphertext d) , testCase ("D" ++ i) (dbs @?= aeadPlaintext d) ] where ctx = cipherInit $ aeadKey d (Just aead) = aeadInit ctx (aeadIV d) aeadHeaded = aeadAppendHeader aead (aeadHeader d) (ebs,aeadEFinal) = aeadEncrypt aeadHeaded (aeadPlaintext d) (dbs,aeadDFinal) = aeadDecrypt aeadHeaded (aeadCiphertext d) etag = aeadFinalize aeadEFinal (aeadTaglen d) dtag = aeadFinalize aeadDFinal (aeadTaglen d) -} testKATs :: BlockCipher cipher => KATs -> cipher -> TestTree testKATs kats cipher = testGroup "KAT" ( maybeGroup makeECBTest "ECB" (kat_ECB kats) ++ maybeGroup makeCBCTest "CBC" (kat_CBC kats) ++ maybeGroup makeCFBTest "CFB" (kat_CFB kats) ++ maybeGroup makeCTRTest "CTR" (kat_CTR kats) -- ++ maybeGroup makeXTSTest "XTS" (kat_XTS kats) -- ++ maybeGroup makeAEADTest "AEAD" (kat_AEAD kats) ) where makeECBTest i d = [ testCase ("E" ++ i) (ecbEncrypt ctx (ecbPlaintext d) @?= ecbCiphertext d) , testCase ("D" ++ i) (ecbDecrypt ctx (ecbCiphertext d) @?= ecbPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ ecbKey d) makeCBCTest i d = [ testCase ("E" ++ i) (cbcEncrypt ctx iv (cbcPlaintext d) @?= cbcCiphertext d) , testCase ("D" ++ i) (cbcDecrypt ctx iv (cbcCiphertext d) @?= cbcPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ cbcKey d) iv = cipherMakeIV cipher $ cbcIV d makeCFBTest i d = [ testCase ("E" ++ i) (cfbEncrypt ctx iv (cfbPlaintext d) @?= cfbCiphertext d) , testCase ("D" ++ i) (cfbDecrypt ctx iv (cfbCiphertext d) @?= cfbPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ cfbKey d) iv = cipherMakeIV cipher $ cfbIV d makeCTRTest i d = [ testCase ("E" ++ i) (ctrCombine ctx iv (ctrPlaintext d) @?= ctrCiphertext d) , testCase ("D" ++ i) (ctrCombine ctx iv (ctrCiphertext d) @?= ctrPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ ctrKey d) iv = cipherMakeIV cipher $ ctrIV d {- makeXTSTest i d = [ testCase ("E" ++ i) (xtsEncrypt ctx iv 0 (xtsPlaintext d) @?= xtsCiphertext d) , testCase ("D" ++ i) (xtsDecrypt ctx iv 0 (xtsCiphertext d) @?= xtsPlaintext d) ] where ctx1 = cipherInit (cipherMakeKey cipher $ xtsKey1 d) ctx2 = cipherInit (cipherMakeKey cipher $ xtsKey2 d) ctx = (ctx1, ctx2) iv = cipherMakeIV cipher $ xtsIV d makeAEADTest i d = [ testCase ("AE" ++ i) (etag @?= aeadTag d) , testCase ("AD" ++ i) (dtag @?= aeadTag d) , testCase ("E" ++ i) (ebs @?= aeadCiphertext d) , testCase ("D" ++ i) (dbs @?= aeadPlaintext d) ] where ctx = cipherInit (cipherMakeKey cipher $ aeadKey d) aead = maybe (error $ "cipher doesn't support aead mode: " ++ show (aeadMode d)) id $ aeadInit (aeadMode d) ctx (aeadIV d) aeadHeaded = aeadAppendHeader aead (aeadHeader d) (ebs,aeadEFinal) = aeadEncrypt aeadHeaded (aeadPlaintext d) (dbs,aeadDFinal) = aeadDecrypt aeadHeaded (aeadCiphertext d) etag = aeadFinalize aeadEFinal (aeadTaglen d) dtag = aeadFinalize aeadDFinal (aeadTaglen d) -} cipherInitNoErr :: BlockCipher c => Key c -> c cipherInitNoErr (Key k) = case cipherInit k of CryptoPassed a -> a CryptoFailed e -> error (show e) ------------------------------------------------------------------------ -- Properties ------------------------------------------------------------------------ -- | any sized bytestring newtype Plaintext a = Plaintext { unPlaintext :: B.ByteString } deriving (Show,Eq) -- | A multiple of blocksize bytestring newtype PlaintextBS a = PlaintextBS { unPlaintextBS :: B.ByteString } deriving (Show,Eq) newtype Key a = Key ByteString deriving (Show,Eq) -- | a ECB unit test data ECBUnit a = ECBUnit (Key a) (PlaintextBS a) deriving (Eq) -- | a CBC unit test data CBCUnit a = CBCUnit (Key a) (IV a) (PlaintextBS a) deriving (Eq) -- | a CBC unit test data CFBUnit a = CFBUnit (Key a) (IV a) (PlaintextBS a) deriving (Eq) -- | a CFB unit test data CFB8Unit a = CFB8Unit (Key a) (IV a) (Plaintext a) deriving (Eq) -- | a CTR unit test data CTRUnit a = CTRUnit (Key a) (IV a) (Plaintext a) deriving (Eq) -- | a XTS unit test data XTSUnit a = XTSUnit (Key a) (Key a) (IV a) (PlaintextBS a) deriving (Eq) -- | a AEAD unit test data AEADUnit a = AEADUnit (Key a) B.ByteString (Plaintext a) (Plaintext a) deriving (Eq) -- | Stream cipher unit test data StreamUnit a = StreamUnit (Key a) (Plaintext a) deriving (Eq) instance Show (ECBUnit a) where show (ECBUnit key b) = "ECB(key=" ++ show key ++ ",input=" ++ show b ++ ")" instance Show (CBCUnit a) where show (CBCUnit key iv b) = "CBC(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (CFBUnit a) where show (CFBUnit key iv b) = "CFB(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (CFB8Unit a) where show (CFB8Unit key iv b) = "CFB8(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (CTRUnit a) where show (CTRUnit key iv b) = "CTR(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (XTSUnit a) where show (XTSUnit key1 key2 iv b) = "XTS(key1=" ++ show key1 ++ ",key2=" ++ show key2 ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (AEADUnit a) where show (AEADUnit key iv aad b) = "AEAD(key=" ++ show key ++ ",iv=" ++ show iv ++ ",aad=" ++ show (unPlaintext aad) ++ ",input=" ++ show b ++ ")" instance Show (StreamUnit a) where show (StreamUnit key b) = "Stream(key=" ++ show key ++ ",input=" ++ show b ++ ")" -- | Generate an arbitrary valid key for a specific block cipher generateKey :: Cipher a => Gen (Key a) generateKey = keyFromCipher undefined where keyFromCipher :: Cipher a => a -> Gen (Key a) keyFromCipher cipher = do sz <- case cipherKeySize cipher of KeySizeRange low high -> choose (low, high) KeySizeFixed v -> return v KeySizeEnum l -> elements l Key . B.pack <$> replicateM sz arbitrary -- | Generate an arbitrary valid IV for a specific block cipher generateIv :: BlockCipher a => Gen (IV a) generateIv = ivFromCipher undefined where ivFromCipher :: BlockCipher a => a -> Gen (IV a) ivFromCipher cipher = fromJust . makeIV . B.pack <$> replicateM (blockSize cipher) arbitrary -- | Generate an arbitrary valid IV for AEAD for a specific block cipher generateIvAEAD :: Gen B.ByteString generateIvAEAD = choose (12,90) >>= \sz -> (B.pack <$> replicateM sz arbitrary) -- | Generate a plaintext multiple of blocksize bytes generatePlaintextMultipleBS :: BlockCipher a => Gen (PlaintextBS a) generatePlaintextMultipleBS = choose (1,128) >>= \size -> replicateM (size * 16) arbitrary >>= return . PlaintextBS . B.pack -- | Generate any sized plaintext generatePlaintext :: Gen (Plaintext a) generatePlaintext = choose (0,324) >>= \size -> replicateM size arbitrary >>= return . Plaintext . B.pack instance BlockCipher a => Arbitrary (ECBUnit a) where arbitrary = ECBUnit <$> generateKey <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (CBCUnit a) where arbitrary = CBCUnit <$> generateKey <*> generateIv <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (CFBUnit a) where arbitrary = CFBUnit <$> generateKey <*> generateIv <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (CFB8Unit a) where arbitrary = CFB8Unit <$> generateKey <*> generateIv <*> generatePlaintext instance BlockCipher a => Arbitrary (CTRUnit a) where arbitrary = CTRUnit <$> generateKey <*> generateIv <*> generatePlaintext instance BlockCipher a => Arbitrary (XTSUnit a) where arbitrary = XTSUnit <$> generateKey <*> generateKey <*> generateIv <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (AEADUnit a) where arbitrary = AEADUnit <$> generateKey <*> generateIvAEAD <*> generatePlaintext <*> generatePlaintext instance StreamCipher a => Arbitrary (StreamUnit a) where arbitrary = StreamUnit <$> generateKey <*> generatePlaintext testBlockCipherBasic :: BlockCipher a => a -> [TestTree] testBlockCipherBasic cipher = [ testProperty "ECB" ecbProp ] where ecbProp = toTests cipher toTests :: BlockCipher a => a -> (ECBUnit a -> Bool) toTests _ = testProperty_ECB testProperty_ECB (ECBUnit key (unPlaintextBS -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` ecbDecrypt ctx (ecbEncrypt ctx plaintext) testBlockCipherModes :: BlockCipher a => a -> [TestTree] testBlockCipherModes cipher = [ testProperty "CBC" cbcProp , testProperty "CFB" cfbProp --, testProperty "CFB8" cfb8Prop , testProperty "CTR" ctrProp ] where (cbcProp,cfbProp,ctrProp) = toTests cipher toTests :: BlockCipher a => a -> ((CBCUnit a -> Bool), (CFBUnit a -> Bool), {-(CFB8Unit a -> Bool),-} (CTRUnit a -> Bool)) toTests _ = (testProperty_CBC ,testProperty_CFB --,testProperty_CFB8 ,testProperty_CTR ) testProperty_CBC (CBCUnit key testIV (unPlaintextBS -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` cbcDecrypt ctx testIV (cbcEncrypt ctx testIV plaintext) testProperty_CFB (CFBUnit key testIV (unPlaintextBS -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` cfbDecrypt ctx testIV (cfbEncrypt ctx testIV plaintext) {- testProperty_CFB8 (CFB8Unit (cipherInit -> ctx) testIV (unPlaintext -> plaintext)) = plaintext `assertEq` cfb8Decrypt ctx testIV (cfb8Encrypt ctx testIV plaintext) -} testProperty_CTR (CTRUnit key testIV (unPlaintext -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` ctrCombine ctx testIV (ctrCombine ctx testIV plaintext) testBlockCipherAEAD :: BlockCipher a => a -> [TestTree] testBlockCipherAEAD cipher = [ testProperty "OCB" (aeadProp AEAD_OCB) , testProperty "CCM" (aeadProp AEAD_CCM) , testProperty "EAX" (aeadProp AEAD_EAX) , testProperty "CWC" (aeadProp AEAD_CWC) , testProperty "GCM" (aeadProp AEAD_GCM) ] where aeadProp = toTests cipher toTests :: BlockCipher a => a -> (AEADMode -> AEADUnit a -> Bool) toTests _ = testProperty_AEAD testProperty_AEAD mode (AEADUnit key testIV (unPlaintext -> aad) (unPlaintext -> plaintext)) = withCtx key $ \ctx -> case aeadInit mode ctx testIV of CryptoPassed iniAead -> let aead = aeadAppendHeader iniAead aad (eText, aeadE) = aeadEncrypt aead plaintext (dText, aeadD) = aeadDecrypt aead eText eTag = aeadFinalize aeadE (blockSize ctx) dTag = aeadFinalize aeadD (blockSize ctx) in (plaintext `assertEq` dText) && (eTag `B.eq` dTag) CryptoFailed err | err == CryptoError_AEADModeNotSupported -> True | otherwise -> error ("testProperty_AEAD: " ++ show err) withCtx :: Cipher c => Key c -> (c -> a) -> a withCtx (Key key) f = case cipherInit key of CryptoFailed e -> error ("init failed: " ++ show e) CryptoPassed ctx -> f ctx {- testBlockCipherXTS :: BlockCipher a => a -> [TestTree] testBlockCipherXTS cipher = [testProperty "XTS" xtsProp] where xtsProp = toTests cipher toTests :: BlockCipher a => a -> (XTSUnit a -> Bool) toTests _ = testProperty_XTS testProperty_XTS (XTSUnit (cipherInit -> ctx1) (cipherInit -> ctx2) testIV (toBytes -> plaintext)) | blockSize ctx1 == 16 = plaintext `assertEq` xtsDecrypt (ctx1, ctx2) testIV 0 (xtsEncrypt (ctx1, ctx2) testIV 0 plaintext) | otherwise = True -} -- | Test a generic block cipher for properties -- related to block cipher modes. testModes :: BlockCipher a => a -> [TestTree] testModes cipher = [ testGroup "decrypt.encrypt==id" -- (testBlockCipherBasic cipher ++ testBlockCipherModes cipher ++ testBlockCipherAEAD cipher ++ testBlockCipherXTS cipher) (testBlockCipherBasic cipher ++ testBlockCipherModes cipher ++ testBlockCipherAEAD cipher) ] -- | Return tests for a specific blockcipher and a list of KATs testBlockCipher :: BlockCipher a => KATs -> a -> TestTree testBlockCipher kats cipher = testGroup (cipherName cipher) ( (if kats == defaultKATs then [] else [testKATs kats cipher]) ++ testModes cipher ) cipherMakeKey :: Cipher cipher => cipher -> ByteString -> Key cipher cipherMakeKey _ bs = Key bs cipherMakeIV :: BlockCipher cipher => cipher -> ByteString -> IV cipher cipherMakeIV _ bs = fromJust $ makeIV bs maybeGroup :: (String -> t -> [TestTree]) -> TestName -> [t] -> [TestTree] maybeGroup mkTest groupName l | null l = [] | otherwise = [testGroup groupName (concatMap (\(i, d) -> mkTest (show i) d) $ zip nbs l)] where nbs :: [Int] nbs = [0..] cryptonite-0.23/tests/ChaCha.hs0000644000000000000000000001504212527624436014646 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module ChaCha (tests) where import qualified Crypto.Cipher.ChaCha as ChaCha import Imports import qualified Data.ByteString as B b8_128_k0_i0 = "\xe2\x8a\x5f\xa4\xa6\x7f\x8c\x5d\xef\xed\x3e\x6f\xb7\x30\x34\x86\xaa\x84\x27\xd3\x14\x19\xa7\x29\x57\x2d\x77\x79\x53\x49\x11\x20\xb6\x4a\xb8\xe7\x2b\x8d\xeb\x85\xcd\x6a\xea\x7c\xb6\x08\x9a\x10\x18\x24\xbe\xeb\x08\x81\x4a\x42\x8a\xab\x1f\xa2\xc8\x16\x08\x1b\x8a\x26\xaf\x44\x8a\x1b\xa9\x06\x36\x8f\xd8\xc8\x38\x31\xc1\x8c\xec\x8c\xed\x81\x1a\x02\x8e\x67\x5b\x8d\x2b\xe8\xfc\xe0\x81\x16\x5c\xea\xe9\xf1\xd1\xb7\xa9\x75\x49\x77\x49\x48\x05\x69\xce\xb8\x3d\xe6\xa0\xa5\x87\xd4\x98\x4f\x19\x92\x5f\x5d\x33\x8e\x43\x0d" b12_128_k0_i0 = "\xe1\x04\x7b\xa9\x47\x6b\xf8\xff\x31\x2c\x01\xb4\x34\x5a\x7d\x8c\xa5\x79\x2b\x0a\xd4\x67\x31\x3f\x1d\xc4\x12\xb5\xfd\xce\x32\x41\x0d\xea\x8b\x68\xbd\x77\x4c\x36\xa9\x20\xf0\x92\xa0\x4d\x3f\x95\x27\x4f\xbe\xff\x97\xbc\x84\x91\xfc\xef\x37\xf8\x59\x70\xb4\x50\x1d\x43\xb6\x1a\x8f\x7e\x19\xfc\xed\xde\xf3\x68\xae\x6b\xfb\x11\x10\x1b\xd9\xfd\x3e\x4d\x12\x7d\xe3\x0d\xb2\xdb\x1b\x47\x2e\x76\x42\x68\x03\xa4\x5e\x15\xb9\x62\x75\x19\x86\xef\x1d\x9d\x50\xf5\x98\xa5\xdc\xdc\x9f\xa5\x29\xa2\x83\x57\x99\x1e\x78\x4e\xa2\x0f" b20_128_k0_i0 = "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06\x2f\x41\xf6\x7a\x75\x2e\x66\xad\x34\x11\x98\x4c\x78\x7e\x30\xad" b8_256_k0_i0 = "\x3e\x00\xef\x2f\x89\x5f\x40\xd6\x7f\x5b\xb8\xe8\x1f\x09\xa5\xa1\x2c\x84\x0e\xc3\xce\x9a\x7f\x3b\x18\x1b\xe1\x88\xef\x71\x1a\x1e\x98\x4c\xe1\x72\xb9\x21\x6f\x41\x9f\x44\x53\x67\x45\x6d\x56\x19\x31\x4a\x42\xa3\xda\x86\xb0\x01\x38\x7b\xfd\xb8\x0e\x0c\xfe\x42\xd2\xae\xfa\x0d\xea\xa5\xc1\x51\xbf\x0a\xdb\x6c\x01\xf2\xa5\xad\xc0\xfd\x58\x12\x59\xf9\xa2\xaa\xdc\xf2\x0f\x8f\xd5\x66\xa2\x6b\x50\x32\xec\x38\xbb\xc5\xda\x98\xee\x0c\x6f\x56\x8b\x87\x2a\x65\xa0\x8a\xbf\x25\x1d\xeb\x21\xbb\x4b\x56\xe5\xd8\x82\x1e\x68\xaa" b12_256_k0_i0 = "\x9b\xf4\x9a\x6a\x07\x55\xf9\x53\x81\x1f\xce\x12\x5f\x26\x83\xd5\x04\x29\xc3\xbb\x49\xe0\x74\x14\x7e\x00\x89\xa5\x2e\xae\x15\x5f\x05\x64\xf8\x79\xd2\x7a\xe3\xc0\x2c\xe8\x28\x34\xac\xfa\x8c\x79\x3a\x62\x9f\x2c\xa0\xde\x69\x19\x61\x0b\xe8\x2f\x41\x13\x26\xbe\x0b\xd5\x88\x41\x20\x3e\x74\xfe\x86\xfc\x71\x33\x8c\xe0\x17\x3d\xc6\x28\xeb\xb7\x19\xbd\xcb\xcc\x15\x15\x85\x21\x4c\xc0\x89\xb4\x42\x25\x8d\xcd\xa1\x4c\xf1\x11\xc6\x02\xb8\x97\x1b\x8c\xc8\x43\xe9\x1e\x46\xca\x90\x51\x51\xc0\x27\x44\xa6\xb0\x17\xe6\x93\x16" b20_256_k0_i0 = "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5\x31\xed\x1f\x28\x51\x0a\xfb\x45\xac\xe1\x0a\x1f\x4b\x79\x4d\x6f" data Vector = Vector Int -- rounds ByteString -- key ByteString -- nonce deriving (Show,Eq) instance Arbitrary Vector where arbitrary = Vector 20 <$> arbitraryBS 16 <*> arbitraryBS 12 tests = testGroup "ChaCha" [ testCase "8-128-K0-I0" (chachaRunSimple b8_128_k0_i0 8 16 8) , testCase "12-128-K0-I0" (chachaRunSimple b12_128_k0_i0 12 16 8) , testCase "20-128-K0-I0" (chachaRunSimple b20_128_k0_i0 20 16 8) , testCase "8-256-K0-I0" (chachaRunSimple b8_256_k0_i0 8 32 8) , testCase "12-256-K0-I0" (chachaRunSimple b12_256_k0_i0 12 32 8) , testCase "20-256-K0-I0" (chachaRunSimple b20_256_k0_i0 20 32 8) , testProperty "generate-combine" chachaGenerateCombine , testProperty "chunking-generate" chachaGenerateChunks , testProperty "chunking-combine" chachaCombineChunks ] where chachaRunSimple expected rounds klen nonceLen = let chacha = ChaCha.initialize rounds (B.replicate klen 0) (B.replicate nonceLen 0) in expected @=? fst (ChaCha.generate chacha (B.length expected)) chachaGenerateChunks :: ChunkingLen -> Vector -> Bool chachaGenerateChunks (ChunkingLen ckLen) (Vector rounds key iv) = let initChaCha = ChaCha.initialize rounds key iv nbBytes = 1048 (expected,_) = ChaCha.generate initChaCha nbBytes chunks = loop nbBytes ckLen initChaCha in expected `propertyEq` B.concat chunks where loop n [] chacha = loop n ckLen chacha loop 0 _ _ = [] loop n (x:xs) chacha = let len = min x n (c, next) = ChaCha.generate chacha len in c : loop (n - len) xs next chachaGenerateCombine :: ChunkingLen0_127 -> Vector -> Int0_2901 -> Bool chachaGenerateCombine (ChunkingLen0_127 ckLen) (Vector rounds key iv) (Int0_2901 nbBytes) = let initChaCha = ChaCha.initialize rounds key iv in loop nbBytes ckLen initChaCha where loop n [] chacha = loop n ckLen chacha loop 0 _ _ = True loop n (x:xs) chacha = let len = min x n (c1, next) = ChaCha.generate chacha len (c2, _) = ChaCha.combine chacha (B.replicate len 0) in if c1 == c2 then loop (n - len) xs next else False chachaCombineChunks :: ChunkingLen0_127 -> Vector -> ArbitraryBS0_2901 -> Bool chachaCombineChunks (ChunkingLen0_127 ckLen) (Vector rounds key iv) (ArbitraryBS0_2901 wholebs) = let initChaCha = ChaCha.initialize rounds key iv (expected,_) = ChaCha.combine initChaCha wholebs chunks = loop wholebs ckLen initChaCha in expected `propertyEq` B.concat chunks where loop bs [] chacha = loop bs ckLen chacha loop bs (x:xs) chacha | B.null bs = [] | otherwise = let (bs1, bs2) = B.splitAt (min x (B.length bs)) bs (c, next) = ChaCha.combine chacha bs1 in c : loop bs2 xs next cryptonite-0.23/tests/BCrypt.hs0000644000000000000000000000770312746570656014756 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module BCrypt ( tests ) where import Crypto.KDF.BCrypt import qualified Data.ByteString as B import Imports -- Openwall bcrypt tests, with 2x versions and 0xFF special cases removed. expected :: [(ByteString, ByteString)] expected = [ ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW", "U*U") , ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK", "U*U*") , ("$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a", "U*U*U") , ("$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui", "0123456789abcdefghijklmnopqrstuvwxyz\ \ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\ \chars after 72 are ignored") , ("$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", "\xff\xff\xa3") , ("$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", "\xff\xff\xa3") , ("$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") , ("$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \chars after 72 are ignored as usual") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy", "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe", "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff") , ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy", "") , ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.", "") , ("$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye", "") , ("$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW", "") , ("$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO", "") , ("$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe", "a") , ("$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.", "a") , ("$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS", "a") , ("$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i", "abc") , ("$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm", "abc") , ("$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi", "abc") , ("$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC", "abcdefghijklmnopqrstuvwxyz") ] makeKATs = concatMap maketest (zip3 is passwords hashes) where is :: [Int] is = [1..] passwords = map snd expected hashes = map fst expected maketest (i, password, hash) = [ testCase (show i) (assertBool "" (validatePassword password hash)) ] tests = testGroup "bcrypt" [ testGroup "KATs" makeKATs , testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString))) ] cryptonite-0.23/tests/Hash.hs0000644000000000000000000005117413063753164014425 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE ExistentialQuantification #-} #if MIN_VERSION_base(4,7,0) {-# LANGUAGE DataKinds #-} #endif module Hash ( tests ) where import Crypto.Hash import qualified Data.ByteString as B import qualified Data.ByteArray.Encoding as B (convertToBase, Base(..)) import Imports v0,v1,v2 :: ByteString v0 = "" v1 = "The quick brown fox jumps over the lazy dog" v2 = "The quick brown fox jumps over the lazy cog" vectors = [ v0, v1, v2 ] instance Arbitrary ByteString where arbitrary = B.pack `fmap` arbitrary data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg expected :: [ (String, HashAlg, [ByteString]) ] expected = [ ("MD2", HashAlg MD2, [ "8350e5a3e24c153df2275c9f80692773", "03d85a0d629d2c442e987525319fc471", "6b890c9292668cdbbfda00a4ebf31f05" ]), ("MD4", HashAlg MD4, [ "31d6cfe0d16ae931b73c59d7e0c089c0", "1bee69a46ba811185c194762abaeae90", "b86e130ce7028da59e672d56ad0113df" ]), ("MD5", HashAlg MD5, [ "d41d8cd98f00b204e9800998ecf8427e", "9e107d9d372bb6826bd81d3542a419d6", "1055d3e698d289f2af8663725127bd4b" ]), ("SHA1", HashAlg SHA1, [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3" ]), ("SHA224", HashAlg SHA224, [ "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525", "fee755f44a55f20fb3362cdc3c493615b3cb574ed95ce610ee5b1e9b" ]), ("SHA256", HashAlg SHA256, [ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", "e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be" ]), ("SHA384", HashAlg SHA384, [ "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", "098cea620b0978caa5f0befba6ddcf22764bea977e1c70b3483edfdf1de25f4b40d6cea3cadf00f809d422feb1f0161b" ]), ("SHA512", HashAlg SHA512, [ "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", "3eeee1d0e11733ef152a6c29503b3ae20c4f1f3cda4cb26f1bc1a41f91c7fe4ab3bd86494049e201c4bd5155f31ecb7a3c8606843c4cc8dfcab7da11c8ae5045" ]), ("SHA512/224", HashAlg SHA512t_224, [ "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37", "2b9d6565a7e40f780ba8ab7c8dcf41e3ed3b77997f4c55aa987eede5" ]), ("SHA512/256", HashAlg SHA512t_256, [ "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d", "cc8d255a7f2f38fd50388fd1f65ea7910835c5c1e73da46fba01ea50d5dd76fb" ]), ("RIPEMD160", HashAlg RIPEMD160, [ "9c1185a5c5e9fc54612808977ee8f548b2258d31", "37f332f68db77bd9d7edd4969571ad671cf9dd3b", "132072df690933835eb8b6ad0b77e7b6f14acad7" ]), ("Tiger", HashAlg Tiger, [ "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", "6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075", "a8f04b0f7201a0d728101c9d26525b31764a3493fcd8458f" ]) {- , ("Skein256-160", HashAlg Skein256_160, [ "ff800bed6d2044ee9d604a674e3fda50d9b24a72", "3265703c166aa3e0d7da070b9cf1b1a5953f0a77", "17b29aa1424b3ec022505bd215ff73fd2e6d1e5a" ]) -} , ("Skein256-256", HashAlg Skein256_256, [ "c8877087da56e072870daa843f176e9453115929094c3a40c463a196c29bf7ba", "c0fbd7d779b20f0a4614a66697f9e41859eaf382f14bf857e8cdb210adb9b3fe", "fb2f2f2deed0e1dd7ee2b91cee34e2d1c22072e1f5eaee288c35a0723eb653cd" ]) {- , ("Skein512-160", HashAlg Skein512_160, [ "49daf1ccebb3544bc93cb5019ba91b0eea8876ee", "826325ee55a6dd18c3b2dbbc9c10420f5475975e", "7544ec7a35712ec953f02b0d0c86641cae4eb6e5" ]) -} , ("Skein512-384", HashAlg Skein512_384, [ "dd5aaf4589dc227bd1eb7bc68771f5baeaa3586ef6c7680167a023ec8ce26980f06c4082c488b4ac9ef313f8cbe70808", "f814c107f3465e7c54048a5503547deddc377264f05c706b0d19db4847b354855ee52ab6a785c238c9e710d848542041", "e06520eeadc1d0a44fee1d2492547499c1e58526387c8b9c53905e5edb79f9840575cbf844e21b1ad1ea126dd8a8ca6f" ]) , ("Skein512-512", HashAlg Skein512_512, [ "bc5b4c50925519c290cc634277ae3d6257212395cba733bbad37a4af0fa06af41fca7903d06564fea7a2d3730dbdb80c1f85562dfcc070334ea4d1d9e72cba7a", "94c2ae036dba8783d0b3f7d6cc111ff810702f5c77707999be7e1c9486ff238a7044de734293147359b4ac7e1d09cd247c351d69826b78dcddd951f0ef912713", "7f81113575e4b4d3441940e87aca331e6d63d103fe5107f29cd877af0d0f5e0ea34164258c60da5190189d0872e63a96596d2ef25e709099842da71d64111e0f" ]) {- , ("Skein512-896", HashAlg Skein512_896, [ "b95175236c83a459ce7ec6c12b761a838b22d750e765b3fdaa892201b2aa714bc3d1d887dd64028bbf177c1dd11baa09c6c4ddb598fd07d6a8c131a09fc5b958e2999a8006754b25abe3bf8492b7eabec70e52e04e5ac867df2393c573f16eee3244554f1d2b724f2c0437c62007f770", "3265708553e7d146e5c7bcbc97b3e9e9f5b53a5e4af53612bdd6454da4fa7b13d413184fe34ed57b6574be10e389d0ec4b1d2b1dd2c80e0257d5a76b2cd86a19a27b1bcb3cc24d911b5dc5ee74d19ad558fd85b5f024e99f56d1d3199f1f9f88ed85fab9f945f11cf9fc00e94e3ca4c7", "3d23d3db9be719bbd2119f8402a28f38d8225faa79d5b68b80738c64a82004aafc7a840cd6dd9bced6644fa894a3d8d7d2ee89525fd1956a2db052c4c2f8d2111c91ef46b0997540d42bcf384826af1a5ef6510077f52d0574cf2b46f1b6a5dad07ed40f3d21a13ca2d079fa602ff02d" ]) -} , ("Whirlpool", HashAlg Whirlpool, [ "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", "b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35", "dce81fc695cfea3d7e1446509238daf89f24cc61896f2d265927daa70f2108f8902f0dfd68be085d5abb9fcd2e482c1dc24f2fabf81f40b73495cad44d7360d3"]) , ("Keccak-224", HashAlg Keccak_224, [ "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe", "0b27ff3b732133287f6831e2af47cf342b7ef1f3fcdee248811090cd" ]) , ("Keccak-256", HashAlg Keccak_256, [ "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15", "ed6c07f044d7573cc53bf1276f8cba3dac497919597a45b4599c8f73e22aa334" ]) , ("Keccak-384", HashAlg Keccak_384, [ "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3", "1cc515e1812491058d8b8b226fd85045e746b4937a58b0111b6b7a39dd431b6295bd6b6d05e01e225586b4dab3cbb87a" ]) , ("Keccak-512", HashAlg Keccak_512, [ "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609", "10f8caabb5b179861da5e447d34b84d604e3eb81830880e1c2135ffc94580a47cb21f6243ec0053d58b1124d13af2090033659075ee718e0f111bb3f69fb24cf" ]) , ("SHA3-224", HashAlg SHA3_224, [ "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", "d15dadceaa4d5d7bb3b48f446421d542e08ad8887305e28d58335795", "b770eb6ac3ac52bd2f9e8dc186d6b604e7c3b7ffc8bd9220b0078ced" ]) , ("SHA3-256", HashAlg SHA3_256, [ "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", "69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04", "cc80b0b13ba89613d93f02ee7ccbe72ee26c6edfe577f22e63a1380221caedbc" ]) , ("SHA3-384", HashAlg SHA3_384, [ "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", "7063465e08a93bce31cd89d2e3ca8f602498696e253592ed26f07bf7e703cf328581e1471a7ba7ab119b1a9ebdf8be41", "e414797403c7d01ab64b41e90df4165d59b7f147e4292ba2da336acba242fd651949eb1cfff7e9012e134b40981842e1" ]) , ("SHA3-512", HashAlg SHA3_512, [ "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", "01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450", "28e361fe8c56e617caa56c28c7c36e5c13be552b77081be82b642f08bb7ef085b9a81910fe98269386b9aacfd2349076c9506126e198f6f6ad44c12017ca77b1" ]) , ("Blake2b-160", HashAlg Blake2b_160, [ "3345524abf6bbe1809449224b5972c41790b6cf2", "3c523ed102ab45a37d54f5610d5a983162fde84f", "a3d365b5fba5d36fbb19c03b7fde496058969c5a" ]) , ("Blake2b-224", HashAlg Blake2b_224, [ "836cc68931c2e4e3e838602eca1902591d216837bafddfe6f0c8cb07", "477c3985751dd4d1b8c93827ea5310b33bb02a26463a050dffd3e857", "a4a1b6851be66891a3deff406c4d7556879ebf952407450755f90eb6" ]) , ("Blake2b-256", HashAlg Blake2b_256, [ "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", "01718cec35cd3d796dd00020e0bfecb473ad23457d063b75eff29c0ffa2e58a9", "036c13096926b3dfccfe3f233bd1b2f583b818b8b15c01be65af69238e900b2c" ]) , ("Blake2b-384", HashAlg Blake2b_384, [ "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", "b7c81b228b6bd912930e8f0b5387989691c1cee1e65aade4da3b86a3c9f678fc8018f6ed9e2906720c8d2a3aeda9c03d", "927a1f297873cbe887a93b2183c4e2eba53966ba92c6db8b87029a1d8c673471d09740676cced79c5016838973f630c3" ]) , ("Blake2b-512", HashAlg Blake2b_512, [ "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918", "af438eea5d8cdb209336a7e85bf58090dc21b49d823f89a7d064c119f127bd361af9c7d109edda0f0e91bdce078d1d86b8e6f25727c98f6d3bb6f50acb2dd376" ]) , ("Blake2s-160", HashAlg Blake2s_160, [ "354c9c33f735962418bdacb9479873429c34916f", "5a604fec9713c369e84b0ed68daed7d7504ef240", "759bef6d041bcbd861b8b51baaece6c8fffd0acf" ]) , ("Blake2s-224", HashAlg Blake2s_224, [ "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", "e4e5cb6c7cae41982b397bf7b7d2d9d1949823ae78435326e8db4912", "e220025fd46a9a635c3f7f60bb96a84c01019ac0817f5901e7eeaa2c" ]) , ("Blake2s-256", HashAlg Blake2s_256, [ "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", "606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812", "94662583a600a12dff357c0a6f1b514a710ef0f587a38e8d2e4d7f67e9c81667" ]) #if MIN_VERSION_base(4,7,0) , ("SHAKE128_4096", HashAlg (SHAKE128 :: SHAKE128 4096), [ "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef263cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e235b8cc873c23dc62b8d260169afa2f75ab916a58d974918835d25e6a435085b2badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea17cda7cfad765f5623474d368ccca8af0007cd9f5e4c849f167a580b14aabdefaee7eef47cb0fca9767be1fda69419dfb927e9df07348b196691abaeb580b32def58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c922a96188d032675c8ac850933c7aff1533b94c834adbb69c6115bad4692d8619f90b0cdf8a7b9c264029ac185b70b83f2801f2f4b3f70c593ea3aeeb613a7f1b1de33fd75081f592305f2e4526edc09631b10958f464d889f31ba010250fda7f1368ec2967fc84ef2ae9aff268e0b1700affc6820b523a3d917135f2dff2ee06bfe72b3124721d4a26c04e53a75e30e73a7a9c4a95d91c55d495e9f51dd0b5e9d83c6d5e8ce803aa62b8d654db53d09b8dcff273cdfeb573fad8bcd45578bec2e770d01efde86e721a3f7c6cce275dabe6e2143f1af18da7efddc4c7b70b5e345db93cc936bea323491ccb38a388f546a9ff00dd4e1300b9b2153d2041d205b443e41b45a653f2a5c4492c1add544512dda2529833462b71a41a45be97290b6f", "f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66eb5585ec6f86021cacf272c798bcf97d368b886b18fec3a571f096086a523717a3732d50db2b0b7998b4117ae66a761ccf1847a1616f4c07d5178d0d965f9feba351420f8bfb6f5ab9a0cb102568eabf3dfa4e22279f8082dce8143eb78235a1a54914ab71abb07f2f3648468370b9fbb071e074f1c030a4030225f40c39480339f3dc71d0f04f71326de1381674cc89e259e219927fae8ea2799a03da862a55afafe670957a2af3318d919d0a3358f3b891236d6a8e8d19999d1076b529968faefbd880d77bb300829dca87e9c8e4c28e0800ff37490a5bd8c36c0b0bdb2701a5d58d03378b9dbd384389e3ef0fd4003b08998fd3f32fe1a0810fc0eccaad94bca8dd83b34559c333f0b16dfc2896ed87b30ba14c81f87cd8b4bb6317db89b0e7e94c0616f9a665fba5b0e6fb3549c9d7b68e66d08a86eb2faec05cc462a771806b93cc38b0a4feb9935c6c8945da6a589891ba5ee99753cfdd38e1abc7147fd74b7c7d1ce0609b6680a2e18888d84949b6e6cf6a2aa4113535aaee079459e3f257b569a9450523c41f5b5ba4b79b3ba5949140a74bb048de0657d04954bdd71dae76f61e2a1f88aecb91cfa5b36c1bf3350a798dc4dcf48628effe3a0c5340c756bd922f78d0e36ef7df12ce78c179cc721ad087e15ea496bf5f60b21b5822d", "22fd225fb8f2c8d0d2097e1f8d38b6a9e619d39664dad3795f0336fda544d305e1be56a9953ecd6e4bec14b622f53da492eccbe257b9af84775a6bdf81aab6b1ba3492149b7ce4ea402c56e343939f78b9a9727193269798420c9323a9eb1fa63006e1482fcf15e3696aa1ae5cb66eb8aad4ac6041ca0b576b78785ad95bc5fb6f8a420ba9e1726552c0f2b97050ae69fc018d3f63b3a812a2d39ef64b8ae368472dec4341511b02cf77363c74f216055d5905412bc2bf57b4010b1bdce2882cb28fc7e4d470ed05219fc4d1ce11d11e10db369c807cd71891653638956b2f9d176e116188aff2fbb8519d9ad8c3fb52fa8bb4a0413364e89d9f9d7db627f2a2288babedcc314a19e45c6b7fb93b16a15d9953ff619ab4d523c481552588f711b450f854c858ebcb8cf49492d6240a753bde2109c486cac666bdba767c6e9254cc723f67855534c34d08ed486c67c1b8dd288c6010ce8e6c1c9b7f927acf4d71ee99729cee55ecec544245d0b51b31dd78eb99c2723e8ba5cf92ac7720e8933d9fd3596b90073f6980c5ed3f1cbfada26bdb6946e72391198e3d1cedebdba092324500e32b8e04e32550f6dd6c4befafa95acc206c5708300d2a8df2765751102f9738a1449c4c0d588f0076d0c1a5ee445eb85c97ada5837d5dc1d34ea081c8411d64a4d9ce9279bfe9feb25696cf741c705ed46f171e2239216d6c45dc8d15" ]) , ("SHAKE256_4096", HashAlg (SHAKE256 :: SHAKE256 4096), [ "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a", "2f671343d9b2e1604dc9dcf0753e5fe15c7c64a0d283cbbf722d411a0e36f6ca1d01d1369a23539cd80f7c054b6e5daf9c962cad5b8ed5bd11998b40d5734442bed798f6e5c915bd8bb07e0188d0a55c1290074f1c287af06352299184492cbdec9acba737ee292e5adaa445547355e72a03a3bac3aac770fe5d6b66600ff15d37d5b4789994ea2aeb097f550aa5e88e4d8ff0ba07b88c1c88573063f5d96df820abc2abd177ab037f351c375e553af917132cf2f563c79a619e1bb76e8e2266b0c5617d695f2c496a25f4073b6840c1833757ebb386f16757a8e16a21e9355e9b248f3b33be672da700266be99b8f8725e8ab06075f0219e655ebc188976364b7db139390d34a6ea67b4b223229183a94cf455ece91fdaf5b9c707fa4b40ec39816c1120c7aaaf47920977be900e6b9ca4b8940e192b927c475bd58e836f512ae3e52924e36ff8e9b1d0251047770a5e465905622b1f159be121ab93819c5e5c6dae299ac73bf1c4ed4a1e2c7fa3caa1039b05e94c9f993d04feb272b6e00bb0276939cf746c42936831fc8f2b4cb0cf94808ae0af405ce4bc67d1e7acfc6fd6590d3de91f795df5aaf57e2cee1845a303d0ea564be3f1299acdce67efe0d62cfc6d6829ff4ecc0a05153c24696c4d34c076453827e796f3062f94f62f4528b7cfc870f0dcd615b7c97b95da4b9be5830e8b3f66cce71e0f622c771994443e2", "fffcaac0606c0edb7bc0d15f033accb68538159016e5ae8470bf9ebea89fa6c9fcc3e027d94f7f967b7246346bd9f6b8084e45a057b976847c4db03bf383c834054866f6a8282a497368c46e1852fc09e20f22c45607a27c8b2a4798ebefada54f8d3795b9f07606b1cd6e41f90d765480ef5c0d5790659cf1d210adfd412378b92e1dd9bd7fd95a1a66677fc6baa0e3a53c9031c1fb59cbad9f5dc5881a3c8e25c80ecb1abf0971488ada1f533dcbf8d37031335378574b8d3fad61159c9fae28caa543b3072ce308d369be340e78c6edc664cc6dde9b2f0a4ad2e60ce9c8b1e5722b8d5b73d0962b74fb9ed86307a180f53933339f9d56d3b345c2a0e98fcf5de7754f3845f6be30089f0e142ad4602f18abdc750bda7c91c3f32872e66640db46045ab4c276b379f1b834c2cbb1bd8601305649ec6b3bf20618695136dee6541492d1d985ea1fb765fd7a559e810eba30f2f710233ae5a411b94ddcaa01a08f1c31320d111c0714422cd5e987c9a76fc865de34003ab12664081be8017d23d977f2bf4ed9e3ce09ea3d64bb4ae8ebfa9d0721f57841008c297e2f455a0441a2bd618ca379dbd239a21e410defb4001b1e11f87e36bf894c222f76f12ddcc3771bbb17d5c0dfd86d89a3e13e084f6dc1c4762bcd393c1757db7afb1434221569e7ddaaffd6318253ec3df8cf5f826b81896d6474ee06a2e30ccc8c6a96bdd5" ]) , ("Blake2b 160", HashAlg (Blake2b :: Blake2b 160), [ "3345524abf6bbe1809449224b5972c41790b6cf2", "3c523ed102ab45a37d54f5610d5a983162fde84f", "a3d365b5fba5d36fbb19c03b7fde496058969c5a" ]) , ("Blake2b 224", HashAlg (Blake2b :: Blake2b 224), [ "836cc68931c2e4e3e838602eca1902591d216837bafddfe6f0c8cb07", "477c3985751dd4d1b8c93827ea5310b33bb02a26463a050dffd3e857", "a4a1b6851be66891a3deff406c4d7556879ebf952407450755f90eb6" ]) , ("Blake2b 256", HashAlg (Blake2b :: Blake2b 256), [ "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", "01718cec35cd3d796dd00020e0bfecb473ad23457d063b75eff29c0ffa2e58a9", "036c13096926b3dfccfe3f233bd1b2f583b818b8b15c01be65af69238e900b2c" ]) , ("Blake2b 384", HashAlg (Blake2b :: Blake2b 384), [ "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", "b7c81b228b6bd912930e8f0b5387989691c1cee1e65aade4da3b86a3c9f678fc8018f6ed9e2906720c8d2a3aeda9c03d", "927a1f297873cbe887a93b2183c4e2eba53966ba92c6db8b87029a1d8c673471d09740676cced79c5016838973f630c3" ]) , ("Blake2b 512", HashAlg (Blake2b :: Blake2b 512), [ "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918", "af438eea5d8cdb209336a7e85bf58090dc21b49d823f89a7d064c119f127bd361af9c7d109edda0f0e91bdce078d1d86b8e6f25727c98f6d3bb6f50acb2dd376" ]) , ("Blake2s 160", HashAlg (Blake2s :: Blake2s 160), [ "354c9c33f735962418bdacb9479873429c34916f", "5a604fec9713c369e84b0ed68daed7d7504ef240", "759bef6d041bcbd861b8b51baaece6c8fffd0acf" ]) , ("Blake2s 224", HashAlg (Blake2s :: Blake2s 224), [ "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", "e4e5cb6c7cae41982b397bf7b7d2d9d1949823ae78435326e8db4912", "e220025fd46a9a635c3f7f60bb96a84c01019ac0817f5901e7eeaa2c" ]) , ("Blake2s 256", HashAlg (Blake2s ::Blake2s 256), [ "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", "606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812", "94662583a600a12dff357c0a6f1b514a710ef0f587a38e8d2e4d7f67e9c81667" ]) #endif ] runhash :: HashAlg -> ByteString -> ByteString runhash (HashAlg hashAlg) v = B.convertToBase B.Base16 $ hashWith hashAlg $ v runhashinc :: HashAlg -> [ByteString] -> ByteString runhashinc (HashAlg hashAlg) v = B.convertToBase B.Base16 $ hashinc $ v where hashinc = hashFinalize . foldl hashUpdate (hashInitWith hashAlg) makeTestAlg (name, hashAlg, results) = testGroup name $ concatMap maketest (zip3 is vectors results) where is :: [Int] is = [1..] maketest (i, v, r) = [ testCase (show i) (r @=? runhash hashAlg v) ] makeTestChunk (hashName, hashAlg, _) = [ testProperty hashName $ \ckLen (ArbitraryBS0_2901 inp) -> runhash hashAlg inp `propertyEq` runhashinc hashAlg (chunkS ckLen inp) ] tests = testGroup "hash" [ testGroup "KATs" (map makeTestAlg expected) , testGroup "Chunking" (concatMap makeTestChunk expected) ] cryptonite-0.23/tests/Imports.hs0000644000000000000000000000075412510212375015163 0ustar0000000000000000module Imports ( -- * Individual Types Word16, Word32, Word64 , ByteString -- * Modules , module X ) where import Data.Word (Word16, Word32, Word64) import Data.ByteString (ByteString) import Control.Applicative as X import Control.Monad as X import Data.Foldable as X (foldl') import Data.Monoid as X import Data.ByteString.Char8 as X () import Test.Tasty as X import Test.Tasty.HUnit as X import Test.Tasty.QuickCheck as X hiding (vector) import Utils as X cryptonite-0.23/tests/KAT_AES/KATCBC.hs0000644000000000000000000005477012570523322015576 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES.KATCBC where import qualified Data.ByteString as B import Data.ByteString.Char8 () type KATCBC = (B.ByteString, B.ByteString, B.ByteString, B.ByteString) vectors_aes128_enc, vectors_aes128_dec , vectors_aes192_enc, vectors_aes192_dec , vectors_aes256_enc, vectors_aes256_dec :: [KATCBC] vectors_aes128_enc = [ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xb6\xae\xaf\xfa\x75\x2d\xc0\x8b\x51\x63\x97\x31\x76\x1a\xed\x00") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xcb\x64\xcf\x3f\x42\x2a\xe8\x4b\xb9\x0e\x3a\xb4\xdb\xa7\xbd\x86") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xe5\xb5\x07\x7f\x93\x46\x46\x2c\x62\xa0\x75\xc0\xc7\x08\xee\x96") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xe1\x4d\x5d\x0e\xe2\x77\x15\xdf\x08\xb4\x15\x2b\xa2\x3d\xa8\xe0") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x5e\x77\xe5\x9f\x8f\x85\x94\x34\x89\xa2\x41\x49\xc7\x5f\x4e\xc9") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x8f\x42\xc2\x4b\xee\x6e\x63\x47\x2b\x16\x5a\xa9\x41\x31\x2f\x7c") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xb0\xea\x4a\xc0\xd2\x5c\xcd\x7c\x82\xcb\x8a\x30\x68\xc6\xfe\x2e") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xe1\x4d\x5d\x0e\xe2\x77\x15\xdf\x08\xb4\x15\x2b\xa2\x3d\xa8\xe0") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x17\xd6\x14\xf3\x79\xa9\x35\x90\x77\xe9\x55\x77\xfd\x31\xc2\x0a") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x8f\x42\xc2\x4b\xee\x6e\x63\x47\x2b\x16\x5a\xa9\x41\x31\x2f\x7c") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\xe5\xb5\x07\x7f\x93\x46\x46\x2c\x62\xa0\x75\xc0\xc7\x08\xee\x96") ] vectors_aes192_enc = [ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xaa\xe0\x69\x92\xac\xbf\x52\xa3\xe8\xf4\xa9\x6e\xc9\x30\x0b\xd7") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x5f\x88\xef\x3f\xbd\xeb\xf2\xe4\xe2\x66\x65\x12\xd3\xbc\xb7\x0f") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xdb\x42\xf5\x1c\xd2\x0e\xca\xd2\x9e\xb0\x13\x2b\x0f\xaa\x4b\x85") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xda\xb4\x01\x5f\x98\x70\x25\xeb\xb8\xa8\x5f\x3c\x7f\x73\x70\x19") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xcf\x1e\xce\x3c\x44\xb0\x78\xfb\x27\xcb\x0a\x3e\x07\x1b\x08\x20") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x98\xb8\x95\xa1\x45\xca\x4e\x0b\xf8\x3e\x69\x32\x81\xc1\xa0\x97") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xf2\xf0\xae\xd8\xcd\xc9\x21\xca\x4b\x55\x84\x5d\xa4\x15\x21\xc2") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x5e\xea\x4b\x13\xdd\xd9\x17\x12\xb0\x14\xe2\x82\x2d\x18\x76\xfb") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xcf\x1e\xce\x3c\x44\xb0\x78\xfb\x27\xcb\x0a\x3e\x07\x1b\x08\x20") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\xeb\x8c\x17\x30\x90\xc7\x5b\x77\xd6\x72\xb4\x57\xa7\x78\xd9\xd0") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xf2\xf0\xae\xd8\xcd\xc9\x21\xca\x4b\x55\x84\x5d\xa4\x15\x21\xc2") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\xda\xb4\x01\x5f\x98\x70\x25\xeb\xb8\xa8\x5f\x3c\x7f\x73\x70\x19") ] vectors_aes256_enc = [ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xdc\x95\xc0\x78\xa2\x40\x89\x89\xad\x48\xa2\x14\x92\x84\x20\x87") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x72\x98\xca\xa5\x65\x03\x1e\xad\xc6\xce\x23\xd2\x3e\xa6\x63\x78") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xf4\x35\xa1\x11\xa3\xe4\xa1\x94\x49\x19\xf9\x12\xc5\xa2\x41\xde") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x91\xc0\x87\x62\x87\x6d\xcc\xf9\xba\x20\x4a\x33\x76\x8f\xa5\xfe") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x7b\xc3\x02\x6c\xd7\x37\x10\x3e\x62\x90\x2b\xcd\x18\xfb\x01\x63") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x9c\xac\x94\xc6\xb4\x85\x61\xf8\xff\xaa\xa7\x86\x16\xba\x48\x92") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\xf9\xc7\x44\x4b\xb0\xcc\x80\x6c\x7c\x39\xee\x22\x11\xf1\x46") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x6d\xed\xd0\xa3\xe6\x94\xa0\xde\x65\x1d\x68\xa6\xb5\x5a\x64\xa2") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x7b\xc3\x02\x6c\xd7\x37\x10\x3e\x62\x90\x2b\xcd\x18\xfb\x01\x63") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x62\xae\x12\xf3\x24\xbf\xea\x08\xd5\xf6\x75\xb5\x13\x02\x6b\xbf") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\xf9\xc7\x44\x4b\xb0\xcc\x80\x6c\x7c\x39\xee\x22\x11\xf1\x46") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x91\xc0\x87\x62\x87\x6d\xcc\xf9\xba\x20\x4a\x33\x76\x8f\xa5\xfe") ] vectors_aes128_dec = [ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x14\x0f\x0f\x10\x11\xb5\x22\x3d\x79\x58\x77\x17\xff\xd9\xec\x3a") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x33\x08\x32\x40\xd6\x5c\xbc\x72\xaa\x0b\x44\xf3\xe1\x9e\xa9\x5a") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x65\x0a\x42\xa0\x3c\x4b\x93\xa4\xb7\x43\xdc\x9e\x9c\xf4\xc0\x9b") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x80\xcd\x20\xe1\xbd\x89\x3c\x5e\xe4\x20\x76\x85\xb0\x9a\x0e\x3e") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x15\x0e\x0e\x11\x10\xb4\x23\x3c\x78\x59\x76\x16\xfe\xd8\xed\x3b") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x32\x09\x33\x41\xd7\x5d\xbd\x73\xab\x0a\x45\xf2\xe0\x9f\xa8\x5b") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x64\x0b\x43\xa1\x3d\x4a\x92\xa5\xb6\x42\xdd\x9f\x9d\xf5\xc1\x9a") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x81\xcc\x21\xe0\xbc\x88\x3d\x5f\xe5\x21\x77\x84\xb1\x9b\x0f\x3f") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xf5\x06\x41\x7e\x6a\x8f\xbc\x32\xdd\xa5\x52\x73\xbf\x9f\x4d\x5c") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\xbf\x6d\x28\xac\x20\xc9\x1d\x65\xa9\xd4\xb0\x96\xc2\xd5\xa5\x09") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x5f\x2a\x46\xab\x8d\xb9\x5b\x22\x15\xfe\x1a\xa4\xdd\x69\x59\x26") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x71\x9b\x21\xb5\x39\x7c\x2f\x16\x7c\x8b\x45\x22\xb5\x20\xec\x2e") ] vectors_aes192_dec = [ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x13\x46\x0e\x87\xa8\xfc\x02\x3e\xf2\x50\x1a\xfe\x7f\xf5\x1c\x51") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x91\x75\x27\xfc\xd4\xa0\x6f\x32\x27\x29\x90\x14\xca\xde\xd4\x1a") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x29\x64\x80\xb6\xa5\xd6\xcf\xb3\x78\x3f\x21\x6b\x80\x31\x3d\xb3") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xbc\xa5\x06\x07\xd0\x67\x30\x85\x2d\x3a\x50\x4b\x68\x0a\x19\xcc") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x12\x47\x0f\x86\xa9\xfd\x03\x3f\xf3\x51\x1b\xff\x7e\xf4\x1d\x50") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x90\x74\x26\xfd\xd5\xa1\x6e\x33\x26\x28\x91\x15\xcb\xdf\xd5\x1b") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x28\x65\x81\xb7\xa4\xd7\xce\xb2\x79\x3e\x20\x6a\x81\x30\x3c\xb2") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xbd\xa4\x07\x06\xd1\x66\x31\x84\x2c\x3b\x51\x4a\x69\x0b\x18\xcd") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x38\xf9\xf9\xd1\x7e\x2c\x82\xaf\xdc\xed\x68\x03\xb6\x31\x46\x3e") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x35\x4e\xc1\x01\x0f\x17\x50\x5e\x63\x37\x40\x4b\x9a\xf2\xc0\x5c") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\xa7\x7c\xc9\xd1\x4f\x44\xf7\xf7\xcc\x45\x80\x83\x19\xb7\xa4\x71") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\xf9\x1d\xb1\x13\x0b\xd1\xc0\x66\x9f\xfa\xc2\x0e\xbe\xdd\xcb\xca") ] vectors_aes256_dec = [ ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x67\x67\x1c\xe1\xfa\x91\xdd\xeb\x0f\x8f\xbb\xb3\x66\xb5\x31\xb4") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x7b\xd3\xfb\x90\x65\x56\x9f\x39\x8b\x09\xcb\x93\x4b\x1e\x01\x23") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xda\xa8\xbf\x5c\xde\x2e\x52\x45\x5f\xa3\xb3\xfe\x33\x32\x47\xca") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x83\x24\xdc\xb4\x30\x12\x73\x6c\xed\x58\xab\x8f\x4b\x05\xca\x0b") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x66\x66\x1d\xe0\xfb\x90\xdc\xea\x0e\x8e\xba\xb2\x67\xb4\x30\xb5") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x7a\xd2\xfa\x91\x64\x57\x9e\x38\x8a\x08\xca\x92\x4a\x1f\x00\x22") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\xdb\xa9\xbe\x5d\xdf\x2f\x53\x44\x5e\xa2\xb2\xff\x32\x33\x46\xcb") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x82\x25\xdd\xb5\x31\x13\x72\x6d\xec\x59\xaa\x8e\x4a\x04\xcb\x0a") , ("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x68\xe9\x07\x16\xe3\x66\x1b\x1d\xb1\x89\x74\xb0\x9c\x46\x47\xe4") , ("\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01","\x7f\xb9\xeb\xa4\xd3\x5f\x70\x40\xab\x52\xec\xd2\x3b\x48\xb7\x6e") , ("\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02","\x6c\x58\x0f\x41\x82\x36\xbc\xff\x64\x1d\xac\xa7\x3e\x34\x11\x18") , ("\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03\x03","\x3f\x62\xd6\x8c\xb1\xf7\x62\x28\xa4\xc3\x82\x4f\x8b\x24\xe7\x4b") ] cryptonite-0.23/tests/KAT_AES/KATECB.hs0000644000000000000000000001202112570523314015560 0ustar0000000000000000module KAT_AES.KATECB where import qualified Data.ByteString as B vectors_aes128_enc = [ ( B.pack [0x10, 0xa5, 0x88, 0x69, 0xd7, 0x4b, 0xe5, 0xa3,0x74,0xcf,0x86,0x7c,0xfb,0x47,0x38,0x59] , B.replicate 16 0 , B.pack [0x6d,0x25,0x1e,0x69,0x44,0xb0,0x51,0xe0,0x4e,0xaa,0x6f,0xb4,0xdb,0xf7,0x84,0x65] ) , ( B.replicate 16 0 , B.replicate 16 0 , B.pack [0x66,0xe9,0x4b,0xd4,0xef,0x8a,0x2c,0x3b,0x88,0x4c,0xfa,0x59,0xca,0x34,0x2b,0x2e] ) , ( B.replicate 16 0 , B.replicate 16 1 , B.pack [0xe1,0x4d,0x5d,0x0e,0xe2,0x77,0x15,0xdf,0x08,0xb4,0x15,0x2b,0xa2,0x3d,0xa8,0xe0] ) , ( B.replicate 16 1 , B.replicate 16 2 , B.pack [0x17,0xd6,0x14,0xf3,0x79,0xa9,0x35,0x90,0x77,0xe9,0x55,0x77,0xfd,0x31,0xc2,0x0a] ) , ( B.replicate 16 2 , B.replicate 16 1 , B.pack [0x8f,0x42,0xc2,0x4b,0xee,0x6e,0x63,0x47,0x2b,0x16,0x5a,0xa9,0x41,0x31,0x2f,0x7c] ) , ( B.replicate 16 3 , B.replicate 16 2 , B.pack [0x90,0x98,0x85,0xe4,0x77,0xbc,0x20,0xf5,0x8a,0x66,0x97,0x1d,0xa0,0xbc,0x75,0xe3] ) ] vectors_aes192_enc = [ ( B.replicate 24 0 , B.replicate 16 0 , B.pack [0xaa,0xe0,0x69,0x92,0xac,0xbf,0x52,0xa3,0xe8,0xf4,0xa9,0x6e,0xc9,0x30,0x0b,0xd7] ) , ( B.replicate 24 0 , B.replicate 16 1 , B.pack [0xcf,0x1e,0xce,0x3c,0x44,0xb0,0x78,0xfb,0x27,0xcb,0x0a,0x3e,0x07,0x1b,0x08,0x20] ) , ( B.replicate 24 1 , B.replicate 16 2 , B.pack [0xeb,0x8c,0x17,0x30,0x90,0xc7,0x5b,0x77,0xd6,0x72,0xb4,0x57,0xa7,0x78,0xd9,0xd0] ) , ( B.replicate 24 2 , B.replicate 16 1 , B.pack [0xf2,0xf0,0xae,0xd8,0xcd,0xc9,0x21,0xca,0x4b,0x55,0x84,0x5d,0xa4,0x15,0x21,0xc2] ) , ( B.replicate 24 3 , B.replicate 16 2 , B.pack [0xca,0xcc,0x30,0x79,0xe4,0xb7,0x95,0x27,0x63,0xd2,0x55,0xd6,0x34,0x10,0x46,0x14] ) ] vectors_aes256_enc = [ ( B.replicate 32 0 , B.replicate 16 0 , B.pack [0xdc,0x95,0xc0,0x78,0xa2,0x40,0x89,0x89,0xad,0x48,0xa2,0x14,0x92,0x84,0x20,0x87] ) , ( B.replicate 32 0 , B.replicate 16 1 , B.pack [0x7b,0xc3,0x02,0x6c,0xd7,0x37,0x10,0x3e,0x62,0x90,0x2b,0xcd,0x18,0xfb,0x01,0x63] ) , ( B.replicate 32 1 , B.replicate 16 2 , B.pack [0x62,0xae,0x12,0xf3,0x24,0xbf,0xea,0x08,0xd5,0xf6,0x75,0xb5,0x13,0x02,0x6b,0xbf] ) , ( B.replicate 32 2 , B.replicate 16 1 , B.pack [0x00,0xf9,0xc7,0x44,0x4b,0xb0,0xcc,0x80,0x6c,0x7c,0x39,0xee,0x22,0x11,0xf1,0x46] ) , ( B.replicate 32 3 , B.replicate 16 2 , B.pack [0xb4,0x05,0x87,0x3e,0xa0,0x76,0x1b,0x9c,0xa9,0x9f,0x70,0xb0,0x16,0x16,0xce,0xb1] ) ] vectors_aes128_dec = [ ( B.replicate 16 0 , B.replicate 16 0 , B.pack [0x14,0x0f,0x0f,0x10,0x11,0xb5,0x22,0x3d,0x79,0x58,0x77,0x17,0xff,0xd9,0xec,0x3a] ) , ( B.replicate 16 0 , B.replicate 16 1 , B.pack [0x15,0x6d,0x0f,0x85,0x75,0xd5,0x33,0x07,0x52,0xf8,0x4a,0xf2,0x72,0xff,0x30,0x50] ) , ( B.replicate 16 1 , B.replicate 16 2 , B.pack [0x34,0x37,0xd6,0xe2,0x31,0xd7,0x02,0x41,0x9b,0x51,0xb4,0x94,0x72,0x71,0xb6,0x11] ) , ( B.replicate 16 2 , B.replicate 16 1 , B.pack [0xe3,0xcd,0xe2,0x37,0xc8,0xf2,0xd9,0x7b,0x8d,0x79,0xf9,0x17,0x1d,0x4b,0xda,0xc1] ) , ( B.replicate 16 3 , B.replicate 16 2 , B.pack [0x5b,0x94,0xaa,0xed,0xd7,0x83,0x99,0x8c,0xd5,0x15,0x35,0x35,0x18,0xcc,0x45,0xe2] ) ] vectors_aes192_dec = [ ( B.replicate 24 0 , B.replicate 16 0 , B.pack [0x13,0x46,0x0e,0x87,0xa8,0xfc,0x02,0x3e,0xf2,0x50,0x1a,0xfe,0x7f,0xf5,0x1c,0x51] ) , ( B.replicate 24 0 , B.replicate 16 1 , B.pack [0x92,0x17,0x07,0xc3,0x3d,0x1c,0xc5,0x96,0x7d,0xa5,0x1d,0xbb,0xb0,0x66,0xb2,0x6c] ) , ( B.replicate 24 1 , B.replicate 16 2 , B.pack [0xee,0x92,0x97,0xc6,0xba,0xe8,0x26,0x4d,0xff,0x08,0x0e,0xbb,0x1e,0x74,0x11,0xc1] ) , ( B.replicate 24 2 , B.replicate 16 1 , B.pack [0x49,0x67,0xdf,0x70,0xd2,0x9e,0x9a,0x7f,0x5d,0x7c,0xb9,0xc1,0x20,0xc3,0x8a,0x71] ) , ( B.replicate 24 3 , B.replicate 16 2 , B.pack [0x74,0x38,0x62,0x42,0x6b,0x56,0x7f,0xd5,0xf0,0x1d,0x1b,0x59,0x56,0x01,0x26,0x29] ) ] vectors_aes256_dec = [ ( B.replicate 32 0 , B.replicate 16 0 , B.pack [0x67,0x67,0x1c,0xe1,0xfa,0x91,0xdd,0xeb,0x0f,0x8f,0xbb,0xb3,0x66,0xb5,0x31,0xb4] ) , ( B.replicate 32 0 , B.replicate 16 1 , B.pack [0xcc,0x09,0x21,0xa3,0xc5,0xca,0x17,0xf7,0x48,0xb7,0xc2,0x7b,0x73,0xba,0x87,0xa2] ) , ( B.replicate 32 1 , B.replicate 16 2 , B.pack [0xc0,0x4b,0x27,0x90,0x1a,0x50,0xcf,0xfa,0xf1,0xbb,0x88,0x9f,0xc0,0x92,0x5e,0x14] ) , ( B.replicate 32 2 , B.replicate 16 1 , B.pack [0x24,0x61,0x53,0x5d,0x16,0x1c,0x15,0x39,0x88,0x32,0x77,0x29,0xc5,0x8c,0xc0,0x3a] ) , ( B.replicate 32 3 , B.replicate 16 2 , B.pack [0x30,0xc9,0x1c,0xce,0xfe,0x89,0x30,0xcf,0xff,0x31,0xdb,0xcc,0xfc,0x11,0xc5,0x23] ) ] cryptonite-0.23/tests/KAT_AES/KATGCM.hs0000644000000000000000000001316212514400150015572 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES.KATGCM where import qualified Data.ByteString as B import Data.ByteString.Char8 () -- (key, iv, aad, input, out, taglen, tag) type KATGCM = (B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString, Int, B.ByteString) vectors_aes128_enc :: [KATGCM] vectors_aes128_enc = [ -- vectors 0 ( {-key = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-iv = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-aad = -}"" , {-input = -}"" , {-out = -}"" , {-taglen = -}16 , {-tag = -}"\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45\x5a") -- vectors 1 , ( {-key = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-iv = -}"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-aad = -}"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" , {-input = -}"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" , {-out = -}"\x09\x82\xd0\xc4\x6a\xbc\xa9\x98\xf9\x22\xc8\xb3\x7b\xb8\xf4\x72\xfd\x9f\xa0\xa1\x43\x41\x53\x29\xfd\xf7\x83\xf5\x9e\x81\xcb\xea" , {-taglen = -}16 , {-tag = -}"\x28\x50\x64\x2f\xa8\x8b\xab\x21\x2a\x67\x1a\x97\x48\x69\xa5\x6c") -- vectors 2 , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-aad = -}"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" , {-input = -}"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" , {-out = -}"\x1c\xa3\xb5\x41\x39\x6f\x19\x7a\x91\x2d\x27\x15\x70\xd1\xf5\x76\xde\xf1\xbe\x84\x42\x2a\xbb\xbe\x0b\x2d\x91\x21\x82\xbf\x7f\x17" , {-taglen = -}16 , {-tag = -}"\x15\x2a\x05\xbb\x7e\x13\x5d\xbe\x93\x7f\xa0\x54\x7a\x8e\x74\xb6") -- vectors 3 , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-aad = -}"\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" , {-input = -}"\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a" , {-out = -}"\xda\x35\xf6\x0a\x65\xc2\xa4\x6c\xb6\x6e\xb6\xf8\x1f\x0b\x9c\x74\x53\x4c\x97\x70\x36\xf7\xdf\x05\x6d\x00\xfe\xbf\xb4\xcb\xf5\x27" , {-taglen = -}16 , {-tag = -}"\xb7\x76\x7c\x3b\x9e\xf1\xe2\xcb\xc9\x11\xf1\x9a\xdc\xfa\x35\x0d") , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-aad = -}"\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76" , {-input = -}"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" , {-out = -}"\xe4\x42\xf8\xc4\xc6\x67\x84\x86\x4a\x5a\x6e\xc7\xe0\xca\x68\xac\x16\xbc\x5b\xbf\xf7\xd5\xf3\xfa\xf3\xb2\xcb\xb0\xa2\x14\xa1\x81" , {-taglen = -}16 , {-tag = -}"\x5f\x63\xb8\xeb\x1d\x6f\xa8\x7a\xeb\x39\xa5\xf6\xd7\xed\xc3\x13") , ( {-key = -}"\x01\x02\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-iv = -}"\xff\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , {-aad = -}"\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76\x76" , {-input = -}"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" , {-out = -}"\xe4\x42\xf8\xc4\xc6\x67\x84\x86\x4a\x5a\x6e\xc7\xe0\xca\x68\xac\x16\xbc\x5b\xbf\xf7\xd5\xf3\xfa\xf3\xb2\xcb\xb0\xa2\x14\xa1" , {-taglen = -}16 , {-tag = -}"\x94\xd1\x47\xc3\xa2\xca\x93\xe9\x66\x93\x1e\x3b\xb3\xbb\x67\x01") ] vectors_aes256_enc :: [KATGCM] vectors_aes256_enc = [ ( "\xb5\x2c\x50\x5a\x37\xd7\x8e\xda\x5d\xd3\x4f\x20\xc2\x25\x40\xea\x1b\x58\x96\x3c\xf8\xe5\xbf\x8f\xfa\x85\xf9\xf2\x49\x25\x05\xb4" , "\x51\x6c\x33\x92\x9d\xf5\xa3\x28\x4f\xf4\x63\xd7" , "" , "" , "" , 16 , "\xbd\xc1\xac\x88\x4d\x33\x24\x57\xa1\xd2\x66\x4f\x16\x8c\x76\xf0") , ( "\x78\xdc\x4e\x0a\xaf\x52\xd9\x35\xc3\xc0\x1e\xea\x57\x42\x8f\x00\xca\x1f\xd4\x75\xf5\xda\x86\xa4\x9c\x8d\xd7\x3d\x68\xc8\xe2\x23" , "\xd7\x9c\xf2\x2d\x50\x4c\xc7\x93\xc3\xfb\x6c\x8a" , "\xb9\x6b\xaa\x8c\x1c\x75\xa6\x71\xbf\xb2\xd0\x8d\x06\xbe\x5f\x36" , "" , "" , 16 , "\x3e\x5d\x48\x6a\xa2\xe3\x0b\x22\xe0\x40\xb8\x57\x23\xa0\x6e\x76") , ( "\xc3\xf1\x05\x86\xf2\x46\xaa\xca\xdc\xce\x37\x01\x44\x17\x70\xc0\x3c\xfe\xc9\x40\xaf\xe1\x90\x8c\x4c\x53\x7d\xf4\xe0\x1c\x50\xa0" , "\x4f\x52\xfa\xa1\xfa\x67\xa0\xe5\xf4\x19\x64\x52" , "\x46\xf9\xa2\x2b\x4e\x52\xe1\x52\x65\x13\xa9\x52\xdb\xee\x3b\x91\xf6\x95\x95\x50\x1e\x01\x77\xd5\x0f\xf3\x64\x63\x85\x88\xc0\x8d\x92\xfa\xb8\xc5\x8a\x96\x9b\xdc\xc8\x4c\x46\x8d\x84\x98\xc4\xf0\x63\x92\xb9\x9e\xd5\xe0\xc4\x84\x50\x7f\xc4\x8d\xc1\x8d\x87\xc4\x0e\x2e\xd8\x48\xb4\x31\x50\xbe\x9d\x36\xf1\x4c\xf2\xce\xf1\x31\x0b\xa4\xa7\x45\xad\xcc\x7b\xdc\x41\xf6" , "\x79\xd9\x7e\xa3\xa2\xed\xd6\x50\x45\x82\x1e\xa7\x45\xa4\x47\x42" , "\x56\x0c\xf7\x16\xe5\x61\x90\xe9\x39\x7c\x2f\x10\x36\x29\xeb\x1f" , 16 , "\xff\x7c\x91\x24\x87\x96\x44\xe8\x05\x55\x68\x7d\x27\x3c\x55\xd8" ) ] cryptonite-0.23/tests/KAT_AES/KATOCB3.hs0000644000000000000000000000316712514400155015663 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES.KATOCB3 where import qualified Data.ByteString as B import Data.ByteString.Char8 () -- (key, iv, aad, input, out, taglen, tag) type KATOCB3 = (B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString, Int, B.ByteString) key1 = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" nonce1 = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" vectors_aes128_enc :: [KATOCB3] vectors_aes128_enc = [ ( {-key = -} key1 , {-iv = -} nonce1 , {-aad = -}"" , {-input = -}"" , {-out = -}"" , {-taglen = -} 16 , {-tag = -} "\x19\x7b\x9c\x3c\x44\x1d\x3c\x83\xea\xfb\x2b\xef\x63\x3b\x91\x82") , ( key1, nonce1 , "\x00\x01\x02\x03\x04\x05\x06\x07" , "\x00\x01\x02\x03\x04\x05\x06\x07" , "\x92\xb6\x57\x13\x0a\x74\xb8\x5a" , 16 , "\x16\xdc\x76\xa4\x6d\x47\xe1\xea\xd5\x37\x20\x9e\x8a\x96\xd1\x4e") , ( key1, nonce1 , "\x00\x01\x02\x03\x04\x05\x06\x07" , "" , "" , 16 , "\x98\xb9\x15\x52\xc8\xc0\x09\x18\x50\x44\xe3\x0a\x6e\xb2\xfe\x21") , ( key1, nonce1 , "" , "\x00\x01\x02\x03\x04\x05\x06\x07" , "\x92\xb6\x57\x13\x0a\x74\xb8\x5a" , 16 , "\x97\x1e\xff\xca\xe1\x9a\xd4\x71\x6f\x88\xe8\x7b\x87\x1f\xbe\xed") , ( key1, nonce1 , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" , "\xbe\xa5\xe8\x79\x8d\xbe\x71\x10\x03\x1c\x14\x4d\xa0\xb2\x61\x22" , 16 , "\x77\x6c\x99\x24\xd6\x72\x3a\x1f\xc4\x52\x45\x32\xac\x3e\x5b\xeb") ] cryptonite-0.23/tests/KAT_AES/KATXTS.hs0000644000000000000000000002611112514400143015642 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES.KATXTS where import qualified Data.ByteString as B import Data.ByteString.Char8 () type KATXTS = (B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString) vectors_aes128_enc, vectors_aes128_dec, vectors_aes256_enc, vectors_aes256_dec :: [KATXTS] vectors_aes128_enc = [ ( "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x66\xe9\x4b\xd4\xef\x8a\x2c\x3b\x88\x4c\xfa\x59\xca\x34\x2b\x2e\xcc\xd2\x97\xa8\xdf\x15\x59\x76\x10\x99\xf4\xb3\x94\x69\x56\x5c" , "\x91\x7c\xf6\x9e\xbd\x68\xb2\xec\x9b\x9f\xe9\xa3\xea\xdd\xa6\x92\xcd\x43\xd2\xf5\x95\x98\xed\x85\x8c\x02\xc2\x65\x2f\xbf\x92\x2e" ) , ( "\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11" , "\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22" , "\x33\x33\x33\x33\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44" , "\x3f\x80\x3b\xcd\x0d\x7f\xd2\xb3\x75\x58\x41\x9f\x59\xd5\xcd\xa6\xf9\x00\x77\x9a\x1b\xfe\xa4\x67\xeb\xb0\x82\x3e\xb3\xaa\x9b\x4d" , "\xc4\x54\x18\x5e\x6a\x16\x93\x6e\x39\x33\x40\x38\xac\xef\x83\x8b\xfb\x18\x6f\xff\x74\x80\xad\xc4\x28\x93\x82\xec\xd6\xd3\x94\xf0" ) , ( "\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6\xf5\xf4\xf3\xf2\xf1\xf0" , "\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22\x22" , "\x33\x33\x33\x33\x33\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44\x44" , "\x3f\x80\x3b\xcd\x0d\x7f\xd2\xb3\x75\x58\x41\x9f\x59\xd5\xcd\xa6\xf9\x00\x77\x9a\x1b\xfe\xa4\x67\xeb\xb0\x82\x3e\xb3\xaa\x9b\x4d" , "\xaf\x85\x33\x6b\x59\x7a\xfc\x1a\x90\x0b\x2e\xb2\x1e\xc9\x49\xd2\x92\xdf\x4c\x04\x7e\x0b\x21\x53\x21\x86\xa5\x97\x1a\x22\x7a\x89" ) , ( "\x27\x18\x28\x18\x28\x45\x90\x45\x23\x53\x60\x28\x74\x71\x35\x26" , "\x31\x41\x59\x26\x53\x58\x97\x93\x23\x84\x62\x64\x33\x83\x27\x95" , "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" , "" , "\x27\xa7\x47\x9b\xef\xa1\xd4\x76\x48\x9f\x30\x8c\xd4\xcf\xa6\xe2\xa9\x6e\x4b\xbe\x32\x08\xff\x25\x28\x7d\xd3\x81\x96\x16\xe8\x9c\xc7\x8c\xf7\xf5\xe5\x43\x44\x5f\x83\x33\xd8\xfa\x7f\x56\x00\x00\x05\x27\x9f\xa5\xd8\xb5\xe4\xad\x40\xe7\x36\xdd\xb4\xd3\x54\x12\x32\x80\x63\xfd\x2a\xab\x53\xe5\xea\x1e\x0a\x9f\x33\x25\x00\xa5\xdf\x94\x87\xd0\x7a\x5c\x92\xcc\x51\x2c\x88\x66\xc7\xe8\x60\xce\x93\xfd\xf1\x66\xa2\x49\x12\xb4\x22\x97\x61\x46\xae\x20\xce\x84\x6b\xb7\xdc\x9b\xa9\x4a\x76\x7a\xae\xf2\x0c\x0d\x61\xad\x02\x65\x5e\xa9\x2d\xc4\xc4\xe4\x1a\x89\x52\xc6\x51\xd3\x31\x74\xbe\x51\xa1\x0c\x42\x11\x10\xe6\xd8\x15\x88\xed\xe8\x21\x03\xa2\x52\xd8\xa7\x50\xe8\x76\x8d\xef\xff\xed\x91\x22\x81\x0a\xae\xb9\x9f\x91\x72\xaf\x82\xb6\x04\xdc\x4b\x8e\x51\xbc\xb0\x82\x35\xa6\xf4\x34\x13\x32\xe4\xca\x60\x48\x2a\x4b\xa1\xa0\x3b\x3e\x65\x00\x8f\xc5\xda\x76\xb7\x0b\xf1\x69\x0d\xb4\xea\xe2\x9c\x5f\x1b\xad\xd0\x3c\x5c\xcf\x2a\x55\xd7\x05\xdd\xcd\x86\xd4\x49\x51\x1c\xeb\x7e\xc3\x0b\xf1\x2b\x1f\xa3\x5b\x91\x3f\x9f\x74\x7a\x8a\xfd\x1b\x13\x0e\x94\xbf\xf9\x4e\xff\xd0\x1a\x91\x73\x5c\xa1\x72\x6a\xcd\x0b\x19\x7c\x4e\x5b\x03\x39\x36\x97\xe1\x26\x82\x6f\xb6\xbb\xde\x8e\xcc\x1e\x08\x29\x85\x16\xe2\xc9\xed\x03\xff\x3c\x1b\x78\x60\xf6\xde\x76\xd4\xce\xcd\x94\xc8\x11\x98\x55\xef\x52\x97\xca\x67\xe9\xf3\xe7\xff\x72\xb1\xe9\x97\x85\xca\x0a\x7e\x77\x20\xc5\xb3\x6d\xc6\xd7\x2c\xac\x95\x74\xc8\xcb\xbc\x2f\x80\x1e\x23\xe5\x6f\xd3\x44\xb0\x7f\x22\x15\x4b\xeb\xa0\xf0\x8c\xe8\x89\x1e\x64\x3e\xd9\x95\xc9\x4d\x9a\x69\xc9\xf1\xb5\xf4\x99\x02\x7a\x78\x57\x2a\xee\xbd\x74\xd2\x0c\xc3\x98\x81\xc2\x13\xee\x77\x0b\x10\x10\xe4\xbe\xa7\x18\x84\x69\x77\xae\x11\x9f\x7a\x02\x3a\xb5\x8c\xca\x0a\xd7\x52\xaf\xe6\x56\xbb\x3c\x17\x25\x6a\x9f\x6e\x9b\xf1\x9f\xdd\x5a\x38\xfc\x82\xbb\xe8\x72\xc5\x53\x9e\xdb\x60\x9e\xf4\xf7\x9c\x20\x3e\xbb\x14\x0f\x2e\x58\x3c\xb2\xad\x15\xb4\xaa\x5b\x65\x50\x16\xa8\x44\x92\x77\xdb\xd4\x77\xef\x2c\x8d\x6c\x01\x7d\xb7\x38\xb1\x8d\xeb\x4a\x42\x7d\x19\x23\xce\x3f\xf2\x62\x73\x57\x79\xa4\x18\xf2\x0a\x28\x2d\xf9\x20\x14\x7b\xea\xbe\x42\x1e\xe5\x31\x9d\x05\x68" ) ] vectors_aes128_dec = [] vectors_aes256_enc = [ ( "\x27\x18\x28\x18\x28\x45\x90\x45\x23\x53\x60\x28\x74\x71\x35\x26\x62\x49\x77\x57\x24\x70\x93\x69\x99\x59\x57\x49\x66\x96\x76\x27" , "\x31\x41\x59\x26\x53\x58\x97\x93\x23\x84\x62\x64\x33\x83\x27\x95\x02\x88\x41\x97\x16\x93\x99\x37\x51\x05\x82\x09\x74\x94\x45\x92" , "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" , "" , "\x1c\x3b\x3a\x10\x2f\x77\x03\x86\xe4\x83\x6c\x99\xe3\x70\xcf\x9b\xea\x00\x80\x3f\x5e\x48\x23\x57\xa4\xae\x12\xd4\x14\xa3\xe6\x3b\x5d\x31\xe2\x76\xf8\xfe\x4a\x8d\x66\xb3\x17\xf9\xac\x68\x3f\x44\x68\x0a\x86\xac\x35\xad\xfc\x33\x45\xbe\xfe\xcb\x4b\xb1\x88\xfd\x57\x76\x92\x6c\x49\xa3\x09\x5e\xb1\x08\xfd\x10\x98\xba\xec\x70\xaa\xa6\x69\x99\xa7\x2a\x82\xf2\x7d\x84\x8b\x21\xd4\xa7\x41\xb0\xc5\xcd\x4d\x5f\xff\x9d\xac\x89\xae\xba\x12\x29\x61\xd0\x3a\x75\x71\x23\xe9\x87\x0f\x8a\xcf\x10\x00\x02\x08\x87\x89\x14\x29\xca\x2a\x3e\x7a\x7d\x7d\xf7\xb1\x03\x55\x16\x5c\x8b\x9a\x6d\x0a\x7d\xe8\xb0\x62\xc4\x50\x0d\xc4\xcd\x12\x0c\x0f\x74\x18\xda\xe3\xd0\xb5\x78\x1c\x34\x80\x3f\xa7\x54\x21\xc7\x90\xdf\xe1\xde\x18\x34\xf2\x80\xd7\x66\x7b\x32\x7f\x6c\x8c\xd7\x55\x7e\x12\xac\x3a\x0f\x93\xec\x05\xc5\x2e\x04\x93\xef\x31\xa1\x2d\x3d\x92\x60\xf7\x9a\x28\x9d\x6a\x37\x9b\xc7\x0c\x50\x84\x14\x73\xd1\xa8\xcc\x81\xec\x58\x3e\x96\x45\xe0\x7b\x8d\x96\x70\x65\x5b\xa5\xbb\xcf\xec\xc6\xdc\x39\x66\x38\x0a\xd8\xfe\xcb\x17\xb6\xba\x02\x46\x9a\x02\x0a\x84\xe1\x8e\x8f\x84\x25\x20\x70\xc1\x3e\x9f\x1f\x28\x9b\xe5\x4f\xbc\x48\x14\x57\x77\x8f\x61\x60\x15\xe1\x32\x7a\x02\xb1\x40\xf1\x50\x5e\xb3\x09\x32\x6d\x68\x37\x8f\x83\x74\x59\x5c\x84\x9d\x84\xf4\xc3\x33\xec\x44\x23\x88\x51\x43\xcb\x47\xbd\x71\xc5\xed\xae\x9b\xe6\x9a\x2f\xfe\xce\xb1\xbe\xc9\xde\x24\x4f\xbe\x15\x99\x2b\x11\xb7\x7c\x04\x0f\x12\xbd\x8f\x6a\x97\x5a\x44\xa0\xf9\x0c\x29\xa9\xab\xc3\xd4\xd8\x93\x92\x72\x84\xc5\x87\x54\xcc\xe2\x94\x52\x9f\x86\x14\xdc\xd2\xab\xa9\x91\x92\x5f\xed\xc4\xae\x74\xff\xac\x6e\x33\x3b\x93\xeb\x4a\xff\x04\x79\xda\x9a\x41\x0e\x44\x50\xe0\xdd\x7a\xe4\xc6\xe2\x91\x09\x00\x57\x5d\xa4\x01\xfc\x07\x05\x9f\x64\x5e\x8b\x7e\x9b\xfd\xef\x33\x94\x30\x54\xff\x84\x01\x14\x93\xc2\x7b\x34\x29\xea\xed\xb4\xed\x53\x76\x44\x1a\x77\xed\x43\x85\x1a\xd7\x7f\x16\xf5\x41\xdf\xd2\x69\xd5\x0d\x6a\x5f\x14\xfb\x0a\xab\x1c\xbb\x4c\x15\x50\xbe\x97\xf7\xab\x40\x66\x19\x3c\x4c\xaa\x77\x3d\xad\x38\x01\x4b\xd2\x09\x2f\xa7\x55\xc8\x24\xbb\x5e\x54\xc4\xf3\x6f\xfd\xa9\xfc\xea\x70\xb9\xc6\xe6\x93\xe1\x48\xc1\x51" ) ] vectors_aes256_dec = [] cryptonite-0.23/tests/KAT_AES.hs0000644000000000000000000000566112522370606014644 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES (tests) where import Imports import BlockCipher import Crypto.Cipher.Types import qualified Crypto.Cipher.AES as AES import qualified KAT_AES.KATECB as KATECB import qualified KAT_AES.KATCBC as KATCBC import qualified KAT_AES.KATXTS as KATXTS import qualified KAT_AES.KATGCM as KATGCM import qualified KAT_AES.KATOCB3 as KATOCB3 {- instance Show AES.AES where show _ = "AES" instance Arbitrary AES.AESIV where arbitrary = AES.aesIV_ . B.pack <$> replicateM 16 arbitrary instance Arbitrary AES.AES where arbitrary = AES.initAES . B.pack <$> replicateM 16 arbitrary -} toKatECB (k,p,c) = KAT_ECB { ecbKey = k, ecbPlaintext = p, ecbCiphertext = c } toKatCBC (k,iv,p,c) = KAT_CBC { cbcKey = k, cbcIV = iv, cbcPlaintext = p, cbcCiphertext = c } toKatXTS (k1,k2,iv,p,_,c) = KAT_XTS { xtsKey1 = k1, xtsKey2 = k2, xtsIV = iv, xtsPlaintext = p, xtsCiphertext = c } toKatAEAD mode (k,iv,h,p,c,taglen,tag) = KAT_AEAD { aeadMode = mode , aeadKey = k , aeadIV = iv , aeadHeader = h , aeadPlaintext = p , aeadCiphertext = c , aeadTaglen = taglen , aeadTag = tag } toKatGCM = toKatAEAD AEAD_GCM toKatOCB = toKatAEAD AEAD_OCB kats128 = defaultKATs { kat_ECB = map toKatECB KATECB.vectors_aes128_enc , kat_CBC = map toKatCBC KATCBC.vectors_aes128_enc , kat_CFB = [ KAT_CFB { cfbKey = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c" , cfbIV = "\xC8\xA6\x45\x37\xA0\xB3\xA9\x3F\xCD\xE3\xCD\xAD\x9F\x1C\xE5\x8B" , cfbPlaintext = "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" , cfbCiphertext = "\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" } ] , kat_XTS = map toKatXTS KATXTS.vectors_aes128_enc , kat_AEAD = map toKatGCM KATGCM.vectors_aes128_enc ++ map toKatOCB KATOCB3.vectors_aes128_enc } kats192 = defaultKATs { kat_ECB = map toKatECB KATECB.vectors_aes192_enc , kat_CBC = map toKatCBC KATCBC.vectors_aes192_enc } kats256 = defaultKATs { kat_ECB = map toKatECB KATECB.vectors_aes256_enc , kat_CBC = map toKatCBC KATCBC.vectors_aes256_enc , kat_XTS = map toKatXTS KATXTS.vectors_aes256_enc , kat_AEAD = map toKatGCM KATGCM.vectors_aes256_enc } tests = testGroup "AES" [ testBlockCipher kats128 (undefined :: AES.AES128) , testBlockCipher kats192 (undefined :: AES.AES192) , testBlockCipher kats256 (undefined :: AES.AES256) {- , testProperty "genCtr" $ \(key, iv1) -> let (bs1, iv2) = AES.genCounter key iv1 32 (bs2, iv3) = AES.genCounter key iv2 32 (bsAll, iv3') = AES.genCounter key iv1 64 in (B.concat [bs1,bs2] == bsAll && iv3 == iv3') -} ] cryptonite-0.23/tests/KAT_AFIS.hs0000644000000000000000000000360512524377653014765 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ExistentialQuantification #-} module KAT_AFIS (tests) where import Imports import Crypto.Hash import Crypto.Random import qualified Crypto.Data.AFIS as AFIS import qualified Data.ByteString as B mergeVec :: [ (Int, SHA1, B.ByteString, B.ByteString) ] mergeVec = [ (3 , SHA1 , "\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02" , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\xd4\x76\xc8\x58\xbd\xf0\x15\xbe\x9f\x40\xe3\x65\x20\x1c\x9c\xb8\xd8\x1c\x16\x64" ) , (3 , SHA1 , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17" , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\xd6\x75\xc8\x59\xbb\xf7\x11\xbb\x95\x4b\xeb\x6c\x2e\x13\x90\xb5\xca\x0f\x06\x75\x17\x70\x39\x28" ) ] mergeKATs = map toProp $ zip mergeVec [(0 :: Int)..] where toProp ((nbExpands, hashAlg, expected, dat), i) = testCase ("merge " ++ show i) (expected @=? AFIS.merge hashAlg nbExpands dat) data AFISParams = AFISParams B.ByteString Int SHA1 ChaChaDRG instance Show AFISParams where show (AFISParams dat expand _ _) = "data: " ++ show dat ++ " expanded: " ++ show expand instance Arbitrary AFISParams where arbitrary = AFISParams <$> arbitraryBSof 3 46 <*> choose (2,2) <*> elements [SHA1] <*> arbitrary instance Arbitrary ChaChaDRG where arbitrary = drgNewTest <$> arbitrary tests = testGroup "AFIS" [ testGroup "KAT merge" mergeKATs , testProperty "merge.split == id" $ \(AFISParams bs e hf rng) -> bs == (AFIS.merge hf e $ fst (AFIS.split hf rng e bs)) ] cryptonite-0.23/tests/KAT_Argon2.hs0000644000000000000000000000232013054050744015350 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Argon2 (tests) where import Crypto.Error import qualified Crypto.KDF.Argon2 as Argon2 import qualified Data.ByteString as B import Imports data KDFVector = KDFVector { kdfPass :: ByteString , kdfSalt :: ByteString , kdfOptions :: Argon2.Options , kdfResult :: ByteString } argon2i_13 :: Argon2.TimeCost -> Argon2.MemoryCost -> Argon2.Options argon2i_13 iters memory = Argon2.Options { Argon2.iterations = iters , Argon2.memory = memory , Argon2.parallelism = 1 , Argon2.variant = Argon2.Argon2i , Argon2.version = Argon2.Version13 } vectors = [ KDFVector "password" "somesalt" (argon2i_13 2 65536) "\xc1\x62\x88\x32\x14\x7d\x97\x20\xc5\xbd\x1c\xfd\x61\x36\x70\x78\x72\x9f\x6d\xfb\x6f\x8f\xea\x9f\xf9\x81\x58\xe0\xd7\x81\x6e\xd0" ] kdfTests :: [TestTree] kdfTests = map toKDFTest $ zip is vectors where toKDFTest (i, v) = testCase (show i) (CryptoPassed (kdfResult v) @=? Argon2.hash (kdfOptions v) (kdfPass v) (kdfSalt v) (B.length $ kdfResult v)) is :: [Int] is = [1..] tests = testGroup "Argon2" [ testGroup "KATs" kdfTests ] cryptonite-0.23/tests/KAT_Blowfish.hs0000644000000000000000000001034212512146401015772 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Blowfish where import Crypto.Cipher.Blowfish import Imports () import BlockCipher vectors_ecb = -- key plaintext cipher [ KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x4E\xF9\x97\x45\x61\x98\xDD\x78" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x51\x86\x6F\xD5\xB8\x5E\xCB\x8A" , KAT_ECB "\x30\x00\x00\x00\x00\x00\x00\x00" "\x10\x00\x00\x00\x00\x00\x00\x01" "\x7D\x85\x6F\x9A\x61\x30\x63\xF2" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x24\x66\xDD\x87\x8B\x96\x3C\x9D" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x61\xF9\xC3\x80\x22\x81\xB0\x96" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x7D\x0C\xC6\x30\xAF\xDA\x1E\xC7" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x4E\xF9\x97\x45\x61\x98\xDD\x78" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x0A\xCE\xAB\x0F\xC6\xA0\xA2\x8D" , KAT_ECB "\x7C\xA1\x10\x45\x4A\x1A\x6E\x57" "\x01\xA1\xD6\xD0\x39\x77\x67\x42" "\x59\xC6\x82\x45\xEB\x05\x28\x2B" , KAT_ECB "\x01\x31\xD9\x61\x9D\xC1\x37\x6E" "\x5C\xD5\x4C\xA8\x3D\xEF\x57\xDA" "\xB1\xB8\xCC\x0B\x25\x0F\x09\xA0" , KAT_ECB "\x07\xA1\x13\x3E\x4A\x0B\x26\x86" "\x02\x48\xD4\x38\x06\xF6\x71\x72" "\x17\x30\xE5\x77\x8B\xEA\x1D\xA4" , KAT_ECB "\x38\x49\x67\x4C\x26\x02\x31\x9E" "\x51\x45\x4B\x58\x2D\xDF\x44\x0A" "\xA2\x5E\x78\x56\xCF\x26\x51\xEB" , KAT_ECB "\x04\xB9\x15\xBA\x43\xFE\xB5\xB6" "\x42\xFD\x44\x30\x59\x57\x7F\xA2" "\x35\x38\x82\xB1\x09\xCE\x8F\x1A" , KAT_ECB "\x01\x13\xB9\x70\xFD\x34\xF2\xCE" "\x05\x9B\x5E\x08\x51\xCF\x14\x3A" "\x48\xF4\xD0\x88\x4C\x37\x99\x18" , KAT_ECB "\x01\x70\xF1\x75\x46\x8F\xB5\xE6" "\x07\x56\xD8\xE0\x77\x47\x61\xD2" "\x43\x21\x93\xB7\x89\x51\xFC\x98" , KAT_ECB "\x43\x29\x7F\xAD\x38\xE3\x73\xFE" "\x76\x25\x14\xB8\x29\xBF\x48\x6A" "\x13\xF0\x41\x54\xD6\x9D\x1A\xE5" , KAT_ECB "\x07\xA7\x13\x70\x45\xDA\x2A\x16" "\x3B\xDD\x11\x90\x49\x37\x28\x02" "\x2E\xED\xDA\x93\xFF\xD3\x9C\x79" , KAT_ECB "\x04\x68\x91\x04\xC2\xFD\x3B\x2F" "\x26\x95\x5F\x68\x35\xAF\x60\x9A" "\xD8\x87\xE0\x39\x3C\x2D\xA6\xE3" , KAT_ECB "\x37\xD0\x6B\xB5\x16\xCB\x75\x46" "\x16\x4D\x5E\x40\x4F\x27\x52\x32" "\x5F\x99\xD0\x4F\x5B\x16\x39\x69" , KAT_ECB "\x1F\x08\x26\x0D\x1A\xC2\x46\x5E" "\x6B\x05\x6E\x18\x75\x9F\x5C\xCA" "\x4A\x05\x7A\x3B\x24\xD3\x97\x7B" , KAT_ECB "\x58\x40\x23\x64\x1A\xBA\x61\x76" "\x00\x4B\xD6\xEF\x09\x17\x60\x62" "\x45\x20\x31\xC1\xE4\xFA\xDA\x8E" , KAT_ECB "\x02\x58\x16\x16\x46\x29\xB0\x07" "\x48\x0D\x39\x00\x6E\xE7\x62\xF2" "\x75\x55\xAE\x39\xF5\x9B\x87\xBD" , KAT_ECB "\x49\x79\x3E\xBC\x79\xB3\x25\x8F" "\x43\x75\x40\xC8\x69\x8F\x3C\xFA" "\x53\xC5\x5F\x9C\xB4\x9F\xC0\x19" , KAT_ECB "\x4F\xB0\x5E\x15\x15\xAB\x73\xA7" "\x07\x2D\x43\xA0\x77\x07\x52\x92" "\x7A\x8E\x7B\xFA\x93\x7E\x89\xA3" , KAT_ECB "\x49\xE9\x5D\x6D\x4C\xA2\x29\xBF" "\x02\xFE\x55\x77\x81\x17\xF1\x2A" "\xCF\x9C\x5D\x7A\x49\x86\xAD\xB5" , KAT_ECB "\x01\x83\x10\xDC\x40\x9B\x26\xD6" "\x1D\x9D\x5C\x50\x18\xF7\x28\xC2" "\xD1\xAB\xB2\x90\x65\x8B\xC7\x78" , KAT_ECB "\x1C\x58\x7F\x1C\x13\x92\x4F\xEF" "\x30\x55\x32\x28\x6D\x6F\x29\x5A" "\x55\xCB\x37\x74\xD1\x3E\xF2\x01" , KAT_ECB "\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xFA\x34\xEC\x48\x47\xB2\x68\xB2" , KAT_ECB "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xA7\x90\x79\x51\x08\xEA\x3C\xAE" , KAT_ECB "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xC3\x9E\x07\x2D\x9F\xAC\x63\x1D" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x01\x49\x33\xE0\xCD\xAF\xF6\xE4" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\xF2\x1E\x9A\x77\xB7\x1C\x49\xBC" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x24\x59\x46\x88\x57\x54\x36\x9A" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x6B\x5C\x5A\x9C\x5D\x9E\x0A\x5A" ] kats = defaultKATs { kat_ECB = vectors_ecb } tests = testBlockCipher kats (undefined :: Blowfish64) cryptonite-0.23/tests/KAT_Camellia.hs0000644000000000000000000000337712512146401015736 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} {-# OPTIONS_GHC -fno-warn-unused-binds #-} {-# OPTIONS_GHC -fno-warn-unused-matches #-} module KAT_Camellia (tests) where import Imports () import BlockCipher import qualified Data.ByteString as B import Crypto.Cipher.Camellia vectors_camellia128 = [ KAT_ECB (B.replicate 16 0) (B.replicate 16 0) (B.pack [0x3d,0x02,0x80,0x25,0xb1,0x56,0x32,0x7c,0x17,0xf7,0x62,0xc1,0xf2,0xcb,0xca,0x71]) , KAT_ECB (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43]) ] vectors_camellia192 = [ KAT_ECB (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77]) (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9]) ] vectors_camellia256 = [ KAT_ECB (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 ,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff]) (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09]) ] kats128 = defaultKATs { kat_ECB = vectors_camellia128 } kats192 = defaultKATs { kat_ECB = vectors_camellia192 } kats256 = defaultKATs { kat_ECB = vectors_camellia256 } tests = testBlockCipher kats128 (undefined :: Camellia128) cryptonite-0.23/tests/KAT_Curve25519.hs0000644000000000000000000000270412673727640015734 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Curve25519 ( tests ) where import Crypto.Error import qualified Crypto.PubKey.Curve25519 as Curve25519 import Data.ByteArray as B import Imports alicePrivate = throwCryptoError $ Curve25519.secretKey ("\x77\x07\x6d\x0a\x73\x18\xa5\x7d\x3c\x16\xc1\x72\x51\xb2\x66\x45\xdf\x4c\x2f\x87\xeb\xc0\x99\x2a\xb1\x77\xfb\xa5\x1d\xb9\x2c\x2a" :: ByteString) alicePublic = throwCryptoError $ Curve25519.publicKey ("\x85\x20\xf0\x09\x89\x30\xa7\x54\x74\x8b\x7d\xdc\xb4\x3e\xf7\x5a\x0d\xbf\x3a\x0d\x26\x38\x1a\xf4\xeb\xa4\xa9\x8e\xaa\x9b\x4e\x6a" :: ByteString) bobPrivate = throwCryptoError $ Curve25519.secretKey ("\x5d\xab\x08\x7e\x62\x4a\x8a\x4b\x79\xe1\x7f\x8b\x83\x80\x0e\xe6\x6f\x3b\xb1\x29\x26\x18\xb6\xfd\x1c\x2f\x8b\x27\xff\x88\xe0\xeb" :: ByteString) bobPublic = throwCryptoError $ Curve25519.publicKey ("\xde\x9e\xdb\x7d\x7b\x7d\xc1\xb4\xd3\x5b\x61\xc2\xec\xe4\x35\x37\x3f\x83\x43\xc8\x5b\x78\x67\x4d\xad\xfc\x7e\x14\x6f\x88\x2b\x4f" :: ByteString) aliceMultBob = "\x4a\x5d\x9d\x5b\xa4\xce\x2d\xe1\x72\x8e\x3b\xf4\x80\x35\x0f\x25\xe0\x7e\x21\xc9\x47\xd1\x9e\x33\x76\xf0\x9b\x3c\x1e\x16\x17\x42" :: ByteString katTests :: [TestTree] katTests = [ testCase "0" (aliceMultBob @=? B.convert (Curve25519.dh alicePublic bobPrivate)) , testCase "1" (aliceMultBob @=? B.convert (Curve25519.dh bobPublic alicePrivate)) ] tests = testGroup "Curve25519" [ testGroup "KATs" katTests ] cryptonite-0.23/tests/KAT_Curve448.hs0000644000000000000000000000403013050556742015551 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Curve448 ( tests ) where import Crypto.Error import qualified Crypto.PubKey.Curve448 as Curve448 import Data.ByteArray as B import Imports alicePrivate = throwCryptoError $ Curve448.secretKey ("\x9a\x8f\x49\x25\xd1\x51\x9f\x57\x75\xcf\x46\xb0\x4b\x58\x00\xd4\xee\x9e\xe8\xba\xe8\xbc\x55\x65\xd4\x98\xc2\x8d\xd9\xc9\xba\xf5\x74\xa9\x41\x97\x44\x89\x73\x91\x00\x63\x82\xa6\xf1\x27\xab\x1d\x9a\xc2\xd8\xc0\xa5\x98\x72\x6b" :: ByteString) alicePublic = throwCryptoError $ Curve448.publicKey ("\x9b\x08\xf7\xcc\x31\xb7\xe3\xe6\x7d\x22\xd5\xae\xa1\x21\x07\x4a\x27\x3b\xd2\xb8\x3d\xe0\x9c\x63\xfa\xa7\x3d\x2c\x22\xc5\xd9\xbb\xc8\x36\x64\x72\x41\xd9\x53\xd4\x0c\x5b\x12\xda\x88\x12\x0d\x53\x17\x7f\x80\xe5\x32\xc4\x1f\xa0" :: ByteString) bobPrivate = throwCryptoError $ Curve448.secretKey ("\x1c\x30\x6a\x7a\xc2\xa0\xe2\xe0\x99\x0b\x29\x44\x70\xcb\xa3\x39\xe6\x45\x37\x72\xb0\x75\x81\x1d\x8f\xad\x0d\x1d\x69\x27\xc1\x20\xbb\x5e\xe8\x97\x2b\x0d\x3e\x21\x37\x4c\x9c\x92\x1b\x09\xd1\xb0\x36\x6f\x10\xb6\x51\x73\x99\x2d" :: ByteString) bobPublic = throwCryptoError $ Curve448.publicKey ("\x3e\xb7\xa8\x29\xb0\xcd\x20\xf5\xbc\xfc\x0b\x59\x9b\x6f\xec\xcf\x6d\xa4\x62\x71\x07\xbd\xb0\xd4\xf3\x45\xb4\x30\x27\xd8\xb9\x72\xfc\x3e\x34\xfb\x42\x32\xa1\x3c\xa7\x06\xdc\xb5\x7a\xec\x3d\xae\x07\xbd\xc1\xc6\x7b\xf3\x36\x09" :: ByteString) aliceMultBob = "\x07\xff\xf4\x18\x1a\xc6\xcc\x95\xec\x1c\x16\xa9\x4a\x0f\x74\xd1\x2d\xa2\x32\xce\x40\xa7\x75\x52\x28\x1d\x28\x2b\xb6\x0c\x0b\x56\xfd\x24\x64\xc3\x35\x54\x39\x36\x52\x1c\x24\x40\x30\x85\xd5\x9a\x44\x9a\x50\x37\x51\x4a\x87\x9d" :: ByteString katTests :: [TestTree] katTests = [ testCase "0" (aliceMultBob @=? B.convert (Curve448.dh alicePublic bobPrivate)) , testCase "1" (aliceMultBob @=? B.convert (Curve448.dh bobPublic alicePrivate)) , testCase "2" (alicePublic @=? Curve448.toPublic alicePrivate) , testCase "3" (bobPublic @=? Curve448.toPublic bobPrivate) ] tests = testGroup "Curve448" [ testGroup "KATs" katTests ] cryptonite-0.23/tests/KAT_DES.hs0000644000000000000000000001046512512146401014636 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} module KAT_DES (tests) where import Imports import BlockCipher import qualified Crypto.Cipher.DES as DES vectors_ecb = -- key plaintext ciphertext [ KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x8C\xA6\x4D\xE9\xC1\xB1\x23\xA7" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x73\x59\xB2\x16\x3E\x4E\xDC\x58" , KAT_ECB "\x30\x00\x00\x00\x00\x00\x00\x00" "\x10\x00\x00\x00\x00\x00\x00\x01" "\x95\x8E\x6E\x62\x7A\x05\x55\x7B" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11" "\xF4\x03\x79\xAB\x9E\x0E\xC5\x33" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x17\x66\x8D\xFC\x72\x92\x53\x2D" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x8A\x5A\xE1\xF8\x1A\xB8\xF2\xDD" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x8C\xA6\x4D\xE9\xC1\xB1\x23\xA7" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xED\x39\xD9\x50\xFA\x74\xBC\xC4" , KAT_ECB "\x7C\xA1\x10\x45\x4A\x1A\x6E\x57" "\x01\xA1\xD6\xD0\x39\x77\x67\x42" "\x69\x0F\x5B\x0D\x9A\x26\x93\x9B" , KAT_ECB "\x01\x31\xD9\x61\x9D\xC1\x37\x6E" "\x5C\xD5\x4C\xA8\x3D\xEF\x57\xDA" "\x7A\x38\x9D\x10\x35\x4B\xD2\x71" , KAT_ECB "\x07\xA1\x13\x3E\x4A\x0B\x26\x86" "\x02\x48\xD4\x38\x06\xF6\x71\x72" "\x86\x8E\xBB\x51\xCA\xB4\x59\x9A" , KAT_ECB "\x38\x49\x67\x4C\x26\x02\x31\x9E" "\x51\x45\x4B\x58\x2D\xDF\x44\x0A" "\x71\x78\x87\x6E\x01\xF1\x9B\x2A" , KAT_ECB "\x04\xB9\x15\xBA\x43\xFE\xB5\xB6" "\x42\xFD\x44\x30\x59\x57\x7F\xA2" "\xAF\x37\xFB\x42\x1F\x8C\x40\x95" , KAT_ECB "\x01\x13\xB9\x70\xFD\x34\xF2\xCE" "\x05\x9B\x5E\x08\x51\xCF\x14\x3A" "\x86\xA5\x60\xF1\x0E\xC6\xD8\x5B" , KAT_ECB "\x01\x70\xF1\x75\x46\x8F\xB5\xE6" "\x07\x56\xD8\xE0\x77\x47\x61\xD2" "\x0C\xD3\xDA\x02\x00\x21\xDC\x09" , KAT_ECB "\x43\x29\x7F\xAD\x38\xE3\x73\xFE" "\x76\x25\x14\xB8\x29\xBF\x48\x6A" "\xEA\x67\x6B\x2C\xB7\xDB\x2B\x7A" , KAT_ECB "\x07\xA7\x13\x70\x45\xDA\x2A\x16" "\x3B\xDD\x11\x90\x49\x37\x28\x02" "\xDF\xD6\x4A\x81\x5C\xAF\x1A\x0F" , KAT_ECB "\x04\x68\x91\x04\xC2\xFD\x3B\x2F" "\x26\x95\x5F\x68\x35\xAF\x60\x9A" "\x5C\x51\x3C\x9C\x48\x86\xC0\x88" , KAT_ECB "\x37\xD0\x6B\xB5\x16\xCB\x75\x46" "\x16\x4D\x5E\x40\x4F\x27\x52\x32" "\x0A\x2A\xEE\xAE\x3F\xF4\xAB\x77" , KAT_ECB "\x1F\x08\x26\x0D\x1A\xC2\x46\x5E" "\x6B\x05\x6E\x18\x75\x9F\x5C\xCA" "\xEF\x1B\xF0\x3E\x5D\xFA\x57\x5A" , KAT_ECB "\x58\x40\x23\x64\x1A\xBA\x61\x76" "\x00\x4B\xD6\xEF\x09\x17\x60\x62" "\x88\xBF\x0D\xB6\xD7\x0D\xEE\x56" , KAT_ECB "\x02\x58\x16\x16\x46\x29\xB0\x07" "\x48\x0D\x39\x00\x6E\xE7\x62\xF2" "\xA1\xF9\x91\x55\x41\x02\x0B\x56" , KAT_ECB "\x49\x79\x3E\xBC\x79\xB3\x25\x8F" "\x43\x75\x40\xC8\x69\x8F\x3C\xFA" "\x6F\xBF\x1C\xAF\xCF\xFD\x05\x56" , KAT_ECB "\x4F\xB0\x5E\x15\x15\xAB\x73\xA7" "\x07\x2D\x43\xA0\x77\x07\x52\x92" "\x2F\x22\xE4\x9B\xAB\x7C\xA1\xAC" , KAT_ECB "\x49\xE9\x5D\x6D\x4C\xA2\x29\xBF" "\x02\xFE\x55\x77\x81\x17\xF1\x2A" "\x5A\x6B\x61\x2C\xC2\x6C\xCE\x4A" , KAT_ECB "\x01\x83\x10\xDC\x40\x9B\x26\xD6" "\x1D\x9D\x5C\x50\x18\xF7\x28\xC2" "\x5F\x4C\x03\x8E\xD1\x2B\x2E\x41" , KAT_ECB "\x1C\x58\x7F\x1C\x13\x92\x4F\xEF" "\x30\x55\x32\x28\x6D\x6F\x29\x5A" "\x63\xFA\xC0\xD0\x34\xD9\xF7\x93" , KAT_ECB "\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x61\x7B\x3A\x0C\xE8\xF0\x71\x00" , KAT_ECB "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xDB\x95\x86\x05\xF8\xC8\xC6\x06" , KAT_ECB "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xED\xBF\xD1\xC6\x6C\x29\xCC\xC7" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x35\x55\x50\xB2\x15\x0E\x24\x51" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\xCA\xAA\xAF\x4D\xEA\xF1\xDB\xAE" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\xD5\xD4\x4F\xF7\x20\x68\x3D\x0D" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x2A\x2B\xB0\x08\xDF\x97\xC2\xF2" ] kats = defaultKATs { kat_ECB = vectors_ecb } tests = localOption (QuickCheckTests 5) $ testBlockCipher kats (undefined :: DES.DES) cryptonite-0.23/tests/KAT_Ed25519.hs0000644000000000000000000000273612514663134015174 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE BangPatterns #-} module KAT_Ed25519 ( tests ) where import Crypto.Error import qualified Crypto.PubKey.Ed25519 as Ed25519 import Imports data Vec = Vec { vecSec :: ByteString , vecPub :: ByteString , vecMsg :: ByteString , vecSig :: ByteString } deriving (Show,Eq) vec1 = Vec { vecSec = "\x4c\xcd\x08\x9b\x28\xff\x96\xda\x9d\xb6\xc3\x46\xec\x11\x4e\x0f\x5b\x8a\x31\x9f\x35\xab\xa6\x24\xda\x8c\xf6\xed\x4f\xb8\xa6\xfb" , vecPub = "\x3d\x40\x17\xc3\xe8\x43\x89\x5a\x92\xb7\x0a\xa7\x4d\x1b\x7e\xbc\x9c\x98\x2c\xcf\x2e\xc4\x96\x8c\xc0\xcd\x55\xf1\x2a\xf4\x66\x0c" , vecMsg = "\x72" , vecSig = "\x92\xa0\x09\xa9\xf0\xd4\xca\xb8\x72\x0e\x82\x0b\x5f\x64\x25\x40\xa2\xb2\x7b\x54\x16\x50\x3f\x8f\xb3\x76\x22\x23\xeb\xdb\x69\xda\x08\x5a\xc1\xe4\x3e\x15\x99\x6e\x45\x8f\x36\x13\xd0\xf1\x1d\x8c\x38\x7b\x2e\xae\xb4\x30\x2a\xee\xb0\x0d\x29\x16\x12\xbb\x0c\x00" } testVec :: String -> Vec -> [TestTree] testVec s vec = [ testCase (s ++ " gen publickey") (pub @=? Ed25519.toPublic sec) , testCase (s ++ " gen signature") (sig @=? Ed25519.sign sec pub (vecMsg vec)) ] where !sig = throwCryptoError $ Ed25519.signature (vecSig vec) !pub = throwCryptoError $ Ed25519.publicKey (vecPub vec) !sec = throwCryptoError $ Ed25519.secretKey (vecSec vec) katTests :: [TestTree] katTests = testVec "vec 1" vec1 tests = testGroup "Ed25519" [ testGroup "KATs" katTests ] cryptonite-0.23/tests/KAT_CMAC.hs0000644000000000000000000001426712702145361014737 0ustar0000000000000000 module KAT_CMAC (tests) where import qualified Crypto.MAC.CMAC as CMAC import Crypto.Cipher.Types (Cipher, cipherInit, BlockCipher, ecbEncrypt, blockSize) import Crypto.Error (eitherCryptoError) import Crypto.Cipher.AES (AES128, AES192, AES256) import Crypto.Cipher.TripleDES (DES_EDE3, DES_EDE2) import Imports import Data.Char (digitToInt) import qualified Data.ByteString as BS import qualified Data.ByteArray as B hxs :: String -> ByteString hxs = BS.pack . rec' where dtoW8 = fromIntegral . digitToInt rec' (' ':xs) = rec' xs rec' (x:y:xs) = dtoW8 x * 16 + dtoW8 y : rec' xs rec' [_] = error "hxs: invalid hex pattern." rec' [] = [] unsafeCipher :: Cipher k => ByteString -> k unsafeCipher = either (error . show) id . eitherCryptoError . cipherInit ecb0 :: BlockCipher k => k -> ByteString ecb0 k = ecbEncrypt k $ BS.replicate (blockSize k) 0 {- Test vectors from NIST data-sheet (AES128-CMAC, AES192-CMAC, AES256-CMAC, Three Key TDEA, Two Key TDEA) http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf The data of AES128-CMAC is same as them in RFC4493. -} msg512 :: ByteString msg512 = hxs $ "6bc1bee2 2e409f96 e93d7e11 7393172a" ++ "ae2d8a57 1e03ac9c 9eb76fac 45af8e51" ++ "30c81c46 a35ce411 e5fbc119 1a0a52ef" ++ "f69f2445 df4f9b17 ad2b417b e66c3710" msg320 :: ByteString msg320 = BS.take 40 msg512 msg256 :: ByteString msg256 = BS.take 32 msg512 msg160 :: ByteString msg160 = BS.take 20 msg512 msg128 :: ByteString msg128 = BS.take 16 msg512 msg64 :: ByteString msg64 = BS.take 8 msg512 msg0 :: ByteString msg0 = BS.empty bsCMAC :: BlockCipher k => k -> ByteString -> ByteString bsCMAC k = B.convert . CMAC.cmac k gAES128 :: TestTree gAES128 = igroup "aes128" [ ecb0 aes128key @?= hxs "7df76b0c 1ab899b3 3e42f047 b91b546f" , aes128k1 @?= hxs "fbeed618 35713366 7c85e08f 7236a8de" , aes128k2 @?= hxs "f7ddac30 6ae266cc f90bc11e e46d513b" , bsCMAC aes128key msg0 @?= hxs "bb1d6929 e9593728 7fa37d12 9b756746" , bsCMAC aes128key msg128 @?= hxs "070a16b4 6b4d4144 f79bdd9d d04a287c" , bsCMAC aes128key msg320 @?= hxs "dfa66747 de9ae630 30ca3261 1497c827" , bsCMAC aes128key msg512 @?= hxs "51f0bebf 7e3b9d92 fc497417 79363cfe" ] where aes128key :: AES128 aes128key = unsafeCipher $ hxs "2b7e1516 28aed2a6 abf71588 09cf4f3c" aes128k1, aes128k2 :: ByteString (aes128k1, aes128k2) = CMAC.subKeys aes128key gAES192 :: TestTree gAES192 = igroup "aes192" [ ecb0 aes192key @?= hxs "22452d8e 49a8a593 9f7321ce ea6d514b" , aes192k1 @?= hxs "448a5b1c 93514b27 3ee6439d d4daa296" , aes192k2 @?= hxs "8914b639 26a2964e 7dcc873b a9b5452c" , bsCMAC aes192key msg0 @?= hxs "d17ddf46 adaacde5 31cac483 de7a9367" , bsCMAC aes192key msg128 @?= hxs "9e99a7bf 31e71090 0662f65e 617c5184" , bsCMAC aes192key msg320 @?= hxs "8a1de5be 2eb31aad 089a82e6 ee908b0e" , bsCMAC aes192key msg512 @?= hxs "a1d5df0e ed790f79 4d775896 59f39a11" ] where aes192key :: AES192 aes192key = unsafeCipher . hxs $ "8e73b0f7 da0e6452 c810f32b 809079e5" ++ "62f8ead2 522c6b7b" aes192k1, aes192k2 :: ByteString (aes192k1, aes192k2) = CMAC.subKeys aes192key gAES256 :: TestTree gAES256 = igroup "aes256" [ ecb0 aes256key @?= hxs "e568f681 94cf76d6 174d4cc0 4310a854" , aes256k1 @?= hxs "cad1ed03 299eedac 2e9a9980 8621502f" , aes256k2 @?= hxs "95a3da06 533ddb58 5d353301 0c42a0d9" , bsCMAC aes256key msg0 @?= hxs "028962f6 1b7bf89e fc6b551f 4667d983" , bsCMAC aes256key msg128 @?= hxs "28a7023f 452e8f82 bd4bf28d 8c37c35c" , bsCMAC aes256key msg320 @?= hxs "aaf3d8f1 de5640c2 32f5b169 b9c911e6" , bsCMAC aes256key msg512 @?= hxs "e1992190 549f6ed5 696a2c05 6c315410" ] where aes256key :: AES256 aes256key = unsafeCipher . hxs $ "603deb10 15ca71be 2b73aef0 857d7781" ++ "1f352c07 3b6108d7 2d9810a3 0914dff4" aes256k1, aes256k2 :: ByteString (aes256k1, aes256k2) = CMAC.subKeys aes256key gTDEA3 :: TestTree gTDEA3 = igroup "Three Key TDEA" [ ecb0 tdea3key @?= hxs "c8cc74e9 8a7329a2" , tdea3k1 @?= hxs "9198e9d3 14e6535f" , tdea3k2 @?= hxs "2331d3a6 29cca6a5" , bsCMAC tdea3key msg0 @?= hxs "b7a688e1 22ffaf95" , bsCMAC tdea3key msg64 @?= hxs "8e8f2931 36283797" , bsCMAC tdea3key msg160 @?= hxs "743ddbe0 ce2dc2ed" , bsCMAC tdea3key msg256 @?= hxs "33e6b109 2400eae5" ] where tdea3key :: DES_EDE3 tdea3key = unsafeCipher . hxs $ "8aa83bf8 cbda1062" ++ "0bc1bf19 fbb6cd58" ++ "bc313d4a 371ca8b5" tdea3k1, tdea3k2 :: ByteString (tdea3k1, tdea3k2) = CMAC.subKeys tdea3key gTDEA2 :: TestTree gTDEA2 = igroup "Two Key TDEA" [ ecb0 tdea2key @?= hxs "c7679b9f 6b8d7d7a" , tdea2k1 @?= hxs "8ecf373e d71afaef" , tdea2k2 @?= hxs "1d9e6e7d ae35f5c5" , bsCMAC tdea2key msg0 @?= hxs "bd2ebf9a 3ba00361" , bsCMAC tdea2key msg64 @?= hxs "4ff2ab81 3c53ce83" , bsCMAC tdea2key msg160 @?= hxs "62dd1b47 1902bd4e" , bsCMAC tdea2key msg256 @?= hxs "31b1e431 dabc4eb8" ] where tdea2key :: DES_EDE2 tdea2key = unsafeCipher . hxs $ "4cf15134 a2850dd5" ++ "8a3d10ba 80570d38" tdea2k1, tdea2k2 :: ByteString (tdea2k1, tdea2k2) = CMAC.subKeys tdea2key igroup :: TestName -> [Assertion] -> TestTree igroup nm = testGroup nm . zipWith (flip ($)) [1..] . map icase where icase c i = testCase (show (i :: Int)) c nistVectors :: TestTree nistVectors = testGroup "KAT - NIST test vectors" [ gAES128, gAES192, gAES256, gTDEA3, gTDEA2 ] tests :: TestTree tests = testGroup "CMAC" [ nistVectors ] cryptonite-0.23/tests/KAT_HKDF.hs0000644000000000000000000000644612673727640014765 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_HKDF (tests) where import qualified Crypto.KDF.HKDF as HKDF import Crypto.Hash (MD5(..), SHA1(..), SHA256(..) , Keccak_224(..), Keccak_256(..), Keccak_384(..), Keccak_512(..) , SHA3_224(..), SHA3_256(..), SHA3_384(..), SHA3_512(..) , HashAlgorithm, digestFromByteString) import qualified Data.ByteString as B import Imports data KDFVector hash = KDFVector { kdfIKM :: ByteString , kdfSalt :: ByteString , kdfInfo :: ByteString , kdfResult :: ByteString } sha256KDFVectors :: [KDFVector SHA256] sha256KDFVectors = [ KDFVector "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" (B.pack [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c]) "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9" "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a\x90\x43\x4f\x64\xd0\x36\x2f\x2a\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf\x34\x00\x72\x08\xd5\xb8\x87\x18\x58\x65" , KDFVector (B.pack [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f]) (B.pack [0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf]) (B.pack [0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff]) (B.pack [0xb1,0x1e,0x39,0x8d,0xc8,0x03,0x27,0xa1,0xc8,0xe7,0xf7,0x8c,0x59,0x6a,0x49,0x34,0x4f,0x01,0x2e,0xda,0x2d,0x4e,0xfa,0xd8,0xa0,0x50,0xcc,0x4c,0x19,0xaf,0xa9,0x7c,0x59,0x04,0x5a,0x99,0xca,0xc7,0x82,0x72,0x71,0xcb,0x41,0xc6,0x5e,0x59,0x0e,0x09,0xda,0x32,0x75,0x60,0x0c,0x2f,0x09,0xb8,0x36,0x77,0x93,0xa9,0xac,0xa3,0xdb,0x71,0xcc,0x30,0xc5,0x81,0x79,0xec,0x3e,0x87,0xc1,0x4c,0x01,0xd5,0xc1,0xf3,0x43,0x4f,0x1d,0x87]) ] kdfTests :: [TestTree] kdfTests = [ testGroup "sha256" $ concatMap toKDFTest $ zip is sha256KDFVectors ] where toKDFTest (i, kdfVector) = [ testCase (show i) (t HKDF.extract kdfVector) ] t :: HashAlgorithm a => (ByteString -> ByteString -> HKDF.PRK a) -> KDFVector a -> Assertion t ext v = let prk = ext (kdfSalt v) (kdfIKM v) in kdfResult v @=? HKDF.expand prk (kdfInfo v) (B.length $ kdfResult v) is :: [Int] is = [1..] tests = testGroup "HKDF" [ testGroup "KATs" kdfTests ] cryptonite-0.23/tests/KAT_HMAC.hs0000644000000000000000000001664412673727640014762 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_HMAC (tests) where import qualified Crypto.MAC.HMAC as HMAC import Crypto.Hash (MD5(..), SHA1(..), SHA256(..) , Keccak_224(..), Keccak_256(..), Keccak_384(..), Keccak_512(..) , SHA3_224(..), SHA3_256(..), SHA3_384(..), SHA3_512(..) , HashAlgorithm, digestFromByteString) import qualified Data.ByteString as B import Imports data MACVector hash = MACVector { macKey :: ByteString , macSecret :: ByteString , macResult :: HMAC.HMAC hash } instance Show (HMAC.HMAC a) where show (HMAC.HMAC d) = show d digest :: HashAlgorithm hash => ByteString -> HMAC.HMAC hash digest = maybe (error "cannot get digest") HMAC.HMAC . digestFromByteString v1 :: ByteString v1 = "The quick brown fox jumps over the lazy dog" md5MACVectors :: [MACVector MD5] md5MACVectors = [ MACVector B.empty B.empty $ digest "\x74\xe6\xf7\x29\x8a\x9c\x2d\x16\x89\x35\xf5\x8c\x00\x1b\xad\x88" , MACVector "key" v1 $ digest "\x80\x07\x07\x13\x46\x3e\x77\x49\xb9\x0c\x2d\xc2\x49\x11\xe2\x75" ] sha1MACVectors :: [MACVector SHA1] sha1MACVectors = [ MACVector B.empty B.empty $ digest "\xfb\xdb\x1d\x1b\x18\xaa\x6c\x08\x32\x4b\x7d\x64\xb7\x1f\xb7\x63\x70\x69\x0e\x1d" , MACVector "key" v1 $ digest "\xde\x7c\x9b\x85\xb8\xb7\x8a\xa6\xbc\x8a\x7a\x36\xf7\x0a\x90\x70\x1c\x9d\xb4\xd9" ] sha256MACVectors :: [MACVector SHA256] sha256MACVectors = [ MACVector B.empty B.empty $ digest "\xb6\x13\x67\x9a\x08\x14\xd9\xec\x77\x2f\x95\xd7\x78\xc3\x5f\xc5\xff\x16\x97\xc4\x93\x71\x56\x53\xc6\xc7\x12\x14\x42\x92\xc5\xad" , MACVector "key" v1 $ digest "\xf7\xbc\x83\xf4\x30\x53\x84\x24\xb1\x32\x98\xe6\xaa\x6f\xb1\x43\xef\x4d\x59\xa1\x49\x46\x17\x59\x97\x47\x9d\xbc\x2d\x1a\x3c\xd8" ] keccak_key1 = "\x4a\x65\x66\x65" keccak_data1 = "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f" keccak_224_MAC_Vectors :: [MACVector Keccak_224] keccak_224_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\xe8\x24\xfe\xc9\x6c\x07\x4f\x22\xf9\x92\x35\xbb\x94\x2d\xa1\x98\x26\x64\xab\x69\x2c\xa8\x50\x10\x53\xcb\xd4\x14" ] keccak_256_MAC_Vectors :: [MACVector Keccak_256] keccak_256_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\xaa\x9a\xed\x44\x8c\x7a\xbc\x8b\x5e\x32\x6f\xfa\x6a\x01\xcd\xed\xf7\xb4\xb8\x31\x88\x14\x68\xc0\x44\xba\x8d\xd4\x56\x63\x69\xa1" ] keccak_384_MAC_Vectors :: [MACVector Keccak_384] keccak_384_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\x5a\xf5\xc9\xa7\x7a\x23\xa6\xa9\x3d\x80\x64\x9e\x56\x2a\xb7\x7f\x4f\x35\x52\xe3\xc5\xca\xff\xd9\x3b\xdf\x8b\x3c\xfc\x69\x20\xe3\x02\x3f\xc2\x67\x75\xd9\xdf\x1f\x3c\x94\x61\x31\x46\xad\x2c\x9d" ] keccak_512_MAC_Vectors :: [MACVector Keccak_512] keccak_512_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\xc2\x96\x2e\x5b\xbe\x12\x38\x00\x78\x52\xf7\x9d\x81\x4d\xbb\xec\xd4\x68\x2e\x6f\x09\x7d\x37\xa3\x63\x58\x7c\x03\xbf\xa2\xeb\x08\x59\xd8\xd9\xc7\x01\xe0\x4c\xec\xec\xfd\x3d\xd7\xbf\xd4\x38\xf2\x0b\x8b\x64\x8e\x01\xbf\x8c\x11\xd2\x68\x24\xb9\x6c\xeb\xbd\xcb" ] sha3_key1 = "\x4a\x65\x66\x65" sha3_data1 = "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f" sha3_224_MAC_Vectors :: [MACVector SHA3_224] sha3_224_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\x7f\xdb\x8d\xd8\x8b\xd2\xf6\x0d\x1b\x79\x86\x34\xad\x38\x68\x11\xc2\xcf\xc8\x5b\xfa\xf5\xd5\x2b\xba\xce\x5e\x66" ] sha3_256_MAC_Vectors :: [MACVector SHA3_256] sha3_256_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\xc7\xd4\x07\x2e\x78\x88\x77\xae\x35\x96\xbb\xb0\xda\x73\xb8\x87\xc9\x17\x1f\x93\x09\x5b\x29\x4a\xe8\x57\xfb\xe2\x64\x5e\x1b\xa5" ] sha3_384_MAC_Vectors :: [MACVector SHA3_384] sha3_384_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\xf1\x10\x1f\x8c\xbf\x97\x66\xfd\x67\x64\xd2\xed\x61\x90\x3f\x21\xca\x9b\x18\xf5\x7c\xf3\xe1\xa2\x3c\xa1\x35\x08\xa9\x32\x43\xce\x48\xc0\x45\xdc\x00\x7f\x26\xa2\x1b\x3f\x5e\x0e\x9d\xf4\xc2\x0a" ] sha3_512_MAC_Vectors :: [MACVector SHA3_512] sha3_512_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\x5a\x4b\xfe\xab\x61\x66\x42\x7c\x7a\x36\x47\xb7\x47\x29\x2b\x83\x84\x53\x7c\xdb\x89\xaf\xb3\xbf\x56\x65\xe4\xc5\xe7\x09\x35\x0b\x28\x7b\xae\xc9\x21\xfd\x7c\xa0\xee\x7a\x0c\x31\xd0\x22\xa9\x5e\x1f\xc9\x2b\xa9\xd7\x7d\xf8\x83\x96\x02\x75\xbe\xb4\xe6\x20\x24" ] macTests :: [TestTree] macTests = [ testGroup "md5" $ concatMap toMACTest $ zip is md5MACVectors , testGroup "sha1" $ concatMap toMACTest $ zip is sha1MACVectors , testGroup "sha256" $ concatMap toMACTest $ zip is sha256MACVectors , testGroup "keccak-224" $ concatMap toMACTest $ zip is keccak_224_MAC_Vectors , testGroup "keccak-256" $ concatMap toMACTest $ zip is keccak_256_MAC_Vectors , testGroup "keccak-384" $ concatMap toMACTest $ zip is keccak_384_MAC_Vectors , testGroup "keccak-512" $ concatMap toMACTest $ zip is keccak_512_MAC_Vectors , testGroup "sha3-224" $ concatMap toMACTest $ zip is sha3_224_MAC_Vectors , testGroup "sha3-256" $ concatMap toMACTest $ zip is sha3_256_MAC_Vectors , testGroup "sha3-384" $ concatMap toMACTest $ zip is sha3_384_MAC_Vectors , testGroup "sha3-512" $ concatMap toMACTest $ zip is sha3_512_MAC_Vectors ] where toMACTest (i, macVector) = [ testCase (show i) (macResult macVector @=? HMAC.hmac (macKey macVector) (macSecret macVector)) , testCase ("incr-" ++ show i) (macResult macVector @=? HMAC.finalize (HMAC.update (HMAC.initialize (macKey macVector)) (macSecret macVector))) ] is :: [Int] is = [1..] data MacIncremental a = MacIncremental ByteString ByteString (HMAC.HMAC a) deriving (Show,Eq) instance HashAlgorithm a => Arbitrary (MacIncremental a) where arbitrary = do key <- arbitraryBSof 1 89 msg <- arbitraryBSof 1 99 return $ MacIncremental key msg (HMAC.hmac key msg) data MacIncrementalList a = MacIncrementalList ByteString [ByteString] (HMAC.HMAC a) deriving (Show,Eq) instance HashAlgorithm a => Arbitrary (MacIncrementalList a) where arbitrary = do key <- arbitraryBSof 1 89 msgs <- choose (1,20) >>= \n -> replicateM n (arbitraryBSof 1 99) return $ MacIncrementalList key msgs (HMAC.hmac key (B.concat msgs)) macIncrementalTests :: [TestTree] macIncrementalTests = [ testProperties MD5 , testProperties SHA1 , testProperties SHA256 , testProperties SHA3_224 , testProperties SHA3_256 , testProperties SHA3_384 , testProperties SHA3_512 ] where --testProperties :: HashAlgorithm a => a -> [Property] testProperties a = testGroup (show a) [ testProperty "list-one" (prop_inc0 a) , testProperty "list-multi" (prop_inc1 a) ] prop_inc0 :: HashAlgorithm a => a -> MacIncremental a -> Bool prop_inc0 _ (MacIncremental secret msg result) = result `assertEq` HMAC.finalize (HMAC.update (HMAC.initialize secret) msg) prop_inc1 :: HashAlgorithm a => a -> MacIncrementalList a -> Bool prop_inc1 _ (MacIncrementalList secret msgs result) = result `assertEq` HMAC.finalize (foldl' HMAC.update (HMAC.initialize secret) msgs) tests = testGroup "HMAC" [ testGroup "KATs" macTests , testGroup "properties" macIncrementalTests ] cryptonite-0.23/tests/KAT_MiyaguchiPreneel.hs0000644000000000000000000000264512727442704017473 0ustar0000000000000000 module KAT_MiyaguchiPreneel (tests) where import Crypto.Cipher.AES (AES128) import Crypto.ConstructHash.MiyaguchiPreneel as MiyaguchiPreneel import Imports import Data.Char (digitToInt) import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteArray as B import Data.ByteArray.Encoding (Base (Base16), convertFromBase) runMP128 :: ByteString -> ByteString runMP128 s = B.convert (MiyaguchiPreneel.compute s :: MiyaguchiPreneel AES128) hxs :: String -> ByteString hxs = either (error . ("hxs:" ++)) id . convertFromBase Base16 . B8.pack . filter (/= ' ') gAES128 :: TestTree gAES128 = igroup "aes128" [ runMP128 B8.empty @?= hxs "66e94bd4 ef8a2c3b 884cfa59 ca342b2e" , runMP128 (hxs "01000000 00000000 00000000 00000000") @?= hxs "46711816 e91d6ff0 59bbbf2b f58e0fd3" , runMP128 (hxs "00000000 00000000 00000000 00000001") @?= hxs "58e2fcce fa7e3061 367f1d57 a4e7455b" , runMP128 (hxs $ "00000000 00000000 00000000 00000000" ++ "01") @?= hxs "a5ff35ae 097adf5d 646abf5e bf4c16f4" ] igroup :: TestName -> [Assertion] -> TestTree igroup nm = testGroup nm . zipWith (flip ($)) [1..] . map icase where icase c i = testCase (show (i :: Int)) c vectors :: TestTree vectors = testGroup "KATs" [ gAES128 ] tests :: TestTree tests = testGroup "MiyaguchiPreneel" [ vectors ] cryptonite-0.23/tests/KAT_PBKDF2.hs0000644000000000000000000001030413050556742015136 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} -- from module KAT_PBKDF2 (tests) where import Crypto.Hash (SHA1(..), SHA256(..), SHA512(..)) import qualified Crypto.KDF.PBKDF2 as PBKDF2 import Data.ByteString (ByteString) import Data.ByteString.Char8 () import Test.Tasty import Test.Tasty.HUnit type VectParams = (ByteString, ByteString, Int, Int) vectors_hmac_sha1 :: [ (VectParams, ByteString) ] vectors_hmac_sha1 = [ ( ("password","salt",2,20) , "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57" ) , ( ("password","salt",4096,20) , "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1" ) , ( ("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25) , "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38" ) , ( ("pass\0word", "sa\0lt", 4096, 16) , "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34\x25\xe0\xc3" ) ] vectors_hmac_sha256 :: [ (VectParams, ByteString) ] vectors_hmac_sha256 = [ ( ("password", "salt", 2, 32) , "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43" ) , ( ("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 40) , "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1\xc6\x35\x51\x8c\x7d\xac\x47\xe9" ) ] vectors_hmac_sha512 :: [ (VectParams, ByteString) ] vectors_hmac_sha512 = [ ( ("password", "salt", 1, 32) , "\x86\x7f\x70\xcf\x1a\xde\x02\xcf\xf3\x75\x25\x99\xa3\xa5\x3d\xc4\xaf\x34\xc7\xa6\x69\x81\x5a\xe5\xd5\x13\x55\x4e\x1c\x8c\xf2\x52" ) , ( ("password", "salt", 2, 32) , "\xe1\xd9\xc1\x6a\xa6\x81\x70\x8a\x45\xf5\xc7\xc4\xe2\x15\xce\xb6\x6e\x01\x1a\x2e\x9f\x00\x40\x71\x3f\x18\xae\xfd\xb8\x66\xd5\x3c" ) , ( ("password", "salt", 4096, 32) , "\xd1\x97\xb1\xb3\x3d\xb0\x14\x3e\x01\x8b\x12\xf3\xd1\xd1\x47\x9e\x6c\xde\xbd\xcc\x97\xc5\xc0\xf8\x7f\x69\x02\xe0\x72\xf4\x57\xb5" ) , ( ("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 1, 72) , "n\x23\xf2\x76\x38\x08\x4b\x0f\x7e\xa1\x73\x4e\x0d\x98\x41\xf5\x5d\xd2\x9e\xa6\x0a\x83\x44\x66\xf3\x39\x6b\xac\x80\x1f\xac\x1e\xeb\x63\x80\x2f\x03\xa0\xb4\xac\xd7\x60\x3e\x36\x99\xc8\xb7\x44\x37\xbe\x83\xff\x01\xad\x7f\x55\xda\xc1\xef\x60\xf4\xd5\x64\x80\xc3\x5e\xe6\x8f\xd5\x2c\x69\x36" ) ] tests = testGroup "PBKDF2" [ testGroup "KATs-HMAC-SHA1" (katTests (PBKDF2.prfHMAC SHA1) vectors_hmac_sha1) , testGroup "KATs-HMAC-SHA1 (fast)" (katTestFastPBKDF2_SHA1 vectors_hmac_sha1) , testGroup "KATs-HMAC-SHA256" (katTests (PBKDF2.prfHMAC SHA256) vectors_hmac_sha256) , testGroup "KATs-HMAC-SHA256 (fast)" (katTestFastPBKDF2_SHA256 vectors_hmac_sha256) , testGroup "KATs-HMAC-SHA512" (katTests (PBKDF2.prfHMAC SHA512) vectors_hmac_sha512) , testGroup "KATs-HMAC-SHA512 (fast)" (katTestFastPBKDF2_SHA512 vectors_hmac_sha512) ] where katTests prf vects = map (toKatTest prf) $ zip is vects toKatTest prf (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.generate prf (PBKDF2.Parameters iter dkLen) pass salt) katTestFastPBKDF2_SHA1 = map toKatTestFastPBKDF2_SHA1 . zip is toKatTestFastPBKDF2_SHA1 (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.fastPBKDF2_SHA1 (PBKDF2.Parameters iter dkLen) pass salt) katTestFastPBKDF2_SHA256 = map toKatTestFastPBKDF2_SHA256 . zip is toKatTestFastPBKDF2_SHA256 (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.fastPBKDF2_SHA256 (PBKDF2.Parameters iter dkLen) pass salt) katTestFastPBKDF2_SHA512 = map toKatTestFastPBKDF2_SHA512 . zip is toKatTestFastPBKDF2_SHA512 (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.fastPBKDF2_SHA512 (PBKDF2.Parameters iter dkLen) pass salt) is :: [Int] is = [1..] cryptonite-0.23/tests/KAT_OTP.hs0000644000000000000000000000570313050556742014677 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_OTP ( tests ) where import Crypto.Hash.Algorithms (SHA1(..), SHA256(..), SHA512(..)) import Crypto.OTP import Data.ByteString (ByteString) import Imports -- | Test values from Appendix D of http://tools.ietf.org/html/rfc4226 hotpExpected :: [(Word64, Word32)] hotpExpected = [ (0, 755224) , (1, 287082) , (3, 969429) , (4, 338314) , (5, 254676) , (6, 287922) , (7, 162583) , (8, 399871) , (9, 520489) ] -- | Test data from Appendix B of http://tools.ietf.org/html/rfc6238 -- Note that the shared keys for the non SHA-1 values are actually -- different (see the errata, or the Java example code). totpSHA1Expected :: [(Word64, Word32)] totpSHA1Expected = [ (59 , 94287082) , (1111111109, 07081804) , (1111111111, 14050471) , (1234567890, 89005924) , (2000000000, 69279037) , (20000000000, 65353130) ] totpSHA256Expected :: [(Word64, Word32)] totpSHA256Expected = [ (59 , 46119246) , (1111111109, 68084774) , (1111111111, 67062674) , (1234567890, 91819424) , (2000000000, 90698825) , (20000000000, 77737706) ] totpSHA512Expected :: [(Word64, Word32)] totpSHA512Expected = [ (59 , 90693936) , (1111111109, 25091201) , (1111111111, 99943326) , (1234567890, 93441116) , (2000000000, 38618901) , (20000000000, 47863826) ] otpKey = "12345678901234567890" :: ByteString totpSHA256Key = "12345678901234567890123456789012" :: ByteString totpSHA512Key = "1234567890123456789012345678901234567890123456789012345678901234" :: ByteString makeKATs otp expected = concatMap (makeTest otp) (zip3 is counts otps) where is :: [Int] is = [1..] counts = map fst expected otps = map snd expected makeTest otp (i, count, password) = [ testCase (show i) (assertEqual "" password (otp count)) ] Right totpSHA1Params = mkTOTPParams SHA1 0 30 OTP8 TwoSteps Right totpSHA256Params = mkTOTPParams SHA256 0 30 OTP8 TwoSteps Right totpSHA512Params = mkTOTPParams SHA512 0 30 OTP8 TwoSteps -- resynching with the expected value should just return the current counter + 1 prop_resyncExpected ctr window = resynchronize SHA1 OTP6 window key ctr (otp, []) == Just (ctr + 1) where key = "1234" :: ByteString otp = hotp SHA1 OTP6 key ctr tests = testGroup "OTP" [ testGroup "HOTP" [ testGroup "KATs" (makeKATs (hotp SHA1 OTP6 otpKey) hotpExpected) , testGroup "properties" [ testProperty "resync-expected" prop_resyncExpected ] ] , testGroup "TOTP" [ testGroup "KATs" [ testGroup "SHA1" (makeKATs (totp totpSHA1Params otpKey . fromIntegral) totpSHA1Expected) , testGroup "SHA256" (makeKATs (totp totpSHA256Params totpSHA256Key . fromIntegral) totpSHA256Expected) , testGroup "SHA512" (makeKATs (totp totpSHA512Params totpSHA512Key . fromIntegral) totpSHA512Expected) ] ] ] cryptonite-0.23/tests/KAT_PubKey/DSA.hs0000644000000000000000000003110312517170245016031 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.DSA (dsaTests) where import qualified Crypto.PubKey.DSA as DSA import Crypto.Hash import Imports data VectorDSA = VectorDSA { pgq :: DSA.Params , msg :: ByteString , x :: Integer , y :: Integer , k :: Integer , r :: Integer , s :: Integer } vectorsSHA1 = [ VectorDSA { msg = "\x3b\x46\x73\x6d\x55\x9b\xd4\xe0\xc2\xc1\xb2\x55\x3a\x33\xad\x3c\x6c\xf2\x3c\xac\x99\x8d\x3d\x0c\x0e\x8f\xa4\xb1\x9b\xca\x06\xf2\xf3\x86\xdb\x2d\xcf\xf9\xdc\xa4\xf4\x0a\xd8\xf5\x61\xff\xc3\x08\xb4\x6c\x5f\x31\xa7\x73\x5b\x5f\xa7\xe0\xf9\xe6\xcb\x51\x2e\x63\xd7\xee\xa0\x55\x38\xd6\x6a\x75\xcd\x0d\x42\x34\xb5\xcc\xf6\xc1\x71\x5c\xca\xaf\x9c\xdc\x0a\x22\x28\x13\x5f\x71\x6e\xe9\xbd\xee\x7f\xc1\x3e\xc2\x7a\x03\xa6\xd1\x1c\x5c\x5b\x36\x85\xf5\x19\x00\xb1\x33\x71\x53\xbc\x6c\x4e\x8f\x52\x92\x0c\x33\xfa\x37\xf4\xe7" , x = 0xc53eae6d45323164c7d07af5715703744a63fc3a , y = 0x313fd9ebca91574e1c2eebe1517c57e0c21b0209872140c5328761bbb2450b33f1b18b409ce9ab7c4cd8fda3391e8e34868357c199e16a6b2eba06d6749def791d79e95d3a4d09b24c392ad89dbf100995ae19c01062056bb14bce005e8731efde175f95b975089bdcdaea562b32786d96f5a31aedf75364008ad4fffebb970b , k = 0x98cbcc4969d845e2461b5f66383dd503712bbcfa , r = 0x50ed0e810e3f1c7cb6ac62332058448bd8b284c0 , s = 0xc6aded17216b46b7e4b6f2a97c1ad7cc3da83fde , pgq = dsaParams } , VectorDSA { msg = "\xd2\xbc\xb5\x3b\x04\x4b\x3e\x2e\x4b\x61\xba\x2f\x91\xc0\x99\x5f\xb8\x3a\x6a\x97\x52\x5e\x66\x44\x1a\x3b\x48\x9d\x95\x94\x23\x8b\xc7\x40\xbd\xee\xa0\xf7\x18\xa7\x69\xc9\x77\xe2\xde\x00\x38\x77\xb5\xd7\xdc\x25\xb1\x82\xae\x53\x3d\xb3\x3e\x78\xf2\xc3\xff\x06\x45\xf2\x13\x7a\xbc\x13\x7d\x4e\x7d\x93\xcc\xf2\x4f\x60\xb1\x8a\x82\x0b\xc0\x7c\x7b\x4b\x5f\xe0\x8b\x4f\x9e\x7d\x21\xb2\x56\xc1\x8f\x3b\x9d\x49\xac\xc4\xf9\x3e\x2c\xe6\xf3\x75\x4c\x78\x07\x75\x7d\x2e\x11\x76\x04\x26\x12\xcb\x32\xfc\x3f\x4f\x70\x70\x0e\x25" , x = 0xe65131d73470f6ad2e5878bdc9bef536faf78831 , y = 0x29bdd759aaa62d4bf16b4861c81cf42eac2e1637b9ecba512bdbc13ac12a80ae8de2526b899ae5e4a231aef884197c944c732693a634d7659abc6975a773f8d3cd5a361fe2492386a3c09aaef12e4a7e73ad7dfc3637f7b093f2c40d6223a195c136adf2ea3fbf8704a675aa7817aa7ec7f9adfb2854d4e05c3ce7f76560313b , k = 0x87256a64e98cf5be1034ecfa766f9d25d1ac7ceb , r = 0xa26c00b5750a2d27fe7435b93476b35438b4d8ab , s = 0x61c9bfcb2938755afa7dad1d1e07c6288617bf70 , pgq = dsaParams } , VectorDSA { msg = "\xd5\x43\x1e\x6b\x16\xfd\xae\x31\x48\x17\x42\xbd\x39\x47\x58\xbe\xb8\xe2\x4f\x31\x94\x7e\x19\xb7\xea\x7b\x45\x85\x21\x88\x22\x70\xc1\xf4\x31\x92\xaa\x05\x0f\x44\x85\x14\x5a\xf8\xf3\xf9\xc5\x14\x2d\x68\xb8\x50\x18\xd2\xec\x9c\xb7\xa3\x7b\xa1\x2e\xd2\x3e\x73\xb9\x5f\xd6\x80\xfb\xa3\xc6\x12\x65\xe9\xf5\xa0\xa0\x27\xd7\x0f\xad\x0c\x8a\xa0\x8a\x3c\xbf\xbe\x99\x01\x8d\x00\x45\x38\x61\x73\xe5\xfa\xe2\x25\xfa\xeb\xe0\xce\xf5\xdd\x45\x91\x0f\x40\x0a\x86\xc2\xbe\x4e\x15\x25\x2a\x16\xde\x41\x20\xa2\x67\xbe\x2b\x59\x4d" , x = 0x20bcabc6d9347a6e79b8e498c60c44a19c73258c , y = 0x23b4f404aa3c575e550bb320fdb1a085cd396a10e5ebc6771da62f037cab19eacd67d8222b6344038c4f7af45f5e62b55480cbe2111154ca9697ca76d87b56944138084e74c6f90a05cf43660dff8b8b3fabfcab3f0e4416775fdf40055864be102b4587392e77752ed2aeb182ee4f70be4a291dbe77b84a44ee34007957b1e0 , k = 0x7d9bcfc9225432de9860f605a38d389e291ca750 , r = 0x3f0a4ad32f0816821b8affb518e9b599f35d57c2 , s = 0xea06638f2b2fc9d1dfe99c2a492806b497e2b0ea , pgq = dsaParams } , VectorDSA { msg = "\x85\x66\x2b\x69\x75\x50\xe4\x91\x5c\x29\xe3\x38\xb6\x24\xb9\x12\x84\x5d\x6d\x1a\x92\x0d\x9e\x4c\x16\x04\xdd\x47\xd6\x92\xbc\x7c\x0f\xfb\x95\xae\x61\x4e\x85\x2b\xeb\xaf\x15\x73\x75\x8a\xd0\x1c\x71\x3c\xac\x0b\x47\x6e\x2f\x12\x17\x45\xa3\xcf\xee\xff\xb2\x44\x1f\xf6\xab\xfb\x9b\xbe\xb9\x8a\xa6\x34\xca\x6f\xf5\x41\x94\x7d\xcc\x99\x27\x65\x9d\x44\xf9\x5c\x5f\xf9\x17\x0f\xdc\x3c\x86\x47\x3c\xb6\x01\xba\x31\xb4\x87\xfe\x59\x36\xba\xc5\xd9\xc6\x32\xcb\xcc\x3d\xb0\x62\x46\xba\x01\xc5\x5a\x03\x8d\x79\x7f\xe3\xf6\xc3" , x = 0x52d1fbe687aa0702a51a5bf9566bd51bd569424c , y = 0x6bc36cb3fa61cecc157be08639a7ca9e3de073b8a0ff23574ce5ab0a867dfd60669a56e60d1c989b3af8c8a43f5695d503e3098963990e12b63566784171058eace85c728cd4c08224c7a6efea75dca20df461013c75f40acbc23799ebee7f3361336dadc4a56f305708667bfe602b8ea75a491a5cf0c06ebd6fdc7161e10497 , k = 0x960c211891c090d05454646ebac1bfe1f381e82b , r = 0x3bc29dee96957050ba438d1b3e17b02c1725d229 , s = 0x0af879cf846c434e08fb6c63782f4d03e0d88865 , pgq = dsaParams } , VectorDSA { msg = "\x87\xb6\xe7\x5b\x9f\x8e\x99\xc4\xdd\x62\xad\xb6\x93\xdd\x58\x90\xed\xff\x1b\xd0\x02\x8f\x4e\xf8\x49\xdf\x0f\x1d\x2c\xe6\xb1\x81\xfc\x3a\x55\xae\xa6\xd0\xa1\xf0\xae\xca\xb8\xed\x9e\x24\x8a\x00\xe9\x6b\xe7\x94\xa7\xcf\xba\x12\x46\xef\xb7\x10\xef\x4b\x37\x47\x1c\xef\x0a\x1b\xcf\x55\xce\xbc\x8d\x5a\xd0\x71\x61\x2b\xd2\x37\xef\xed\xd5\x10\x23\x62\xdb\x07\xa1\xe2\xc7\xa6\xf1\x5e\x09\xfe\x64\xba\x42\xb6\x0a\x26\x28\xd8\x69\xae\x05\xef\x61\x1f\xe3\x8d\x9c\xe1\x5e\xee\xc9\xbb\x3d\xec\xc8\xdc\x17\x80\x9f\x3b\x6e\x95" , x = 0xc86a54ec5c4ec63d7332cf43ddb082a34ed6d5f5 , y = 0x014ac746d3605efcb8a2c7dae1f54682a262e27662b252c09478ce87d0aaa522d7c200043406016c0c42896d21750b15dbd57f9707ec37dcea5651781b67ad8d01f5099fe7584b353b641bb159cc717d8ceb18b66705e656f336f1214b34f0357e577ab83641969e311bf40bdcb3ffd5e0bb59419f229508d2f432cc2859ff75 , k = 0x6c445cee68042553fbe63be61be4ddb99d8134af , r = 0x637e07a5770f3dc65e4506c68c770e5ef6b8ced3 , s = 0x7dfc6f83e24f09745e01d3f7ae0ed1474e811d47 , pgq = dsaParams } , VectorDSA { msg = "\x22\x59\xee\xad\x2d\x6b\xbc\x76\xd4\x92\x13\xea\x0d\xc8\xb7\x35\x0a\x97\x69\x9f\x22\x34\x10\x44\xc3\x94\x07\x82\x36\x4a\xc9\xea\x68\x31\x79\xa4\x38\xa5\xea\x45\x99\x8d\xf9\x7c\x29\x72\xda\xe0\x38\x51\xf5\xbe\x23\xfa\x9f\x04\x18\x2e\x79\xdd\xb2\xb5\x6d\xc8\x65\x23\x93\xec\xb2\x7f\x3f\x3b\x7c\x8a\x8d\x76\x1a\x86\xb3\xb8\xf4\xd4\x1a\x07\xb4\xbe\x7d\x02\xfd\xde\xfc\x42\xb9\x28\x12\x4a\x5a\x45\xb9\xf4\x60\x90\x42\x20\x9b\x3a\x7f\x58\x5b\xd5\x14\xcc\x39\xc0\x0e\xff\xcc\x42\xc7\xfe\x70\xfa\x83\xed\xf8\xa3\x2b\xf4" , x = 0xaee6f213b9903c8069387e64729a08999e5baf65 , y = 0x0fe74045d7b0d472411202831d4932396f242a9765e92be387fd81bbe38d845054528b348c03984179b8e505674cb79d88cc0d8d3e8d7392f9aa773b29c29e54a9e326406075d755c291fcedbcc577934c824af988250f64ed5685fce726cff65e92d708ae11cbfaa958ab8d8b15340a29a137b5b4357f7ed1c7a5190cbf98a4 , k = 0xe1704bae025942e2e63c6d76bab88da79640073a , r = 0x83366ba3fed93dfb38d541203ecbf81c363998e2 , s = 0x1fe299c36a1332f23bf2e10a6c6a4e0d3cdd2bf4 , pgq = dsaParams } , VectorDSA { msg = "\x21\x9e\x8d\xf5\xbf\x88\x15\x90\x43\x0e\xce\x60\x82\x50\xf7\x67\x0d\xc5\x65\x37\x24\x93\x02\x42\x9e\x28\xec\xfe\xb9\xce\xaa\xa5\x49\x10\xa6\x94\x90\xf7\x65\xf3\xdf\x82\xe8\xb0\x1c\xd7\xd7\x6e\x56\x1d\x0f\x6c\xe2\x26\xef\x3c\xf7\x52\xca\xda\x6f\xeb\xdc\x5b\xf0\x0d\x67\x94\x7f\x92\xd4\x20\x51\x6b\x9e\x37\xc9\x6c\x8f\x1f\x2d\xa0\xb0\x75\x09\x7c\x3b\xda\x75\x8a\x8d\x91\xbd\x2e\xbe\x9c\x75\xcf\x14\x7f\x25\x4c\x25\x69\x63\xb3\x3b\x67\xd0\x2b\x6a\xa0\x9e\x7d\x74\x65\xd0\x38\xe5\x01\x95\xec\xe4\x18\x9b\x41\xe7\x68" , x = 0x699f1c07aa458c6786e770b40197235fe49cf21a , y = 0x3a41b0678ff3c4dde20fa39772bac31a2f18bae4bedec9e12ee8e02e30e556b1a136013bef96b0d30b568233dcecc71e485ed75c922afb4d0654e709bee84993792130220e3005fdb06ebdfc0e2df163b5ec424e836465acd6d92e243c86f2b94b26b8d73bd9cf722c757e0b80b0af16f185de70e8ca850b1402d126ea60f309 , k = 0x5bbb795bfa5fa72191fed3434a08741410367491 , r = 0x579761039ae0ddb81106bf4968e320083bbcb947 , s = 0x503ea15dbac9dedeba917fa8e9f386b93aa30353 , pgq = dsaParams } , VectorDSA { msg = "\x2d\xa7\x9d\x06\x78\x85\xeb\x3c\xcf\x5e\x29\x3a\xe3\xb1\xd8\x22\x53\x22\x20\x3a\xbb\x5a\xdf\xde\x3b\x0f\x53\xbb\xe2\x4c\x4f\xe0\x01\x54\x1e\x11\x83\xd8\x70\xa9\x97\xf1\xf9\x46\x01\x00\xb5\xd7\x11\x92\x31\x80\x15\x43\x45\x28\x7a\x02\x14\xcf\x1c\xac\x37\xb7\xa4\x7d\xfb\xb2\xa0\xe8\xce\x49\x16\xf9\x4e\xbd\x6f\xa5\x4e\x31\x5b\x7a\x8e\xb5\xb6\x3c\xd9\x54\xc5\xba\x05\xc1\xbf\x7e\x33\xa4\xe8\xa1\x51\xf3\x2d\x28\x77\xb0\x17\x29\xc1\xad\x0e\x7c\x01\xbb\x8a\xe7\x23\xc9\x95\x18\x38\x03\xe4\x56\x36\x52\x0e\xa3\x8c\xa1" , x = 0xd6e08c20c82949ddba93ea81eb2fea8c595894dc , y = 0x56f7272210f316c51af8bfc45a421fd4e9b1043853271b7e79f40936f0adcf262a86097aa86e19e6cb5307685d863dba761342db6c973b3849b1e060aca926f41fe07323601062515ae85f3172b8f34899c621d59fa21f73d5ae97a3deb5e840b25a18fd580862fd7b1cf416c7ae9fc5842a0197fdb0c5173ff4a4f102a8cf89 , k = 0x6d72c30d4430959800740f2770651095d0c181c2 , r = 0x5dd90d69add67a5fae138eec1aaff0229aa4afc4 , s = 0x47f39c4db2387f10762f45b80dfd027906d7ef04 , pgq = dsaParams } , VectorDSA { msg = "\xba\x30\xd8\x5b\xe3\x57\xe7\xfb\x29\xf8\xa0\x7e\x1f\x12\x7b\xaa\xa2\x4b\x2e\xe0\x27\xf6\x4c\xb5\xef\xee\xc6\xaa\xea\xbc\xc7\x34\x5c\x5d\x55\x6e\xbf\x4b\xdc\x7a\x61\xc7\x7c\x7b\x7e\xa4\x3c\x73\xba\xbc\x18\xf7\xb4\x80\x77\x22\xda\x23\x9e\x45\xdd\xf2\x49\x84\x9c\xbb\xfe\x35\x07\x11\x2e\xbf\x87\xd7\xef\x56\x0c\x2e\x7d\x39\x1e\xd8\x42\x4f\x87\x10\xce\xa4\x16\x85\x14\x3e\x30\x06\xf8\x1b\x68\xfb\xb4\xd5\xf9\x64\x4c\x7c\xd1\x0f\x70\x92\xef\x24\x39\xb8\xd1\x8c\x0d\xf6\x55\xe0\x02\x89\x37\x2a\x41\x66\x38\x5d\x64\x0c" , x = 0x50018482864c1864e9db1f04bde8dbfd3875c76d , y = 0x0942a5b7a72ab116ead29308cf658dfe3d55d5d61afed9e3836e64237f9d6884fdd827d2d5890c9a41ae88e7a69fc9f345ade9c480c6f08cff067c183214c227236cedb6dd1283ca2a602574e8327510221d4c27b162143b7002d8c726916826265937b87be9d5ec6d7bd28fb015f84e0ab730da7a4eaf4ef3174bf0a22a6392 , k = 0xdf3a9348f37b5d2d4c9176db266ae388f1fa7e0f , r = 0x448434b214eee38bde080f8ec433e8d19b3ddf0d , s = 0x0c02e881b777923fe0ea674f2621298e00199d5f , pgq = dsaParams } , VectorDSA { msg = "\x83\x49\x9e\xfb\x06\xbb\x7f\xf0\x2f\xfb\x46\xc2\x78\xa5\xe9\x26\x30\xac\x5b\xc3\xf9\xe5\x3d\xd2\xe7\x8f\xf1\x5e\x36\x8c\x7e\x31\xaa\xd7\x7c\xf7\x71\xf3\x5f\xa0\x2d\x0b\x5f\x13\x52\x08\xa4\xaf\xdd\x86\x7b\xb2\xec\x26\xea\x2e\x7d\xd6\x4c\xde\xf2\x37\x50\x8a\x38\xb2\x7f\x39\xd8\xb2\x2d\x45\xca\xc5\xa6\x8a\x90\xb6\xea\x76\x05\x86\x45\xf6\x35\x6a\x93\x44\xd3\x6f\x00\xec\x66\x52\xea\xa4\xe9\xba\xe7\xb6\x94\xf9\xf1\xfc\x8c\x6c\x5e\x86\xfa\xdc\x7b\x27\xa2\x19\xb5\xc1\xb2\xae\x80\xa7\x25\xe5\xf6\x11\x65\xfe\x2e\xdc" , x = 0xae56f66b0a9405b9cca54c60ec4a3bb5f8be7c3f , y = 0xa01542c3da410dd57930ca724f0f507c4df43d553c7f69459939685941ceb95c7dcc3f175a403b359621c0d4328e98f15f330a63865baf3e7eb1604a0715e16eed64fd14b35d3a534259a6a7ddf888c4dbb5f51bbc6ed339e5bb2a239d5cfe2100ac8e2f9c16e536f25119ab435843af27dc33414a9e4602f96d7c94d6021cec , k = 0x8857ff301ad0169d164fa269977a116e070bac17 , r = 0x8c2fab489c34672140415d41a65cef1e70192e23 , s = 0x3df86a9e2efe944a1c7ea9c30cac331d00599a0e , pgq = dsaParams } ] where -- (p,g,q) dsaParams = DSA.Params { DSA.params_p = 0xa8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283 , DSA.params_g = 0x2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33 , DSA.params_q = 0xf85f0f83ac4df7ea0cdf8f469bfeeaea14156495 } vectorToPrivate :: VectorDSA -> DSA.PrivateKey vectorToPrivate vector = DSA.PrivateKey { DSA.private_x = x vector , DSA.private_params = pgq vector } vectorToPublic :: VectorDSA -> DSA.PublicKey vectorToPublic vector = DSA.PublicKey { DSA.public_y = y vector , DSA.public_params = pgq vector } doSignatureTest (i, vector) = testCase (show i) (expected @=? actual) where expected = Just $ DSA.Signature (r vector) (s vector) actual = DSA.signWith (k vector) (vectorToPrivate vector) SHA1 (msg vector) doVerifyTest (i, vector) = testCase (show i) (True @=? actual) where actual = DSA.verify SHA1 (vectorToPublic vector) (DSA.Signature (r vector) (s vector)) (msg vector) dsaTests = testGroup "DSA" [ testGroup "SHA1" [ testGroup "signature" $ map doSignatureTest (zip [katZero..] vectorsSHA1) , testGroup "verify" $ map doVerifyTest (zip [katZero..] vectorsSHA1) ] ] cryptonite-0.23/tests/KAT_PubKey/ECC.hs0000644000000000000000000001734312766577754016054 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.ECC (eccTests, eccKatTests) where import Control.Arrow (second) import qualified Crypto.PubKey.ECC.Types as ECC import qualified Crypto.PubKey.ECC.Prim as ECC import Test.Tasty.KAT import Test.Tasty.KAT.FileLoader import Imports instance Arbitrary ECC.Curve where arbitrary = ECC.getCurveByName <$> elements [ ECC.SEC_p112r1 , ECC.SEC_p112r2 , ECC.SEC_p128r1 , ECC.SEC_p128r2 , ECC.SEC_p160k1 , ECC.SEC_p160r1 , ECC.SEC_p160r2 , ECC.SEC_p192k1 , ECC.SEC_p192r1 , ECC.SEC_p224k1 , ECC.SEC_p224r1 , ECC.SEC_p256k1 , ECC.SEC_p256r1 , ECC.SEC_p384r1 , ECC.SEC_p521r1 , ECC.SEC_t113r1 , ECC.SEC_t113r2 , ECC.SEC_t131r1 , ECC.SEC_t131r2 , ECC.SEC_t163k1 , ECC.SEC_t163r1 , ECC.SEC_t163r2 , ECC.SEC_t193r1 , ECC.SEC_t193r2 , ECC.SEC_t233k1 , ECC.SEC_t233r1 , ECC.SEC_t239k1 , ECC.SEC_t283k1 , ECC.SEC_t283r1 , ECC.SEC_t409k1 , ECC.SEC_t409r1 , ECC.SEC_t571k1 , ECC.SEC_t571r1 ] data VectorPoint = VectorPoint { curve :: ECC.Curve , x :: Integer , y :: Integer , valid :: Bool } vectorsPoint = [ VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x491c0c4761b0a4a147b5e4ce03a531546644f5d1e3d05e57 , y = 0x6fa5addd47c5d6be3933fbff88f57a6c8ca0232c471965de , valid = False -- point not on curve } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x646c22e8aa5f7833390e0399155ac198ae42470bba4fc834 , y = 0x8d4afcfffd80e69a4d180178b37c44572495b7b267ee32a9 , valid = True } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x4c6b9ea0dec92ecfff7799470be6a2277b9169daf45d54bb , y = 0xf0eab42826704f51b26ae98036e83230becb639dd1964627 , valid = False -- point not on curve } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x0673c8bb717b055c3d6f55c06acfcfb7260361ed3ec0f414 , y = 0xba8b172826eb0b854026968d2338a180450a27906f6eddea , valid = True } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x82c949295156192df0b52480e38c810751ac570daec460a3 , y = 0x200057ada615c80b8ff256ce8d47f2562b74a438f1921ac3 , valid = False -- point not on curve } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x284fbaa76ce0faae2ca4867d01092fa1ace5724cd12c8dd0 , y = 0xe42af3dbf3206be3fcbcc3a7ccaf60c73dc29e7bb9b44fca , valid = True } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x1b574acd4fb0f60dde3e3b5f3f0e94211f95112e43cba6fd2 , y = 0xbcc1b8a770f01a22e84d7f14e44932ffe094d8e3b1e6ac26 , valid = False -- x or y out of range } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x16ba109f1f1bb44e0d05b80181c03412ea764a59601d17e9f , y = 0x0569a843dbb4e287db420d6b9fe30cd7b5d578b052315f56 , valid = False -- x or y out of range } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x1333308a7c833ede5189d25ea3525919c9bd16370d904938d , y = 0xb10fd01d67df75ff9b726c700c1b50596c9f0766ea56f80e , valid = False -- x or y out of range } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x9671ec444cff24c8a5be80b018fa505ed6109a731e88c91a , y = 0xfe79dae23008e46bf4230c895aab261a95845a77f06d0655 , valid = True } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0x158e8b6f0b14216bc52fe8897b4305d870ede70436a96741d , y = 0xfb3f970b19a313571a1a23be310923f85acc1cab0a157cbd , valid = False -- x or y out of range } , VectorPoint { curve = ECC.getCurveByName ECC.SEC_p192r1 , x = 0xace95b650c08f73dbb4fa7b4bbdebd6b809a25b28ed135ef , y = 0xe9b8679404166d1329dd539ad52aad9a1b6681f5f26bb9aa , valid = False -- point not on curve } ] doPointValidTest (i, vector) = testCase (show i) (valid vector @=? ECC.isPointValid (curve vector) (ECC.Point (x vector) (y vector))) arbitraryPoint :: ECC.Curve -> Gen ECC.Point arbitraryPoint aCurve = frequency [(5, return ECC.PointO), (95, pointGen)] where n = ECC.ecc_n (ECC.common_curve aCurve) pointGen = ECC.pointBaseMul aCurve <$> choose (1, n - 1) eccTests = testGroup "ECC" [ testGroup "valid-point" $ map doPointValidTest (zip [katZero..] vectorsPoint) , testGroup "property" [ testProperty "point-add" $ \aCurve (QAInteger r1) (QAInteger r2) -> let curveN = ECC.ecc_n . ECC.common_curve $ aCurve curveGen = ECC.ecc_g . ECC.common_curve $ aCurve p1 = ECC.pointMul aCurve r1 curveGen p2 = ECC.pointMul aCurve r2 curveGen pR = ECC.pointMul aCurve ((r1 + r2) `mod` curveN) curveGen in pR `propertyEq` ECC.pointAdd aCurve p1 p2 , localOption (QuickCheckTests 20) $ testProperty "point-mul-mul" $ \aCurve (QAInteger n1) (QAInteger n2) -> do p <- arbitraryPoint aCurve let pRes = ECC.pointMul aCurve (n1 * n2) p let pDef = ECC.pointMul aCurve n1 (ECC.pointMul aCurve n2 p) return $ pRes `propertyEq` pDef , localOption (QuickCheckTests 20) $ testProperty "double-scalar-mult" $ \aCurve (QAInteger n1) (QAInteger n2) -> do p1 <- arbitraryPoint aCurve p2 <- arbitraryPoint aCurve let pRes = ECC.pointAddTwoMuls aCurve n1 p1 n2 p2 let pDef = ECC.pointAdd aCurve (ECC.pointMul aCurve n1 p1) (ECC.pointMul aCurve n2 p2) return $ pRes `propertyEq` pDef ] ] eccKatTests = do res <- testKatLoad "KATs/ECC-PKV.txt" (map (second (map toVector)) . katLoaderSimple) return $ testKatDetailed {-Grouped-} "ECC/valid-point" res (\g vect -> do let mCurve = ECC.getCurveByName <$> case g of "P-192" -> Just ECC.SEC_p192r1 "P-224" -> Just ECC.SEC_p224r1 "P-256" -> Just ECC.SEC_p256r1 "P-384" -> Just ECC.SEC_p384r1 "P-521" -> Just ECC.SEC_p521r1 "B-163" -> Just ECC.SEC_t163r2 "B-233" -> Just ECC.SEC_t233r1 "B-283" -> Just ECC.SEC_t283r1 "B-409" -> Just ECC.SEC_t409r1 "B-571" -> Just ECC.SEC_t571r1 "" -> Nothing _ -> Nothing {- "K-163" -> Just ECC.SEC_t163k1 "K-233" -> Just ECC.SEC_t233k1 "K-283" -> Just ECC.SEC_t283k1 "K-409" -> Just ECC.SEC_t409k1 "K-571" -> Just ECC.SEC_t571k1 -} case mCurve of Nothing -> return True Just c -> do return (ECC.isPointValid c (ECC.Point (x vect) (y vect)) == valid vect) ) where toVector kvs = case sequence $ map (flip lookup kvs) [ "Qx", "Qy", "Result" ] of Just [qx,qy,res] -> VectorPoint undefined (valueHexInteger qx) (valueHexInteger qy) (head res /= 'F') Just _ -> error ("ERROR: " ++ show kvs) Nothing -> error ("ERROR: " ++ show kvs) -- VectorPoint undefined 0 0 True cryptonite-0.23/tests/KAT_PubKey/ECDSA.hs0000644000000000000000000010456712766572243016272 0ustar0000000000000000-- Test vectors for SHA1 are taken from GEC2: www.secg.org/collateral/gec2.pdf -- Test vectors for SHA224, SHA256, SHA384, SHA512 are taken from RFC 6979 {-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.ECDSA (ecdsaTests) where import Crypto.Number.Serialize import qualified Crypto.PubKey.ECC.ECDSA as ECDSA import qualified Crypto.PubKey.ECC.Types as ECC import Crypto.Hash (SHA1(..), SHA224(..), SHA256(..), SHA384(..), SHA512(..)) import Imports data VectorECDSA = VectorECDSA { curve :: ECC.Curve , msg :: ByteString , d :: Integer , q :: ECC.Point , k :: Integer , r :: Integer , s :: Integer } vectorsSHA1 = [ VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p160r1 , msg = "abc" , d = 971761939728640320549601132085879836204587084162 , q = ECC.Point 466448783855397898016055842232266600516272889280 1110706324081757720403272427311003102474457754220 , k = 702232148019446860144825009548118511996283736794 , r = 1176954224688105769566774212902092897866168635793 , s = 299742580584132926933316745664091704165278518100 } -- from official ECDSA KATs , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_t163k1 , msg = i2osp 0xa2c1a03fdd00521bb08fc88d20344321977aaf637ef9d5470dd7d2c8628fc8d0d1f1d3587c6b3fd02386f8c13db341b14748a9475cc63baf065df64054b27d5c2cdf0f98e3bbb81d0b5dc94f8cdb87acf75720f6163de394c8c6af360bc1acb85b923a493b7b27cc111a257e36337bd94eb0fab9d5e633befb1ae7f1b244bfaa , d = 0x00000011f2626d90d26cb4c0379043b26e64107fc , q = ECC.Point 0x0389fa5ad7f8304325a8c060ef7dcb83042c045bc 0x0eefa094a5054da196943cc80509dcb9f59e5bc2e , k = 0x0000000c3a4ff97286126dab1e5089395fcc47ebb , r = 0x0dbe6c3a1dc851e7f2338b5c26c62b4b37bf8035c , s = 0x1c76458135b1ff9fbd23009b8414a47996126b56a } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_t163k1 , msg = i2osp 0x67048080daaeb77d3ac31babdf8be23dbe75ceb4dfb94aa8113db5c5dcb6fe14b70f717b7b0ed0881835a66a86e6d840ffcb7d976c75ef2d1d4322fbbc86357384e24707aef88cea2c41a01a9a3d1b9e72ce650c7fdecc4f9448d3a77df6cdf13647ab295bb3132de0b1b2c402d8d2de7d452f1e003e0695de1470d1064eee16 , d = 0x00000006a3803301daee9af09bb5b6c991a4f49a4 , q = ECC.Point 0x4b500f555e857da8c299780130c5c3f48f02ee322 0x5c1c0ae25b47f06cc46fb86b12d2d8c0ba6a4bf07 , k = 0x0000002f39fbf77f3e0dc046116de692b6cf91b16 , r = 0x3d3eeda42f65d727f4a564f1415654356c6c57a6c , s = 0x35e4d43c5f08baddf138449db1ad0b7872552b7cd } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_t163k1 , msg = i2osp 0x77e007dc2acd7248256165a4b30e98986f51a81efd926b85f74c81bc2a6d2bcd030060a844091e22fbb0ff3db5a20caaefb5d58ccdcbc27f0ff8a4d940e78f303079ec1ca5b0ca3d4ecc7580f8b34a9f0496c9e719d2ec3e1614b7644bc11179e895d2c0b58a1da204fbf0f6e509f97f983eacb6487092caf6e8e4e6b3c458b2 , d = 0x0000002e28676514bd93fea11b62db0f6e324b18d , q = ECC.Point 0x3f9c90b71f6a1de20a2716f38ef1b5f98c757bd42 0x2ff0a5d266d447ef62d43fbca6c34c08c1ce35a40 , k = 0x00000001233ae699883e74e7f4dfb5279ff22280a , r = 0x39de3cd2cf04145e522b8fba3f23e9218226e0860 , s = 0x2af62bfb3cfa202e2342606ee5bb0934c3b0375b6 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_t163k1 , msg = i2osp 0xfbacfcce4688748406ddf5c3495021eef8fb399865b649eb2395a04a1ab28335da2c236d306fcc59f7b65ea931cf0139571e1538ede5688958c3ac69f47a285362f5ad201f89cc735b7b465408c2c41b310fc8908d0be45054df2a7351fae36b390e842f3b5cdd9ad832940df5b2d25c2ed43ce86eaf2508bcf401ae58bb1d47 , d = 0x000000361dd088e3a6d3c910686c8dce57e5d4d8e , q = ECC.Point 0x064f905c1da9d7e9c32d81890ae6f30dcc7839d32 0x06f1faedb6d9032016d3b681e7cf69c29d29eb27b , k = 0x00000022f723e9f5da56d3d0837d5dca2f937395f , r = 0x374cdc8571083fecfbd4e25e1cd69ecc66b715f2d , s = 0x313b10949222929b2f20b15d446c27d6dcae3f086 } ] rfc6979_vectorsSHA224 = [ VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "sample" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0x4381526b3fc1e7128f202e194505592f01d5ff4c5af015d8 , r = 0xa1f00dad97aeec91c95585f36200c65f3c01812aa60378f5 , s = 0xe07ec1304c7c6c9debbe980b9692668f81d4de7922a0f97a } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "test" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0xf5dc805f76ef851800700cce82e7b98d8911b7d510059fbe , r = 0x6945a1c1d1b2206b8145548f633bb61cef04891baf26ed34 , s = 0xb7fb7fdfc339c0b9bd61a9f5a8eaf9be58fc5cba2cb15293 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "sample" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0xc1d1f2f10881088301880506805feb4825fe09acb6816c36991aa06d , r = 0x1cdfe6662dde1e4a1ec4cdedf6a1f5a2fb7fbd9145c12113e6abfd3e , s = 0xa6694fd7718a21053f225d3f46197ca699d45006c06f871808f43ebc } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "test" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0xdf8b38d40dca3e077d0ac520bf56b6d565134d9b5f2eae0d34900524 , r = 0xc441ce8e261ded634e4cf84910e4c5d1d22c5cf3b732bb204dbef019 , s = 0x902f42847a63bdc5f6046ada114953120f99442d76510150f372a3f4 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "sample" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0x103f90ee9dc52e5e7fb5132b7033c63066d194321491862059967c715985d473 , r = 0x53b2fff5d1752b2c689df257c04c40a587fababb3f6fc2702f1343af7ca9aa3f , s = 0xb9afb64fdc03dc1a131c7d2386d11e349f070aa432a4acc918bea988bf75c74c } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "test" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0x669f4426f2688b8be0db3a6bd1989bdaefff84b649eeb84f3dd26080f667faa7 , r = 0xc37edb6f0ae79d47c3c27e962fa269bb4f441770357e114ee511f662ec34a692 , s = 0xc820053a05791e521fcaad6042d40aea1d6b1a540138558f47d0719800e18f2d } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "sample" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0xa4e4d2f0e729eb786b31fc20ad5d849e304450e0ae8e3e341134a5c1afa03cab8083ee4e3c45b06a5899ea56c51b5879 , r = 0x42356e76b55a6d9b4631c865445dbe54e056d3b3431766d0509244793c3f9366450f76ee3de43f5a125333a6be060122 , s = 0x9da0c81787064021e78df658f2fbb0b042bf304665db721f077a4298b095e4834c082c03d83028efbf93a3c23940ca8d } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "test" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0x18fa39db95aa5f561f30fa3591dc59c0fa3653a80daffa0b48d1a4c6dfcbff6e3d33be4dc5eb8886a8ecd093f2935726 , r = 0xe8c9d0b6ea72a0e7837fea1d14a1a9557f29faa45d3e7ee888fc5bf954b5e62464a9a817c47ff78b8c11066b24080e72 , s = 0x07041d4a7a0379ac7232ff72e6f77b6ddb8f09b16cce0ec3286b2bd43fa8c6141c53ea5abef0d8231077a04540a96b66 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "sample" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x121415ec2cd7726330a61f7f3fa5de14be9436019c4db8cb4041f3b54cf31be0493ee3f427fb906393d895a19c9523f3a1d54bb8702bd4aa9c99dab2597b92113f3 , r = 0x1776331cfcdf927d666e032e00cf776187bc9fdd8e69d0dabb4109ffe1b5e2a30715f4cc923a4a5e94d2503e9acfed92857b7f31d7152e0f8c00c15ff3d87e2ed2e , s = 0x050cb5265417fe2320bbb5a122b8e1a32bd699089851128e360e620a30c7e17ba41a666af126ce100e5799b153b60528d5300d08489ca9178fb610a2006c254b41f } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "test" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x040d09fcf3c8a5f62cf4fb223cbbb2b9937f6b0577c27020a99602c25a01136987e452988781484edbbcf1c47e554e7fc901bc3085e5206d9f619cff07e73d6f706 , r = 0x1c7ed902e123e6815546065a2c4af977b22aa8eaddb68b2c1110e7ea44d42086bfe4a34b67ddc0e17e96536e358219b23a706c6a6e16ba77b65e1c595d43cae17fb , s = 0x177336676304fcb343ce028b38e7b4fba76c1c1b277da18cad2a8478b2a9a9f5bec0f3ba04f35db3e4263569ec6aade8c92746e4c82f8299ae1b8f1739f8fd519a4 } ] rfc6979_vectorsSHA256 = [ VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "sample" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0x32b1b6d7d42a05cb449065727a84804fb1a3e34d8f261496 , r = 0x4b0b8ce98a92866a2820e20aa6b75b56382e0f9bfd5ecb55 , s = 0xccdb006926ea9565cbadc840829d8c384e06de1f1e381b85 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "test" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0x5c4ce89cf56d9e7c77c8585339b006b97b5f0680b4306c6c , r = 0x3a718bd8b4926c3b52ee6bbe67ef79b18cb6eb62b1ad97ae , s = 0x5662e6848a4a19b1f1ae2f72acd4b8bbe50f1eac65d9124f } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "sample" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0xad3029e0278f80643de33917ce6908c70a8ff50a411f06e41dedfcdc , r = 0x61aa3da010e8e8406c656bc477a7a7189895e7e840cdfe8ff42307ba , s = 0xbc814050dab5d23770879494f9e0a680dc1af7161991bde692b10101 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "test" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0xff86f57924da248d6e44e8154eb69f0ae2aebaee9931d0b5a969f904 , r = 0xad04dde87b84747a243a631ea47a1ba6d1faa059149ad2440de6fba6 , s = 0x178d49b1ae90e3d8b629be3db5683915f4e8c99fdf6e666cf37adcfd } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "sample" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0xa6e3c57dd01abe90086538398355dd4c3b17aa873382b0f24d6129493d8aad60 , r = 0xefd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716 , s = 0xf7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "test" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0xd16b6ae827f17175e040871a1c7ec3500192c4c92677336ec2537acaee0008e0 , r = 0xf1abb023518351cd71d881567b1ea663ed3efcf6c5132b354f28d3b0b7d38367 , s = 0x019f4113742a2b14bd25926b49c649155f267e60d3814b4c0cc84250e46f0083 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "sample" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0x180ae9f9aec5438a44bc159a1fcb277c7be54fa20e7cf404b490650a8acc414e375572342863c899f9f2edf9747a9b60 , r = 0x21b13d1e013c7fa1392d03c5f99af8b30c570c6f98d4ea8e354b63a21d3daa33bde1e888e63355d92fa2b3c36d8fb2cd , s = 0xf3aa443fb107745bf4bd77cb3891674632068a10ca67e3d45db2266fa7d1feebefdc63eccd1ac42ec0cb8668a4fa0ab0 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "test" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0x0cfac37587532347dc3389fdc98286bba8c73807285b184c83e62e26c401c0faa48dd070ba79921a3457abff2d630ad7 , r = 0x6d6defac9ab64dabafe36c6bf510352a4cc27001263638e5b16d9bb51d451559f918eedaf2293be5b475cc8f0188636b , s = 0x2d46f3becbcc523d5f1a1256bf0c9b024d879ba9e838144c8ba6baeb4b53b47d51ab373f9845c0514eefb14024787265 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "sample" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x0edf38afcaaecab4383358b34d67c9f2216c8382aaea44a3dad5fdc9c32575761793fef24eb0fc276dfc4f6e3ec476752f043cf01415387470bcbd8678ed2c7e1a0 , r = 0x1511bb4d675114fe266fc4372b87682baecc01d3cc62cf2303c92b3526012659d16876e25c7c1e57648f23b73564d67f61c6f14d527d54972810421e7d87589e1a7 , s = 0x04a171143a83163d6df460aaf61522695f207a58b95c0644d87e52aa1a347916e4f7a72930b1bc06dbe22ce3f58264afd23704cbb63b29b931f7de6c9d949a7ecfc } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "test" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x01de74955efaabc4c4f17f8e84d881d1310b5392d7700275f82f145c61e843841af09035bf7a6210f5a431a6a9e81c9323354a9e69135d44ebd2fcaa7731b909258 , r = 0x00e871c4a14f993c6c7369501900c4bc1e9c7b0b4ba44e04868b30b41d8071042eb28c4c250411d0ce08cd197e4188ea4876f279f90b3d8d74a3c76e6f1e4656aa8 , s = 0x0cd52dbaa33b063c3a6cd8058a1fb0a46a4754b034fcc644766ca14da8ca5ca9fde00e88c1ad60ccba759025299079d7a427ec3cc5b619bfbc828e7769bcd694e86 } ] rfc6979_vectorsSHA384 = [ VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "sample" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0x4730005c4fcb01834c063a7b6760096dbe284b8252ef4311 , r = 0xda63bf0b9abcf948fbb1e9167f136145f7a20426dcc287d5 , s = 0xc3aa2c960972bd7a2003a57e1c4c77f0578f8ae95e31ec5e } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "test" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0x5afefb5d3393261b828db6c91fbc68c230727b030c975693 , r = 0xb234b60b4db75a733e19280a7a6034bd6b1ee88af5332367 , s = 0x7994090b2d59bb782be57e74a44c9a1c700413f8abefe77a } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "sample" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0x52b40f5a9d3d13040f494e83d3906c6079f29981035c7bd51e5cac40 , r = 0x0b115e5e36f0f9ec81f1325a5952878d745e19d7bb3eabfaba77e953 , s = 0x830f34ccdfe826ccfdc81eb4129772e20e122348a2bbd889a1b1af1d } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "test" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0x7046742b839478c1b5bd31db2e862ad868e1a45c863585b5f22bdc2d , r = 0x389b92682e399b26518a95506b52c03bc9379a9dadf3391a21fb0ea4 , s = 0x414a718ed3249ff6dbc5b50c27f71f01f070944da22ab1f78f559aab } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "sample" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0x09f634b188cefd98e7ec88b1aa9852d734d0bc272f7d2a47decc6ebeb375aad4 , r = 0x0eafea039b20e9b42309fb1d89e213057cbf973dc0cfc8f129edddc800ef7719 , s = 0x4861f0491e6998b9455193e34e7b0d284ddd7149a74b95b9261f13abde940954 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "test" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0x16aeffa357260b04b1dd199693960740066c1a8f3e8edd79070aa914d361b3b8 , r = 0x83910e8b48bb0c74244ebdf7f07a1c5413d61472bd941ef3920e623fbccebeb6 , s = 0x8ddbec54cf8cd5874883841d712142a56a8d0f218f5003cb0296b6b509619f2c } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "sample" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0x94ed910d1a099dad3254e9242ae85abde4ba15168eaf0ca87a555fd56d10fbca2907e3e83ba95368623b8c4686915cf9 , r = 0x94edbb92a5ecb8aad4736e56c691916b3f88140666ce9fa73d64c4ea95ad133c81a648152e44acf96e36dd1e80fabe46 , s = 0x99ef4aeb15f178cea1fe40db2603138f130e740a19624526203b6351d0a3a94fa329c145786e679e7b82c71a38628ac8 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "test" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0x015ee46a5bf88773ed9123a5ab0807962d193719503c527b031b4c2d225092ada71f4a459bc0da98adb95837db8312ea , r = 0x8203b63d3c853e8d77227fb377bcf7b7b772e97892a80f36ab775d509d7a5feb0542a7f0812998da8f1dd3ca3cf023db , s = 0xddd0760448d42d8a43af45af836fce4de8be06b485e9b61b827c2f13173923e06a739f040649a667bf3b828246baa5a5 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "sample" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x1546a108bc23a15d6f21872f7ded661fa8431ddbd922d0dcdb77cc878c8553ffad064c95a920a750ac9137e527390d2d92f153e66196966ea554d9adfcb109c4211 , r = 0x1ea842a0e17d2de4f92c15315c63ddf72685c18195c2bb95e572b9c5136ca4b4b576ad712a52be9730627d16054ba40cc0b8d3ff035b12ae75168397f5d50c67451 , s = 0x1f21a3cee066e1961025fb048bd5fe2b7924d0cd797babe0a83b66f1e35eeaf5fde143fa85dc394a7dee766523393784484bdf3e00114a1c857cde1aa203db65d61 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "test" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x1f1fc4a349a7da9a9e116bfdd055dc08e78252ff8e23ac276ac88b1770ae0b5dceb1ed14a4916b769a523ce1e90ba22846af11df8b300c38818f713dadd85de0c88 , r = 0x14bee21a18b6d8b3c93fab08d43e739707953244fdbe924fa926d76669e7ac8c89df62ed8975c2d8397a65a49dcc09f6b0ac62272741924d479354d74ff6075578c , s = 0x133330865c067a0eaf72362a65e2d7bc4e461e8c8995c3b6226a21bd1aa78f0ed94fe536a0dca35534f0cd1510c41525d163fe9d74d134881e35141ed5e8e95b979 } ] rfc6979_vectorsSHA512 = [ VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "sample" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0xa2ac7ab055e4f20692d49209544c203a7d1f2c0bfbc75db1 , r = 0x4d60c5ab1996bd848343b31c00850205e2ea6922dac2e4b8 , s = 0x3f6e837448f027a1bf4b34e796e32a811cbb4050908d8f67 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p192r1 , msg = "test" , d = 0x6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 , q = ECC.Point 0xac2c77f529f91689fea0ea5efec7f210d8eea0b9e047ed56 0x3bc723e57670bd4887ebc732c523063d0a7c957bc97c1c43 , k = 0x0758753a5254759c7cfbad2e2d9b0792eee44136c9480527 , r = 0xfe4f4ae86a58b6507946715934fe2d8ff9d95b6b098fe739 , s = 0x74cf5605c98fba0e1ef34d4b5a1577a7dcf59457cae52290 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "sample" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0x9db103ffededf9cfdba05184f925400c1653b8501bab89cea0fbec14 , r = 0x074bd1d979d5f32bf958ddc61e4fb4872adcafeb2256497cdac30397 , s = 0xa4ceca196c3d5a1ff31027b33185dc8ee43f288b21ab342e5d8eb084 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p224r1 , msg = "test" , d = 0xf220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 , q = ECC.Point 0x00cf08da5ad719e42707fa431292dea11244d64fc51610d94b130d6c 0xeeab6f3debe455e3dbf85416f7030cbd94f34f2d6f232c69f3c1385a , k = 0xe39c2aa4ea6be2306c72126d40ed77bf9739bb4d6ef2bbb1dcb6169d , r = 0x049f050477c5add858cac56208394b5a55baebbe887fdf765047c17c , s = 0x077eb13e7005929cefa3cd0403c7cdcc077adf4e44f3c41b2f60ecff } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "sample" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0x5fa81c63109badb88c1f367b47da606da28cad69aa22c4fe6ad7df73a7173aa5 , r = 0x8496a60b5e9b47c825488827e0495b0e3fa109ec4568fd3f8d1097678eb97f00 , s = 0x2362ab1adbe2b8adf9cb9edab740ea6049c028114f2460f96554f61fae3302fe } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p256r1 , msg = "test" , d = 0xc9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 , q = ECC.Point 0x60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6 0x7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299 , k = 0x6915d11632aca3c40d5d51c08daf9c555933819548784480e93499000d9f0b7f , r = 0x461d93f31b6540894788fd206c07cfa0cc35f46fa3c91816fff1040ad1581a04 , s = 0x39af9f15de0db8d97e72719c74820d304ce5226e32dedae67519e840d1194e55 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "sample" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0x92fc3c7183a883e24216d1141f1a8976c5b0dd797dfa597e3d7b32198bd35331a4e966532593a52980d0e3aaa5e10ec3 , r = 0xed0959d5880ab2d869ae7f6c2915c6d60f96507f9cb3e047c0046861da4a799cfe30f35cc900056d7c99cd7882433709 , s = 0x512c8cceee3890a84058ce1e22dbc2198f42323ce8aca9135329f03c068e5112dc7cc3ef3446defceb01a45c2667fdd5 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p384r1 , msg = "test" , d = 0x6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d896d5724e4c70a825f872c9ea60d2edf5 , q = ECC.Point 0xec3a4e415b4e19a4568618029f427fa5da9a8bc4ae92e02e06aae5286b300c64def8f0ea9055866064a254515480bc13 0x8015d9b72d7d57244ea8ef9ac0c621896708a59367f9dfb9f54ca84b3f1c9db1288b231c3ae0d4fe7344fd2533264720 , k = 0x3780c4f67cb15518b6acae34c9f83568d2e12e47deab6c50a4e4ee5319d1e8ce0e2cc8a136036dc4b9c00e6888f66b6c , r = 0xa0d5d090c9980faf3c2ce57b7ae951d31977dd11c775d314af55f76c676447d06fb6495cd21b4b6e340fc236584fb277 , s = 0x976984e59b4c77b0e8e4460dca3d9f20e07b9bb1f63beefaf576f6b2e8b224634a2092cd3792e0159ad9cee37659c736 } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "sample" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x1dae2ea071f8110dc26882d4d5eae0621a3256fc8847fb9022e2b7d28e6f10198b1574fdd03a9053c08a1854a168aa5a57470ec97dd5ce090124ef52a2f7ecbffd3 , r = 0x0c328fafcbd79dd77850370c46325d987cb525569fb63c5d3bc53950e6d4c5f174e25a1ee9017b5d450606add152b534931d7d4e8455cc91f9b15bf05ec36e377fa , s = 0x0617cce7cf5064806c467f678d3b4080d6f1cc50af26ca209417308281b68af282623eaa63e5b5c0723d8b8c37ff0777b1a20f8ccb1dccc43997f1ee0e44da4a67a } , VectorECDSA { curve = ECC.getCurveByName ECC.SEC_p521r1 , msg = "test" , d = 0x0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75caa896eb32f1f47c70855836a6d16fcc1466f6d8fbec67db89ec0c08b0e996b83538 , q = ECC.Point 0x1894550d0785932e00eaa23b694f213f8c3121f86dc97a04e5a7167db4e5bcd371123d46e45db6b5d5370a7f20fb633155d38ffa16d2bd761dcac474b9a2f5023a4 0x0493101c962cd4d2fddf782285e64584139c2f91b47f87ff82354d6630f746a28a0db25741b5b34a828008b22acc23f924faafbd4d33f81ea66956dfeaa2bfdfcf5 , k = 0x16200813020ec986863bedfc1b121f605c1215645018aea1a7b215a564de9eb1b38a67aa1128b80ce391c4fb71187654aaa3431027bfc7f395766ca988c964dc56d , r = 0x13e99020abf5cee7525d16b69b229652ab6bdf2affcaef38773b4b7d08725f10cdb93482fdcc54edcee91eca4166b2a7c6265ef0ce2bd7051b7cef945babd47ee6d , s = 0x1fbd0013c674aa79cb39849527916ce301c66ea7ce8b80682786ad60f98f7e78a19ca69eff5c57400e3b3a0ad66ce0978214d13baf4e9ac60752f7b155e2de4dce3 } ] vectorToPrivate :: VectorECDSA -> ECDSA.PrivateKey vectorToPrivate vector = ECDSA.PrivateKey (curve vector) (d vector) vectorToPublic :: VectorECDSA -> ECDSA.PublicKey vectorToPublic vector = ECDSA.PublicKey (curve vector) (q vector) doSignatureTest hashAlg (i, vector) = testCase (show i) (expected @=? actual) where expected = Just $ ECDSA.Signature (r vector) (s vector) actual = ECDSA.signWith (k vector) (vectorToPrivate vector) hashAlg (msg vector) doVerifyTest hashAlg (i, vector) = testCase (show i) (True @=? actual) where actual = ECDSA.verify hashAlg (vectorToPublic vector) (ECDSA.Signature (r vector) (s vector)) (msg vector) ecdsaTests = testGroup "ECDSA" [ testGroup "SHA1" [ testGroup "signature" $ map (doSignatureTest SHA1) (zip [katZero..] vectorsSHA1) , testGroup "verify" $ map (doVerifyTest SHA1) (zip [katZero..] vectorsSHA1) ] , testGroup "SHA224" [ testGroup "signature" $ map (doSignatureTest SHA224) (zip [katZero..] rfc6979_vectorsSHA224) , testGroup "verify" $ map (doVerifyTest SHA224) (zip [katZero..] rfc6979_vectorsSHA224) ] , testGroup "SHA256" [ testGroup "signature" $ map (doSignatureTest SHA256) (zip [katZero..] rfc6979_vectorsSHA256) , testGroup "verify" $ map (doVerifyTest SHA256) (zip [katZero..] rfc6979_vectorsSHA256) ] , testGroup "SHA384" [ testGroup "signature" $ map (doSignatureTest SHA384) (zip [katZero..] rfc6979_vectorsSHA384) , testGroup "verify" $ map (doVerifyTest SHA384) (zip [katZero..] rfc6979_vectorsSHA384) ] , testGroup "SHA512" [ testGroup "signature" $ map (doSignatureTest SHA512) (zip [katZero..] rfc6979_vectorsSHA512) , testGroup "verify" $ map (doVerifyTest SHA512) (zip [katZero..] rfc6979_vectorsSHA512) ] ] cryptonite-0.23/tests/KAT_PubKey/OAEP.hs0000644000000000000000000002262312517170224016152 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.OAEP (oaepTests) where import Crypto.PubKey.RSA import qualified Crypto.PubKey.RSA.OAEP as OAEP import Crypto.Hash import Imports rsaKeyInt = PrivateKey { private_pub = PublicKey { public_n = 0xbbf82f090682ce9c2338ac2b9da871f7368d07eed41043a440d6b6f07454f51fb8dfbaaf035c02ab61ea48ceeb6fcd4876ed520d60e1ec4619719d8a5b8b807fafb8e0a3dfc737723ee6b4b7d93a2584ee6a649d060953748834b2454598394ee0aab12d7b61a51f527a9a41f6c1687fe2537298ca2a8f5946f8e5fd091dbdcb , public_e = 0x11 , public_size = 128 } , private_d = 0xa5dafc5341faf289c4b988db30c1cdf83f31251e0668b42784813801579641b29410b3c7998d6bc465745e5c392669d6870da2c082a939e37fdcb82ec93edac97ff3ad5950accfbc111c76f1a9529444e56aaf68c56c092cd38dc3bef5d20a939926ed4f74a13eddfbe1a1cecc4894af9428c2b7b8883fe4463a4bc85b1cb3c1 , private_p = 0xeecfae81b1b9b3c908810b10a1b5600199eb9f44aef4fda493b81a9e3d84f632124ef0236e5d1e3b7e28fae7aa040a2d5b252176459d1f397541ba2a58fb6599 , private_q = 0xc97fb1f027f453f6341233eaaad1d9353f6c42d08866b1d05a0f2035028b9d869840b41666b42e92ea0da3b43204b5cfce3352524d0416a5a441e700af461503 , private_dP = 0x54494ca63eba0337e4e24023fcd69a5aeb07dddc0183a4d0ac9b54b051f2b13ed9490975eab77414ff59c1f7692e9a2e202b38fc910a474174adc93c1f67c981 , private_dQ = 0x471e0290ff0af0750351b7f878864ca961adbd3a8a7e991c5c0556a94c3146a7f9803f8f6f8ae342e931fd8ae47a220d1b99a495849807fe39f9245a9836da3d , private_qinv = 0xb06c4fdabb6301198d265bdbae9423b380f271f73453885093077fcd39e2119fc98632154f5883b167a967bf402b4e9e2e0f9656e698ea3666edfb25798039f7 } rsaKey1 = PrivateKey { private_pub = PublicKey { public_n = 0xa8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb , public_e = 0x010001 , public_size = 128 } , private_d = 0x53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1 , private_p = 0xd32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d , private_q = 0xcc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77 , private_dP = 0x0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1 , private_dQ = 0x95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583 , private_qinv = 0x4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1 } data VectorOAEP = VectorOAEP { seed :: ByteString , message :: ByteString , cipherText :: ByteString } vectorInt = VectorOAEP { message = "\xd4\x36\xe9\x95\x69\xfd\x32\xa7\xc8\xa0\x5b\xbc\x90\xd3\x2c\x49" , seed = "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f" , cipherText = "\x12\x53\xe0\x4d\xc0\xa5\x39\x7b\xb4\x4a\x7a\xb8\x7e\x9b\xf2\xa0\x39\xa3\x3d\x1e\x99\x6f\xc8\x2a\x94\xcc\xd3\x00\x74\xc9\x5d\xf7\x63\x72\x20\x17\x06\x9e\x52\x68\xda\x5d\x1c\x0b\x4f\x87\x2c\xf6\x53\xc1\x1d\xf8\x23\x14\xa6\x79\x68\xdf\xea\xe2\x8d\xef\x04\xbb\x6d\x84\xb1\xc3\x1d\x65\x4a\x19\x70\xe5\x78\x3b\xd6\xeb\x96\xa0\x24\xc2\xca\x2f\x4a\x90\xfe\x9f\x2e\xf5\xc9\xc1\x40\xe5\xbb\x48\xda\x95\x36\xad\x87\x00\xc8\x4f\xc9\x13\x0a\xde\xa7\x4e\x55\x8d\x51\xa7\x4d\xdf\x85\xd8\xb5\x0d\xe9\x68\x38\xd6\x06\x3e\x09\x55" } vectorsKey1 = [ VectorOAEP -- 1.1 { message = "\x66\x28\x19\x4e\x12\x07\x3d\xb0\x3b\xa9\x4c\xda\x9e\xf9\x53\x23\x97\xd5\x0d\xba\x79\xb9\x87\x00\x4a\xfe\xfe\x34" , seed = "\x18\xb7\x76\xea\x21\x06\x9d\x69\x77\x6a\x33\xe9\x6b\xad\x48\xe1\xdd\xa0\xa5\xef" , cipherText = "\x35\x4f\xe6\x7b\x4a\x12\x6d\x5d\x35\xfe\x36\xc7\x77\x79\x1a\x3f\x7b\xa1\x3d\xef\x48\x4e\x2d\x39\x08\xaf\xf7\x22\xfa\xd4\x68\xfb\x21\x69\x6d\xe9\x5d\x0b\xe9\x11\xc2\xd3\x17\x4f\x8a\xfc\xc2\x01\x03\x5f\x7b\x6d\x8e\x69\x40\x2d\xe5\x45\x16\x18\xc2\x1a\x53\x5f\xa9\xd7\xbf\xc5\xb8\xdd\x9f\xc2\x43\xf8\xcf\x92\x7d\xb3\x13\x22\xd6\xe8\x81\xea\xa9\x1a\x99\x61\x70\xe6\x57\xa0\x5a\x26\x64\x26\xd9\x8c\x88\x00\x3f\x84\x77\xc1\x22\x70\x94\xa0\xd9\xfa\x1e\x8c\x40\x24\x30\x9c\xe1\xec\xcc\xb5\x21\x00\x35\xd4\x7a\xc7\x2e\x8a" } , VectorOAEP -- 1.2 { message = "\x75\x0c\x40\x47\xf5\x47\xe8\xe4\x14\x11\x85\x65\x23\x29\x8a\xc9\xba\xe2\x45\xef\xaf\x13\x97\xfb\xe5\x6f\x9d\xd5" , seed = "\x0c\xc7\x42\xce\x4a\x9b\x7f\x32\xf9\x51\xbc\xb2\x51\xef\xd9\x25\xfe\x4f\xe3\x5f" , cipherText = "\x64\x0d\xb1\xac\xc5\x8e\x05\x68\xfe\x54\x07\xe5\xf9\xb7\x01\xdf\xf8\xc3\xc9\x1e\x71\x6c\x53\x6f\xc7\xfc\xec\x6c\xb5\xb7\x1c\x11\x65\x98\x8d\x4a\x27\x9e\x15\x77\xd7\x30\xfc\x7a\x29\x93\x2e\x3f\x00\xc8\x15\x15\x23\x6d\x8d\x8e\x31\x01\x7a\x7a\x09\xdf\x43\x52\xd9\x04\xcd\xeb\x79\xaa\x58\x3a\xdc\xc3\x1e\xa6\x98\xa4\xc0\x52\x83\xda\xba\x90\x89\xbe\x54\x91\xf6\x7c\x1a\x4e\xe4\x8d\xc7\x4b\xbb\xe6\x64\x3a\xef\x84\x66\x79\xb4\xcb\x39\x5a\x35\x2d\x5e\xd1\x15\x91\x2d\xf6\x96\xff\xe0\x70\x29\x32\x94\x6d\x71\x49\x2b\x44" } , VectorOAEP -- 1.3 { message = "\xd9\x4a\xe0\x83\x2e\x64\x45\xce\x42\x33\x1c\xb0\x6d\x53\x1a\x82\xb1\xdb\x4b\xaa\xd3\x0f\x74\x6d\xc9\x16\xdf\x24\xd4\xe3\xc2\x45\x1f\xff\x59\xa6\x42\x3e\xb0\xe1\xd0\x2d\x4f\xe6\x46\xcf\x69\x9d\xfd\x81\x8c\x6e\x97\xb0\x51" , seed = "\x25\x14\xdf\x46\x95\x75\x5a\x67\xb2\x88\xea\xf4\x90\x5c\x36\xee\xc6\x6f\xd2\xfd" , cipherText = "\x42\x37\x36\xed\x03\x5f\x60\x26\xaf\x27\x6c\x35\xc0\xb3\x74\x1b\x36\x5e\x5f\x76\xca\x09\x1b\x4e\x8c\x29\xe2\xf0\xbe\xfe\xe6\x03\x59\x5a\xa8\x32\x2d\x60\x2d\x2e\x62\x5e\x95\xeb\x81\xb2\xf1\xc9\x72\x4e\x82\x2e\xca\x76\xdb\x86\x18\xcf\x09\xc5\x34\x35\x03\xa4\x36\x08\x35\xb5\x90\x3b\xc6\x37\xe3\x87\x9f\xb0\x5e\x0e\xf3\x26\x85\xd5\xae\xc5\x06\x7c\xd7\xcc\x96\xfe\x4b\x26\x70\xb6\xea\xc3\x06\x6b\x1f\xcf\x56\x86\xb6\x85\x89\xaa\xfb\x7d\x62\x9b\x02\xd8\xf8\x62\x5c\xa3\x83\x36\x24\xd4\x80\x0f\xb0\x81\xb1\xcf\x94\xeb" } , VectorOAEP { message = "\x52\xe6\x50\xd9\x8e\x7f\x2a\x04\x8b\x4f\x86\x85\x21\x53\xb9\x7e\x01\xdd\x31\x6f\x34\x6a\x19\xf6\x7a\x85" , seed = "\xc4\x43\x5a\x3e\x1a\x18\xa6\x8b\x68\x20\x43\x62\x90\xa3\x7c\xef\xb8\x5d\xb3\xfb" , cipherText = "\x45\xea\xd4\xca\x55\x1e\x66\x2c\x98\x00\xf1\xac\xa8\x28\x3b\x05\x25\xe6\xab\xae\x30\xbe\x4b\x4a\xba\x76\x2f\xa4\x0f\xd3\xd3\x8e\x22\xab\xef\xc6\x97\x94\xf6\xeb\xbb\xc0\x5d\xdb\xb1\x12\x16\x24\x7d\x2f\x41\x2f\xd0\xfb\xa8\x7c\x6e\x3a\xcd\x88\x88\x13\x64\x6f\xd0\xe4\x8e\x78\x52\x04\xf9\xc3\xf7\x3d\x6d\x82\x39\x56\x27\x22\xdd\xdd\x87\x71\xfe\xc4\x8b\x83\xa3\x1e\xe6\xf5\x92\xc4\xcf\xd4\xbc\x88\x17\x4f\x3b\x13\xa1\x12\xaa\xe3\xb9\xf7\xb8\x0e\x0f\xc6\xf7\x25\x5b\xa8\x80\xdc\x7d\x80\x21\xe2\x2a\xd6\xa8\x5f\x07\x55" } , VectorOAEP { message = "\x8d\xa8\x9f\xd9\xe5\xf9\x74\xa2\x9f\xef\xfb\x46\x2b\x49\x18\x0f\x6c\xf9\xe8\x02" , seed = "\xb3\x18\xc4\x2d\xf3\xbe\x0f\x83\xfe\xa8\x23\xf5\xa7\xb4\x7e\xd5\xe4\x25\xa3\xb5" , cipherText = "\x36\xf6\xe3\x4d\x94\xa8\xd3\x4d\xaa\xcb\xa3\x3a\x21\x39\xd0\x0a\xd8\x5a\x93\x45\xa8\x60\x51\xe7\x30\x71\x62\x00\x56\xb9\x20\xe2\x19\x00\x58\x55\xa2\x13\xa0\xf2\x38\x97\xcd\xcd\x73\x1b\x45\x25\x7c\x77\x7f\xe9\x08\x20\x2b\xef\xdd\x0b\x58\x38\x6b\x12\x44\xea\x0c\xf5\x39\xa0\x5d\x5d\x10\x32\x9d\xa4\x4e\x13\x03\x0f\xd7\x60\xdc\xd6\x44\xcf\xef\x20\x94\xd1\x91\x0d\x3f\x43\x3e\x1c\x7c\x6d\xd1\x8b\xc1\xf2\xdf\x7f\x64\x3d\x66\x2f\xb9\xdd\x37\xea\xd9\x05\x91\x90\xf4\xfa\x66\xca\x39\xe8\x69\xc4\xeb\x44\x9c\xbd\xc4\x39" } , VectorOAEP -- 1.6 { message = "\x26\x52\x10\x50\x84\x42\x71" , seed = "\xe4\xec\x09\x82\xc2\x33\x6f\x3a\x67\x7f\x6a\x35\x61\x74\xeb\x0c\xe8\x87\xab\xc2" , cipherText = "\x42\xce\xe2\x61\x7b\x1e\xce\xa4\xdb\x3f\x48\x29\x38\x6f\xbd\x61\xda\xfb\xf0\x38\xe1\x80\xd8\x37\xc9\x63\x66\xdf\x24\xc0\x97\xb4\xab\x0f\xac\x6b\xdf\x59\x0d\x82\x1c\x9f\x10\x64\x2e\x68\x1a\xd0\x5b\x8d\x78\xb3\x78\xc0\xf4\x6c\xe2\xfa\xd6\x3f\x74\xe0\xad\x3d\xf0\x6b\x07\x5d\x7e\xb5\xf5\x63\x6f\x8d\x40\x3b\x90\x59\xca\x76\x1b\x5c\x62\xbb\x52\xaa\x45\x00\x2e\xa7\x0b\xaa\xce\x08\xde\xd2\x43\xb9\xd8\xcb\xd6\x2a\x68\xad\xe2\x65\x83\x2b\x56\x56\x4e\x43\xa6\xfa\x42\xed\x19\x9a\x09\x97\x69\x74\x2d\xf1\x53\x9e\x82\x55" } ] doEncryptionTest key (i, vec) = testCase (show i) (Right (cipherText vec) @=? actual) where actual = OAEP.encryptWithSeed (seed vec) (OAEP.defaultOAEPParams SHA1) key (message vec) doDecryptionTest key (i, vec) = testCase (show i) (Right (message vec) @=? actual) where actual = OAEP.decrypt Nothing (OAEP.defaultOAEPParams SHA1) key (cipherText vec) oaepTests = testGroup "RSA-OAEP" [ testGroup "internal" [ doEncryptionTest (private_pub rsaKeyInt) (0 :: Int, vectorInt) , doDecryptionTest rsaKeyInt (0 :: Int, vectorInt) ] , testGroup "encryption key 1024 bits" $ map (doEncryptionTest $ private_pub rsaKey1) (zip [katZero..] vectorsKey1) , testGroup "decryption key 1024 bits" $ map (doDecryptionTest rsaKey1) (zip [katZero..] vectorsKey1) ] cryptonite-0.23/tests/KAT_PubKey/PSS.hs0000644000000000000000000006413212510212421016061 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.PSS (pssTests) where import Crypto.PubKey.RSA import qualified Crypto.PubKey.RSA.PSS as PSS import Imports data VectorPSS = VectorPSS { message :: ByteString , salt :: ByteString , signature :: ByteString } rsaKeyInt = PrivateKey { private_pub = PublicKey { public_n = 0xa2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5 , public_e = 0x010001 , public_size = 128 } , private_d = 0x50e2c3e38d886110288dfc68a9533e7e12e27d2aa56d2cdb3fb6efa990bcff29e1d2987fb711962860e7391b1ce01ebadb9e812d2fbdfaf25df4ae26110a6d7a26f0b810f54875e17dd5c9fb6d641761245b81e79f8c88f0e55a6dcd5f133abd35f8f4ec80adf1bf86277a582894cb6ebcd2162f1c7534f1f4947b129151b71 , private_p = 0xd17f655bf27c8b16d35462c905cc04a26f37e2a67fa9c0ce0dced472394a0df743fe7f929e378efdb368eddff453cf007af6d948e0ade757371f8a711e278f6b , private_q = 0xc6d92b6fee7414d1358ce1546fb62987530b90bd15e0f14963a5e2635adb69347ec0c01b2ab1763fd8ac1a592fb22757463a982425bb97a3a437c5bf86d03f2f , private_dP = 0x9d0dbf83e5ce9e4b1754dcd5cd05bcb7b55f1508330ea49f14d4e889550f8256cb5f806dff34b17ada44208853577d08e4262890acf752461cea05547601bc4f , private_dQ = 0x1291a524c6b7c059e90e46dc83b2171eb3fa98818fd179b6c8bf6cecaa476303abf283fe05769cfc495788fe5b1ddfde9e884a3cd5e936b7e955ebf97eb563b1 , private_qinv = 0xa63f1da38b950c9ad1c67ce0d677ec2914cd7d40062df42a67eb198a176f9742aac7c5fea14f2297662b84812c4defc49a8025ab4382286be4c03788dd01d69f } rsaKey1 = PrivateKey { private_pub = PublicKey { public_n = 0xa56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137 , public_e = 0x010001 , public_size = 128 } , private_d = 0x33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325 , private_p = 0xe7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443 , private_q = 0xb69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd , private_dP = 0x28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979 , private_dQ = 0x1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729 , private_qinv = 0x27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d } vectorInt = VectorPSS { message = "\x85\x9e\xef\x2f\xd7\x8a\xca\x00\x30\x8b\xdc\x47\x11\x93\xbf\x55\xbf\x9d\x78\xdb\x8f\x8a\x67\x2b\x48\x46\x34\xf3\xc9\xc2\x6e\x64\x78\xae\x10\x26\x0f\xe0\xdd\x8c\x08\x2e\x53\xa5\x29\x3a\xf2\x17\x3c\xd5\x0c\x6d\x5d\x35\x4f\xeb\xf7\x8b\x26\x02\x1c\x25\xc0\x27\x12\xe7\x8c\xd4\x69\x4c\x9f\x46\x97\x77\xe4\x51\xe7\xf8\xe9\xe0\x4c\xd3\x73\x9c\x6b\xbf\xed\xae\x48\x7f\xb5\x56\x44\xe9\xca\x74\xff\x77\xa5\x3c\xb7\x29\x80\x2f\x6e\xd4\xa5\xff\xa8\xba\x15\x98\x90\xfc" , salt = "\xe3\xb5\xd5\xd0\x02\xc1\xbc\xe5\x0c\x2b\x65\xef\x88\xa1\x88\xd8\x3b\xce\x7e\x61" , signature = "\x8d\xaa\x62\x7d\x3d\xe7\x59\x5d\x63\x05\x6c\x7e\xc6\x59\xe5\x44\x06\xf1\x06\x10\x12\x8b\xaa\xe8\x21\xc8\xb2\xa0\xf3\x93\x6d\x54\xdc\x3b\xdc\xe4\x66\x89\xf6\xb7\x95\x1b\xb1\x8e\x84\x05\x42\x76\x97\x18\xd5\x71\x5d\x21\x0d\x85\xef\xbb\x59\x61\x92\x03\x2c\x42\xbe\x4c\x29\x97\x2c\x85\x62\x75\xeb\x6d\x5a\x45\xf0\x5f\x51\x87\x6f\xc6\x74\x3d\xed\xdd\x28\xca\xec\x9b\xb3\x0e\xa9\x9e\x02\xc3\x48\x82\x69\x60\x4f\xe4\x97\xf7\x4c\xcd\x7c\x7f\xca\x16\x71\x89\x71\x23\xcb\xd3\x0d\xef\x5d\x54\xa2\xb5\x53\x6a\xd9\x0a\x74\x7e" } {- # mHash = Hash(M) # salt = random string of octets # M' = Padding || mHash || salt # H = Hash(M') # DB = Padding || salt # dbMask = MGF(H, length(DB)) # maskedDB = DB xor dbMask (leftmost bit set to # zero) # EM = maskedDB || H || 0xbc # mHash: 37 b6 6a e0 44 58 43 35 3d 47 ec b0 b4 fd 14 c1 10 e6 2d 6a # salt: # M': 00 00 00 00 00 00 00 00 37 b6 6a e0 44 58 43 35 3d 47 ec b0 b4 fd 14 c1 10 e6 2d 6a e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8 3b ce 7e 61 # H: df 1a 89 6f 9d 8b c8 16 d9 7c d7 a2 c4 3b ad 54 6f be 8c fe # DB: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8 3b ce 7e 61 # dbMask: 66 e4 67 2e 83 6a d1 21 ba 24 4b ed 65 76 b8 67 d9 a4 47 c2 8a 6e 66 a5 b8 7d ee 7f bc 7e 65 af 50 57 f8 6f ae 89 84 d9 ba 7f 96 9a d6 fe 02 a4 d7 5f 74 45 fe fd d8 5b 6d 3a 47 7c 28 d2 4b a1 e3 75 6f 79 2d d1 dc e8 ca 94 44 0e cb 52 79 ec d3 18 3a 31 1f c8 97 39 a9 66 43 13 6e 8b 0f 46 5e 87 a4 53 5c d4 c5 9b 10 02 8d # maskedDB: 66 e4 67 2e 83 6a d1 21 ba 24 4b ed 65 76 b8 67 d9 a4 47 c2 8a 6e 66 a5 b8 7d ee 7f bc 7e 65 af 50 57 f8 6f ae 89 84 d9 ba 7f 96 9a d6 fe 02 a4 d7 5f 74 45 fe fd d8 5b 6d 3a 47 7c 28 d2 4b a1 e3 75 6f 79 2d d1 dc e8 ca 94 44 0e cb 52 79 ec d3 18 3a 31 1f c8 96 da 1c b3 93 11 af 37 ea 4a 75 e2 4b db fd 5c 1d a0 de 7c ec # Encoded message EM: 66 e4 67 2e 83 6a d1 21 ba 24 4b ed 65 76 b8 67 d9 a4 47 c2 8a 6e 66 a5 b8 7d ee 7f bc 7e 65 af 50 57 f8 6f ae 89 84 d9 ba 7f 96 9a d6 fe 02 a4 d7 5f 74 45 fe fd d8 5b 6d 3a 47 7c 28 d2 4b a1 e3 75 6f 79 2d d1 dc e8 ca 94 44 0e cb 52 79 ec d3 18 3a 31 1f c8 96 da 1c b3 93 11 af 37 ea 4a 75 e2 4b db fd 5c 1d a0 de 7c ec df 1a 89 6f 9d 8b c8 16 d9 7c d7 a2 c4 3b ad 54 6f be 8c fe bc -} vectorsKey1 = [ -- Example 1.1 VectorPSS { message = "\xcd\xc8\x7d\xa2\x23\xd7\x86\xdf\x3b\x45\xe0\xbb\xbc\x72\x13\x26\xd1\xee\x2a\xf8\x06\xcc\x31\x54\x75\xcc\x6f\x0d\x9c\x66\xe1\xb6\x23\x71\xd4\x5c\xe2\x39\x2e\x1a\xc9\x28\x44\xc3\x10\x10\x2f\x15\x6a\x0d\x8d\x52\xc1\xf4\xc4\x0b\xa3\xaa\x65\x09\x57\x86\xcb\x76\x97\x57\xa6\x56\x3b\xa9\x58\xfe\xd0\xbc\xc9\x84\xe8\xb5\x17\xa3\xd5\xf5\x15\xb2\x3b\x8a\x41\xe7\x4a\xa8\x67\x69\x3f\x90\xdf\xb0\x61\xa6\xe8\x6d\xfa\xae\xe6\x44\x72\xc0\x0e\x5f\x20\x94\x57\x29\xcb\xeb\xe7\x7f\x06\xce\x78\xe0\x8f\x40\x98\xfb\xa4\x1f\x9d\x61\x93\xc0\x31\x7e\x8b\x60\xd4\xb6\x08\x4a\xcb\x42\xd2\x9e\x38\x08\xa3\xbc\x37\x2d\x85\xe3\x31\x17\x0f\xcb\xf7\xcc\x72\xd0\xb7\x1c\x29\x66\x48\xb3\xa4\xd1\x0f\x41\x62\x95\xd0\x80\x7a\xa6\x25\xca\xb2\x74\x4f\xd9\xea\x8f\xd2\x23\xc4\x25\x37\x02\x98\x28\xbd\x16\xbe\x02\x54\x6f\x13\x0f\xd2\xe3\x3b\x93\x6d\x26\x76\xe0\x8a\xed\x1b\x73\x31\x8b\x75\x0a\x01\x67\xd0" , salt = "\xde\xe9\x59\xc7\xe0\x64\x11\x36\x14\x20\xff\x80\x18\x5e\xd5\x7f\x3e\x67\x76\xaf" , signature = "\x90\x74\x30\x8f\xb5\x98\xe9\x70\x1b\x22\x94\x38\x8e\x52\xf9\x71\xfa\xac\x2b\x60\xa5\x14\x5a\xf1\x85\xdf\x52\x87\xb5\xed\x28\x87\xe5\x7c\xe7\xfd\x44\xdc\x86\x34\xe4\x07\xc8\xe0\xe4\x36\x0b\xc2\x26\xf3\xec\x22\x7f\x9d\x9e\x54\x63\x8e\x8d\x31\xf5\x05\x12\x15\xdf\x6e\xbb\x9c\x2f\x95\x79\xaa\x77\x59\x8a\x38\xf9\x14\xb5\xb9\xc1\xbd\x83\xc4\xe2\xf9\xf3\x82\xa0\xd0\xaa\x35\x42\xff\xee\x65\x98\x4a\x60\x1b\xc6\x9e\xb2\x8d\xeb\x27\xdc\xa1\x2c\x82\xc2\xd4\xc3\xf6\x6c\xd5\x00\xf1\xff\x2b\x99\x4d\x8a\x4e\x30\xcb\xb3\x3c" } -- Example 1.2 , VectorPSS { message = "\x85\x13\x84\xcd\xfe\x81\x9c\x22\xed\x6c\x4c\xcb\x30\xda\xeb\x5c\xf0\x59\xbc\x8e\x11\x66\xb7\xe3\x53\x0c\x4c\x23\x3e\x2b\x5f\x8f\x71\xa1\xcc\xa5\x82\xd4\x3e\xcc\x72\xb1\xbc\xa1\x6d\xfc\x70\x13\x22\x6b\x9e" , salt = "\xef\x28\x69\xfa\x40\xc3\x46\xcb\x18\x3d\xab\x3d\x7b\xff\xc9\x8f\xd5\x6d\xf4\x2d" , signature = "\x3e\xf7\xf4\x6e\x83\x1b\xf9\x2b\x32\x27\x41\x42\xa5\x85\xff\xce\xfb\xdc\xa7\xb3\x2a\xe9\x0d\x10\xfb\x0f\x0c\x72\x99\x84\xf0\x4e\xf2\x9a\x9d\xf0\x78\x07\x75\xce\x43\x73\x9b\x97\x83\x83\x90\xdb\x0a\x55\x05\xe6\x3d\xe9\x27\x02\x8d\x9d\x29\xb2\x19\xca\x2c\x45\x17\x83\x25\x58\xa5\x5d\x69\x4a\x6d\x25\xb9\xda\xb6\x60\x03\xc4\xcc\xcd\x90\x78\x02\x19\x3b\xe5\x17\x0d\x26\x14\x7d\x37\xb9\x35\x90\x24\x1b\xe5\x1c\x25\x05\x5f\x47\xef\x62\x75\x2c\xfb\xe2\x14\x18\xfa\xfe\x98\xc2\x2c\x4d\x4d\x47\x72\x4f\xdb\x56\x69\xe8\x43" } -- Example 1.3 , VectorPSS { message = "\xa4\xb1\x59\x94\x17\x61\xc4\x0c\x6a\x82\xf2\xb8\x0d\x1b\x94\xf5\xaa\x26\x54\xfd\x17\xe1\x2d\x58\x88\x64\x67\x9b\x54\xcd\x04\xef\x8b\xd0\x30\x12\xbe\x8d\xc3\x7f\x4b\x83\xaf\x79\x63\xfa\xff\x0d\xfa\x22\x54\x77\x43\x7c\x48\x01\x7f\xf2\xbe\x81\x91\xcf\x39\x55\xfc\x07\x35\x6e\xab\x3f\x32\x2f\x7f\x62\x0e\x21\xd2\x54\xe5\xdb\x43\x24\x27\x9f\xe0\x67\xe0\x91\x0e\x2e\x81\xca\x2c\xab\x31\xc7\x45\xe6\x7a\x54\x05\x8e\xb5\x0d\x99\x3c\xdb\x9e\xd0\xb4\xd0\x29\xc0\x6d\x21\xa9\x4c\xa6\x61\xc3\xce\x27\xfa\xe1\xd6\xcb\x20\xf4\x56\x4d\x66\xce\x47\x67\x58\x3d\x0e\x5f\x06\x02\x15\xb5\x90\x17\xbe\x85\xea\x84\x89\x39\x12\x7b\xd8\xc9\xc4\xd4\x7b\x51\x05\x6c\x03\x1c\xf3\x36\xf1\x7c\x99\x80\xf3\xb8\xf5\xb9\xb6\x87\x8e\x8b\x79\x7a\xa4\x3b\x88\x26\x84\x33\x3e\x17\x89\x3f\xe9\xca\xa6\xaa\x29\x9f\x7e\xd1\xa1\x8e\xe2\xc5\x48\x64\xb7\xb2\xb9\x9b\x72\x61\x8f\xb0\x25\x74\xd1\x39\xef\x50\xf0\x19\xc9\xee\xf4\x16\x97\x13\x38\xe7\xd4\x70" , salt = "\x71\x0b\x9c\x47\x47\xd8\x00\xd4\xde\x87\xf1\x2a\xfd\xce\x6d\xf1\x81\x07\xcc\x77" , signature = "\x66\x60\x26\xfb\xa7\x1b\xd3\xe7\xcf\x13\x15\x7c\xc2\xc5\x1a\x8e\x4a\xa6\x84\xaf\x97\x78\xf9\x18\x49\xf3\x43\x35\xd1\x41\xc0\x01\x54\xc4\x19\x76\x21\xf9\x62\x4a\x67\x5b\x5a\xbc\x22\xee\x7d\x5b\xaa\xff\xaa\xe1\xc9\xba\xca\x2c\xc3\x73\xb3\xf3\x3e\x78\xe6\x14\x3c\x39\x5a\x91\xaa\x7f\xac\xa6\x64\xeb\x73\x3a\xfd\x14\xd8\x82\x72\x59\xd9\x9a\x75\x50\xfa\xca\x50\x1e\xf2\xb0\x4e\x33\xc2\x3a\xa5\x1f\x4b\x9e\x82\x82\xef\xdb\x72\x8c\xc0\xab\x09\x40\x5a\x91\x60\x7c\x63\x69\x96\x1b\xc8\x27\x0d\x2d\x4f\x39\xfc\xe6\x12\xb1" } -- Example 1.4 , VectorPSS { message = "\xbc\x65\x67\x47\xfa\x9e\xaf\xb3\xf0" , salt = "\x05\x6f\x00\x98\x5d\xe1\x4d\x8e\xf5\xce\xa9\xe8\x2f\x8c\x27\xbe\xf7\x20\x33\x5e" , signature = "\x46\x09\x79\x3b\x23\xe9\xd0\x93\x62\xdc\x21\xbb\x47\xda\x0b\x4f\x3a\x76\x22\x64\x9a\x47\xd4\x64\x01\x9b\x9a\xea\xfe\x53\x35\x9c\x17\x8c\x91\xcd\x58\xba\x6b\xcb\x78\xbe\x03\x46\xa7\xbc\x63\x7f\x4b\x87\x3d\x4b\xab\x38\xee\x66\x1f\x19\x96\x34\xc5\x47\xa1\xad\x84\x42\xe0\x3d\xa0\x15\xb1\x36\xe5\x43\xf7\xab\x07\xc0\xc1\x3e\x42\x25\xb8\xde\x8c\xce\x25\xd4\xf6\xeb\x84\x00\xf8\x1f\x7e\x18\x33\xb7\xee\x6e\x33\x4d\x37\x09\x64\xca\x79\xfd\xb8\x72\xb4\xd7\x52\x23\xb5\xee\xb0\x81\x01\x59\x1f\xb5\x32\xd1\x55\xa6\xde\x87" } -- Example 1.5 , VectorPSS { message = "\xb4\x55\x81\x54\x7e\x54\x27\x77\x0c\x76\x8e\x8b\x82\xb7\x55\x64\xe0\xea\x4e\x9c\x32\x59\x4d\x6b\xff\x70\x65\x44\xde\x0a\x87\x76\xc7\xa8\x0b\x45\x76\x55\x0e\xee\x1b\x2a\xca\xbc\x7e\x8b\x7d\x3e\xf7\xbb\x5b\x03\xe4\x62\xc1\x10\x47\xea\xdd\x00\x62\x9a\xe5\x75\x48\x0a\xc1\x47\x0f\xe0\x46\xf1\x3a\x2b\xf5\xaf\x17\x92\x1d\xc4\xb0\xaa\x8b\x02\xbe\xe6\x33\x49\x11\x65\x1d\x7f\x85\x25\xd1\x0f\x32\xb5\x1d\x33\xbe\x52\x0d\x3d\xdf\x5a\x70\x99\x55\xa3\xdf\xe7\x82\x83\xb9\xe0\xab\x54\x04\x6d\x15\x0c\x17\x7f\x03\x7f\xdc\xcc\x5b\xe4\xea\x5f\x68\xb5\xe5\xa3\x8c\x9d\x7e\xdc\xcc\xc4\x97\x5f\x45\x5a\x69\x09\xb4" , salt = "\x80\xe7\x0f\xf8\x6a\x08\xde\x3e\xc6\x09\x72\xb3\x9b\x4f\xbf\xdc\xea\x67\xae\x8e" , signature = "\x1d\x2a\xad\x22\x1c\xa4\xd3\x1d\xdf\x13\x50\x92\x39\x01\x93\x98\xe3\xd1\x4b\x32\xdc\x34\xdc\x5a\xf4\xae\xae\xa3\xc0\x95\xaf\x73\x47\x9c\xf0\xa4\x5e\x56\x29\x63\x5a\x53\xa0\x18\x37\x76\x15\xb1\x6c\xb9\xb1\x3b\x3e\x09\xd6\x71\xeb\x71\xe3\x87\xb8\x54\x5c\x59\x60\xda\x5a\x64\x77\x6e\x76\x8e\x82\xb2\xc9\x35\x83\xbf\x10\x4c\x3f\xdb\x23\x51\x2b\x7b\x4e\x89\xf6\x33\xdd\x00\x63\xa5\x30\xdb\x45\x24\xb0\x1c\x3f\x38\x4c\x09\x31\x0e\x31\x5a\x79\xdc\xd3\xd6\x84\x02\x2a\x7f\x31\xc8\x65\xa6\x64\xe3\x16\x97\x8b\x75\x9f\xad" } -- Example 1.6 , VectorPSS { message = "\x10\xaa\xe9\xa0\xab\x0b\x59\x5d\x08\x41\x20\x7b\x70\x0d\x48\xd7\x5f\xae\xdd\xe3\xb7\x75\xcd\x6b\x4c\xc8\x8a\xe0\x6e\x46\x94\xec\x74\xba\x18\xf8\x52\x0d\x4f\x5e\xa6\x9c\xbb\xe7\xcc\x2b\xeb\xa4\x3e\xfd\xc1\x02\x15\xac\x4e\xb3\x2d\xc3\x02\xa1\xf5\x3d\xc6\xc4\x35\x22\x67\xe7\x93\x6c\xfe\xbf\x7c\x8d\x67\x03\x57\x84\xa3\x90\x9f\xa8\x59\xc7\xb7\xb5\x9b\x8e\x39\xc5\xc2\x34\x9f\x18\x86\xb7\x05\xa3\x02\x67\xd4\x02\xf7\x48\x6a\xb4\xf5\x8c\xad\x5d\x69\xad\xb1\x7a\xb8\xcd\x0c\xe1\xca\xf5\x02\x5a\xf4\xae\x24\xb1\xfb\x87\x94\xc6\x07\x0c\xc0\x9a\x51\xe2\xf9\x91\x13\x11\xe3\x87\x7d\x00\x44\xc7\x1c\x57\xa9\x93\x39\x50\x08\x80\x6b\x72\x3a\xc3\x83\x73\xd3\x95\x48\x18\x18\x52\x8c\x1e\x70\x53\x73\x92\x82\x05\x35\x29\x51\x0e\x93\x5c\xd0\xfa\x77\xb8\xfa\x53\xcc\x2d\x47\x4b\xd4\xfb\x3c\xc5\xc6\x72\xd6\xff\xdc\x90\xa0\x0f\x98\x48\x71\x2c\x4b\xcf\xe4\x6c\x60\x57\x36\x59\xb1\x1e\x64\x57\xe8\x61\xf0\xf6\x04\xb6\x13\x8d\x14\x4f\x8c\xe4\xe2\xda\x73" , salt = "\xa8\xab\x69\xdd\x80\x1f\x00\x74\xc2\xa1\xfc\x60\x64\x98\x36\xc6\x16\xd9\x96\x81" , signature = "\x2a\x34\xf6\x12\x5e\x1f\x6b\x0b\xf9\x71\xe8\x4f\xbd\x41\xc6\x32\xbe\x8f\x2c\x2a\xce\x7d\xe8\xb6\x92\x6e\x31\xff\x93\xe9\xaf\x98\x7f\xbc\x06\xe5\x1e\x9b\xe1\x4f\x51\x98\xf9\x1f\x3f\x95\x3b\xd6\x7d\xa6\x0a\x9d\xf5\x97\x64\xc3\xdc\x0f\xe0\x8e\x1c\xbe\xf0\xb7\x5f\x86\x8d\x10\xad\x3f\xba\x74\x9f\xef\x59\xfb\x6d\xac\x46\xa0\xd6\xe5\x04\x36\x93\x31\x58\x6f\x58\xe4\x62\x8f\x39\xaa\x27\x89\x82\x54\x3b\xc0\xee\xb5\x37\xdc\x61\x95\x80\x19\xb3\x94\xfb\x27\x3f\x21\x58\x58\xa0\xa0\x1a\xc4\xd6\x50\xb9\x55\xc6\x7f\x4c\x58" } ] {- # =================================== # Example 10: A 2048-bit RSA Key Pair # =================================== # ------------------------------ # Components of the RSA Key Pair # ------------------------------ # RSA modulus n: a5 dd 86 7a c4 cb 02 f9 0b 94 57 d4 8c 14 a7 70 ef 99 1c 56 c3 9c 0e c6 5f d1 1a fa 89 37 ce a5 7b 9b e7 ac 73 b4 5c 00 17 61 5b 82 d6 22 e3 18 75 3b 60 27 c0 fd 15 7b e1 2f 80 90 fe e2 a7 ad cd 0e ef 75 9f 88 ba 49 97 c7 a4 2d 58 c9 aa 12 cb 99 ae 00 1f e5 21 c1 3b b5 43 14 45 a8 d5 ae 4f 5e 4c 7e 94 8a c2 27 d3 60 40 71 f2 0e 57 7e 90 5f be b1 5d fa f0 6d 1d e5 ae 62 53 d6 3a 6a 21 20 b3 1a 5d a5 da bc 95 50 60 0e 20 f2 7d 37 39 e2 62 79 25 fe a3 cc 50 9f 21 df f0 4e 6e ea 45 49 c5 40 d6 80 9f f9 30 7e ed e9 1f ff 58 73 3d 83 85 a2 37 d6 d3 70 5a 33 e3 91 90 09 92 07 0d f7 ad f1 35 7c f7 e3 70 0c e3 66 7d e8 3f 17 b8 df 17 78 db 38 1d ce 09 cb 4a d0 58 a5 11 00 1a 73 81 98 ee 27 cf 55 a1 3b 75 45 39 90 65 82 ec 8b 17 4b d5 8d 5d 1f 3d 76 7c 61 37 21 ae 05 # RSA public exponent e: 01 00 01 # RSA private exponent d: 2d 2f f5 67 b3 fe 74 e0 61 91 b7 fd ed 6d e1 12 29 0c 67 06 92 43 0d 59 69 18 40 47 da 23 4c 96 93 de ed 16 73 ed 42 95 39 c9 69 d3 72 c0 4d 6b 47 e0 f5 b8 ce e0 84 3e 5c 22 83 5d bd 3b 05 a0 99 79 84 ae 60 58 b1 1b c4 90 7c bf 67 ed 84 fa 9a e2 52 df b0 d0 cd 49 e6 18 e3 5d fd fe 59 bc a3 dd d6 6c 33 ce bb c7 7a d4 41 aa 69 5e 13 e3 24 b5 18 f0 1c 60 f5 a8 5c 99 4a d1 79 f2 a6 b5 fb e9 34 02 b1 17 67 be 01 bf 07 34 44 d6 ba 1d d2 bc a5 bd 07 4d 4a 5f ae 35 31 ad 13 03 d8 4b 30 d8 97 31 8c bb ba 04 e0 3c 2e 66 de 6d 91 f8 2f 96 ea 1d 4b b5 4a 5a ae 10 2d 59 46 57 f5 c9 78 95 53 51 2b 29 6d ea 29 d8 02 31 96 35 7e 3e 3a 6e 95 8f 39 e3 c2 34 40 38 ea 60 4b 31 ed c6 f0 f7 ff 6e 71 81 a5 7c 92 82 6a 26 8f 86 76 8e 96 f8 78 56 2f c7 1d 85 d6 9e 44 86 12 f7 04 8f # Prime p: cf d5 02 83 fe ee b9 7f 6f 08 d7 3c bc 7b 38 36 f8 2b bc d4 99 47 9f 5e 6f 76 fd fc b8 b3 8c 4f 71 dc 9e 88 bd 6a 6f 76 37 1a fd 65 d2 af 18 62 b3 2a fb 34 a9 5f 71 b8 b1 32 04 3f fe be 3a 95 2b af 75 92 44 81 48 c0 3f 9c 69 b1 d6 8e 4c e5 cf 32 c8 6b af 46 fe d3 01 ca 1a b4 03 06 9b 32 f4 56 b9 1f 71 89 8a b0 81 cd 8c 42 52 ef 52 71 91 5c 97 94 b8 f2 95 85 1d a7 51 0f 99 cb 73 eb # Prime q: cc 4e 90 d2 a1 b3 a0 65 d3 b2 d1 f5 a8 fc e3 1b 54 44 75 66 4e ab 56 1d 29 71 b9 9f b7 be f8 44 e8 ec 1f 36 0b 8c 2a c8 35 96 92 97 1e a6 a3 8f 72 3f cc 21 1f 5d bc b1 77 a0 fd ac 51 64 a1 d4 ff 7f bb 4e 82 99 86 35 3c b9 83 65 9a 14 8c dd 42 0c 7d 31 ba 38 22 ea 90 a3 2b e4 6c 03 0e 8c 17 e1 fa 0a d3 78 59 e0 6b 0a a6 fa 3b 21 6d 9c be 6c 0e 22 33 97 69 c0 a6 15 91 3e 5d a7 19 cf # p's CRT exponent dP: 1c 2d 1f c3 2f 6b c4 00 4f d8 5d fd e0 fb bf 9a 4c 38 f9 c7 c4 e4 1d ea 1a a8 82 34 a2 01 cd 92 f3 b7 da 52 65 83 a9 8a d8 5b b3 60 fb 98 3b 71 1e 23 44 9d 56 1d 17 78 d7 a5 15 48 6b cb f4 7b 46 c9 e9 e1 a3 a1 f7 70 00 ef be b0 9a 8a fe 47 e5 b8 57 cd a9 9c b1 6d 7f ff 9b 71 2e 3b d6 0c a9 6d 9c 79 73 d6 16 d4 69 34 a9 c0 50 28 1c 00 43 99 ce ff 1d b7 dd a7 87 66 a8 a9 b9 cb 08 73 # q's CRT exponent dQ: cb 3b 3c 04 ca a5 8c 60 be 7d 9b 2d eb b3 e3 96 43 f4 f5 73 97 be 08 23 6a 1e 9e af aa 70 65 36 e7 1c 3a cf e0 1c c6 51 f2 3c 9e 05 85 8f ee 13 bb 6a 8a fc 47 df 4e dc 9a 4b a3 0b ce cb 73 d0 15 78 52 32 7e e7 89 01 5c 2e 8d ee 7b 9f 05 a0 f3 1a c9 4e b6 17 31 64 74 0c 5c 95 14 7c d5 f3 b5 ae 2c b4 a8 37 87 f0 1d 8a b3 1f 27 c2 d0 ee a2 dd 8a 11 ab 90 6a ba 20 7c 43 c6 ee 12 53 31 # CRT coefficient qInv: 12 f6 b2 cf 13 74 a7 36 fa d0 56 16 05 0f 96 ab 4b 61 d1 17 7c 7f 9d 52 5a 29 f3 d1 80 e7 76 67 e9 9d 99 ab f0 52 5d 07 58 66 0f 37 52 65 5b 0f 25 b8 df 84 31 d9 a8 ff 77 c1 6c 12 a0 a5 12 2a 9f 0b f7 cf d5 a2 66 a3 5c 15 9f 99 12 08 b9 03 16 ff 44 4f 3e 0b 6b d0 e9 3b 8a 7a 24 48 e9 57 e3 dd a6 cf cf 22 66 b1 06 01 3a c4 68 08 d3 b3 88 7b 3b 00 34 4b aa c9 53 0b 4c e7 08 fc 32 b6 # --------------------------------- # RSASSA-PSS Signature Example 10.1 # --------------------------------- # Message to be signed: 88 31 77 e5 12 6b 9b e2 d9 a9 68 03 27 d5 37 0c 6f 26 86 1f 58 20 c4 3d a6 7a 3a d6 09 # Salt: 04 e2 15 ee 6f f9 34 b9 da 70 d7 73 0c 87 34 ab fc ec de 89 # Signature: 82 c2 b1 60 09 3b 8a a3 c0 f7 52 2b 19 f8 73 54 06 6c 77 84 7a bf 2a 9f ce 54 2d 0e 84 e9 20 c5 af b4 9f fd fd ac e1 65 60 ee 94 a1 36 96 01 14 8e ba d7 a0 e1 51 cf 16 33 17 91 a5 72 7d 05 f2 1e 74 e7 eb 81 14 40 20 69 35 d7 44 76 5a 15 e7 9f 01 5c b6 6c 53 2c 87 a6 a0 59 61 c8 bf ad 74 1a 9a 66 57 02 28 94 39 3e 72 23 73 97 96 c0 2a 77 45 5d 0f 55 5b 0e c0 1d df 25 9b 62 07 fd 0f d5 76 14 ce f1 a5 57 3b aa ff 4e c0 00 69 95 16 59 b8 5f 24 30 0a 25 16 0c a8 52 2d c6 e6 72 7e 57 d0 19 d7 e6 36 29 b8 fe 5e 89 e2 5c c1 5b eb 3a 64 75 77 55 92 99 28 0b 9b 28 f7 9b 04 09 00 0b e2 5b bd 96 40 8b a3 b4 3c c4 86 18 4d d1 c8 e6 25 53 fa 1a f4 04 0f 60 66 3d e7 f5 e4 9c 04 38 8e 25 7f 1c e8 9c 95 da b4 8a 31 5d 9b 66 b1 b7 62 82 33 87 6f f2 38 52 30 d0 70 d0 7e 16 66 # --------------------------------- # RSASSA-PSS Signature Example 10.2 # --------------------------------- # Message to be signed: dd 67 0a 01 46 58 68 ad c9 3f 26 13 19 57 a5 0c 52 fb 77 7c db aa 30 89 2c 9e 12 36 11 64 ec 13 97 9d 43 04 81 18 e4 44 5d b8 7b ee 58 dd 98 7b 34 25 d0 20 71 d8 db ae 80 70 8b 03 9d bb 64 db d1 de 56 57 d9 fe d0 c1 18 a5 41 43 74 2e 0f f3 c8 7f 74 e4 58 57 64 7a f3 f7 9e b0 a1 4c 9d 75 ea 9a 1a 04 b7 cf 47 8a 89 7a 70 8f d9 88 f4 8e 80 1e db 0b 70 39 df 8c 23 bb 3c 56 f4 e8 21 ac # Salt: 8b 2b dd 4b 40 fa f5 45 c7 78 dd f9 bc 1a 49 cb 57 f9 b7 1b # Signature: 14 ae 35 d9 dd 06 ba 92 f7 f3 b8 97 97 8a ed 7c d4 bf 5f f0 b5 85 a4 0b d4 6c e1 b4 2c d2 70 30 53 bb 90 44 d6 4e 81 3d 8f 96 db 2d d7 00 7d 10 11 8f 6f 8f 84 96 09 7a d7 5e 1f f6 92 34 1b 28 92 ad 55 a6 33 a1 c5 5e 7f 0a 0a d5 9a 0e 20 3a 5b 82 78 ae c5 4d d8 62 2e 28 31 d8 71 74 f8 ca ff 43 ee 6c 46 44 53 45 d8 4a 59 65 9b fb 92 ec d4 c8 18 66 86 95 f3 47 06 f6 68 28 a8 99 59 63 7f 2b f3 e3 25 1c 24 bd ba 4d 4b 76 49 da 00 22 21 8b 11 9c 84 e7 9a 65 27 ec 5b 8a 5f 86 1c 15 99 52 e2 3e c0 5e 1e 71 73 46 fa ef e8 b1 68 68 25 bd 2b 26 2f b2 53 10 66 c0 de 09 ac de 2e 42 31 69 07 28 b5 d8 5e 11 5a 2f 6b 92 b7 9c 25 ab c9 bd 93 99 ff 8b cf 82 5a 52 ea 1f 56 ea 76 dd 26 f4 3b aa fa 18 bf a9 2a 50 4c bd 35 69 9e 26 d1 dc c5 a2 88 73 85 f3 c6 32 32 f0 6f 32 44 c3 # --------------------------------- # RSASSA-PSS Signature Example 10.3 # --------------------------------- # Message to be signed: 48 b2 b6 a5 7a 63 c8 4c ea 85 9d 65 c6 68 28 4b 08 d9 6b dc aa be 25 2d b0 e4 a9 6c b1 ba c6 01 93 41 db 6f be fb 8d 10 6b 0e 90 ed a6 bc c6 c6 26 2f 37 e7 ea 9c 7e 5d 22 6b d7 df 85 ec 5e 71 ef ff 2f 54 c5 db 57 7f f7 29 ff 91 b8 42 49 1d e2 74 1d 0c 63 16 07 df 58 6b 90 5b 23 b9 1a f1 3d a1 23 04 bf 83 ec a8 a7 3e 87 1f f9 db # Salt: 4e 96 fc 1b 39 8f 92 b4 46 71 01 0c 0d c3 ef d6 e2 0c 2d 73 # Signature: 6e 3e 4d 7b 6b 15 d2 fb 46 01 3b 89 00 aa 5b bb 39 39 cf 2c 09 57 17 98 70 42 02 6e e6 2c 74 c5 4c ff d5 d7 d5 7e fb bf 95 0a 0f 5c 57 4f a0 9d 3f c1 c9 f5 13 b0 5b 4f f5 0d d8 df 7e df a2 01 02 85 4c 35 e5 92 18 01 19 a7 0c e5 b0 85 18 2a a0 2d 9e a2 aa 90 d1 df 03 f2 da ae 88 5b a2 f5 d0 5a fd ac 97 47 6f 06 b9 3b 5b c9 4a 1a 80 aa 91 16 c4 d6 15 f3 33 b0 98 89 2b 25 ff ac e2 66 f5 db 5a 5a 3b cc 10 a8 24 ed 55 aa d3 5b 72 78 34 fb 8c 07 da 28 fc f4 16 a5 d9 b2 22 4f 1f 8b 44 2b 36 f9 1e 45 6f de a2 d7 cf e3 36 72 68 de 03 07 a4 c7 4e 92 41 59 ed 33 39 3d 5e 06 55 53 1c 77 32 7b 89 82 1b de df 88 01 61 c7 8c d4 19 6b 54 19 f7 ac c3 f1 3e 5e bf 16 1b 6e 7c 67 24 71 6c a3 3b 85 c2 e2 56 40 19 2a c2 85 96 51 d5 0b de 7e b9 76 e5 1c ec 82 8b 98 b6 56 3b 86 bb # --------------------------------- # RSASSA-PSS Signature Example 10.4 # --------------------------------- # Message to be signed: 0b 87 77 c7 f8 39 ba f0 a6 4b bb db c5 ce 79 75 5c 57 a2 05 b8 45 c1 74 e2 d2 e9 05 46 a0 89 c4 e6 ec 8a df fa 23 a7 ea 97 ba e6 b6 5d 78 2b 82 db 5d 2b 5a 56 d2 2a 29 a0 5e 7c 44 33 e2 b8 2a 62 1a bb a9 0a dd 05 ce 39 3f c4 8a 84 05 42 45 1a # Salt: c7 cd 69 8d 84 b6 51 28 d8 83 5e 3a 8b 1e b0 e0 1c b5 41 ec # Signature: 34 04 7f f9 6c 4d c0 dc 90 b2 d4 ff 59 a1 a3 61 a4 75 4b 25 5d 2e e0 af 7d 8b f8 7c 9b c9 e7 dd ee de 33 93 4c 63 ca 1c 0e 3d 26 2c b1 45 ef 93 2a 1f 2c 0a 99 7a a6 a3 4f 8e ae e7 47 7d 82 cc f0 90 95 a6 b8 ac ad 38 d4 ee c9 fb 7e ab 7a d0 2d a1 d1 1d 8e 54 c1 82 5e 55 bf 58 c2 a2 32 34 b9 02 be 12 4f 9e 90 38 a8 f6 8f a4 5d ab 72 f6 6e 09 45 bf 1d 8b ac c9 04 4c 6f 07 09 8c 9f ce c5 8a 3a ab 10 0c 80 51 78 15 5f 03 0a 12 4c 45 0e 5a cb da 47 d0 e4 f1 0b 80 a2 3f 80 3e 77 4d 02 3b 00 15 c2 0b 9f 9b be 7c 91 29 63 38 d5 ec b4 71 ca fb 03 20 07 b6 7a 60 be 5f 69 50 4a 9f 01 ab b3 cb 46 7b 26 0e 2b ce 86 0b e8 d9 5b f9 2c 0c 8e 14 96 ed 1e 52 85 93 a4 ab b6 df 46 2d de 8a 09 68 df fe 46 83 11 68 57 a2 32 f5 eb f6 c8 5b e2 38 74 5a d0 f3 8f 76 7a 5f db f4 86 fb # --------------------------------- # RSASSA-PSS Signature Example 10.5 # --------------------------------- # Message to be signed: f1 03 6e 00 8e 71 e9 64 da dc 92 19 ed 30 e1 7f 06 b4 b6 8a 95 5c 16 b3 12 b1 ed df 02 8b 74 97 6b ed 6b 3f 6a 63 d4 e7 78 59 24 3c 9c cc dc 98 01 65 23 ab b0 24 83 b3 55 91 c3 3a ad 81 21 3b b7 c7 bb 1a 47 0a ab c1 0d 44 25 6c 4d 45 59 d9 16 # Salt: ef a8 bf f9 62 12 b2 f4 a3 f3 71 a1 0d 57 41 52 65 5f 5d fb # Signature: 7e 09 35 ea 18 f4 d6 c1 d1 7c e8 2e b2 b3 83 6c 55 b3 84 58 9c e1 9d fe 74 33 63 ac 99 48 d1 f3 46 b7 bf dd fe 92 ef d7 8a db 21 fa ef c8 9a de 42 b1 0f 37 40 03 fe 12 2e 67 42 9a 1c b8 cb d1 f8 d9 01 45 64 c4 4d 12 01 16 f4 99 0f 1a 6e 38 77 4c 19 4b d1 b8 21 32 86 b0 77 b0 49 9d 2e 7b 3f 43 4a b1 22 89 c5 56 68 4d ee d7 81 31 93 4b b3 dd 65 37 23 6f 7c 6f 3d cb 09 d4 76 be 07 72 1e 37 e1 ce ed 9b 2f 7b 40 68 87 bd 53 15 73 05 e1 c8 b4 f8 4d 73 3b c1 e1 86 fe 06 cc 59 b6 ed b8 f4 bd 7f fe fd f4 f7 ba 9c fb 9d 57 06 89 b5 a1 a4 10 9a 74 6a 69 08 93 db 37 99 25 5a 0c b9 21 5d 2d 1c d4 90 59 0e 95 2e 8c 87 86 aa 00 11 26 52 52 47 0c 04 1d fb c3 ee c7 c3 cb f7 1c 24 86 9d 11 5c 0c b4 a9 56 f5 6d 53 0b 80 ab 58 9a cf ef c6 90 75 1d df 36 e8 d3 83 f8 3c ed d2 cc # --------------------------------- # RSASSA-PSS Signature Example 10.6 # --------------------------------- # Message to be signed: 25 f1 08 95 a8 77 16 c1 37 45 0b b9 51 9d fa a1 f2 07 fa a9 42 ea 88 ab f7 1e 9c 17 98 00 85 b5 55 ae ba b7 62 64 ae 2a 3a b9 3c 2d 12 98 11 91 dd ac 6f b5 94 9e b3 6a ee 3c 5d a9 40 f0 07 52 c9 16 d9 46 08 fa 7d 97 ba 6a 29 15 b6 88 f2 03 23 d4 e9 d9 68 01 d8 9a 72 ab 58 92 dc 21 17 c0 74 34 fc f9 72 e0 58 cf 8c 41 ca 4b 4f f5 54 f7 d5 06 8a d3 15 5f ce d0 f3 12 5b c0 4f 91 93 37 8a 8f 5c 4c 3b 8c b4 dd 6d 1c c6 9d 30 ec ca 6e aa 51 e3 6a 05 73 0e 9e 34 2e 85 5b af 09 9d ef b8 af d7 # Salt: ad 8b 15 23 70 36 46 22 4b 66 0b 55 08 85 91 7c a2 d1 df 28 # Signature: 6d 3b 5b 87 f6 7e a6 57 af 21 f7 54 41 97 7d 21 80 f9 1b 2c 5f 69 2d e8 29 55 69 6a 68 67 30 d9 b9 77 8d 97 07 58 cc b2 60 71 c2 20 9f fb d6 12 5b e2 e9 6e a8 1b 67 cb 9b 93 08 23 9f da 17 f7 b2 b6 4e cd a0 96 b6 b9 35 64 0a 5a 1c b4 2a 91 55 b1 c9 ef 7a 63 3a 02 c5 9f 0d 6e e5 9b 85 2c 43 b3 50 29 e7 3c 94 0f f0 41 0e 8f 11 4e ed 46 bb d0 fa e1 65 e4 2b e2 52 8a 40 1c 3b 28 fd 81 8e f3 23 2d ca 9f 4d 2a 0f 51 66 ec 59 c4 23 96 d6 c1 1d bc 12 15 a5 6f a1 71 69 db 95 75 34 3e f3 4f 9d e3 2a 49 cd c3 17 49 22 f2 29 c2 3e 18 e4 5d f9 35 31 19 ec 43 19 ce dc e7 a1 7c 64 08 8c 1f 6f 52 be 29 63 41 00 b3 91 9d 38 f3 d1 ed 94 e6 89 1e 66 a7 3b 8f b8 49 f5 87 4d f5 94 59 e2 98 c7 bb ce 2e ee 78 2a 19 5a a6 6f e2 d0 73 2b 25 e5 95 f5 7d 3e 06 1b 1f c3 e4 06 3b f9 8f -} doSignTest key (i, vector) = testCase (show i) (Right (signature vector) @=? actual) where actual = PSS.signWithSalt (salt vector) Nothing PSS.defaultPSSParamsSHA1 key (message vector) doVerifyTest key (i, vector) = testCase (show i) (True @=? actual) where actual = PSS.verify PSS.defaultPSSParamsSHA1 (private_pub key) (message vector) (signature vector) pssTests = testGroup "RSA-PSS" [ testGroup "signature internal" [ doSignTest rsaKeyInt (katZero, vectorInt) ] , testGroup "verify internal" [ doVerifyTest rsaKeyInt (katZero, vectorInt) ] , testGroup "signature key 1024" $ map (doSignTest rsaKey1) (zip [katZero..] vectorsKey1) , testGroup "verify key 1024" $ map (doVerifyTest rsaKey1) (zip [katZero..] vectorsKey1) ] cryptonite-0.23/tests/KAT_PubKey/P256.hs0000644000000000000000000001426313020314275016057 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} module KAT_PubKey.P256 (tests) where import qualified Crypto.PubKey.ECC.Types as ECC import qualified Crypto.PubKey.ECC.Prim as ECC import qualified Crypto.PubKey.ECC.P256 as P256 import Data.ByteArray (Bytes) import Crypto.Number.Serialize (i2ospOf, os2ip) import Crypto.Number.ModArithmetic (inverseCoprimes) import Crypto.Error import Imports newtype P256Scalar = P256Scalar Integer deriving (Show,Eq,Ord) instance Arbitrary P256Scalar where arbitrary = P256Scalar . getQAInteger <$> arbitrary curve = ECC.getCurveByName ECC.SEC_p256r1 curveN = ECC.ecc_n . ECC.common_curve $ curve curveGen = ECC.ecc_g . ECC.common_curve $ curve pointP256ToECC :: P256.Point -> ECC.Point pointP256ToECC = uncurry ECC.Point . P256.pointToIntegers unP256Scalar :: P256Scalar -> P256.Scalar unP256Scalar (P256Scalar r') = let r = if r' == 0 then 0x2901 else (r' `mod` curveN) rBytes = i2ospScalar r in case P256.scalarFromBinary rBytes of CryptoFailed err -> error ("cannot convert scalar: " ++ show err) CryptoPassed scalar -> scalar where i2ospScalar :: Integer -> Bytes i2ospScalar i = case i2ospOf 32 i of Nothing -> error "invalid size of P256 scalar" Just b -> b unP256 :: P256Scalar -> Integer unP256 (P256Scalar r') = if r' == 0 then 0x2901 else (r' `mod` curveN) p256ScalarToInteger :: P256.Scalar -> Integer p256ScalarToInteger s = os2ip (P256.scalarToBinary s :: Bytes) xS = 0xde2444bebc8d36e682edd27e0f271508617519b3221a8fa0b77cab3989da97c9 yS = 0xc093ae7ff36e5380fc01a5aad1e66659702de80f53cec576b6350b243042a256 xT = 0x55a8b00f8da1d44e62f6b3b25316212e39540dc861c89575bb8cf92e35e0986b yT = 0x5421c3209c2d6c704835d82ac4c3dd90f61a8a52598b9e7ab656e9d8c8b24316 xR = 0x72b13dd4354b6b81745195e98cc5ba6970349191ac476bd4553cf35a545a067e yR = 0x8d585cbb2e1327d75241a8a122d7620dc33b13315aa5c9d46d013011744ac264 tests = testGroup "P256" [ testGroup "scalar" [ testProperty "marshalling" $ \(QAInteger r') -> let r = r' `mod` curveN rBytes = i2ospScalar r in case P256.scalarFromBinary rBytes of CryptoFailed err -> error (show err) CryptoPassed scalar -> rBytes `propertyEq` P256.scalarToBinary scalar , testProperty "add" $ \r1 r2 -> let r = (unP256 r1 + unP256 r2) `mod` curveN r' = P256.scalarAdd (unP256Scalar r1) (unP256Scalar r2) in r `propertyEq` p256ScalarToInteger r' , testProperty "add0" $ \r -> let v = unP256 r v' = P256.scalarAdd (unP256Scalar r) P256.scalarZero in v `propertyEq` p256ScalarToInteger v' , testProperty "add-n-1" $ \r -> let nm1 = throwCryptoError $ P256.scalarFromInteger (curveN - 1) v = unP256 r v' = P256.scalarAdd (unP256Scalar r) nm1 in (((curveN - 1) + v) `mod` curveN) `propertyEq` p256ScalarToInteger v' , testProperty "sub" $ \r1 r2 -> let r = (unP256 r1 - unP256 r2) `mod` curveN r' = P256.scalarSub (unP256Scalar r1) (unP256Scalar r2) v = (unP256 r2 - unP256 r1) `mod` curveN v' = P256.scalarSub (unP256Scalar r2) (unP256Scalar r1) in propertyHold [ eqTest "r1-r2" r (p256ScalarToInteger r') , eqTest "r2-r1" v (p256ScalarToInteger v') ] , testProperty "sub-n-1" $ \r -> let nm1 = throwCryptoError $ P256.scalarFromInteger (curveN - 1) v = unP256 r v' = P256.scalarSub (unP256Scalar r) nm1 in ((v - (curveN - 1)) `mod` curveN) `propertyEq` p256ScalarToInteger v' , testProperty "inv" $ \r' -> let inv = inverseCoprimes (unP256 r') curveN inv' = P256.scalarInv (unP256Scalar r') in if unP256 r' == 0 then True else inv `propertyEq` p256ScalarToInteger inv' ] , testGroup "point" [ testProperty "marshalling" $ \rx ry -> let p = P256.pointFromIntegers (unP256 rx, unP256 ry) b = P256.pointToBinary p :: Bytes p' = P256.pointFromBinary b in propertyHold [ eqTest "point" (CryptoPassed p) p' ] , testProperty "marshalling-integer" $ \rx ry -> let p = P256.pointFromIntegers (unP256 rx, unP256 ry) (x,y) = P256.pointToIntegers p in propertyHold [ eqTest "x" (unP256 rx) x, eqTest "y" (unP256 ry) y ] , testCase "valid-point-1" $ casePointIsValid (xS,yS) , testCase "valid-point-2" $ casePointIsValid (xR,yR) , testCase "valid-point-3" $ casePointIsValid (xT,yT) , testCase "point-add-1" $ let s = P256.pointFromIntegers (xS, yS) t = P256.pointFromIntegers (xT, yT) r = P256.pointFromIntegers (xR, yR) in r @=? P256.pointAdd s t , testProperty "lift-to-curve" $ propertyLiftToCurve , testProperty "point-add" $ propertyPointAdd ] ] where casePointIsValid pointTuple = let s = P256.pointFromIntegers pointTuple in True @=? P256.pointIsValid s propertyLiftToCurve r = let p = P256.toPoint (unP256Scalar r) (x,y) = P256.pointToIntegers p pEcc = ECC.pointMul curve (unP256 r) curveGen in pEcc `propertyEq` ECC.Point x y propertyPointAdd r1 r2 = let p1 = P256.toPoint (unP256Scalar r1) p2 = P256.toPoint (unP256Scalar r2) pe1 = ECC.pointMul curve (unP256 r1) curveGen pe2 = ECC.pointMul curve (unP256 r2) curveGen pR = P256.toPoint (P256.scalarAdd (unP256Scalar r1) (unP256Scalar r2)) peR = ECC.pointAdd curve pe1 pe2 in propertyHold [ eqTest "p256" pR (P256.pointAdd p1 p2) , eqTest "ecc" peR (pointP256ToECC pR) ] i2ospScalar :: Integer -> Bytes i2ospScalar i = case i2ospOf 32 i of Nothing -> error "invalid size of P256 scalar" Just b -> b cryptonite-0.23/tests/KAT_PubKey.hs0000644000000000000000000000276412533034410015424 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey (tests) where import Test.Tasty import Test.Tasty.HUnit import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.ByteString.Char8 () import Crypto.PubKey.MaskGenFunction import Crypto.Hash import KAT_PubKey.OAEP import KAT_PubKey.PSS import KAT_PubKey.DSA import KAT_PubKey.ECC import KAT_PubKey.ECDSA import Utils import qualified KAT_PubKey.P256 as P256 data VectorMgf = VectorMgf { seed :: ByteString , dbMask :: ByteString } doMGFTest (i, vmgf) = testCase (show i) (dbMask vmgf @=? actual) where actual = mgf1 SHA1 (seed vmgf) (B.length $ dbMask vmgf) vectorsMGF = [ VectorMgf { seed = "\xdf\x1a\x89\x6f\x9d\x8b\xc8\x16\xd9\x7c\xd7\xa2\xc4\x3b\xad\x54\x6f\xbe\x8c\xfe" , dbMask = "\x66\xe4\x67\x2e\x83\x6a\xd1\x21\xba\x24\x4b\xed\x65\x76\xb8\x67\xd9\xa4\x47\xc2\x8a\x6e\x66\xa5\xb8\x7d\xee\x7f\xbc\x7e\x65\xaf\x50\x57\xf8\x6f\xae\x89\x84\xd9\xba\x7f\x96\x9a\xd6\xfe\x02\xa4\xd7\x5f\x74\x45\xfe\xfd\xd8\x5b\x6d\x3a\x47\x7c\x28\xd2\x4b\xa1\xe3\x75\x6f\x79\x2d\xd1\xdc\xe8\xca\x94\x44\x0e\xcb\x52\x79\xec\xd3\x18\x3a\x31\x1f\xc8\x97\x39\xa9\x66\x43\x13\x6e\x8b\x0f\x46\x5e\x87\xa4\x53\x5c\xd4\xc5\x9b\x10\x02\x8d" } ] tests = testGroup "PubKey" [ testGroup "MGF1" $ map doMGFTest (zip [katZero..] vectorsMGF) , pssTests , oaepTests , dsaTests , eccTests , ecdsaTests , P256.tests ] --newKats = [ eccKatTests ] cryptonite-0.23/tests/KAT_RC4.hs0000644000000000000000000000155712400310060014603 0ustar0000000000000000{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE OverloadedStrings #-} module KAT_RC4 where import Test.Tasty import Test.Tasty.HUnit import Data.ByteString (ByteString) import Data.ByteString.Char8 () import qualified Crypto.Cipher.RC4 as RC4 -- taken from wikipedia pages vectors :: [(ByteString, ByteString, ByteString)] vectors = [ ("Key" ,"Plaintext" ,"\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3" ) , ("Wiki" ,"pedia" ,"\x10\x21\xBF\x04\x20" ) , ("Secret" ,"Attack at dawn" ,"\x45\xA0\x1F\x64\x5F\xC3\x5B\x38\x35\x52\x54\x4B\x9B\xF5" ) ] tests = testGroup "RC4" $ map toKatTest $ zip is vectors where toKatTest (i, (key, plainText, cipherText)) = testCase (show i) (cipherText @=? snd (RC4.combine (RC4.initialize key) plainText)) is :: [Int] is = [1..] cryptonite-0.23/tests/KAT_Scrypt.hs0000644000000000000000000000355012527635130015514 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Scrypt (tests) where import Data.ByteString (ByteString) import Data.ByteString.Char8 () import Test.Tasty import Test.Tasty.HUnit import Data.Word import qualified Crypto.KDF.Scrypt as Scrypt vectors :: [ ((ByteString, ByteString, Word64, Int, Int, Int), ByteString) ] vectors = [ ( ("", "", 16, 1, 1, 64) , "\x77\xd6\x57\x62\x38\x65\x7b\x20\x3b\x19\xca\x42\xc1\x8a\x04\x97\xf1\x6b\x48\x44\xe3\x07\x4a\xe8\xdf\xdf\xfa\x3f\xed\xe2\x14\x42\xfc\xd0\x06\x9d\xed\x09\x48\xf8\x32\x6a\x75\x3a\x0f\xc8\x1f\x17\xe8\xd3\xe0\xfb\x2e\x0d\x36\x28\xcf\x35\xe2\x0c\x38\xd1\x89\x06" ) , ( ("password", "NaCl", 1024, 8, 16, 64) , "\xfd\xba\xbe\x1c\x9d\x34\x72\x00\x78\x56\xe7\x19\x0d\x01\xe9\xfe\x7c\x6a\xd7\xcb\xc8\x23\x78\x30\xe7\x73\x76\x63\x4b\x37\x31\x62\x2e\xaf\x30\xd9\x2e\x22\xa3\x88\x6f\xf1\x09\x27\x9d\x98\x30\xda\xc7\x27\xaf\xb9\x4a\x83\xee\x6d\x83\x60\xcb\xdf\xa2\xcc\x06\x40" ) , ( ("pleaseletmein", "SodiumChloride", 16384, 8, 1, 64) , "\x70\x23\xbd\xcb\x3a\xfd\x73\x48\x46\x1c\x06\xcd\x81\xfd\x38\xeb\xfd\xa8\xfb\xba\x90\x4f\x8e\x3e\xa9\xb5\x43\xf6\x54\x5d\xa1\xf2\xd5\x43\x29\x55\x61\x3f\x0f\xcf\x62\xd4\x97\x05\x24\x2a\x9a\xf9\xe6\x1e\x85\xdc\x0d\x65\x1e\x40\xdf\xcf\x01\x7b\x45\x57\x58\x87" ) , ( ("pleaseletmein", "SodiumChloride", 1048576, 8, 1, 64) , "\x21\x01\xcb\x9b\x6a\x51\x1a\xae\xad\xdb\xbe\x09\xcf\x70\xf8\x81\xec\x56\x8d\x57\x4a\x2f\xfd\x4d\xab\xe5\xee\x98\x20\xad\xaa\x47\x8e\x56\xfd\x8f\x4b\xa5\xd0\x9f\xfa\x1c\x6d\x92\x7c\x40\xf4\xc3\x37\x30\x40\x49\xe8\xa9\x52\xfb\xcb\xf4\x5c\x6f\xa7\x7a\x41\xa4" ) ] tests = testGroup "Scrypt" $ map toCase $ zip [(1::Int)..] vectors where toCase (i, ((pass,salt,n,r,p,dklen), output)) = testCase (show i) (output @=? Scrypt.generate (Scrypt.Parameters n r p dklen) pass salt) cryptonite-0.23/tests/KAT_TripleDES.hs0000644000000000000000000000047112512146401016012 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} module KAT_TripleDES (tests) where import Imports import BlockCipher import qualified Crypto.Cipher.TripleDES as TripleDES kats = defaultKATs tests = localOption (QuickCheckTests 5) $ testBlockCipher kats (undefined :: TripleDES.DES_EEE3) cryptonite-0.23/tests/KAT_Twofish.hs0000644000000000000000000000554313075454604015663 0ustar0000000000000000module KAT_Twofish (tests) where import Imports import BlockCipher import qualified Data.ByteString as B import Crypto.Cipher.Twofish vectors_twofish128 = [ KAT_ECB (B.replicate 16 0x00) (B.replicate 16 0x00) (B.pack [0x9F,0x58,0x9F,0x5C,0xF6,0x12,0x2C,0x32,0xB6,0xBF,0xEC,0x2F,0x2A,0xE8,0xC3,0x5A]) , KAT_ECB (B.pack [0x9F,0x58,0x9F,0x5C,0xF6,0x12,0x2C,0x32,0xB6,0xBF,0xEC,0x2F,0x2A,0xE8,0xC3,0x5A]) (B.pack [0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19]) (B.pack [0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3]) ] vectors_twofish192 = [ KAT_ECB (B.pack [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]) (B.pack [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) (B.pack [0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48]) , KAT_ECB (B.pack [0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44]) (B.pack [0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2]) (B.pack [0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65])] vectors_twofish256 = [ KAT_ECB (B.pack [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]) (B.pack [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) (B.pack [0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20]) , KAT_ECB (B.pack [0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F]) (B.pack [0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6]) (B.pack [0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA])] kats128 = defaultKATs { kat_ECB = vectors_twofish128 } kats192 = defaultKATs { kat_ECB = vectors_twofish192 } kats256 = defaultKATs { kat_ECB = vectors_twofish256 } tests = testGroup "Twofish" [ testBlockCipher kats128 (undefined :: Twofish128) , testBlockCipher kats192 (undefined :: Twofish192) , testBlockCipher kats256 (undefined :: Twofish256) ] cryptonite-0.23/tests/ChaChaPoly1305.hs0000644000000000000000000001015512673727640016026 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module ChaChaPoly1305 where import qualified Crypto.Cipher.ChaChaPoly1305 as AEAD import Imports import Crypto.Error import Poly1305 () import qualified Data.ByteString as B import qualified Data.ByteArray as B (convert) plaintext, aad, key, iv, ciphertext, tag, nonce1, nonce2, nonce3, nonce4, nonce5, nonce6, nonce7, nonce8, nonce9, nonce10 :: B.ByteString plaintext = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it." aad = "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" iv = "\x40\x41\x42\x43\x44\x45\x46\x47" constant = "\x07\x00\x00\x00" ciphertext = "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b\x61\x16" tag = "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" nonce1 = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce2 = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce3 = "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce4 = "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce5 = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" nonce6 = "\x00\x00\x00\x00\x00\x00\x00\x00" nonce7 = "\x01\x00\x00\x00\x00\x00\x00\x00" nonce8 = "\xff\x00\x00\x00\x00\x00\x00\x00" nonce9 = "\x00\x01\x00\x00\x00\x00\x00\x00" nonce10 = "\xff\xff\xff\xff\xff\xff\xff\xff" tests = testGroup "ChaChaPoly1305" [ testCase "V1" runEncrypt , testCase "V1-decrypt" runDecrypt , testCase "nonce increment" runNonceInc ] where runEncrypt = let ini = throwCryptoError $ AEAD.initialize key (throwCryptoError $ AEAD.nonce8 constant iv) afterAAD = AEAD.finalizeAAD (AEAD.appendAAD aad ini) (out, afterEncrypt) = AEAD.encrypt plaintext afterAAD outtag = AEAD.finalize afterEncrypt in propertyHoldCase [ eqTest "ciphertext" ciphertext out , eqTest "tag" tag (B.convert outtag) ] runDecrypt = let ini = throwCryptoError $ AEAD.initialize key (throwCryptoError $ AEAD.nonce8 constant iv) afterAAD = AEAD.finalizeAAD (AEAD.appendAAD aad ini) (out, afterDecrypt) = AEAD.decrypt ciphertext afterAAD outtag = AEAD.finalize afterDecrypt in propertyHoldCase [ eqTest "plaintext" plaintext out , eqTest "tag" tag (B.convert outtag) ] runNonceInc = let n1 = throwCryptoError . AEAD.nonce12 $ nonce1 n3 = throwCryptoError . AEAD.nonce12 $ nonce3 n5 = throwCryptoError . AEAD.nonce12 $ nonce5 n6 = throwCryptoError . AEAD.nonce8 constant $ nonce6 n8 = throwCryptoError . AEAD.nonce8 constant $ nonce8 n10 = throwCryptoError . AEAD.nonce8 constant $ nonce10 in propertyHoldCase [ eqTest "nonce12a" nonce2 $ B.convert . AEAD.incrementNonce $ n1 , eqTest "nonce12b" nonce4 $ B.convert . AEAD.incrementNonce $ n3 , eqTest "nonce12c" nonce1 $ B.convert . AEAD.incrementNonce $ n5 , eqTest "nonce8a" (B.concat [constant, nonce7]) $ B.convert . AEAD.incrementNonce $ n6 , eqTest "nonce8b" (B.concat [constant, nonce9]) $ B.convert . AEAD.incrementNonce $ n8 , eqTest "nonce8c" (B.concat [constant, nonce6]) $ B.convert . AEAD.incrementNonce $ n10 ] cryptonite-0.23/tests/Number.hs0000644000000000000000000001512213050556742014762 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Number (tests) where import Imports import Data.ByteArray (Bytes) import Crypto.Number.Basic import Crypto.Number.Generate import Crypto.Number.Serialize import Crypto.Number.Prime import Data.Bits serializationVectors :: [(Int, Integer, ByteString)] serializationVectors = [ (128, 468189858948067662094510918729062682059955669513914188715630930503497261316361784677177564296207557978182700664806717692596876084916561811001371208806217360635705059859428069669992937334724312890015700331031248133952795914192719979937664050389500162437642525331653766885896869239678885404647468665996400635, "\x00\xaa\xae\x74\xc8\xec\x3c\x36\x06\x5e\x46\xca\x8e\x57\xab\x09\x87\xfd\xcd\x1f\xa4\xe7\xf9\xd2\x60\xd5\x4a\x1b\x74\xdc\xa8\x75\xd8\xdd\xff\x2b\x74\x28\x14\x59\x67\x6c\x82\xae\xa3\xa5\x1d\x3f\xb4\xb7\xfe\x5c\xd2\xf0\x7f\xd8\xd9\xa9\xb0\xce\x26\xc1\x26\x74\x96\xf5\xf6\x4c\x8f\x66\x7f\x5d\xf1\x68\x38\xd4\x03\x62\xe9\x30\xc8\xa1\xc1\x84\x97\x62\x20\xfd\xd7\x03\x35\xc1\x25\x45\x1b\x86\x81\x3d\xa4\x92\xc0\xd3\xdd\xfa\x86\x1d\xdf\x0a\xbb\xf4\xc0\x56\xf7\xa2\xb0\x3b\x52\xf7\xa5\x89\x4c\x69\x34\x91\x46\xd9\x57\xfb") , (128, 40031303476923779996794876613623495515025748694978019540894726181695410095832601107261950025830235596060960914255795497479135806963313279476038687192202016132891881954743054164975707083302554941058329647014950354509055121290280892911153779672733723699997592027662953953692834215577119173225643193201177329, "\x00\x0e\x97\xf9\xd5\x79\xb9\x90\x7c\x85\x48\x49\x01\x19\x64\xfb\x76\x31\xcd\x51\xfb\x8a\x9d\x55\xe5\xd3\x7b\x87\x2d\xad\x63\x2d\x6b\x1c\x84\x3f\x65\x95\xb6\xf3\x1a\xa9\x43\x3f\x06\x46\x7b\xf8\xf3\x35\x45\x84\x11\x56\x91\x53\x43\xd7\xe1\x6d\x80\x64\x14\x45\x35\x4e\x93\x7d\x5e\x48\xec\xe0\x79\x7b\x44\x8e\xab\x0f\xc4\x5f\xc6\xa1\x71\xee\x37\xb1\x55\x51\x98\x44\x57\xe3\xc3\x56\x3a\x50\x27\xaf\xa5\x1d\x1a\x0a\x90\x19\x0d\x14\xed\x3d\x93\x40\x62\x76\xa3\xaa\x00\x23\x86\xca\x98\xb2\x6e\x02\x43\xa7\xbc\xb1\xb2\xf1") , (128, 75152325976543603337003024341071663845101857195436434620947904288957274825323005869230041326941600298094896018190395352332646796347130114769768242670539699217743549573961461985255265474392937773768121046339453584830072421569334022498680626938734088755136253492360177084153487115846920446085149631919580041, "\x00\x1b\x65\xb1\x73\x74\xed\xd2\xcb\xb8\xf3\x6b\x3f\xc2\x05\xaa\x91\xab\x48\x5b\x03\x30\xae\x24\xa3\xec\x7a\x6a\xf0\x34\x73\x18\x04\xea\xe4\xd6\x19\x97\xc4\xc1\x13\x7d\x12\x0d\xd5\xcb\xbd\x18\x05\xc2\xce\x87\x66\x84\x12\xe8\x24\xa3\x31\x69\xfa\xf4\x2c\x21\x53\xa6\x04\x74\x78\xc4\x93\x0d\x38\x7f\x28\xfe\x80\x8e\xd2\x7b\x20\xc8\xf5\x1f\x0f\x73\x68\xb2\xe5\x08\xf1\x94\xa1\xe6\xcf\x3a\x2c\x12\x63\xda\x08\x3a\x78\x12\xb8\x11\x23\x3c\x38\x38\x10\x94\x2b\xac\x64\x5d\x67\x0c\xb6\x0d\xc3\x9a\x45\x39\x50\x8a\x63\x89") , (128, 132094272981815297755209818914225029878347650582749561568514551350741192910991391836297682842650690115955454061006435646226436379226218676796260483719213285072886626400953065229934239690821114513313427305727000011361769875430428291375851099221794646192854831002408178061474948738788927399080262963320752452, "\x00\x30\x27\xe0\xbf\x46\xec\x77\x2d\xc6\x06\x77\xbc\x68\x87\x3c\x1b\x2e\xc7\xb7\x6c\x88\x25\xec\x8c\x95\xbf\x74\xe5\x37\x01\x25\x96\xe1\x70\x33\x5c\x7d\xab\x1f\xc2\x9c\xad\xf7\xca\x26\x85\x2d\xfc\x8f\xc7\xab\x49\x28\xa4\x47\xe6\xd5\x6e\xfa\x0a\xbb\x57\xe4\xa2\x51\xc7\xc6\x12\x0f\xa9\x98\x69\xb8\x05\x84\xc5\xe3\x28\x86\x0f\x54\x1d\xf9\x92\x42\x9f\xb1\x77\x2b\x58\x89\xe2\xfc\x22\xb0\x1e\x71\x78\xea\x39\xc1\x87\x4f\xd4\x83\x2c\x96\x1d\xea\xd5\xf9\xf9\xb9\x7b\x86\xfa\xf6\xad\x5b\xb1\x3c\xe7\x11\xd7\x96\x89\x44") , (128, 577245873336454863811643140721674509319073059708446946821011267146688442860798353087462545395033001525475835015592425207995480357299993009193426638306801669333644226765032464458284920004140299209138389393494751627076239104390434285377314678827349631962212281858308570255468721491493027423799738158196939966, "\x00\xd2\x70\x41\xdb\x3d\xb5\xfe\x8c\xef\x79\xcf\x5b\x7b\x37\xb0\x05\xb8\x5a\x9b\x7d\x01\x28\xc7\xf5\x5a\x02\xba\xce\xbc\xf5\x8e\x91\x59\xd0\x42\x6f\x04\x82\x4b\x78\xb0\xdd\x91\x2e\x15\x9d\xea\x4f\x0c\x21\xc0\x67\x54\xa2\x39\xa8\xe1\x13\x8f\xa9\xff\x46\x2d\x11\x56\x04\xa0\xde\x64\xc8\x0f\xf4\x2c\xd2\x31\xdf\x2a\xfd\xac\xc7\x25\x58\xc8\xea\xfd\x47\x6e\xdd\x2a\x53\x02\x77\x49\xa7\x0d\x18\xfb\x05\x18\x4b\x28\xd3\xa2\x39\x8c\x83\x80\x90\xd1\xa8\x81\x56\x6f\xd1\x94\x9d\x65\x34\x95\x79\xc1\x27\xbc\x76\xc3\x5c\xbe") ] tests = testGroup "number" [ testProperty "num-bits" $ \(Int1_2901 i) -> and [ (numBits (2^i-1) == i) , (numBits (2^i) == i+1) , (numBits (2^i + (2^i-1)) == i+1) ] , testProperty "num-bits2" $ \(Positive i) -> not (i `testBit` numBits i) && (i `testBit` (numBits i - 1)) , testProperty "generate-param" $ \testDRG (Int1_2901 bits) -> let r = withTestDRG testDRG $ generateParams bits (Just SetHighest) False in r >= 0 && numBits r == bits && testBit r (bits-1) , testProperty "generate-param2" $ \testDRG (Int1_2901 m1bits) -> let bits = m1bits + 1 -- make sure minimum is 2 r = withTestDRG testDRG $ generateParams bits (Just SetTwoHighest) False in r >= 0 && numBits r == bits && testBit r (bits-1) && testBit r (bits-2) , testProperty "generate-param-odd" $ \testDRG (Int1_2901 bits) -> let r = withTestDRG testDRG $ generateParams bits Nothing True in r >= 0 && odd r , testProperty "generate-range" $ \testDRG (Positive range) -> let r = withTestDRG testDRG $ generateMax range in 0 <= r && r < range , testProperty "generate-prime" $ \testDRG (Int0_2901 baseBits') -> let baseBits = baseBits' `mod` 800 bits = 5 + baseBits -- generating lower than 5 bits causes an error .. prime = withTestDRG testDRG $ generatePrime bits in bits == numBits prime , testProperty "generate-safe-prime" $ \testDRG (Int0_2901 baseBits') -> let baseBits = baseBits' `mod` 200 bits = 6 + baseBits prime = withTestDRG testDRG $ generateSafePrime bits in bits == numBits prime , testProperty "marshalling" $ \qaInt -> getQAInteger qaInt == os2ip (i2osp (getQAInteger qaInt) :: Bytes) , testGroup "marshalling-kat-to-bytearray" $ map toSerializationKat $ zip [katZero..] serializationVectors , testGroup "marshalling-kat-to-integer" $ map toSerializationKatInteger $ zip [katZero..] serializationVectors ] where toSerializationKat (i, (sz, n, ba)) = testCase (show i) (ba @=? i2ospOf_ sz n) toSerializationKatInteger (i, (_, n, ba)) = testCase (show i) (n @=? os2ip ba) cryptonite-0.23/tests/Number/F2m.hs0000644000000000000000000000601112746570656015416 0ustar0000000000000000module Number.F2m (tests) where import Imports hiding ((.&.)) import Data.Bits import Crypto.Number.Basic (log2) import Crypto.Number.F2m addTests = testGroup "addF2m" [ testProperty "commutative" $ \a b -> a `addF2m` b == b `addF2m` a , testProperty "associative" $ \a b c -> (a `addF2m` b) `addF2m` c == a `addF2m` (b `addF2m` c) , testProperty "0 is neutral" $ \a -> a `addF2m` 0 == a , testProperty "nullable" $ \a -> a `addF2m` a == 0 , testProperty "works per bit" $ \a b -> (a `addF2m` b) .&. b == (a .&. b) `addF2m` b ] modTests = testGroup "modF2m" [ testProperty "idempotent" $ \(Positive m) (NonNegative a) -> modF2m m a == modF2m m (modF2m m a) , testProperty "upper bound" $ \(Positive m) (NonNegative a) -> modF2m m a < 2 ^ log2 m , testProperty "reach upper" $ \(Positive m) -> let a = 2 ^ log2 m - 1 in modF2m m (m `addF2m` a) == a , testProperty "lower bound" $ \(Positive m) (NonNegative a) -> modF2m m a >= 0 , testProperty "reach lower" $ \(Positive m) -> modF2m m m == 0 , testProperty "additive" $ \(Positive m) (NonNegative a) (NonNegative b) -> modF2m m a `addF2m` modF2m m b == modF2m m (a `addF2m` b) ] mulTests = testGroup "mulF2m" [ testProperty "commutative" $ \(Positive m) (NonNegative a) (NonNegative b) -> mulF2m m a b == mulF2m m b a , testProperty "associative" $ \(Positive m) (NonNegative a) (NonNegative b) (NonNegative c) -> mulF2m m (mulF2m m a b) c == mulF2m m a (mulF2m m b c) , testProperty "1 is neutral" $ \(Positive m) (NonNegative a) -> mulF2m m a 1 == modF2m m a , testProperty "0 is annihilator" $ \(Positive m) (NonNegative a) -> mulF2m m a 0 == 0 , testProperty "distributive" $ \(Positive m) (NonNegative a) (NonNegative b) (NonNegative c) -> mulF2m m a (b `addF2m` c) == mulF2m m a b `addF2m` mulF2m m a c ] squareTests = testGroup "squareF2m" [ testProperty "sqr(a) == a * a" $ \(Positive m) (NonNegative a) -> mulF2m m a a == squareF2m m a ] invTests = testGroup "invF2m" [ testProperty "1 / a * a == 1" $ \(Positive m) (NonNegative a) -> maybe True (\c -> mulF2m m c a == modF2m m 1) (invF2m m a) , testProperty "1 / a == a (mod a^2-1)" $ \(NonNegative a) -> a < 2 || invF2m (squareF2m' a `addF2m` 1) a == Just a ] divTests = testGroup "divF2m" [ testProperty "1 / a == inv a" $ \(Positive m) (NonNegative a) -> divF2m m 1 a == invF2m m a , testProperty "a / b == a * inv b" $ \(Positive m) (NonNegative a) (NonNegative b) -> divF2m m a b == (mulF2m m a <$> invF2m m b) , testProperty "a * b / b == a" $ \(Positive m) (NonNegative a) (NonNegative b) -> invF2m m b == Nothing || divF2m m (mulF2m m a b) b == Just (modF2m m a) ] tests = testGroup "number.F2m" [ addTests , modTests , mulTests , squareTests , invTests , divTests ] cryptonite-0.23/tests/Padding.hs0000644000000000000000000000252312727442704015103 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Padding (tests) where import qualified Data.ByteString as B import Imports import Crypto.Error import Crypto.Data.Padding cases = [ ("abcdef", 8, "abcdef\x02\x02") , ("abcd", 4, "abcd\x04\x04\x04\x04") , ("xyze", 5, "xyze\x01") ] zeroCases = [ ("", 4, "\NUL\NUL\NUL\NUL", Nothing) , ("abcdef", 8, "abcdef\NUL\NUL", Nothing) , ("0123456789abcdef", 16, "0123456789abcdef", Just "0123456789abcdef") ] --instance Arbitrary where testPad :: Int -> (B.ByteString, Int, B.ByteString) -> TestTree testPad n (inp, sz, padded) = testCase (show n) $ propertyHoldCase [ eqTest "padded" padded (pad (PKCS7 sz) inp) , eqTest "unpadded" (Just inp) (unpad (PKCS7 sz) padded) ] testZeroPad :: Int -> (B.ByteString, Int, B.ByteString, Maybe B.ByteString) -> TestTree testZeroPad n (inp, sz, padded, unpadded) = testCase (show n) $ propertyHoldCase [ eqTest "padded" padded (pad (ZERO sz) inp) , eqTest "unpadded" unpadded (unpad (ZERO sz) padded) ] tests = testGroup "Padding" [ testGroup "Cases" $ map (uncurry testPad) (zip [1..] cases) , testGroup "ZeroCases" $ map (uncurry testZeroPad) (zip [1..] zeroCases) ] cryptonite-0.23/tests/Poly1305.hs0000644000000000000000000000260212567303757014775 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Poly1305 (tests) where import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B () import Imports import Crypto.Error import qualified Crypto.MAC.Poly1305 as Poly1305 import qualified Data.ByteArray as B (convert) instance Show Poly1305.Auth where show _ = "Auth" data Chunking = Chunking Int Int deriving (Show,Eq) instance Arbitrary Chunking where arbitrary = Chunking <$> choose (1,34) <*> choose (1,2048) tests = testGroup "Poly1305" [ testCase "V0" $ let key = "\x85\xd6\xbe\x78\x57\x55\x6d\x33\x7f\x44\x52\xfe\x42\xd5\x06\xa8\x01\x03\x80\x8a\xfb\x0d\xb2\xfd\x4a\xbf\xf6\xaf\x41\x49\xf5\x1b" :: ByteString msg = "Cryptographic Forum Research Group" :: ByteString tag = "\xa8\x06\x1d\xc1\x30\x51\x36\xc6\xc2\x2b\x8b\xaf\x0c\x01\x27\xa9" :: ByteString in tag @=? B.convert (Poly1305.auth key msg) , testProperty "Chunking" $ \(Chunking chunkLen totalLen) -> let key = B.replicate 32 0 msg = B.pack $ take totalLen $ concat (replicate 10 [1..255]) in Poly1305.auth key msg == Poly1305.finalize (foldr (flip Poly1305.update) (throwCryptoError $ Poly1305.initialize key) (chunks chunkLen msg)) ] where chunks i bs | B.length bs < i = [bs] | otherwise = let (b1,b2) = B.splitAt i bs in b1 : chunks i b2 cryptonite-0.23/tests/Salsa.hs0000644000000000000000000001431512527624334014601 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Salsa (tests) where import qualified Data.ByteString as B import qualified Crypto.Cipher.Salsa as Salsa import Imports type Vector = (Int, B.ByteString, B.ByteString, [(Int, B.ByteString)]) vectors :: [Vector] vectors = [ (20, key, iv , [ (0, "\x99\xA8\xCC\xEC\x6C\x5B\x2A\x0B\x6E\x33\x6C\xB2\x06\x52\x24\x1C\x32\xB2\x4D\x34\xAC\xC0\x45\x7E\xF6\x79\x17\x8E\xDE\x7C\xF8\x05\x80\x5A\x93\x05\xC7\xC4\x99\x09\x68\x3B\xD1\xA8\x03\x32\x78\x17\x62\x7C\xA4\x6F\xE8\xB9\x29\xB6\xDF\x00\x12\xBD\x86\x41\x83\xBE") , (192, "\x2D\x22\x6C\x11\xF4\x7B\x3C\x0C\xCD\x09\x59\xB6\x1F\x59\xD5\xCC\x30\xFC\xEF\x6D\xBB\x8C\xBB\x3D\xCC\x1C\xC2\x52\x04\xFC\xD4\x49\x8C\x37\x42\x6A\x63\xBE\xA3\x28\x2B\x1A\x8A\x0D\x60\xE1\x3E\xB2\xFE\x59\x24\x1A\x9F\x6A\xF4\x26\x68\x98\x66\xED\xC7\x69\xE1\xE6\x48\x2F\xE1\xC1\x28\xA1\x5C\x11\x23\xB5\x65\x5E\xD5\x46\xDF\x01\x4C\xE0\xC4\x55\xDB\xF5\xD3\xA1\x3D\x9C\xD4\xF0\xE2\xD1\xDA\xB9\xF1\x2F\xB6\x8C\x54\x42\x61\xD7\xF8\x8E\xAC\x1C\x6C\xBF\x99\x3F\xBB\xB8\xE0\xAA\x85\x10\xBF\xF8\xE7\x38\x35\xA1\xE8\x6E\xAD\xBB") , (448, "\x05\x97\x18\x8A\x1C\x19\x25\x57\x69\xBE\x1C\x21\x03\x99\xAD\x17\x2E\xB4\x6C\x52\xF9\x2F\xD5\x41\xDF\x2E\xAD\x71\xB1\xFF\x8E\xA7\xAD\xD3\x80\xEC\x71\xA5\xFD\x7A\xDB\x51\x81\xEA\xDD\x18\x25\xEC\x02\x77\x9A\x45\x09\xBE\x58\x32\x70\x8C\xA2\x83\x6C\x16\x93\xA5") ]) , (20 , "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D" , "\x0D\x74\xDB\x42\xA9\x10\x77\xDE" , [ (0, "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71") , (65472, "\xB7\x0C\x50\x13\x9C\x63\x33\x2E\xF6\xE7\x7A\xC5\x43\x38\xA4\x07\x9B\x82\xBE\xC9\xF9\xA4\x03\xDF\xEA\x82\x1B\x83\xF7\x86\x07\x91\x65\x0E\xF1\xB2\x48\x9D\x05\x90\xB1\xDE\x77\x2E\xED\xA4\xE3\xBC\xD6\x0F\xA7\xCE\x9C\xD6\x23\xD9\xD2\xFD\x57\x58\xB8\x65\x3E\x70\x81\x58\x2C\x65\xD7\x56\x2B\x80\xAE\xC2\xF1\xA6\x73\xA9\xD0\x1C\x9F\x89\x2A\x23\xD4\x91\x9F\x6A\xB4\x7B\x91\x54\xE0\x8E\x69\x9B\x41\x17\xD7\xC6\x66\x47\x7B\x60\xF8\x39\x14\x81\x68\x2F\x5D\x95\xD9\x66\x23\xDB\xC4\x89\xD8\x8D\xAA\x69\x56\xB9\xF0\x64\x6B\x6E") , (131008, "\xA1\x3F\xFA\x12\x08\xF8\xBF\x50\x90\x08\x86\xFA\xAB\x40\xFD\x10\xE8\xCA\xA3\x06\xE6\x3D\xF3\x95\x36\xA1\x56\x4F\xB7\x60\xB2\x42\xA9\xD6\xA4\x62\x8C\xDC\x87\x87\x62\x83\x4E\x27\xA5\x41\xDA\x2A\x5E\x3B\x34\x45\x98\x9C\x76\xF6\x11\xE0\xFE\xC6\xD9\x1A\xCA\xCC") ]) ] where key :: B.ByteString key = "\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09" iv = B.replicate 8 0 newtype RandomVector = RandomVector Vector deriving (Show,Eq) instance Arbitrary RandomVector where arbitrary = RandomVector <$> elements vectors tests = testGroup "Salsa" [ testGroup "KAT" $ map (\(i,f) -> testCase (show (i :: Int)) f) $ zip [1..] $ map (\(r, k,i,e) -> salsaRunSimple e r k i) vectors , testProperty "generate-combine" salsaGenerateCombine , testProperty "chunking-generate" salsaGenerateChunks , testProperty "chunking-combine" salsaCombineChunks ] where salsaRunSimple expected rounds key nonce = let salsa = Salsa.initialize rounds key nonce in map snd expected @=? salsaLoop 0 salsa expected salsaLoop _ _ [] = [] salsaLoop current salsa (r@(ofs,expectBs):rs) | current < ofs = let (_, salsaNext) = Salsa.generate salsa (ofs - current) :: (ByteString, Salsa.State) in salsaLoop ofs salsaNext (r:rs) | current == ofs = let (e, salsaNext) = Salsa.generate salsa (B.length expectBs) in e : salsaLoop (current + B.length expectBs) salsaNext rs | otherwise = error "internal error in salsaLoop" salsaGenerateCombine :: ChunkingLen0_127 -> RandomVector -> Int0_2901 -> Bool salsaGenerateCombine (ChunkingLen0_127 ckLen) (RandomVector (rounds, key, iv, _)) (Int0_2901 nbBytes) = let initSalsa = Salsa.initialize rounds key iv in loop nbBytes ckLen initSalsa where loop n [] salsa = loop n ckLen salsa loop 0 _ _ = True loop n (x:xs) salsa = let len = min x n (c1, next) = Salsa.generate salsa len (c2, _) = Salsa.combine salsa (B.replicate len 0) in if c1 == c2 then loop (n - len) xs next else False salsaGenerateChunks :: ChunkingLen -> RandomVector -> Bool salsaGenerateChunks (ChunkingLen ckLen) (RandomVector (rounds, key, iv, _)) = let initSalsa = Salsa.initialize rounds key iv nbBytes = 1048 (expected,_) = Salsa.generate initSalsa nbBytes chunks = loop nbBytes ckLen (Salsa.initialize rounds key iv) in expected == B.concat chunks where loop n [] salsa = loop n ckLen salsa loop 0 _ _ = [] loop n (x:xs) salsa = let len = min x n (c, next) = Salsa.generate salsa len in c : loop (n - len) xs next salsaCombineChunks :: ChunkingLen -> RandomVector -> ArbitraryBS0_2901 -> Bool salsaCombineChunks (ChunkingLen ckLen) (RandomVector (rounds, key, iv, _)) (ArbitraryBS0_2901 wholebs) = let initSalsa = Salsa.initialize rounds key iv (expected,_) = Salsa.combine initSalsa wholebs chunks = loop wholebs ckLen initSalsa in expected `propertyEq` B.concat chunks where loop bs [] salsa = loop bs ckLen salsa loop bs (x:xs) salsa | B.null bs = [] | otherwise = let (bs1, bs2) = B.splitAt (min x (B.length bs)) bs (c, next) = Salsa.combine salsa bs1 in c : loop bs2 xs next cryptonite-0.23/tests/Utils.hs0000644000000000000000000001130612567614233014634 0ustar0000000000000000{-# LANGUAGE ExistentialQuantification #-} module Utils where import Control.Applicative import Control.Monad (replicateM) import Data.Char import Data.Word import Data.List import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Crypto.Random import Crypto.Number.Serialize (os2ip) import Prelude import Test.Tasty.QuickCheck import Test.Tasty.HUnit ((@=?)) newtype TestDRG = TestDRG (Word64, Word64, Word64, Word64, Word64) deriving (Show,Eq) instance Arbitrary TestDRG where arbitrary = TestDRG `fmap` arbitrary withTestDRG (TestDRG l) f = fst $ withDRG (drgNewTest l) f newtype ChunkingLen = ChunkingLen [Int] deriving (Show,Eq) instance Arbitrary ChunkingLen where arbitrary = ChunkingLen `fmap` replicateM 16 (choose (0,14)) newtype ChunkingLen0_127 = ChunkingLen0_127 [Int] deriving (Show,Eq) instance Arbitrary ChunkingLen0_127 where arbitrary = ChunkingLen0_127 `fmap` replicateM 16 (choose (0,127)) newtype ArbitraryBS0_2901 = ArbitraryBS0_2901 ByteString deriving (Show,Eq,Ord) instance Arbitrary ArbitraryBS0_2901 where arbitrary = ArbitraryBS0_2901 `fmap` arbitraryBSof 0 2901 newtype Int0_2901 = Int0_2901 Int deriving (Show,Eq,Ord) newtype Int1_2901 = Int1_2901 Int deriving (Show,Eq,Ord) instance Arbitrary Int0_2901 where arbitrary = Int0_2901 `fmap` choose (0,2901) instance Arbitrary Int1_2901 where arbitrary = Int1_2901 `fmap` choose (1,2901) -- | a integer wrapper with a better range property newtype QAInteger = QAInteger { getQAInteger :: Integer } deriving (Show,Eq) instance Arbitrary QAInteger where arbitrary = oneof [ QAInteger . fromIntegral <$> (choose (0, 65536) :: Gen Int) -- small integer , larger <$> choose (0,4096) <*> choose (0, 65536) -- medium integer , QAInteger . os2ip . B.pack <$> (choose (0,32) >>= \n -> replicateM n arbitrary) -- [ 0 .. 2^32 ] sized integer ] where larger :: Int -> Int -> QAInteger larger p b = QAInteger (fromIntegral p * somePrime + fromIntegral b) somePrime :: Integer somePrime = 18446744073709551557 arbitraryBS :: Int -> Gen ByteString arbitraryBS n = B.pack `fmap` replicateM n arbitrary arbitraryBSof :: Int -> Int -> Gen ByteString arbitraryBSof minSize maxSize = choose (minSize, maxSize) >>= \n -> (B.pack `fmap` replicateM n arbitrary) chunkS :: ChunkingLen -> ByteString -> [ByteString] chunkS (ChunkingLen originalChunks) = loop originalChunks where loop l bs | B.null bs = [] | otherwise = case l of (x:xs) -> let (b1, b2) = B.splitAt x bs in b1 : loop xs b2 [] -> loop originalChunks bs chunksL :: ChunkingLen -> L.ByteString -> L.ByteString chunksL (ChunkingLen originalChunks) = L.fromChunks . loop originalChunks . L.toChunks where loop _ [] = [] loop l (b:bs) | B.null b = loop l bs | otherwise = case l of (x:xs) -> let (b1, b2) = B.splitAt x b in b1 : loop xs (b2:bs) [] -> loop originalChunks (b:bs) katZero :: Int katZero = 0 --hexalise :: String -> [Word8] hexalise s = concatMap (\c -> [ hex $ c `div` 16, hex $ c `mod` 16 ]) s where hex i | i >= 0 && i <= 9 = fromIntegral (ord '0') + i | i >= 10 && i <= 15 = fromIntegral (ord 'a') + i - 10 | otherwise = 0 splitB :: Int -> ByteString -> [ByteString] splitB l b = if B.length b > l then let (b1, b2) = B.splitAt l b in b1 : splitB l b2 else [ b ] assertBytesEq :: ByteString -> ByteString -> Bool assertBytesEq b1 b2 | b1 /= b2 = error ("expected: " ++ show b1 ++ " got: " ++ show b2) | otherwise = True assertEq :: (Show a, Eq a) => a -> a -> Bool assertEq b1 b2 | b1 /= b2 = error ("expected: " ++ show b1 ++ " got: " ++ show b2) | otherwise = True propertyEq :: (Show a, Eq a) => a -> a -> Bool propertyEq = assertEq data PropertyTest = forall a . (Show a, Eq a) => EqTest String a a type PropertyName = String eqTest :: (Show a, Eq a) => PropertyName -> a -- ^ expected value -> a -- ^ got -> PropertyTest eqTest name a b = EqTest name a b propertyHold :: [PropertyTest] -> Bool propertyHold l = case foldl runProperty [] l of [] -> True failed -> error (intercalate "\n" failed) where runProperty acc (EqTest name a b) | a == b = acc | otherwise = (name ++ ": expected " ++ show a ++ " but got: " ++ show b) : acc propertyHoldCase :: [PropertyTest] -> IO () propertyHoldCase l = True @=? propertyHold l cryptonite-0.23/tests/XSalsa.hs0000644000000000000000000005467512777073622014753 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module XSalsa (tests) where import qualified Data.ByteString as B import qualified Crypto.Cipher.XSalsa as XSalsa import Imports type Vector = (Int, B.ByteString, B.ByteString, B.ByteString, B.ByteString) -- Test vectors generated by naclcrypto library (https://nacl.cr.yp.to) vectors :: [Vector] vectors = [ ( 20 , "\xA6\xA7\x25\x1C\x1E\x72\x91\x6D\x11\xC2\xCB\x21\x4D\x3C\x25\x25\x39\x12\x1D\x8E\x23\x4E\x65\x2D\x65\x1F\xA4\xC8\xCF\xF8\x80\x30" , "\x9E\x64\x5A\x74\xE9\xE0\xA6\x0D\x82\x43\xAC\xD9\x17\x7A\xB5\x1A\x1B\xEB\x8D\x5A\x2F\x5D\x70\x0C" , "\x09\x3C\x5E\x55\x85\x57\x96\x25\x33\x7B\xD3\xAB\x61\x9D\x61\x57\x60\xD8\xC5\xB2\x24\xA8\x5B\x1D\x0E\xFE\x0E\xB8\xA7\xEE\x16\x3A\xBB\x03\x76\x52\x9F\xCC\x09\xBA\xB5\x06\xC6\x18\xE1\x3C\xE7\x77\xD8\x2C\x3A\xE9\xD1\xA6\xF9\x72\xD4\x16\x02\x87\xCB\xFE\x60\xBF\x21\x30\xFC\x0A\x6F\xF6\x04\x9D\x0A\x5C\x8A\x82\xF4\x29\x23\x1F\x00\x80\x82\xE8\x45\xD7\xE1\x89\xD3\x7F\x9E\xD2\xB4\x64\xE6\xB9\x19\xE6\x52\x3A\x8C\x12\x10\xBD\x52\xA0\x2A\x4C\x3F\xE4\x06\xD3\x08\x5F\x50\x68\xD1\x90\x9E\xEE\xCA\x63\x69\xAB\xC9\x81\xA4\x2E\x87\xFE\x66\x55\x83\xF0\xAB\x85\xAE\x71\xF6\xF8\x4F\x52\x8E\x6B\x39\x7A\xF8\x6F\x69\x17\xD9\x75\x4B\x73\x20\xDB\xDC\x2F\xEA\x81\x49\x6F\x27\x32\xF5\x32\xAC\x78\xC4\xE9\xC6\xCF\xB1\x8F\x8E\x9B\xDF\x74\x62\x2E\xB1\x26\x14\x14\x16\x77\x69\x71\xA8\x4F\x94\xD1\x56\xBE\xAF\x67\xAE\xCB\xF2\xAD\x41\x2E\x76\xE6\x6E\x8F\xAD\x76\x33\xF5\xB6\xD7\xF3\xD6\x4B\x5C\x6C\x69\xCE\x29\x00\x3C\x60\x24\x46\x5A\xE3\xB8\x9B\xE7\x8E\x91\x5D\x88\xB4\xB5\x62\x1D" , "\xB2\xAF\x68\x8E\x7D\x8F\xC4\xB5\x08\xC0\x5C\xC3\x9D\xD5\x83\xD6\x71\x43\x22\xC6\x4D\x7F\x3E\x63\x14\x7A\xED\xE2\xD9\x53\x49\x34\xB0\x4F\xF6\xF3\x37\xB0\x31\x81\x5C\xD0\x94\xBD\xBC\x6D\x7A\x92\x07\x7D\xCE\x70\x94\x12\x28\x68\x22\xEF\x07\x37\xEE\x47\xF6\xB7\xFF\xA2\x2F\x9D\x53\xF1\x1D\xD2\xB0\xA3\xBB\x9F\xC0\x1D\x9A\x88\xF9\xD5\x3C\x26\xE9\x36\x5C\x2C\x3C\x06\x3B\xC4\x84\x0B\xFC\x81\x2E\x4B\x80\x46\x3E\x69\xD1\x79\x53\x0B\x25\xC1\x58\xF5\x43\x19\x1C\xFF\x99\x31\x06\x51\x1A\xA0\x36\x04\x3B\xBC\x75\x86\x6A\xB7\xE3\x4A\xFC\x57\xE2\xCC\xE4\x93\x4A\x5F\xAA\xE6\xEA\xBE\x4F\x22\x17\x70\x18\x3D\xD0\x60\x46\x78\x27\xC2\x7A\x35\x41\x59\xA0\x81\x27\x5A\x29\x1F\x69\xD9\x46\xD6\xFE\x28\xED\x0B\x9C\xE0\x82\x06\xCF\x48\x49\x25\xA5\x1B\x94\x98\xDB\xDE\x17\x8D\xDD\x3A\xE9\x1A\x85\x81\xB9\x16\x82\xD8\x60\xF8\x40\x78\x2F\x6E\xEA\x49\xDB\xB9\xBD\x72\x15\x01\xD2\xC6\x71\x22\xDE\xA3\xB7\x28\x38\x48\xC5\xF1\x3E\x0C\x0D\xE8\x76\xBD\x22\x7A\x85\x6E\x4D\xE5\x93\xA3") , ( 20 , "\x9E\x1D\xA2\x39\xD1\x55\xF5\x2A\xD3\x7F\x75\xC7\x36\x8A\x53\x66\x68\xB0\x51\x95\x29\x23\xAD\x44\xF5\x7E\x75\xAB\x58\x8E\x47\x5A" , "\xAF\x06\xF1\x78\x59\xDF\xFA\x79\x98\x91\xC4\x28\x8F\x66\x35\xB5\xC5\xA4\x5E\xEE\x90\x17\xFD\x72" , "\xFE\xAC\x9D\x54\xFC\x8C\x11\x5A\xE2\x47\xD9\xA7\xE9\x19\xDD\x76\xCF\xCB\xC7\x2D\x32\xCA\xE4\x94\x48\x60\x81\x7C\xBD\xFB\x8C\x04\xE6\xB1\xDF\x76\xA1\x65\x17\xCD\x33\xCC\xF1\xAC\xDA\x92\x06\x38\x9E\x9E\x31\x8F\x59\x66\xC0\x93\xCF\xB3\xEC\x2D\x9E\xE2\xDE\x85\x64\x37\xED\x58\x1F\x55\x2F\x26\xAC\x29\x07\x60\x9D\xF8\xC6\x13\xB9\xE3\x3D\x44\xBF\xC2\x1F\xF7\x91\x53\xE9\xEF\x81\xA9\xD6\x6C\xC3\x17\x85\x7F\x75\x2C\xC1\x75\xFD\x88\x91\xFE\xFE\xBB\x7D\x04\x1E\x65\x17\xC3\x16\x2D\x19\x7E\x21\x12\x83\x7D\x3B\xC4\x10\x43\x12\xAD\x35\xB7\x5E\xA6\x86\xE7\xC7\x0D\x4E\xC0\x47\x46\xB5\x2F\xF0\x9C\x42\x14\x51\x45\x9F\xB5\x9F" , "\x2C\x26\x1A\x2F\x4E\x61\xA6\x2E\x1B\x27\x68\x99\x16\xBF\x03\x45\x3F\xCB\xC9\x7B\xB2\xAF\x6F\x32\x93\x91\xEF\x06\x3B\x5A\x21\x9B\xF9\x84\xD0\x7D\x70\xF6\x02\xD8\x5F\x6D\xB6\x14\x74\xE9\xD9\xF5\xA2\xDE\xEC\xB4\xFC\xD9\x01\x84\xD1\x6F\x3B\x5B\x5E\x16\x8E\xE0\x3E\xA8\xC9\x3F\x39\x33\xA2\x2B\xC3\xD1\xA5\xAE\x8C\x2D\x8B\x02\x75\x7C\x87\xC0\x73\x40\x90\x52\xA2\xA8\xA4\x1E\x7F\x48\x7E\x04\x1F\x9A\x49\xA0\x99\x7B\x54\x0E\x18\x62\x1C\xAD\x3A\x24\xF0\xA5\x6D\x9B\x19\x22\x79\x29\x05\x7A\xB3\xBA\x95\x0F\x62\x74\xB1\x21\xF1\x93\xE3\x2E\x06\xE5\x38\x87\x81\xA1\xCB\x57\x31\x7C\x0B\xA6\x30\x5E\x91\x09\x61\xD0\x10\x02\xF0") , ( 20 , "\xD5\xC7\xF6\x79\x7B\x7E\x7E\x9C\x1D\x7F\xD2\x61\x0B\x2A\xBF\x2B\xC5\xA7\x88\x5F\xB3\xFF\x78\x09\x2F\xB3\xAB\xE8\x98\x6D\x35\xE2" , "\x74\x4E\x17\x31\x2B\x27\x96\x9D\x82\x64\x44\x64\x0E\x9C\x4A\x37\x8A\xE3\x34\xF1\x85\x36\x9C\x95" , "\x77\x58\x29\x8C\x62\x8E\xB3\xA4\xB6\x96\x3C\x54\x45\xEF\x66\x97\x12\x22\xBE\x5D\x1A\x4A\xD8\x39\x71\x5D\x11\x88\x07\x17\x39\xB7\x7C\xC6\xE0\x5D\x54\x10\xF9\x63\xA6\x41\x67\x62\x97\x57" , "\x27\xB8\xCF\xE8\x14\x16\xA7\x63\x01\xFD\x1E\xEC\x6A\x4D\x99\x67\x50\x69\xB2\xDA\x27\x76\xC3\x60\xDB\x1B\xDF\xEA\x7C\x0A\xA6\x13\x91\x3E\x10\xF7\xA6\x0F\xEC\x04\xD1\x1E\x65\xF2\xD6\x4E") , ( 20 , "\x73\x7D\x78\x11\xCE\x96\x47\x2E\xFE\xD1\x22\x58\xB7\x81\x22\xF1\x1D\xEA\xEC\x87\x59\xCC\xBD\x71\xEA\xC6\xBB\xEF\xA6\x27\x78\x5C" , "\x6F\xB2\xEE\x3D\xDA\x6D\xBD\x12\xF1\x27\x4F\x12\x67\x01\xEC\x75\xC3\x5C\x86\x60\x7A\xDB\x3E\xDD" , "\x50\x13\x25\xFB\x26\x45\x26\x48\x64\xDF\x11\xFA\xA1\x7B\xBD\x58\x31\x2B\x77\xCA\xD3\xD9\x4A\xC8\xFB\x85\x42\xF0\xEB\x65\x3A\xD7\x3D\x7F\xCE\x93\x2B\xB8\x74\xCB\x89\xAC\x39\xFC\x47\xF8\x26\x7C\xF0\xF0\xC2\x09\xF2\x04\xB2\xD8\x57\x8A\x3B\xDF\x46\x1C\xB6\xA2\x71\xA4\x68\xBE\xBA\xCC\xD9\x68\x50\x14\xCC\xBC\x9A\x73\x61\x8C\x6A\x5E\x77\x8A\x21\xCC\x84\x16\xC6\x0A\xD2\x4D\xDC\x41\x7A\x13\x0D\x53\xED\xA6\xDF\xBF\xE4\x7D\x09\x17\x0A\x7B\xE1\xA7\x08\xB7\xB5\xF3\xAD\x46\x43\x10\xBE\x36\xD9\xA2\xA9\x5D\xC3\x9E\x83\xD3\x86\x67\xE8\x42\xEB\x64\x11\xE8\xA2\x37\x12\x29\x7B\x16\x5F\x69\x0C\x2D\x7C\xA1\xB1\x34\x6E\x3C\x1F\xCC\xF5\xCA\xFD\x4F\x8B\xE0" , "\x67\x24\xC3\x72\xD2\xE9\x07\x4D\xA5\xE2\x7A\x6C\x54\xB2\xD7\x03\xDC\x1D\x4C\x9B\x1F\x8D\x90\xF0\x0C\x12\x2E\x69\x2A\xCE\x77\x00\xEA\xDC\xA9\x42\x54\x45\x07\xF1\x37\x5B\x65\x81\xD5\xA8\xFB\x39\x98\x1C\x1C\x0E\x6E\x1F\xF2\x14\x0B\x08\x2E\x9E\xC0\x16\xFC\xE1\x41\xD5\x19\x96\x47\xD4\x3B\x0B\x68\xBF\xD0\xFE\xA5\xE0\x0F\x46\x89\x62\xC7\x38\x4D\xD6\x12\x9A\xEA\x6A\x3F\xDF\xE7\x5A\xBB\x21\x0E\xD5\x60\x7C\xEF\x8F\xA0\xE1\x52\x83\x3D\x5A\xC3\x7D\x52\xE5\x57\xB9\x10\x98\xA3\x22\xE7\x6A\x45\xBB\xBC\xF4\x89\x9E\x79\x06\x18\xAA\x3F\x4C\x2E\x5E\x0F\xC3\xDE\x93\x26\x9A\x57\x7D\x77\xA5\x50\x2E\x8E\xA0\x2F\x71\x7B\x1D\xD2\xDF\x1E\xC6\x9D\x8B\x61\xCA") , ( 20 , "\x76\x01\x58\xDA\x09\xF8\x9B\xBA\xB2\xC9\x9E\x69\x97\xF9\x52\x3A\x95\xFC\xEF\x10\x23\x9B\xCC\xA2\x57\x3B\x71\x05\xF6\x89\x8D\x34" , "\x43\x63\x6B\x2C\xC3\x46\xFC\x8B\x7C\x85\xA1\x9B\xF5\x07\xBD\xC3\xDA\xFE\x95\x3B\x88\xC6\x9D\xBA" , "\xD3\x0A\x6D\x42\xDF\xF4\x9F\x0E\xD0\x39\xA3\x06\xBA\xE9\xDE\xC8\xD9\xE8\x83\x66\xCC\x19\xE8\xC3\x64\x2F\xD5\x8F\xA0\x79\x4E\xBF\x80\x29\xD9\x49\x73\x03\x39\xB0\x82\x3A\x51\xF0\xF4\x9F\x0D\x2C\x71\xF1\x05\x1C\x1E\x0E\x2C\x86\x94\x1F\x17\x27\x89\xCD\xB1\xB0\x10\x74\x13\xE7\x0F\x98\x2F\xF9\x76\x18\x77\xBB\x52\x6E\xF1\xC3\xEB\x11\x06\xA9\x48\xD6\x0E\xF2\x1B\xD3\x5D\x32\xCF\xD6\x4F\x89\xB7\x9E\xD6\x3E\xCC\x5C\xCA\x56\x24\x6A\xF7\x36\x76\x6F\x28\x5D\x8E\x6B\x0D\xA9\xCB\x1C\xD2\x10\x20\x22\x3F\xFA\xCC\x5A\x32" , "\xC8\x15\xB6\xB7\x9B\x64\xF9\x36\x9A\xEC\x8D\xCE\x8C\x75\x3D\xF8\xA5\x0F\x2B\xC9\x7C\x70\xCE\x2F\x01\x4D\xB3\x3A\x65\xAC\x58\x16\xBA\xC9\xE3\x0A\xC0\x8B\xDD\xED\x30\x8C\x65\xCB\x87\xE2\x8E\x2E\x71\xB6\x77\xDC\x25\xC5\xA6\x49\x9C\x15\x53\x55\x5D\xAF\x1F\x55\x27\x0A\x56\x95\x9D\xFF\xA0\xC6\x6F\x24\xE0\xAF\x00\x95\x1E\xC4\xBB\x59\xCC\xC3\xA6\xC5\xF5\x2E\x09\x81\x64\x7E\x53\xE4\x39\x31\x3A\x52\xC4\x0F\xA7\x00\x4C\x85\x5B\x6E\x6E\xB2\x5B\x21\x2A\x13\x8E\x84\x3A\x9B\xA4\x6E\xDB\x2A\x03\x9E\xE8\x2A\x26\x3A\xBE") , ( 20 , "\x27\xBA\x7E\x81\xE7\xED\xD4\xE7\x1B\xE5\x3C\x07\xCE\x8E\x63\x31\x38\xF2\x87\xE1\x55\xC7\xFA\x9E\x84\xC4\xAD\x80\x4B\x7F\xA1\xB9" , "\xEA\x05\xF4\xEB\xCD\x2F\xB6\xB0\x00\xDA\x06\x12\x86\x1B\xA5\x4F\xF5\xC1\x76\xFB\x60\x13\x91\xAA" , "\xE0\x9F\xF5\xD2\xCB\x05\x0D\x69\xB2\xD4\x24\x94\xBD\xE5\x82\x52\x38\xC7\x56\xD6\x99\x1D\x99\xD7\xA2\x0D\x1E\xF0\xB8\x3C\x37\x1C\x89\x87\x26\x90\xB2\xFC\x11\xD5\x36\x9F\x4F\xC4\x97\x1B\x6D\x3D\x6C\x07\x8A\xEF\x9B\x0F\x05\xC0\xE6\x1A\xB8\x9C\x02\x51\x68\x05\x4D\xEF\xEB\x03\xFE\xF6\x33\x85\x87\x00\xC5\x8B\x12\x62\xCE\x01\x13\x00\x01\x26\x73\xE8\x93\xE4\x49\x01\xDC\x18\xEE\xE3\x10\x56\x99\xC4\x4C\x80\x58\x97\xBD\xAF\x77\x6A\xF1\x83\x31\x62\xA2\x1A" , "\xA2\x3E\x7E\xF9\x3C\x5D\x06\x67\xC9\x6D\x9E\x40\x4D\xCB\xE6\xBE\x62\x02\x6F\xA9\x8F\x7A\x3F\xF9\xBA\x5D\x45\x86\x43\xA1\x6A\x1C\xEF\x72\x72\xDC\x60\x97\xA9\xB5\x2F\x35\x98\x35\x57\xC7\x7A\x11\xB3\x14\xB4\xF7\xD5\xDC\x2C\xCA\x15\xEE\x47\x61\x6F\x86\x18\x73\xCB\xFE\xD1\xD3\x23\x72\x17\x1A\x61\xE3\x8E\x44\x7F\x3C\xF3\x62\xB3\xAB\xBB\x2E\xD4\x17\x0D\x89\xDC\xB2\x81\x87\xB7\xBF\xD2\x06\xA3\xE0\x26\xF0\x84\xA7\xE0\xED\x63\xD3\x19\xDE\x6B\xC9\xAF\xC0") , ( 20 , "\x67\x99\xD7\x6E\x5F\xFB\x5B\x49\x20\xBC\x27\x68\xBA\xFD\x3F\x8C\x16\x55\x4E\x65\xEF\xCF\x9A\x16\xF4\x68\x3A\x7A\x06\x92\x7C\x11" , "\x61\xAB\x95\x19\x21\xE5\x4F\xF0\x6D\x9B\x77\xF3\x13\xA4\xE4\x9D\xF7\xA0\x57\xD5\xFD\x62\x79\x89" , "\x47\x27\x66" , "\x8F\xD7\xDF") , ( 20 , "\xF6\x82\x38\xC0\x83\x65\xBB\x29\x3D\x26\x98\x0A\x60\x64\x88\xD0\x9C\x2F\x10\x9E\xDA\xFA\x0B\xBA\xE9\x93\x7B\x5C\xC2\x19\xA4\x9C" , "\x51\x90\xB5\x1E\x9B\x70\x86\x24\x82\x0B\x5A\xBD\xF4\xE4\x0F\xAD\x1F\xB9\x50\xAD\x1A\xDC\x2D\x26" , "\x47\xEC\x6B\x1F\x73\xC4\xB7\xFF\x52\x74\xA0\xBF\xD7\xF4\x5F\x86\x48\x12\xC8\x5A\x12\xFB\xCB\x3C\x2C\xF8\xA3\xE9\x0C\xF6\x6C\xCF\x2E\xAC\xB5\x21\xE7\x48\x36\x3C\x77\xF5\x2E\xB4\x26\xAE\x57\xA0\xC6\xC7\x8F\x75\xAF\x71\x28\x45\x69\xE7\x9D\x1A\x92\xF9\x49\xA9\xD6\x9C\x4E\xFC\x0B\x69\x90\x2F\x1E\x36\xD7\x56\x27\x65\x54\x3E\x2D\x39\x42\xD9\xF6\xFF\x59\x48\xD8\xA3\x12\xCF\xF7\x2C\x1A\xFD\x9E\xA3\x08\x8A\xFF\x76\x40\xBF\xD2\x65\xF7\xA9\x94\x6E\x60\x6A\xBC\x77\xBC\xED\xAE\x6B\xDD\xC7\x5A\x0D\xBA\x0B\xD9\x17\xD7\x3E\x3B\xD1\x26\x8F\x72\x7E\x00\x96\x34\x5D\xA1\xED\x25\xCF\x55\x3E\xA7\xA9\x8F\xEA\x6B\x6F\x28\x57\x32\xDE\x37\x43\x15\x61\xEE\x1B\x30\x64\x88\x7F\xBC\xBD\x71\x93\x5E\x02" , "\x36\x16\x0E\x88\xD3\x50\x05\x29\xBA\x4E\xDB\xA1\x7B\xC2\x4D\x8C\xFA\xCA\x9A\x06\x80\xB3\xB1\xFC\x97\xCF\x03\xF3\x67\x5B\x7A\xC3\x01\xC8\x83\xA6\x8C\x07\x1B\xC5\x4A\xCD\xD3\xB6\x3A\xF4\xA2\xD7\x2F\x98\x5E\x51\xF9\xD6\x0A\x4C\x7F\xD4\x81\xAF\x10\xB2\xFC\x75\xE2\x52\xFD\xEE\x7E\xA6\xB6\x45\x31\x90\x61\x7D\xCC\x6E\x2F\xE1\xCD\x56\x58\x5F\xC2\xF0\xB0\xE9\x7C\x5C\x3F\x8A\xD7\xEB\x4F\x31\xBC\x48\x90\xC0\x38\x82\xAA\xC2\x4C\xC5\x3A\xCC\x19\x82\x29\x65\x26\x69\x0A\x22\x02\x71\xC2\xF6\xE3\x26\x75\x0D\x3F\xBD\xA5\xD5\xB6\x35\x12\xC8\x31\xF6\x78\x30\xF5\x9A\xC4\x9A\xAE\x33\x0B\x3E\x0E\x02\xC9\xEA\x00\x91\xD1\x98\x41\xF1\xB0\xE1\x3D\x69\xC9\xFB\xFE\x8A\x12\xD6\xF3\x0B\xB7\x34\xD9\xD2") , ( 20 , "\x45\xB2\xBD\x0D\xE4\xED\x92\x93\xEC\x3E\x26\xC4\x84\x0F\xAA\xF6\x4B\x7D\x61\x9D\x51\xE9\xD7\xA2\xC7\xE3\x6C\x83\xD5\x84\xC3\xDF" , "\x54\x6C\x8C\x5D\x6B\xE8\xF9\x09\x52\xCA\xB3\xF3\x6D\x7C\x19\x57\xBA\xAA\x7A\x59\xAB\xE3\xD7\xE5" , "\x50\x07\xC8\xCD\x5B\x3C\x40\xE1\x7D\x7F\xE4\x23\xA8\x7A\xE0\xCE\xD8\x6B\xEC\x1C\x39\xDC\x07\xA2\x57\x72\xF3\xE9\x6D\xAB\xD5\x6C\xD3\xFD\x73\x19\xF6\xC9\x65\x49\x25\xF2\xD8\x70\x87\xA7\x00\xE1\xB1\x30\xDA\x79\x68\x95\xD1\xC9\xB9\xAC\xD6\x2B\x26\x61\x44\x06\x7D\x37\x3E\xD5\x1E\x78\x74\x98\xB0\x3C\x52\xFA\xAD\x16\xBB\x38\x26\xFA\x51\x1B\x0E\xD2\xA1\x9A\x86\x63\xF5\xBA\x2D\x6E\xA7\xC3\x8E\x72\x12\xE9\x69\x7D\x91\x48\x6C\x49\xD8\xA0\x00\xB9\xA1\x93\x5D\x6A\x7F\xF7\xEF\x23\xE7\x20\xA4\x58\x55\x48\x14\x40\x46\x3B\x4A\xC8\xC4\xF6\xE7\x06\x2A\xDC\x1F\x1E\x1E\x25\xD3\xD6\x5A\x31\x81\x2F\x58\xA7\x11\x60" , "\x8E\xAC\xFB\xA5\x68\x89\x8B\x10\xC0\x95\x7A\x7D\x44\x10\x06\x85\xE8\x76\x3A\x71\xA6\x9A\x8D\x16\xBC\x7B\x3F\x88\x08\x5B\xB9\xA2\xF0\x96\x42\xE4\xD0\x9A\x9F\x0A\xD0\x9D\x0A\xAD\x66\xB2\x26\x10\xC8\xBD\x02\xFF\x66\x79\xBB\x92\xC2\xC0\x26\xA2\x16\xBF\x42\x5C\x6B\xE3\x5F\xB8\xDA\xE7\xFF\x0C\x72\xB0\xEF\xD6\xA1\x80\x37\xC7\x0E\xED\x0C\xA9\x00\x62\xA4\x9A\x3C\x97\xFD\xC9\x0A\x8F\x9C\x2E\xA5\x36\xBF\xDC\x41\x91\x8A\x75\x82\xC9\x92\x7F\xAE\x47\xEF\xAA\x3D\xC8\x79\x67\xB7\x88\x7D\xEE\x1B\xF0\x71\x73\x4C\x76\x65\x90\x1D\x91\x05\xDA\xE2\xFD\xF6\x6B\x49\x18\xE5\x1D\x8F\x4A\x48\xC6\x0D\x19\xFB\xFB\xBC\xBA") , ( 20 , "\xFE\x55\x9C\x9A\x28\x2B\xEB\x40\x81\x4D\x01\x6D\x6B\xFC\xB2\xC0\xC0\xD8\xBF\x07\x7B\x11\x10\xB8\x70\x3A\x3C\xE3\x9D\x70\xE0\xE1" , "\xB0\x76\x20\x0C\xC7\x01\x12\x59\x80\x5E\x18\xB3\x04\x09\x27\x54\x00\x27\x23\xEB\xEC\x5D\x62\x00" , "\x6D\xB6\x5B\x9E\xC8\xB1\x14\xA9\x44\x13\x7C\x82\x1F\xD6\x06\xBE\x75\x47\x8D\x92\x83\x66\xD5\x28\x40\x96\xCD\xEF\x78\x2F\xCF\xF7\xE8\xF5\x9C\xB8\xFF\xCD\xA9\x79\x75\x79\x02\xC5\xFF\xA6\xBC\x47\x7C\xEA\xA4\xCB\x5D\x5E\xA7\x6F\x94\xD9\x1E\x83\x3F\x82\x3A\x6B\xC7\x8F\x10\x55\xDF\xA6\xA9\x7B\xEA\x89\x65\xC1\xCD\xE6\x7A\x66\x8E\x00\x12\x57\x33\x4A\x58\x57\x27\xD9\xE0\xF7\xC1\xA0\x6E\x88\xD3\xD2\x5A\x4E\x6D\x90\x96\xC9\x68\xBF\x13\x8E\x11\x6A\x3E\xBE\xFF\xD4\xBB\x48\x08\xAD\xB1\xFD\x69\x81\x64\xBA\x0A\x35\xC7\x09\xA4\x7F\x16\xF1\xF4\x43\x5A\x23\x45\xA9\x19\x4A\x00\xB9\x5A\xBD\x51\x85\x1D\x50\x58\x09\xA6\x07\x7D\xA9\xBA\xCA\x58\x31\xAF\xFF\x31\x57\x8C\x48\x7E\xE6\x8F\x27\x67\x97\x4A\x98\xA7\xE8\x03\xAA\xC7\x88\xDA\x98\x31\x9C\x4E\xA8\xEA\xA3\xD3\x94\x85\x56\x51\xF4\x84\xCE\xF5\x43\xF5\x37\xE3\x51\x58\xEE\x29" , "\x4D\xCE\x9C\x8F\x97\xA0\x28\x05\x1B\x07\x27\xF3\x4E\x1B\x9E\xF2\x1F\x06\xF0\x76\x0F\x36\xE7\x17\x13\x20\x40\x27\x90\x20\x90\xBA\x2B\xB6\xB1\x34\x36\xEE\x77\x8D\x9F\x50\x53\x0E\xFB\xD7\xA3\x2B\x0D\x41\x44\x3F\x58\xCC\xAE\xE7\x81\xC7\xB7\x16\xD3\xA9\x6F\xDE\xC0\xE3\x76\x4E\xD7\x95\x9F\x34\xC3\x94\x12\x78\x59\x1E\xA0\x33\xB5\xCB\xAD\xC0\xF1\x91\x60\x32\xE9\xBE\xBB\xD1\xA8\x39\x5B\x83\xFB\x63\xB1\x45\x4B\xD7\x75\xBD\x20\xB3\xA2\xA9\x6F\x95\x12\x46\xAC\x14\xDA\xF6\x81\x66\xBA\x62\xF6\xCB\xFF\x8B\xD1\x21\xAC\x94\x98\xFF\x88\x52\xFD\x2B\xE9\x75\xDF\x52\xB5\xDA\xEF\x38\x29\xD1\x8E\xDA\x42\xE7\x15\x02\x2D\xCB\xF9\x30\xD0\xA7\x89\xEE\x6A\x14\x6C\x2C\x70\x88\xC3\x57\x73\xC6\x3C\x06\xB4\xAF\x45\x59\x85\x6A\xC1\x99\xCE\xD8\x68\x63\xE4\x29\x47\x07\x82\x53\x37\xC5\x85\x79\x70\xEB\x7F\xDD\xEB\x26\x37\x81\x30\x90\x11") , ( 20 , "\x0A\xE1\x00\x12\xD7\xE5\x66\x14\xB0\x3D\xCC\x89\xB1\x4B\xAE\x92\x42\xFF\xE6\x30\xF3\xD7\xE3\x5C\xE8\xBB\xB9\x7B\xBC\x2C\x92\xC3" , "\xF9\x6B\x02\x5D\x6C\xF4\x6A\x8A\x12\xAC\x2A\xF1\xE2\xAE\xF1\xFB\x83\x59\x0A\xDA\xDA\xA5\xC5\xEA" , "\xEA\x0F\x35\x4E\x96\xF1\x2B\xC7\x2B\xBA\xA3\xD1\x2B\x4A\x8E\xD8\x79\xB0\x42\xF0\x68\x98\x78\xF4\x6B\x65\x1C\xC4\x11\x6D\x6F\x78\x40\x9B\x11\x43\x0B\x3A\xAA\x30\xB2\x07\x68\x91\xE8\xE1\xFA\x52\x8F\x2F\xD1\x69\xED\x93\xDC\x9F\x84\xE2\x44\x09\xEE\xC2\x10\x1D\xAF\x4D\x05\x7B\xE2\x49\x2D\x11\xDE\x64\x0C\xBD\x7B\x35\x5A\xD2\x9F\xB7\x04\x00\xFF\xFD\x7C\xD6\xD4\x25\xAB\xEE\xB7\x32\xA0\xEA\xA4\x33\x0A\xF4\xC6\x56\x25\x2C\x41\x73\xDE\xAB\x65\x3E\xB8\x5C\x58\x46\x2D\x7A\xB0\xF3\x5F\xD1\x2B\x61\x3D\x29\xD4\x73\xD3\x30\x31\x0D\xC3\x23\xD3\xC6\x63\x48\xBB\xDB\xB6\x8A\x32\x63\x24\x65\x7C\xAE\x7B\x77\xA9\xE3\x43\x58\xF2\xCE\xC5\x0C\x85\x60\x9E\x73\x05\x68\x56\x79\x6E\x3B\xE8\xD6\x2B\x6E\x2F\xE9\xF9\x53" , "\xE8\xAB\xD4\x89\x24\xB5\x4E\x5B\x80\x86\x6B\xE7\xD4\xEB\xE5\xCF\x42\x74\xCA\xFF\xF0\x8B\x39\xCB\x2D\x40\xA8\xF0\xB4\x72\x39\x8A\xED\xC7\x76\xE0\x79\x38\x12\xFB\xF1\xF6\x00\x78\x63\x5D\x2E\xD8\x6B\x15\xEF\xCD\xBA\x60\x41\x1E\xE2\x3B\x07\x23\x35\x92\xA4\x4E\xC3\x1B\x10\x13\xCE\x89\x64\x23\x66\x75\xF8\xF1\x83\xAE\xF8\x85\xE8\x64\xF2\xA7\x2E\xDF\x42\x15\xB5\x33\x8F\xA2\xB5\x46\x53\xDF\xA1\xA8\xC5\x5C\xE5\xD9\x5C\xC6\x05\xB9\xB3\x11\x52\x7F\x2E\x34\x63\xFF\xBE\xC7\x8A\x9D\x1D\x65\xDA\xBA\xD2\xF3\x38\x76\x9C\x9F\x43\xF1\x33\xA7\x91\xA1\x1C\x7E\xCA\x9A\xF0\xB7\x71\xA4\xAC\x32\x96\x3D\xC8\xF6\x31\xA2\xC1\x12\x17\xAC\x6E\x1B\x94\x30\xC1\xAA\xE1\xCE\xEB\xE2\x27\x03\xF4\x29\x99\x8A\x8F\xB8\xC6\x41") , ( 20 , "\x08\x2C\x53\x9B\xC5\xB2\x0F\x97\xD7\x67\xCD\x3F\x22\x9E\xDA\x80\xB2\xAD\xC4\xFE\x49\xC8\x63\x29\xB5\xCD\x62\x50\xA9\x87\x74\x50" , "\x84\x55\x43\x50\x2E\x8B\x64\x91\x2D\x8F\x2C\x8D\x9F\xFF\xB3\xC6\x93\x65\x68\x65\x87\xC0\x8D\x0C" , "\xA9\x6B\xB7\xE9\x10\x28\x1A\x6D\xFA\xD7\xC8\xA9\xC3\x70\x67\x4F\x0C\xEE\xC1\xAD\x8D\x4F\x0D\xE3\x2F\x9A\xE4\xA2\x3E\xD3\x29\xE3\xD6\xBC\x70\x8F\x87\x66\x40\xA2\x29\x15\x3A\xC0\xE7\x28\x1A\x81\x88\xDD\x77\x69\x51\x38\xF0\x1C\xDA\x5F\x41\xD5\x21\x5F\xD5\xC6\xBD\xD4\x6D\x98\x2C\xB7\x3B\x1E\xFE\x29\x97\x97\x0A\x9F\xDB\xDB\x1E\x76\x8D\x7E\x5D\xB7\x12\x06\x8D\x8B\xA1\xAF\x60\x67\xB5\x75\x34\x95\xE2\x3E\x6E\x19\x63\xAF\x01\x2F\x9C\x7C\xE4\x50\xBF\x2D\xE6\x19\xD3\xD5\x95\x42\xFB\x55\xF3" , "\x83\x5D\xA7\x4F\xC6\xDE\x08\xCB\xDA\x27\x7A\x79\x66\xA0\x7C\x8D\xCD\x62\x7E\x7B\x17\xAD\xDE\x6D\x93\x0B\x65\x81\xE3\x12\x4B\x8B\xAA\xD0\x96\xF6\x93\x99\x1F\xED\xB1\x57\x29\x30\x60\x1F\xC7\x70\x95\x41\x83\x9B\x8E\x3F\xFD\x5F\x03\x3D\x20\x60\xD9\x99\xC6\xC6\xE3\x04\x82\x76\x61\x3E\x64\x80\x00\xAC\xB5\x21\x2C\xC6\x32\xA9\x16\xAF\xCE\x29\x0E\x20\xEB\xDF\x61\x2D\x08\xA6\xAA\x4C\x79\xA7\x4B\x07\x0D\x3F\x87\x2A\x86\x1F\x8D\xC6\xBB\x07\x61\x4D\xB5\x15\xD3\x63\x34\x9D\x3A\x8E\x33\x36\xA3") , ( 20 , "\x3D\x02\xBF\xF3\x37\x5D\x40\x30\x27\x35\x6B\x94\xF5\x14\x20\x37\x37\xEE\x9A\x85\xD2\x05\x2D\xB3\xE4\xE5\xA2\x17\xC2\x59\xD1\x8A" , "\x74\x21\x6C\x95\x03\x18\x95\xF4\x8C\x1D\xBA\x65\x15\x55\xEB\xFA\x3C\xA3\x26\xA7\x55\x23\x70\x25" , "\x0D\x4B\x0F\x54\xFD\x09\xAE\x39\xBA\xA5\xFA\x4B\xAC\xCF\x2E\x66\x82\xE6\x1B\x25\x7E\x01\xF4\x2B\x8F" , "\x16\xC4\x00\x6C\x28\x36\x51\x90\x41\x1E\xB1\x59\x38\x14\xCF\x15\xE7\x4C\x22\x23\x8F\x21\x0A\xFC\x3D") , ( 20 , "\xAD\x1A\x5C\x47\x68\x88\x74\xE6\x66\x3A\x0F\x3F\xA1\x6F\xA7\xEF\xB7\xEC\xAD\xC1\x75\xC4\x68\xE5\x43\x29\x14\xBD\xB4\x80\xFF\xC6" , "\xE4\x89\xEE\xD4\x40\xF1\xAA\xE1\xFA\xC8\xFB\x7A\x98\x25\x63\x54\x54\xF8\xF8\xF1\xF5\x2E\x2F\xCC" , "\xAA\x6C\x1E\x53\x58\x0F\x03\xA9\xAB\xB7\x3B\xFD\xAD\xED\xFE\xCA\xDA\x4C\x6B\x0E\xBE\x02\x0E\xF1\x0D\xB7\x45\xE5\x4B\xA8\x61\xCA\xF6\x5F\x0E\x40\xDF\xC5\x20\x20\x3B\xB5\x4D\x29\xE0\xA8\xF7\x8F\x16\xB3\xF1\xAA\x52\x5D\x6B\xFA\x33\xC5\x47\x26\xE5\x99\x88\xCF\xBE\xC7\x80\x56" , "\x02\xFE\x84\xCE\x81\xE1\x78\xE7\xAA\xBD\xD3\xBA\x92\x5A\x76\x6C\x3C\x24\x75\x6E\xEF\xAE\x33\x94\x2A\xF7\x5E\x8B\x46\x45\x56\xB5\x99\x7E\x61\x6F\x3F\x2D\xFC\x7F\xCE\x91\x84\x8A\xFD\x79\x91\x2D\x9F\xB5\x52\x01\xB5\x81\x3A\x5A\x07\x4D\x2C\x0D\x42\x92\xC1\xFD\x44\x18\x07\xC5") , ( 20 , "\x05\x3A\x02\xBE\xDD\x63\x68\xC1\xFB\x8A\xFC\x7A\x1B\x19\x9F\x7F\x7E\xA2\x22\x0C\x9A\x4B\x64\x2A\x68\x50\x09\x1C\x9D\x20\xAB\x9C" , "\xC7\x13\xEE\xA5\xC2\x6D\xAD\x75\xAD\x3F\x52\x45\x1E\x00\x3A\x9C\xB0\xD6\x49\xF9\x17\xC8\x9D\xDE" , "\x8F\x0A\x8A\x16\x47\x60\x42\x65\x67\xE3\x88\x84\x02\x76\xDE\x3F\x95\xCB\x5E\x3F\xAD\xC6\xED\x3F\x3E\x4F\xE8\xBC\x16\x9D\x93\x88\x80\x4D\xCB\x94\xB6\x58\x7D\xBB\x66\xCB\x0B\xD5\xF8\x7B\x8E\x98\xB5\x2A\xF3\x7B\xA2\x90\x62\x9B\x85\x8E\x0E\x2A\xA7\x37\x80\x47\xA2\x66\x02" , "\x51\x67\x10\xE5\x98\x43\xE6\xFB\xD4\xF2\x5D\x0D\x8C\xA0\xEC\x0D\x47\xD3\x9D\x12\x5E\x9D\xAD\x98\x7E\x05\x18\xD4\x91\x07\x01\x4C\xB0\xAE\x40\x5E\x30\xC2\xEB\x37\x94\x75\x0B\xCA\x14\x2C\xE9\x5E\x29\x0C\xF9\x5A\xBE\x15\xE8\x22\x82\x3E\x2E\x7D\x3A\xB2\x1B\xC8\xFB\xD4\x45") , ( 20 ,"\x5B\x14\xAB\x0F\xBE\xD4\xC5\x89\x52\x54\x8A\x6C\xB1\xE0\x00\x0C\xF4\x48\x14\x21\xF4\x12\x88\xEA\x0A\xA8\x4A\xDD\x9F\x7D\xEB\x96" , "\x54\xBF\x52\xB9\x11\x23\x1B\x95\x2B\xA1\xA6\xAF\x8E\x45\xB1\xC5\xA2\x9D\x97\xE2\xAB\xAD\x7C\x83" , "\x37\xFB\x44\xA6\x75\x97\x8B\x56\x0F\xF9\xA4\xA8\x70\x11\xD6\xF3\xAD\x2D\x37\xA2\xC3\x81\x5B\x45\xA3\xC0\xE6\xD1\xB1\xD8\xB1\x78\x4C\xD4\x68\x92\x7C\x2E\xE3\x9E\x1D\xCC\xD4\x76\x5E\x1C\x3D\x67\x6A\x33\x5B\xE1\xCC\xD6\x90\x0A\x45\xF5\xD4\x1A\x31\x76\x48\x31\x5D\x8A\x8C\x24\xAD\xC6\x4E\xB2\x85\xF6\xAE\xBA\x05\xB9\x02\x95\x86\x35\x3D\x30\x3F\x17\xA8\x07\x65\x8B\x9F\xF7\x90\x47\x4E\x17\x37\xBD\x5F\xDC\x60\x4A\xEF\xF8\xDF\xCA\xF1\x42\x7D\xCC\x3A\xAC\xBB\x02\x56\xBA\xDC\xD1\x83\xED\x75\xA2\xDC\x52\x45\x2F\x87\xD3\xC1\xED\x2A\xA5\x83\x47\x2B\x0A\xB9\x1C\xDA\x20\x61\x4E\x9B\x6F\xDB\xDA\x3B\x49\xB0\x98\xC9\x58\x23\xCC\x72\xD8\xE5\xB7\x17\xF2\x31\x4B\x03\x24\xE9\xCE" , "\xAE\x6D\xEB\x5D\x6C\xE4\x3D\x4B\x09\xD0\xE6\xB1\xC0\xE9\xF4\x61\x57\xBC\xD8\xAB\x50\xEA\xA3\x19\x7F\xF9\xFA\x2B\xF7\xAF\x64\x9E\xB5\x2C\x68\x54\x4F\xD3\xAD\xFE\x6B\x1E\xB3\x16\xF1\xF2\x35\x38\xD4\x70\xC3\x0D\xBF\xEC\x7E\x57\xB6\x0C\xBC\xD0\x96\xC7\x82\xE7\x73\x6B\x66\x91\x99\xC8\x25\x3E\x70\x21\x4C\xF2\xA0\x98\xFD\xA8\xEA\xC5\xDA\x79\xA9\x49\x6A\x3A\xAE\x75\x4D\x03\xB1\x7C\x6D\x70\xD1\x02\x7F\x42\xBF\x7F\x95\xCE\x3D\x1D\x9C\x33\x88\x54\xE1\x58\xFC\xC8\x03\xE4\xD6\x26\x2F\xB6\x39\x52\x1E\x47\x11\x6E\xF7\x8A\x7A\x43\x7C\xA9\x42\x7B\xA6\x45\xCD\x64\x68\x32\xFE\xAB\x82\x2A\x20\x82\x78\xE4\x5E\x93\xE1\x18\xD7\x80\xB9\x88\xD6\x53\x97\xED\xDF\xD7\xA8\x19\x52\x6E") , ( 20 , "\xD7\x46\x36\xE3\x41\x3A\x88\xD8\x5F\x32\x2C\xA8\x0F\xB0\xBD\x65\x0B\xD0\xBF\x01\x34\xE2\x32\x91\x60\xB6\x96\x09\xCD\x58\xA4\xB0" , "\xEF\xB6\x06\xAA\x1D\x9D\x9F\x0F\x46\x5E\xAA\x7F\x81\x65\xF1\xAC\x09\xF5\xCB\x46\xFE\xCF\x2A\x57" , "\xF8\x54\x71\xB7\x5F\x6E\xC8\x1A\xBA\xC2\x79\x9E\xC0\x9E\x98\xE2\x80\xB2\xFF\xD6\x4C\xA2\x85\xE5\xA0\x10\x9C\xFB\x31\xFF\xAB\x2D\x61\x7B\x2C\x29\x52\xA2\xA8\xA7\x88\xFC\x0D\xA2\xAF\x7F\x53\x07\x58\xF7\x4F\x1A\xB5\x63\x91\xAB\x5F\xF2\xAD\xBC\xC5\xBE\x2D\x6C\x7F\x49\xFB\xE8\x11\x81\x04\xC6\xFF\x9A\x23\xC6\xDF\xE5\x2F\x57\x95\x4E\x6A\x69\xDC\xEE\x5D\xB0\x6F\x51\x4F\x4A\x0A\x57\x2A\x9A\x85\x25\xD9\x61\xDA\xE7\x22\x69\xB9\x87\x18\x9D\x46\x5D\xF6\x10\x71\x19\xC7\xFA\x79\x08\x53\xE0\x63\xCB\xA0\xFA\xB7\x80\x0C\xA9\x32\xE2\x58\x88\x0F\xD7\x4C\x33\xC7\x84\x67\x5B\xED\xAD\x0E\x7C\x09\xE9\xCC\x4D\x63\xDD\x5E\x97\x13\xD5\xD4\xA0\x19\x6E\x6B\x56\x22\x26\xAC\x31\xB4\xF5\x7C\x04\xF9\x0A\x18\x19\x73\x73\x7D\xDC\x7E\x80\xF3\x64\x11\x2A\x9F\xBB\x43\x5E\xBD\xBC\xAB\xF7\xD4\x90\xCE\x52" , "\xB2\xB7\x95\xFE\x6C\x1D\x4C\x83\xC1\x32\x7E\x01\x5A\x67\xD4\x46\x5F\xD8\xE3\x28\x13\x57\x5C\xBA\xB2\x63\xE2\x0E\xF0\x58\x64\xD2\xDC\x17\xE0\xE4\xEB\x81\x43\x6A\xDF\xE9\xF6\x38\xDC\xC1\xC8\xD7\x8F\x6B\x03\x06\xBA\xF9\x38\xE5\xD2\xAB\x0B\x3E\x05\xE7\x35\xCC\x6F\xFF\x2D\x6E\x02\xE3\xD6\x04\x84\xBE\xA7\xC7\xA8\xE1\x3E\x23\x19\x7F\xEA\x7B\x04\xD4\x7D\x48\xF4\xA4\xE5\x94\x41\x74\x53\x94\x92\x80\x0D\x3E\xF5\x1E\x2E\xE5\xE4\xC8\xA0\xBD\xF0\x50\xC2\xDD\x3D\xD7\x4F\xCE\x5E\x7E\x5C\x37\x36\x4F\x75\x47\xA1\x14\x80\xA3\x06\x3B\x9A\x0A\x15\x7B\x15\xB1\x0A\x5A\x95\x4D\xE2\x73\x1C\xED\x05\x5A\xA2\xE2\x76\x7F\x08\x91\xD4\x32\x9C\x42\x6F\x38\x08\xEE\x86\x7B\xED\x0D\xC7\x5B\x59\x22\xB7\xCF\xB8\x95\x70\x0F\xDA\x01\x61\x05\xA4\xC7\xB7\xF0\xBB\x90\xF0\x29\xF6\xBB\xCB\x04\xAC\x36\xAC\x16") ] tests = testGroup "XSalsa" [ testGroup "KAT" $ map (\(i,f) -> testCase (show (i :: Int)) f) $ zip [1..] $ map (\(r, k, i, p, e) -> salsaRunSimple r k i p e) vectors ] where salsaRunSimple rounds key nonce plain expected = let salsa = XSalsa.initialize rounds key nonce in fst (XSalsa.combine salsa plain) @?= expected cryptonite-0.23/benchs/Bench.hs0000644000000000000000000001533413075454604014657 0ustar0000000000000000{-# LANGUAGE PackageImports #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ExistentialQuantification #-} module Main where import Criterion.Main import Crypto.Cipher.AES import Crypto.Cipher.Blowfish import qualified Crypto.Cipher.ChaChaPoly1305 as CP import Crypto.Cipher.DES import Crypto.Cipher.Types import Crypto.Error import Crypto.Hash import qualified Crypto.KDF.PBKDF2 as PBKDF2 import qualified Crypto.PubKey.ECC.Types as ECC import qualified Crypto.PubKey.ECC.Prim as ECC import Crypto.Random import Data.ByteArray (ByteArray, Bytes) import qualified Data.ByteString as B import System.IO.Unsafe (unsafePerformIO) import Number.F2m data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg benchHash = [ bgroup "1KB" $ map (doHashBench oneKB) hashAlgs , bgroup "1MB" $ map (doHashBench oneMB) hashAlgs ] where doHashBench b (name, HashAlg alg) = bench name $ nf (hashWith alg) b oneKB :: Bytes oneKB = unsafePerformIO (getRandomBytes 1024) {-# NOINLINE oneKB #-} oneMB :: Bytes oneMB = unsafePerformIO (getRandomBytes $ 1024 * 1024) {-# NOINLINE oneMB #-} hashAlgs = [ ("MD2", HashAlg MD2) , ("MD4", HashAlg MD4) , ("MD5", HashAlg MD5) , ("SHA1", HashAlg SHA1) , ("SHA224", HashAlg SHA224) , ("SHA256", HashAlg SHA256) , ("SHA384", HashAlg SHA384) , ("SHA512", HashAlg SHA512) , ("SHA512t_224", HashAlg SHA512t_224) , ("SHA512t_256", HashAlg SHA512t_256) , ("RIPEMD160", HashAlg RIPEMD160) , ("Tiger", HashAlg Tiger) --, ("Skein256-160", HashAlg Skein256_160) , ("Skein256-256", HashAlg Skein256_256) --, ("Skein512-160", HashAlg Skein512_160) , ("Skein512-384", HashAlg Skein512_384) , ("Skein512-512", HashAlg Skein512_512) --, ("Skein512-896", HashAlg Skein512_896) , ("Whirlpool", HashAlg Whirlpool) , ("Keccak-224", HashAlg Keccak_224) , ("Keccak-256", HashAlg Keccak_256) , ("Keccak-384", HashAlg Keccak_384) , ("Keccak-512", HashAlg Keccak_512) , ("SHA3-224", HashAlg SHA3_224) , ("SHA3-256", HashAlg SHA3_256) , ("SHA3-384", HashAlg SHA3_384) , ("SHA3-512", HashAlg SHA3_512) , ("Blake2b-160", HashAlg Blake2b_160) , ("Blake2b-224", HashAlg Blake2b_224) , ("Blake2b-256", HashAlg Blake2b_256) , ("Blake2b-384", HashAlg Blake2b_384) , ("Blake2b-512", HashAlg Blake2b_512) , ("Blake2s-160", HashAlg Blake2s_160) , ("Blake2s-224", HashAlg Blake2s_224) , ("Blake2s-256", HashAlg Blake2s_256) ] benchPBKDF2 = [ bgroup "64" [ bench "cryptonite-PBKDF2-100-64" $ nf (pbkdf2 64) 100 , bench "cryptonite-PBKDF2-1000-64" $ nf (pbkdf2 64) 1000 , bench "cryptonite-PBKDF2-10000-64" $ nf (pbkdf2 64) 10000 ] , bgroup "128" [ bench "cryptonite-PBKDF2-100-128" $ nf (pbkdf2 128) 100 , bench "cryptonite-PBKDF2-1000-128" $ nf (pbkdf2 128) 1000 , bench "cryptonite-PBKDF2-10000-128" $ nf (pbkdf2 128) 10000 ] ] where pbkdf2 :: Int -> Int -> B.ByteString pbkdf2 n iter = PBKDF2.generate (PBKDF2.prfHMAC SHA512) (params n iter) mypass mysalt mypass, mysalt :: B.ByteString mypass = "password" mysalt = "salt" params n iter = PBKDF2.Parameters iter n benchBlockCipher = [ bgroup "ECB" benchECB , bgroup "CBC" benchCBC ] where benchECB = [ bench "DES-input=1024" $ nf (run (undefined :: DES) cipherInit key8) input1024 , bench "Blowfish128-input=1024" $ nf (run (undefined :: Blowfish128) cipherInit key16) input1024 , bench "AES128-input=1024" $ nf (run (undefined :: AES128) cipherInit key16) input1024 , bench "AES256-input=1024" $ nf (run (undefined :: AES256) cipherInit key32) input1024 ] where run :: (ByteArray ba, ByteArray key, BlockCipher c) => c -> (key -> CryptoFailable c) -> key -> ba -> ba run witness initF key input = (ecbEncrypt (throwCryptoError (initF key))) input benchCBC = [ bench "DES-input=1024" $ nf (run (undefined :: DES) cipherInit key8 iv8) input1024 , bench "Blowfish128-input=1024" $ nf (run (undefined :: Blowfish128) cipherInit key16 iv8) input1024 , bench "AES128-input=1024" $ nf (run (undefined :: AES128) cipherInit key16 iv16) input1024 , bench "AES256-input=1024" $ nf (run (undefined :: AES256) cipherInit key32 iv16) input1024 ] where run :: (ByteArray ba, ByteArray key, BlockCipher c) => c -> (key -> CryptoFailable c) -> key -> IV c -> ba -> ba run witness initF key iv input = (cbcEncrypt (throwCryptoError (initF key))) iv input key8 = B.replicate 8 0 key16 = B.replicate 16 0 key32 = B.replicate 32 0 input1024 = B.replicate 1024 0 iv8 :: BlockCipher c => IV c iv8 = maybe (error "iv size 8") id $ makeIV key8 iv16 :: BlockCipher c => IV c iv16 = maybe (error "iv size 16") id $ makeIV key16 benchAE = [ bench "ChaChaPoly1305" $ nf (run key32) (input64, input1024) ] where run k (ini, plain) = let iniState = throwCryptoError $ CP.initialize k (throwCryptoError $ CP.nonce12 nonce12) afterAAD = CP.finalizeAAD (CP.appendAAD ini iniState) (out, afterEncrypt) = CP.encrypt plain afterAAD outtag = CP.finalize afterEncrypt in (out, outtag) input64 = B.replicate 64 0 input1024 = B.replicate 1024 0 nonce12 :: B.ByteString nonce12 = B.replicate 12 0 key32 = B.replicate 32 0 benchECC = [ bench "pointAddTwoMuls-baseline" $ nf run_b (n1, p1, n2, p2) , bench "pointAddTwoMuls-optimized" $ nf run_o (n1, p1, n2, p2) ] where run_b (n, p, k, q) = ECC.pointAdd c (ECC.pointMul c n p) (ECC.pointMul c k q) run_o (n, p, k, q) = ECC.pointAddTwoMuls c n p k q c = ECC.getCurveByName ECC.SEC_p256r1 r1 = 7 r2 = 11 p1 = ECC.pointBaseMul c r1 p2 = ECC.pointBaseMul c r2 n1 = 0x2ba9daf2363b2819e69b34a39cf496c2458a9b2a21505ea9e7b7cbca42dc7435 n2 = 0xf054a7f60d10b8c2cf847ee90e9e029f8b0e971b09ca5f55c4d49921a11fadc1 main = defaultMain [ bgroup "hash" benchHash , bgroup "block-cipher" benchBlockCipher , bgroup "AE" benchAE , bgroup "pbkdf2" benchPBKDF2 , bgroup "ECC" benchECC , bgroup "F2m" benchF2m ] cryptonite-0.23/benchs/Number/F2m.hs0000644000000000000000000000236713075454604015516 0ustar0000000000000000{-# LANGUAGE PackageImports #-} module Number.F2m (benchF2m) where import Criterion.Main import System.Random import Crypto.Number.Basic (log2) import Crypto.Number.F2m genInteger :: Int -> Int -> Integer genInteger salt bits = head . dropWhile ((< bits) . log2) . scanl (\a r -> a * 2^(31 :: Int) + abs r) 0 . randoms . mkStdGen $ salt + bits benchMod :: Int -> Benchmark benchMod bits = bench (show bits) $ nf (modF2m m) a where m = genInteger 0 bits a = genInteger 1 (2 * bits) benchMul :: Int -> Benchmark benchMul bits = bench (show bits) $ nf (mulF2m m a) b where m = genInteger 0 bits a = genInteger 1 bits b = genInteger 2 bits benchSquare :: Int -> Benchmark benchSquare bits = bench (show bits) $ nf (squareF2m m) a where m = genInteger 0 bits a = genInteger 1 bits benchInv :: Int -> Benchmark benchInv bits = bench (show bits) $ nf (invF2m m) a where m = genInteger 0 bits a = genInteger 1 bits bitsList :: [Int] bitsList = [64, 128, 256, 512, 1024, 2048] benchF2m = [ bgroup "modF2m" $ map benchMod bitsList , bgroup "mulF2m" $ map benchMul bitsList , bgroup "squareF2m" $ map benchSquare bitsList , bgroup "invF2m" $ map benchInv bitsList ] cryptonite-0.23/README.md0000644000000000000000000000656412777073622013333 0ustar0000000000000000cryptonite ========== [![Join the chat at https://gitter.im/vincenthz/cryptonite](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/vincenthz/cryptonite?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/haskell-crypto/cryptonite.png?branch=master)](https://travis-ci.org/haskell-crypto/cryptonite) [![BSD](http://b.repl.ca/v1/license-BSD-blue.png)](http://en.wikipedia.org/wiki/BSD_licenses) [![Haskell](http://b.repl.ca/v1/language-haskell-lightgrey.png)](http://haskell.org) Cryptonite is a haskell repository of cryptographic primitives. Each crypto algorithm has specificities that are hard to wrap in common APIs and types, so instead of trying to provide a common ground for algorithms, this package provides a non-consistent low-level API. If you have no idea what you're doing, please do not use this directly. Instead, rely on higher level protocols or implementations. Documentation: [cryptonite on hackage](http://hackage.haskell.org/package/cryptonite) Versioning ---------- Development versions are an incremental number prefixed by 0. There is no API stability between development versions. Production versions : TBD Coding Style ------------ The coding style of this project mostly follows: [haskell-style](https://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md) Support ------- cryptonite supports the following platforms: * Windows >= 8 * OSX >= 10.8 * Linux * BSDs On the following architectures: * x86-64 * i386 On the following haskell versions: * GHC 7.0.x * GHC 7.4.x * GHC 7.6.x * GHC 7.8.x * GHC 7.10.x Further platforms and architectures probably work too, but since the maintainer(s) don't have regular access to them, we can't commit to further support. Known Building Issues --------------------- On OSX <= 10.7, the system compiler doesn't understand the '-maes' option, and with the lack of autodetection feature builtin in .cabal file, it is left on the user to disable the aesni. See the [Disabling AESNI] section Disabling AESNI --------------- It may be useful to disable AESNI for building, testing or runtime purposes. This is achieved with the *support_aesni* flag. As part of configure of cryptonite: ``` cabal configure --flag='-support_aesni' ``` or as part of an installation: ``` cabal install --constraint="cryptonite -support_aesni" ``` For help with cabal flags, see: [stackoverflow : is there a way to define flags for cabal](http://stackoverflow.com/questions/23523869/is-there-any-way-to-define-flags-for-cabal-dependencies) Links ----- * [ChaCha](http://cr.yp.to/chacha.html) * [ChaCha-test-vectors](https://github.com/secworks/chacha_testvectors.git) * [Poly1305](http://cr.yp.to/mac.html) * [Poly1305-test-vectors](http://tools.ietf.org/html/draft-nir-cfrg-chacha20-poly1305-06#page-12) * [Salsa](http://cr.yp.to/snuffle.html) * [Salsa128-test-vectors](https://github.com/alexwebr/salsa20/blob/master/test_vectors.128) * [Salsa256-test-vectors](https://github.com/alexwebr/salsa20/blob/master/test_vectors.256) * [XSalsa](https://cr.yp.to/snuffle/xsalsa-20081128.pdf) * [PBKDF2](http://tools.ietf.org/html/rfc2898) * [PBKDF2-test-vectors](http://www.ietf.org/rfc/rfc6070.txt) * [Scrypt](http://www.tarsnap.com/scrypt.html) * [Curve25519](http://cr.yp.to/ecdh.html) * [Ed25519](http://ed25519.cr.yp.to/papers.html) * [AFIS](http://clemens.endorphin.org/cryptography) cryptonite-0.23/CHANGELOG.md0000644000000000000000000001230213077673556013656 0ustar0000000000000000## 0.23 * Digest memory usage improvement by using unpinned memory * Fix generateBetween to generate within the right bounds * Add pure Twofish implementation * Fix memory allocation in P256 when using a temp point * Consolidate hash benchmark code * Add Nat-length Blake2 support (GHC > 8.0) * Update tutorial ## 0.22 * Add Argon2 (Password Hashing Competition winner) hash function * Update blake2 to latest upstream version * Add extra blake2 hashing size * Add faster PBKDF2 functions for SHA1/SHA256/SHA512 * Add SHAKE128 and SHAKE256 * Cleanup prime generation, and add tests * Add Time-based One Time Password (TOTP) and HMAC-based One Time Password (HOTP) * Rename Ed448 module name to Curve448, old module name still valid for now ## 0.21 * Drop automated tests with GHC 7.0, GHC 7.4, GHC 7.6. support dropped, but probably still working. * Improve non-aligned support in C sources, ChaCha and SHA3 now probably work on arch without support for unaligned access. not complete or tested. * Add another ECC framework that is more flexible, allowing different implementations to work instead of the existing Pure haskell NIST implementation. * Add ECIES basic primitives * Add XSalsa20 stream cipher * Process partial buffer correctly with Poly1305 ## 0.20 * Fixed hash truncation used in ECDSA signature & verification (Olivier Chéron) * Fix ECDH when scalar and coordinate bit sizes differ (Olivier Chéron) * Speed up ECDSA verification using Shamir's trick (Olivier Chéron) * Fix rdrand on windows ## 0.19 * Add tutorial (Yann Esposito) * Derive Show instance for better interaction with Show pretty printer (Eric Mertens) ## 0.18 * Re-used standard rdrand instructions instead of bytedump of rdrand instruction * Improvement to F2m, including lots of tests (Andrew Lelechenko) * Add error check on salt length in bcrypt ## 0.17 * Add Miyaguchi-Preneel construction (Kei Hibino) * Fix buffer length in scrypt (Luke Taylor) * build fixes for i686 and arm related to rdrand ## 0.16 * Fix basepoint for Ed448 * Enable 64-bit Curve25519 implementation ## 0.15 * Fix serialization of DH and ECDH ## 0.14 * Reduce size of SHA3 context instead of allocating all-size fit memory. save up to 72 bytes of memory per context for SHA3-512. * Add a Seed capability to the main DRG, to be able to debug/reproduce randomized program where you would want to disable the randomness. * Add support for Cipher-based Message Authentication Code (CMAC) (Kei Hibino) * *CHANGE* Change the `SharedKey` for `Crypto.PubKey.DH` and `Crypto.PubKey.ECC.DH`, from an Integer newtype to a ScrubbedBytes newtype. Prevent mistake where the bytes representation is generated without the right padding (when needed). * *CHANGE* Keep The field size in bits, in the `Params` in `Crypto.PubKey.DH`, moving from 2 elements to 3 elements in the structure. ## 0.13 * *SECURITY* Fix buffer overflow issue in SHA384, copying 16 extra bytes from the SHA512 context to the destination memory pointer leading to memory corruption, segfault. (Mikael Bung) ## 0.12 * Fix compilation issue with Ed448 on 32 bits machine. ## 0.11 * Truncate hashing correctly for DSA * Add support for HKDF (RFC 5869) * Add support for Ed448 * Extends support for Blake2s to 224 bits version. * Compilation workaround for old distribution (RHEL 4.1) * Compilation fix for AIX * Compilation fix with AESNI and ghci compiling C source in a weird order. * Fix example compilation, typo, and warning ## 0.10 * Add reference implementation of blake2 for non-SSE2 platform * Add support\_blake2\_sse flag ## 0.9 * Quiet down unused module imports * Move Curve25519 over to Crypto.Error instead of using Either String. * Add documentation for ChaChaPoly1305 * Add missing documentation for various modules * Add a way to create Poly1305 Auth tag. * Added support for the BLAKE2 family of hash algorithms * Fix endianness of incrementNonce function for ChaChaPoly1305 ## 0.8 * Add support for ChaChaPoly1305 Nonce Increment (John Galt) * Move repository to the haskell-crypto organisation ## 0.7 * Add PKCS5 / PKCS7 padding and unpadding methods * Fix ChaChaPoly1305 Decryption * Add support for BCrypt (Luke Taylor) ## 0.6 * Add ChaChaPoly1305 AE cipher * Add instructions in README for building on old OSX * Fix blocking /dev/random Andrey Sverdlichenko ## 0.5 * Fix all strays exports to all be under the cryptonite prefix. ## 0.4 * Add a System DRG that represent a referentially transparent of evaluated bytes while using lazy evaluation for future entropy values. ## 0.3 * Allow drgNew to run in any MonadRandom, providing cascading initialization * Remove Crypto.PubKey.HashDescr in favor of just having the algorithm specified in PKCS15 RSA function. * Fix documentation in cipher sub section (Luke Taylor) * Cleanup AES dead functions (Luke Taylor) * Fix Show instance of Digest to display without quotes similar to cryptohash * Use scrubbed bytes instead of bytes for P256 scalar ## 0.2 * Fix P256 compilation and exactness, + add tests * Add a raw memory number serialization capability (i2osp, os2ip) * Improve tests for number serialization * Improve tests for ECC arithmetics * Add Ord instance for Digest (Nicolas Di Prima) * Fix entropy compilation on windows 64 bits. ## 0.1 * Initial release cryptonite-0.23/LICENSE0000644000000000000000000000273012521065000013022 0ustar0000000000000000Copyright (c) 2006-2015 Vincent Hanquez All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the author nor the names of his contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. cryptonite-0.23/Setup.hs0000644000000000000000000000005613054074213013460 0ustar0000000000000000import Distribution.Simple main = defaultMain cryptonite-0.23/cryptonite.cabal0000644000000000000000000003517513077673562015243 0ustar0000000000000000Name: cryptonite Version: 0.23 Synopsis: Cryptography Primitives sink Description: A repository of cryptographic primitives. . * Symmetric ciphers: AES, DES, 3DES, Blowfish, Camellia, RC4, Salsa, XSalsa, ChaCha. . * Hash: SHA1, SHA2, SHA3, SHAKE, MD2, MD4, MD5, Keccak, Skein, Ripemd, Tiger, Whirlpool, Blake2 . * MAC: HMAC, Poly1305 . * Asymmetric crypto: DSA, RSA, DH, ECDH, ECDSA, ECC, Curve25519, Curve448, Ed25519 . * Key Derivation Function: PBKDF2, Scrypt, HKDF, Argon2 . * Cryptographic Random generation: System Entropy, Deterministic Random Generator . * Data related: Anti-Forensic Information Splitter (AFIS) . If anything cryptographic related is missing from here, submit a pull request to have it added. This package strive to be a cryptographic kitchen sink that provides cryptography for everyone. . Evaluate the security related to your requirements before using. . Read "Crypto.Tutorial" for a quick start guide. License: BSD3 License-file: LICENSE Copyright: Vincent Hanquez Author: Vincent Hanquez Maintainer: vincent@snarc.org Category: Cryptography Stability: experimental Build-Type: Simple Homepage: https://github.com/haskell-crypto/cryptonite Bug-reports: https://github.com/haskell-crypto/cryptonite/issues Cabal-Version: >=1.18 extra-doc-files: README.md CHANGELOG.md extra-source-files: cbits/*.h cbits/aes/*.h cbits/ed25519/*.h cbits/ed448/*.h cbits/p256/*.h cbits/blake2/ref/*.h cbits/blake2/sse/*.h cbits/argon2/*.h cbits/argon2/*.c cbits/aes/x86ni_impl.c tests/*.hs source-repository head type: git location: https://github.com/haskell-crypto/cryptonite Flag support_aesni Description: allow compilation with AESNI on system and architecture that supports it Default: True Manual: True Flag support_rdrand Description: allow compilation with RDRAND on system and architecture that supports it Default: True Manual: True Flag support_pclmuldq Description: Allow compilation with pclmuldq on architecture that supports it Default: False Manual: True Flag support_sse Description: Use SSE optimized version when existing (BLAKE2, ARGON2) Default: False Manual: True Flag support_blake2_sse Description: Use SSE optimized version of BLAKE2. Default: False Manual: True Flag integer-gmp Description: Whether or not to use GMP for some functions Default: True Manual: True Flag support_deepseq Description: add deepseq instances for cryptographic types Default: True Manual: True Flag old_toolchain_inliner Description: use -fgnu89-inline to workaround an old compiler / linker / glibc issue. Default: False Manual: True Flag check_alignment Description: extra check on alignment in C layers, which cause lowlevel assert errors. for debugging only. Default: False Manual: True Library Exposed-modules: Crypto.Cipher.AES Crypto.Cipher.Blowfish Crypto.Cipher.Camellia Crypto.Cipher.ChaCha Crypto.Cipher.ChaChaPoly1305 Crypto.Cipher.DES Crypto.Cipher.RC4 Crypto.Cipher.Salsa Crypto.Cipher.TripleDES Crypto.Cipher.Twofish Crypto.Cipher.Types Crypto.Cipher.Utils Crypto.Cipher.XSalsa Crypto.ConstructHash.MiyaguchiPreneel Crypto.Data.AFIS Crypto.Data.Padding Crypto.ECC Crypto.Error Crypto.MAC.CMAC Crypto.MAC.Poly1305 Crypto.MAC.HMAC Crypto.Number.Basic Crypto.Number.F2m Crypto.Number.Generate Crypto.Number.ModArithmetic Crypto.Number.Prime Crypto.Number.Serialize Crypto.Number.Serialize.Internal Crypto.KDF.Argon2 Crypto.KDF.PBKDF2 Crypto.KDF.Scrypt Crypto.KDF.BCrypt Crypto.KDF.HKDF Crypto.Hash Crypto.Hash.IO Crypto.Hash.Algorithms Crypto.OTP Crypto.PubKey.Curve25519 Crypto.PubKey.Curve448 Crypto.PubKey.MaskGenFunction Crypto.PubKey.DH Crypto.PubKey.DSA Crypto.PubKey.ECC.Generate Crypto.PubKey.ECC.Prim Crypto.PubKey.ECC.DH Crypto.PubKey.ECC.ECDSA Crypto.PubKey.ECC.P256 Crypto.PubKey.ECC.Types Crypto.PubKey.ECIES Crypto.PubKey.Ed25519 Crypto.PubKey.Ed448 Crypto.PubKey.RSA Crypto.PubKey.RSA.PKCS15 Crypto.PubKey.RSA.Prim Crypto.PubKey.RSA.PSS Crypto.PubKey.RSA.OAEP Crypto.PubKey.RSA.Types Crypto.Random Crypto.Random.Types Crypto.Random.Entropy Crypto.Random.EntropyPool Crypto.Random.Entropy.Unsafe Crypto.Tutorial Other-modules: Crypto.Cipher.AES.Primitive Crypto.Cipher.Blowfish.Box Crypto.Cipher.Blowfish.Primitive Crypto.Cipher.Camellia.Primitive Crypto.Cipher.DES.Primitive Crypto.Cipher.Twofish.Primitive Crypto.Cipher.Types.AEAD Crypto.Cipher.Types.Base Crypto.Cipher.Types.Block Crypto.Cipher.Types.GF Crypto.Cipher.Types.Stream Crypto.Cipher.Types.Utils Crypto.Error.Types Crypto.Number.Compat Crypto.Hash.Types Crypto.Hash.Blake2s Crypto.Hash.Blake2sp Crypto.Hash.Blake2b Crypto.Hash.Blake2bp Crypto.Hash.SHA1 Crypto.Hash.SHA224 Crypto.Hash.SHA256 Crypto.Hash.SHA384 Crypto.Hash.SHA512 Crypto.Hash.SHA512t Crypto.Hash.SHA3 Crypto.Hash.Keccak Crypto.Hash.MD2 Crypto.Hash.MD4 Crypto.Hash.MD5 Crypto.Hash.RIPEMD160 Crypto.Hash.Skein256 Crypto.Hash.Skein512 Crypto.Hash.Tiger Crypto.Hash.Whirlpool Crypto.Random.Entropy.Source Crypto.Random.Entropy.Backend Crypto.Random.ChaChaDRG Crypto.Random.SystemDRG Crypto.Random.Probabilistic Crypto.PubKey.Internal Crypto.PubKey.ElGamal Crypto.ECC.Simple.Types Crypto.ECC.Simple.Prim Crypto.Internal.Proxy Crypto.Internal.ByteArray Crypto.Internal.Compat Crypto.Internal.CompatPrim Crypto.Internal.DeepSeq Crypto.Internal.Imports Crypto.Internal.Words Crypto.Internal.WordArray if impl(ghc >= 7.8) Other-modules: Crypto.Hash.SHAKE Crypto.Hash.Blake2 Crypto.Internal.Nat Build-depends: base >= 4.3 && < 5 , bytestring , memory >= 0.14.5 , foundation >= 0.0.8 , ghc-prim ghc-options: -Wall -fwarn-tabs -optc-O3 -fno-warn-unused-imports default-language: Haskell2010 cc-options: -std=gnu99 if flag(old_toolchain_inliner) cc-options: -fgnu89-inline C-sources: cbits/cryptonite_chacha.c , cbits/cryptonite_salsa.c , cbits/cryptonite_xsalsa.c , cbits/cryptonite_rc4.c , cbits/cryptonite_cpu.c , cbits/ed25519/ed25519.c , cbits/ed448/x448.c , cbits/p256/p256.c , cbits/p256/p256_ec.c , cbits/cryptonite_blake2s.c , cbits/cryptonite_blake2sp.c , cbits/cryptonite_blake2b.c , cbits/cryptonite_blake2bp.c , cbits/cryptonite_poly1305.c , cbits/cryptonite_sha1.c , cbits/cryptonite_sha256.c , cbits/cryptonite_sha512.c , cbits/cryptonite_sha3.c , cbits/cryptonite_md2.c , cbits/cryptonite_md4.c , cbits/cryptonite_md5.c , cbits/cryptonite_ripemd.c , cbits/cryptonite_skein256.c , cbits/cryptonite_skein512.c , cbits/cryptonite_tiger.c , cbits/cryptonite_whirlpool.c , cbits/cryptonite_scrypt.c , cbits/cryptonite_pbkdf2.c include-dirs: cbits cbits/ed25519 if arch(x86_64) C-sources: cbits/curve25519/curve25519-donna-c64.c else C-sources: cbits/curve25519/curve25519-donna.c -- FIXME armel or mispel is also little endian. -- might be a good idea to also add a runtime autodetect mode. -- ARCH_ENDIAN_UNKNOWN if (arch(i386) || arch(x86_64)) CPP-options: -DARCH_IS_LITTLE_ENDIAN if arch(i386) CPP-options: -DARCH_X86 if arch(x86_64) CPP-options: -DARCH_X86_64 if flag(support_rdrand) && (arch(i386) || arch(x86_64)) && !os(windows) CPP-options: -DSUPPORT_RDRAND Other-modules: Crypto.Random.Entropy.RDRand c-sources: cbits/cryptonite_rdrand.c if flag(support_aesni) && (os(linux) || os(freebsd) || os(osx)) && (arch(i386) || arch(x86_64)) CC-options: -mssse3 -maes -DWITH_AESNI if flag(support_pclmuldq) CC-options: -msse4.1 -mpclmul -DWITH_PCLMUL C-sources: cbits/aes/x86ni.c , cbits/aes/generic.c , cbits/aes/gf.c , cbits/cryptonite_aes.c else C-sources: cbits/aes/generic.c , cbits/aes/gf.c , cbits/cryptonite_aes.c if arch(x86_64) || flag(support_blake2_sse) C-sources: cbits/blake2/sse/blake2s.c , cbits/blake2/sse/blake2sp.c , cbits/blake2/sse/blake2b.c , cbits/blake2/sse/blake2bp.c include-dirs: cbits/blake2/sse else C-sources: cbits/blake2/ref/blake2s-ref.c , cbits/blake2/ref/blake2sp-ref.c , cbits/blake2/ref/blake2b-ref.c , cbits/blake2/ref/blake2bp-ref.c include-dirs: cbits/blake2/ref if arch(x86_64) || flag(support_sse) CPP-options: -DSUPPORT_SSE C-sources: cbits/argon2/argon2.c include-dirs: cbits/argon2 if os(windows) cpp-options: -DWINDOWS Build-Depends: Win32 Other-modules: Crypto.Random.Entropy.Windows extra-libraries: advapi32 else Other-modules: Crypto.Random.Entropy.Unix if impl(ghc) && flag(integer-gmp) Build-depends: integer-gmp if flag(support_deepseq) CPP-options: -DWITH_DEEPSEQ_SUPPORT Build-depends: deepseq if flag(check_alignment) cc-options: -DWITH_ASSERT_ALIGNMENT Test-Suite test-cryptonite type: exitcode-stdio-1.0 hs-source-dirs: tests Main-is: Tests.hs Other-modules: BlockCipher ChaCha BCrypt Hash Imports KAT_AES.KATCBC KAT_AES.KATECB KAT_AES.KATGCM KAT_AES.KATOCB3 KAT_AES.KATXTS KAT_AES KAT_AFIS KAT_Argon2 KAT_Blowfish KAT_Camellia KAT_Curve25519 KAT_Curve448 KAT_DES KAT_Ed25519 KAT_CMAC KAT_HKDF KAT_HMAC KAT_MiyaguchiPreneel KAT_PBKDF2 KAT_OTP KAT_PubKey.DSA KAT_PubKey.ECC KAT_PubKey.ECDSA KAT_PubKey.OAEP KAT_PubKey.PSS KAT_PubKey.P256 KAT_PubKey KAT_RC4 KAT_Scrypt KAT_TripleDES KAT_Twofish ChaChaPoly1305 Number Number.F2m Padding Poly1305 Salsa Utils XSalsa Build-Depends: base >= 3 && < 5 , bytestring , memory , tasty , tasty-quickcheck , tasty-hunit , tasty-kat , cryptonite ghc-options: -Wall -fno-warn-orphans -fno-warn-missing-signatures -fno-warn-unused-imports -rtsopts default-language: Haskell2010 Benchmark bench-cryptonite type: exitcode-stdio-1.0 hs-source-dirs: benchs Main-is: Bench.hs Other-modules: Number.F2m Build-Depends: base >= 3 && < 5 , bytestring , memory , criterion , random , cryptonite ghc-options: -Wall -fno-warn-missing-signatures default-language: Haskell2010 cryptonite-0.23/cbits/cryptonite_aes.h0000644000000000000000000001057012455734561016350 0ustar0000000000000000/* * Copyright (C) 2008 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * AES implementation */ #ifndef CRYPTONITE_AES_H #define CRYPTONITE_AES_H #include #include "aes/block128.h" typedef block128 aes_block; /* size = 456 */ typedef struct { uint8_t nbr; /* number of rounds: 10 (128), 12 (192), 14 (256) */ uint8_t strength; /* 128 = 0, 192 = 1, 256 = 2 */ uint8_t _padding[6]; uint8_t data[16*14*2]; } aes_key; /* size = 4*16+2*8= 80 */ typedef struct { aes_block tag; aes_block h; aes_block iv; aes_block civ; uint64_t length_aad; uint64_t length_input; } aes_gcm; typedef struct { block128 offset_aad; block128 offset_enc; block128 sum_aad; block128 sum_enc; block128 lstar; block128 ldollar; block128 li[4]; } aes_ocb; /* in bytes: either 16,24,32 */ void cryptonite_aes_initkey(aes_key *ctx, uint8_t *key, uint8_t size); void cryptonite_aes_encrypt(aes_block *output, aes_key *key, aes_block *input); void cryptonite_aes_decrypt(aes_block *output, aes_key *key, aes_block *input); void cryptonite_aes_encrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_decrypt_ecb(aes_block *output, aes_key *key, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_encrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_decrypt_cbc(aes_block *output, aes_key *key, aes_block *iv, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_gen_ctr(aes_block *output, aes_key *key, const aes_block *iv, uint32_t nb_blocks); void cryptonite_aes_gen_ctr_cont(aes_block *output, aes_key *key, aes_block *iv, uint32_t nb_blocks); void cryptonite_aes_encrypt_xts(aes_block *output, aes_key *key, aes_key *key2, aes_block *sector, uint32_t spoint, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_decrypt_xts(aes_block *output, aes_key *key, aes_key *key2, aes_block *sector, uint32_t spoint, aes_block *input, uint32_t nb_blocks); void cryptonite_aes_gcm_init(aes_gcm *gcm, aes_key *key, uint8_t *iv, uint32_t len); void cryptonite_aes_gcm_aad(aes_gcm *gcm, uint8_t *input, uint32_t length); void cryptonite_aes_gcm_encrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_gcm_decrypt(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_gcm_finish(uint8_t *tag, aes_gcm *gcm, aes_key *key); void cryptonite_aes_ocb_init(aes_ocb *ocb, aes_key *key, uint8_t *iv, uint32_t len); void cryptonite_aes_ocb_aad(aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_ocb_encrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_ocb_decrypt(uint8_t *output, aes_ocb *ocb, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_ocb_finish(uint8_t *tag, aes_ocb *ocb, aes_key *key); #endif cryptonite-0.23/cbits/cryptonite_align.h0000644000000000000000000000524013052512104016645 0ustar0000000000000000#ifndef CRYPTONITE_ALIGN_H #define CRYPTONITE_ALIGN_H #include "cryptonite_bitfn.h" #if (defined(__i386__)) # define UNALIGNED_ACCESS_OK #elif defined(__x86_64__) # define UNALIGNED_ACCESS_OK #else # define UNALIGNED_ACCESS_FAULT #endif /* n need to be power of 2. * IS_ALIGNED(p,8) */ #define IS_ALIGNED(p,alignment) (((uintptr_t) (p)) & ((alignment)-1)) #ifdef WITH_ASSERT_ALIGNMENT #include #include #include # define ASSERT_ALIGNMENT(up, alignment) \ do { if (IS_ALIGNED(up, alignment)) \ { printf("ALIGNMENT-ASSERT-FAILURE: %s:%d: ptr=%p alignment=%d\n", __FILE__, __LINE__, (void *) up, (alignment)); \ exit(99); \ }; } while (0) #else # define ASSERT_ALIGNMENT(p, n) do {} while (0) #endif #ifdef UNALIGNED_ACCESS_OK #define need_alignment(p,n) (0) #else #define need_alignment(p,n) IS_ALIGNED(p,n) #endif static inline uint32_t load_le32_aligned(const uint8_t *p) { return le32_to_cpu(*((uint32_t *) p)); } static inline void store_le32_aligned(uint8_t *dst, const uint32_t v) { *((uint32_t *) dst) = cpu_to_le32(v); } static inline void store_be32_aligned(uint8_t *dst, const uint32_t v) { *((uint32_t *) dst) = cpu_to_be32(v); } static inline void store_le64_aligned(uint8_t *dst, const uint64_t v) { *((uint64_t *) dst) = cpu_to_le64(v); } static inline void store_be64_aligned(uint8_t *dst, const uint64_t v) { *((uint64_t *) dst) = cpu_to_be64(v); } #ifdef UNALIGNED_ACCESS_OK #define load_le32(a) load_le32_aligned(a) #else static inline uint32_t load_le32(const uint8_t *p) { return ((uint32_t)p[0]) | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); } #endif #ifdef UNALIGNED_ACCESS_OK #define store_le32(a, b) store_le32_aligned(a, b) #else static inline void store_le32(uint8_t *dst, const uint32_t v) { dst[0] = v; dst[1] = v >> 8; dst[2] = v >> 16; dst[3] = v >> 24; } #endif #ifdef UNALIGNED_ACCESS_OK #define store_be32(a, b) store_be32_aligned(a, b) #else static inline void store_be32(uint8_t *dst, const uint32_t v) { dst[3] = v; dst[2] = v >> 8; dst[1] = v >> 16; dst[0] = v >> 24; } #endif #ifdef UNALIGNED_ACCESS_OK #define store_le64(a, b) store_le64_aligned(a, b) #else static inline void store_le64(uint8_t *dst, const uint64_t v) { dst[0] = v ; dst[1] = v >> 8 ; dst[2] = v >> 16; dst[3] = v >> 24; dst[4] = v >> 32; dst[5] = v >> 40; dst[6] = v >> 48; dst[7] = v >> 56; } #endif #ifdef UNALIGNED_ACCESS_OK #define store_be64(a, b) store_be64_aligned(a, b) #else static inline void store_be64(uint8_t *dst, const uint64_t v) { dst[7] = v ; dst[6] = v >> 8 ; dst[5] = v >> 16; dst[4] = v >> 24; dst[3] = v >> 32; dst[2] = v >> 40; dst[1] = v >> 48; dst[0] = v >> 56; } #endif #endif cryptonite-0.23/cbits/cryptonite_bitfn.h0000644000000000000000000001570113052511171016663 0ustar0000000000000000/* * Copyright (C) 2006-2014 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef BITFN_H #define BITFN_H #include #ifndef NO_INLINE_ASM /**********************************************************/ # if (defined(__i386__)) # define ARCH_HAS_SWAP32 static inline uint32_t bitfn_swap32(uint32_t a) { asm ("bswap %0" : "=r" (a) : "0" (a)); return a; } /**********************************************************/ # elif (defined(__arm__)) # define ARCH_HAS_SWAP32 static inline uint32_t bitfn_swap32(uint32_t a) { uint32_t tmp = a; asm volatile ("eor %1, %0, %0, ror #16\n" "bic %1, %1, #0xff0000\n" "mov %0, %0, ror #8\n" "eor %0, %0, %1, lsr #8\n" : "=r" (a), "=r" (tmp) : "0" (a), "1" (tmp)); return a; } /**********************************************************/ # elif defined(__x86_64__) # define ARCH_HAS_SWAP32 # define ARCH_HAS_SWAP64 static inline uint32_t bitfn_swap32(uint32_t a) { asm ("bswap %0" : "=r" (a) : "0" (a)); return a; } static inline uint64_t bitfn_swap64(uint64_t a) { asm ("bswap %0" : "=r" (a) : "0" (a)); return a; } # endif #endif /* NO_INLINE_ASM */ /**********************************************************/ #ifndef ARCH_HAS_ROL32 static inline uint32_t rol32(uint32_t word, uint32_t shift) { return (word << shift) | (word >> (32 - shift)); } #endif #ifndef ARCH_HAS_ROR32 static inline uint32_t ror32(uint32_t word, uint32_t shift) { return (word >> shift) | (word << (32 - shift)); } #endif #ifndef ARCH_HAS_ROL64 static inline uint64_t rol64(uint64_t word, uint32_t shift) { return (word << shift) | (word >> (64 - shift)); } #endif #ifndef ARCH_HAS_ROR64 static inline uint64_t ror64(uint64_t word, uint32_t shift) { return (word >> shift) | (word << (64 - shift)); } #endif #ifndef ARCH_HAS_SWAP32 static inline uint32_t bitfn_swap32(uint32_t a) { return (a << 24) | ((a & 0xff00) << 8) | ((a >> 8) & 0xff00) | (a >> 24); } #endif #ifndef ARCH_HAS_ARRAY_SWAP32 static inline void array_swap32(uint32_t *d, uint32_t *s, uint32_t nb) { while (nb--) *d++ = bitfn_swap32(*s++); } #endif #ifndef ARCH_HAS_SWAP64 static inline uint64_t bitfn_swap64(uint64_t a) { return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) | (((uint64_t) bitfn_swap32((uint32_t) a)) << 32); } #endif #ifndef ARCH_HAS_ARRAY_SWAP64 static inline void array_swap64(uint64_t *d, uint64_t *s, uint32_t nb) { while (nb--) *d++ = bitfn_swap64(*s++); } #endif #ifndef ARCH_HAS_MEMORY_ZERO static inline void memory_zero(void *ptr, uint32_t len) { uint32_t *ptr32 = ptr; uint8_t *ptr8; int i; for (i = 0; i < len / 4; i++) *ptr32++ = 0; if (len % 4) { ptr8 = (uint8_t *) ptr32; for (i = len % 4; i >= 0; i--) ptr8[i] = 0; } } #endif #ifndef ARCH_HAS_ARRAY_COPY32 static inline void array_copy32(uint32_t *d, uint32_t *s, uint32_t nb) { while (nb--) *d++ = *s++; } #endif #ifndef ARCH_HAS_ARRAY_XOR32 static inline void array_xor32(uint32_t *d, uint32_t *s, uint32_t nb) { while (nb--) *d++ ^= *s++; } #endif #ifndef ARCH_HAS_ARRAY_COPY64 static inline void array_copy64(uint64_t *d, uint64_t *s, uint32_t nb) { while (nb--) *d++ = *s++; } #endif #ifdef __GNUC__ #define bitfn_ntz(n) __builtin_ctz(n) #else #error "define ntz for your platform" #endif #ifdef __MINGW32__ # define LITTLE_ENDIAN 1234 # define BYTE_ORDER LITTLE_ENDIAN #elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) # include #elif defined(__OpenBSD__) || defined(__SVR4) # include #elif defined(__APPLE__) # include #elif defined( BSD ) && ( BSD >= 199103 ) # include #elif defined( __QNXNTO__ ) && defined( __LITTLEENDIAN__ ) # define LITTLE_ENDIAN 1234 # define BYTE_ORDER LITTLE_ENDIAN #elif defined( __QNXNTO__ ) && defined( __BIGENDIAN__ ) # define BIG_ENDIAN 1234 # define BYTE_ORDER BIG_ENDIAN #elif defined( _AIX ) # include #else # include #endif /* big endian to cpu */ #if LITTLE_ENDIAN == BYTE_ORDER # define be32_to_cpu(a) bitfn_swap32(a) # define cpu_to_be32(a) bitfn_swap32(a) # define le32_to_cpu(a) (a) # define cpu_to_le32(a) (a) # define be64_to_cpu(a) bitfn_swap64(a) # define cpu_to_be64(a) bitfn_swap64(a) # define le64_to_cpu(a) (a) # define cpu_to_le64(a) (a) # define cpu_to_le32_array(d, s, l) array_copy32(d, s, l) # define le32_to_cpu_array(d, s, l) array_copy32(d, s, l) # define cpu_to_be32_array(d, s, l) array_swap32(d, s, l) # define be32_to_cpu_array(d, s, l) array_swap32(d, s, l) # define cpu_to_le64_array(d, s, l) array_copy64(d, s, l) # define le64_to_cpu_array(d, s, l) array_copy64(d, s, l) # define cpu_to_be64_array(d, s, l) array_swap64(d, s, l) # define be64_to_cpu_array(d, s, l) array_swap64(d, s, l) # define ror32_be(a, s) rol32(a, s) # define rol32_be(a, s) ror32(a, s) # define ARCH_IS_LITTLE_ENDIAN #elif BIG_ENDIAN == BYTE_ORDER # define be32_to_cpu(a) (a) # define cpu_to_be32(a) (a) # define be64_to_cpu(a) (a) # define cpu_to_be64(a) (a) # define le64_to_cpu(a) bitfn_swap64(a) # define cpu_to_le64(a) bitfn_swap64(a) # define le32_to_cpu(a) bitfn_swap32(a) # define cpu_to_le32(a) bitfn_swap32(a) # define cpu_to_le32_array(d, s, l) array_swap32(d, s, l) # define le32_to_cpu_array(d, s, l) array_swap32(d, s, l) # define cpu_to_be32_array(d, s, l) array_copy32(d, s, l) # define be32_to_cpu_array(d, s, l) array_copy32(d, s, l) # define cpu_to_le64_array(d, s, l) array_swap64(d, s, l) # define le64_to_cpu_array(d, s, l) array_swap64(d, s, l) # define cpu_to_be64_array(d, s, l) array_copy64(d, s, l) # define be64_to_cpu_array(d, s, l) array_copy64(d, s, l) # define ror32_be(a, s) ror32(a, s) # define rol32_be(a, s) rol32(a, s) # define ARCH_IS_BIG_ENDIAN #else # error "endian not supported" #endif #endif /* !BITFN_H */ cryptonite-0.23/cbits/cryptonite_blake2b.h0000644000000000000000000000054712673727640017107 0ustar0000000000000000#ifndef CRYPTOHASH_BLAKE2B_H #define CRYPTOHASH_BLAKE2B_H #include "blake2.h" typedef blake2b_state blake2b_ctx; void cryptonite_blake2b_init(blake2b_ctx *ctx, uint32_t hashlen); void cryptonite_blake2b_update(blake2b_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_blake2b_finalize(blake2b_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_blake2bp.h0000644000000000000000000000056112673727640017263 0ustar0000000000000000#ifndef CRYPTOHASH_BLAKE2BP_H #define CRYPTOHASH_BLAKE2BP_H #include "blake2.h" typedef blake2bp_state blake2bp_ctx; void cryptonite_blake2bp_init(blake2bp_ctx *ctx, uint32_t hashlen); void cryptonite_blake2bp_update(blake2bp_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_blake2bp_finalize(blake2bp_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_blake2s.h0000644000000000000000000000054712673727640017130 0ustar0000000000000000#ifndef CRYPTOHASH_BLAKE2S_H #define CRYPTOHASH_BLAKE2S_H #include "blake2.h" typedef blake2s_state blake2s_ctx; void cryptonite_blake2s_init(blake2s_ctx *ctx, uint32_t hashlen); void cryptonite_blake2s_update(blake2s_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_blake2s_finalize(blake2s_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_blake2sp.h0000644000000000000000000000056112673727640017304 0ustar0000000000000000#ifndef CRYPTOHASH_BLAKE2SP_H #define CRYPTOHASH_BLAKE2SP_H #include "blake2.h" typedef blake2sp_state blake2sp_ctx; void cryptonite_blake2sp_init(blake2sp_ctx *ctx, uint32_t hashlen); void cryptonite_blake2sp_update(blake2sp_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_blake2sp_finalize(blake2sp_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_chacha.h0000644000000000000000000000454112527607223017002 0ustar0000000000000000/* * Copyright (c) 2014 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef CRYPTONITE_CHACHA #define CRYPTONITE_CHACHA typedef union { uint64_t q[8]; uint32_t d[16]; uint8_t b[64]; } block; typedef block cryptonite_chacha_state; typedef struct { cryptonite_chacha_state st; uint8_t prev[64]; uint8_t prev_ofs; uint8_t prev_len; uint8_t nb_rounds; } cryptonite_chacha_context; void cryptonite_chacha_init_core(cryptonite_chacha_state *st, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv); void cryptonite_chacha_init(cryptonite_chacha_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv); void cryptonite_chacha_combine(uint8_t *dst, cryptonite_chacha_context *st, const uint8_t *src, uint32_t bytes); void cryptonite_chacha_generate(uint8_t *dst, cryptonite_chacha_context *st, uint32_t bytes); #endif cryptonite-0.23/cbits/cryptonite_cpu.h0000644000000000000000000000350012541542114016345 0ustar0000000000000000/* * Copyright (C) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #ifndef CPU_H #define CPU_H #if defined(__i386__) || defined(__x86_64__) #define ARCH_X86 #define USE_AESNI #endif #ifdef USE_AESNI void cryptonite_aesni_initialize_hw(void (*init_table)(int, int)); #else #define cryptonite_aesni_initialize_hw(init_table) (0) #endif #endif cryptonite-0.23/cbits/cryptonite_curve25519.h0000644000000000000000000000023712462144657017330 0ustar0000000000000000#ifndef CRYPTONITE_CURVE25519_H #define CRYPTONITE_CURVE25519_H int cryptonite_curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint); #endif cryptonite-0.23/cbits/cryptonite_md2.h0000644000000000000000000000334212514540320016241 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_MD2_H #define CRYPTOHASH_MD2_H #include struct md2_ctx { uint64_t sz; uint8_t buf[16]; uint8_t h[16]; uint8_t cksum[16]; }; #define MD2_DIGEST_SIZE 16 #define MD2_CTX_SIZE sizeof(struct md2_ctx) void cryptonite_md2_init(struct md2_ctx *ctx); void cryptonite_md2_update(struct md2_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_md2_finalize(struct md2_ctx *ctx, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_md4.h0000644000000000000000000000331412514540320016242 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_MD4_H #define CRYPTOHASH_MD4_H #include struct md4_ctx { uint64_t sz; uint8_t buf[64]; uint32_t h[4]; }; #define MD4_DIGEST_SIZE 16 #define MD4_CTX_SIZE sizeof(struct md4_ctx) void cryptonite_md4_init(struct md4_ctx *ctx); void cryptonite_md4_update(struct md4_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_md4_finalize(struct md4_ctx *ctx, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_md5.h0000644000000000000000000000331412514540320016243 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_MD5_H #define CRYPTOHASH_MD5_H #include struct md5_ctx { uint64_t sz; uint8_t buf[64]; uint32_t h[4]; }; #define MD5_DIGEST_SIZE 16 #define MD5_CTX_SIZE sizeof(struct md5_ctx) void cryptonite_md5_init(struct md5_ctx *ctx); void cryptonite_md5_update(struct md5_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_md5_finalize(struct md5_ctx *ctx, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_pbkdf2.h0000644000000000000000000000211413050556742016736 0ustar0000000000000000#ifndef CRYPTONITE_PBKDF2_H_ #define CRYPTONITE_PBKDF2_H_ #include #include #ifdef __cplusplus extern "C" { #endif void cryptonite_fastpbkdf2_hmac_sha1( const uint8_t *pw, size_t npw , const uint8_t *salt, size_t nsalt , uint32_t iterations , uint8_t *out, size_t nout ); void cryptonite_fastpbkdf2_hmac_sha256( const uint8_t *pw, size_t npw , const uint8_t *salt, size_t nsalt , uint32_t iterations , uint8_t *out, size_t nout ); void cryptonite_fastpbkdf2_hmac_sha512( const uint8_t *pw, size_t npw , const uint8_t *salt, size_t nsalt , uint32_t iterations , uint8_t *out, size_t nout ); #ifdef __cplusplus } #endif #endif cryptonite-0.23/cbits/cryptonite_poly1305.h0000644000000000000000000000410112365237076017064 0ustar0000000000000000/* * Copyright (c) 2014 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef CRYPTONITE_POLY1305_H # define CRYPTONITE_POLY1305_H /* 8*8+1*16+1*4 = 84 */ typedef struct { uint32_t r[5]; uint32_t h[5]; uint32_t pad[4]; uint32_t index; uint8_t buf[16]; /* previous partial block */ } poly1305_ctx; typedef uint8_t poly1305_mac[16]; typedef uint8_t poly1305_key[32]; void cryptonite_poly1305_init(poly1305_ctx *ctx, poly1305_key *key); void cryptonite_poly1305_update(poly1305_ctx *ctx, uint8_t *data, uint32_t length); void cryptonite_poly1305_finalize(poly1305_mac mac, poly1305_ctx *ctx); #endif cryptonite-0.23/cbits/cryptonite_rc4.h0000644000000000000000000000046012400310060016233 0ustar0000000000000000#ifndef CRYPTONITE_RC4_H # define CRYPTONITE_RC4_H struct rc4_ctx { uint8_t state[256]; uint32_t i; uint32_t j; }; void cryptonite_rc4_init(uint8_t * key, uint32_t keylen, struct rc4_ctx *ctx); void cryptonite_rc4_combine(struct rc4_ctx *ctx, uint8_t *input, uint32_t len, uint8_t *output); #endif cryptonite-0.23/cbits/cryptonite_ripemd.h0000644000000000000000000000341412514540320017037 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_RIPEMD_H #define CRYPTOHASH_RIPEMD_H #include struct ripemd160_ctx { uint64_t sz; uint8_t buf[64]; uint32_t h[5]; }; #define RIPEMD160_DIGEST_SIZE 20 #define RIPEMD160_CTX_SIZE sizeof(struct ripemd160_ctx) void cryptonite_ripemd160_init(struct ripemd160_ctx *ctx); void cryptonite_ripemd160_update(struct ripemd160_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_ripemd160_finalize(struct ripemd160_ctx *ctx, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_salsa.h0000644000000000000000000000465112527614745016707 0ustar0000000000000000/* * Copyright (c) 2014 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef CRYPTONITE_SALSA #define CRYPTONITE_SALSA typedef union { uint64_t q[8]; uint32_t d[16]; uint8_t b[64]; } block; typedef block cryptonite_salsa_state; typedef struct { cryptonite_salsa_state st; uint8_t prev[64]; uint8_t prev_ofs; uint8_t prev_len; uint8_t nb_rounds; } cryptonite_salsa_context; /* for scrypt */ void cryptonite_salsa_core_xor(int rounds, block *out, block *in); void cryptonite_salsa_init_core(cryptonite_salsa_state *st, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv); void cryptonite_salsa_init(cryptonite_salsa_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv); void cryptonite_salsa_combine(uint8_t *dst, cryptonite_salsa_context *st, const uint8_t *src, uint32_t bytes); void cryptonite_salsa_generate(uint8_t *dst, cryptonite_salsa_context *st, uint32_t bytes); #endif cryptonite-0.23/cbits/cryptonite_sha1.h0000644000000000000000000000340413050556742016425 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SHA1_H #define CRYPTOHASH_SHA1_H #include # define SHA1_BLOCK_SIZE 64 struct sha1_ctx { uint64_t sz; uint8_t buf[SHA1_BLOCK_SIZE]; uint32_t h[5]; }; #define SHA1_DIGEST_SIZE 20 #define SHA1_CTX_SIZE (sizeof(struct sha1_ctx)) void cryptonite_sha1_init(struct sha1_ctx *ctx); void cryptonite_sha1_update(struct sha1_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_sha1_finalize(struct sha1_ctx *ctx, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_sha256.h0000644000000000000000000000413113050556742016577 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SHA256_H #define CRYPTOHASH_SHA256_H #include #define SHA256_BLOCK_SIZE 64 struct sha256_ctx { uint64_t sz; uint8_t buf[128]; uint32_t h[8]; }; #define sha224_ctx sha256_ctx #define SHA224_DIGEST_SIZE 28 #define SHA224_CTX_SIZE sizeof(struct sha224_ctx) #define SHA256_DIGEST_SIZE 32 #define SHA256_CTX_SIZE sizeof(struct sha256_ctx) void cryptonite_sha224_init(struct sha224_ctx *ctx); void cryptonite_sha224_update(struct sha224_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_sha224_finalize(struct sha224_ctx *ctx, uint8_t *out); void cryptonite_sha256_init(struct sha256_ctx *ctx); void cryptonite_sha256_update(struct sha256_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_sha256_finalize(struct sha256_ctx *ctx, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_sha3.h0000644000000000000000000000543613054050744016431 0ustar0000000000000000/* * Copyright (C) 2012 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SHA3_H #define CRYPTOHASH_SHA3_H #include struct sha3_ctx { uint32_t bufindex; uint32_t bufsz; uint64_t state[25]; uint8_t buf[0]; /* maximum SHAKE128 is 168 bytes, otherwise buffer can be decreased */ }; #define SHA3_CTX_SIZE sizeof(struct sha3_ctx) #define SHA3_CTX_BUF_MAX_SIZE (SHA3_CTX_SIZE + SHA3_BUF_SIZE_MAX) #define SHA3_BITSIZE_MIN 128 #define SHA3_BITSIZE_MAX 512 #define SHA3_BUF_SIZE(bitsize) (200 - 2 * ((bitsize) / 8)) #define SHA3_BUF_SIZE_MIN SHA3_BUF_SIZE(SHA3_BITSIZE_MAX) #define SHA3_BUF_SIZE_MAX SHA3_BUF_SIZE(SHA3_BITSIZE_MIN) /* * buffer size: * * 128 bits (shake 128 bits) => 200 - 2 * (128 / 8) = 200 - 2*16 = 200 - 32 = 168 bytes * 224 bits (SHA3 224 bits) => 200 - 2 * (224 / 8) = 200 - 2*28 = 200 - 56 = 144 bytes * 512 bits (SHA3 512 bits) => 200 - 2 * (512 / 8) = 200 - 2*64 = 200 - 128 = 72 bytes */ void cryptonite_sha3_init(struct sha3_ctx *ctx, uint32_t hashlen); void cryptonite_sha3_update(struct sha3_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_sha3_finalize(struct sha3_ctx *ctx, uint32_t hashlen, uint8_t *out); void cryptonite_sha3_finalize_shake(struct sha3_ctx *ctx); void cryptonite_sha3_output(struct sha3_ctx *ctx, uint8_t *out, uint32_t len); void cryptonite_keccak_init(struct sha3_ctx *ctx, uint32_t hashlen); void cryptonite_keccak_update(struct sha3_ctx *ctx, uint8_t *data, uint32_t len); void cryptonite_keccak_finalize(struct sha3_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_sha512.h0000644000000000000000000000464113050556742016600 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SHA512_H #define CRYPTOHASH_SHA512_H #include # define SHA512_BLOCK_SIZE 128 struct sha512_ctx { uint64_t sz[2]; uint8_t buf[SHA512_BLOCK_SIZE]; uint64_t h[8]; }; #define sha384_ctx sha512_ctx #define SHA384_DIGEST_SIZE 48 #define SHA384_CTX_SIZE sizeof(struct sha384_ctx) #define SHA512_DIGEST_SIZE 64 #define SHA512_CTX_SIZE sizeof(struct sha512_ctx) void cryptonite_sha384_init(struct sha384_ctx *ctx); void cryptonite_sha384_update(struct sha384_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_sha384_finalize(struct sha384_ctx *ctx, uint8_t *out); void cryptonite_sha512_init(struct sha512_ctx *ctx); void cryptonite_sha512_update(struct sha512_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_sha512_finalize(struct sha512_ctx *ctx, uint8_t *out); /* only multiples of 8 are supported as valid t values */ void cryptonite_sha512t_init(struct sha512_ctx *ctx, uint32_t hashlen); void cryptonite_sha512t_update(struct sha512_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_sha512t_finalize(struct sha512_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_skein.h0000644000000000000000000000353212365237076016710 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SKEIN_H #define CRYPTOHASH_SKEIN_H #define SKEIN_VERSION 1ULL #define SKEIN_IDSTRING 0x33414853ULL /* t0 0-63 || t1 64-127 0-95 96-111 112-118 119 120-125 126 127 Position reserved TreeLevel BitPad Type First Final */ #define FLAG_FIRST (1ULL << 62) #define FLAG_FINAL (1ULL << 63) #define FLAG_TYPE(x) (((uint64_t) ((x) & 0x3f)) << 56) #define TYPE_KEY 0x00 #define TYPE_CFG 0x04 #define TYPE_MSG 0x30 #define TYPE_OUT 0x3f #define SET_TYPE(ctx, ty) ctx->t0 = 0; ctx->t1 = (ty) #endif cryptonite-0.23/cbits/cryptonite_skein256.h0000644000000000000000000000345212673727640017151 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SKEIN256_H #define CRYPTOHASH_SKEIN256_H #include struct skein256_ctx { uint8_t buf[32]; uint64_t h[4]; uint64_t t0; uint64_t t1; uint32_t bufindex; }; #define SKEIN256_CTX_SIZE sizeof(struct skein256_ctx) void cryponite_skein256_init(struct skein256_ctx *ctx, uint32_t hashlen); void cryponite_skein256_update(struct skein256_ctx *ctx, const uint8_t *data, uint32_t len); void cryponite_skein256_finalize(struct skein256_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_skein512.h0000644000000000000000000000345212673727640017144 0ustar0000000000000000/* * Copyright (C) 2006-2010 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_SKEIN512_H #define CRYPTOHASH_SKEIN512_H #include struct skein512_ctx { uint8_t buf[64]; uint64_t h[8]; uint64_t t0; uint64_t t1; uint32_t bufindex; }; #define SKEIN512_CTX_SIZE sizeof(struct skein512_ctx) void cryponite_skein512_init(struct skein512_ctx *ctx, uint32_t hashlen); void cryponite_skein512_update(struct skein512_ctx *ctx, const uint8_t *data, uint32_t len); void cryponite_skein512_finalize(struct skein512_ctx *ctx, uint32_t hashlen, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_tiger.h0000644000000000000000000000334612514540320016675 0ustar0000000000000000/* * Copyright (C) 2006-2009 Vincent Hanquez * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef CRYPTOHASH_TIGER_H #define CRYPTOHASH_TIGER_H #include struct tiger_ctx { uint64_t sz; uint8_t buf[64]; uint64_t h[3]; }; #define TIGER_DIGEST_SIZE 24 #define TIGER_CTX_SIZE (sizeof(struct tiger_ctx)) void cryptonite_tiger_init(struct tiger_ctx *ctx); void cryptonite_tiger_update(struct tiger_ctx *ctx, const uint8_t *data, uint32_t len); void cryptonite_tiger_finalize(struct tiger_ctx *ctx, uint8_t *out); #endif cryptonite-0.23/cbits/cryptonite_whirlpool.h0000644000000000000000000000206412365237076017615 0ustar0000000000000000#ifndef CRYPTOHASH_WHIRLPOOL_H #define CRYPTOHASH_WHIRLPOOL_H #include /* * Whirlpool-specific definitions. */ #define DIGESTBYTES 64 #define DIGESTBITS (8*DIGESTBYTES) /* 512 */ #define WBLOCKBYTES 64 #define WBLOCKBITS (8*WBLOCKBYTES) /* 512 */ #define LENGTHBYTES 32 #define LENGTHBITS (8*LENGTHBYTES) /* 256 */ typedef struct whirlpool_ctx { uint8_t bitLength[LENGTHBYTES]; /* global number of hashed bits (256-bit counter) */ uint8_t buffer[WBLOCKBYTES]; /* buffer of data to hash */ uint32_t bufferBits; /* current number of bits on the buffer */ uint32_t bufferPos; /* current (possibly incomplete) byte slot on the buffer */ uint64_t hash[DIGESTBYTES/8]; /* the hashing state */ } whirlpool_ctx; void cryptonite_whirlpool_init(struct whirlpool_ctx * const ctx); void cryptonite_whirlpool_update(struct whirlpool_ctx * const ctx, const uint8_t * const source, uint32_t len); void cryptonite_whirlpool_finalize(struct whirlpool_ctx * const ctx, uint8_t * const result); #endif cryptonite-0.23/cbits/cryptonite_xsalsa.h0000644000000000000000000000344612777073622017100 0ustar0000000000000000/* * Copyright (c) 2016 Brandon Hamilton * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef CRYPTONITE_XSALSA #define CRYPTONITE_XSALSA #include "cryptonite_salsa.h" void cryptonite_xsalsa_init(cryptonite_salsa_context *ctx, uint8_t nb_rounds, uint32_t keylen, const uint8_t *key, uint32_t ivlen, const uint8_t *iv); #endif cryptonite-0.23/cbits/aes/block128.h0000644000000000000000000000553312455734561015420 0ustar0000000000000000/* * Copyright (c) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef BLOCK128_H #define BLOCK128_H #include typedef union { uint64_t q[2]; uint32_t d[4]; uint16_t w[8]; uint8_t b[16]; } block128; static inline void block128_copy_bytes(block128 *block, uint8_t *src, uint32_t len) { int i; for (i = 0; i < len; i++) block->b[i] = src[i]; } static inline void block128_copy(block128 *d, const block128 *s) { d->q[0] = s->q[0]; d->q[1] = s->q[1]; } static inline void block128_zero(block128 *d) { d->q[0] = 0; d->q[1] = 0; } static inline void block128_xor(block128 *d, const block128 *s) { d->q[0] ^= s->q[0]; d->q[1] ^= s->q[1]; } static inline void block128_vxor(block128 *d, const block128 *s1, const block128 *s2) { d->q[0] = s1->q[0] ^ s2->q[0]; d->q[1] = s1->q[1] ^ s2->q[1]; } static inline void block128_xor_bytes(block128 *block, uint8_t *src, uint32_t len) { int i; for (i = 0; i < len; i++) block->b[i] ^= src[i]; } static inline void block128_inc_be(block128 *b) { uint64_t v = be64_to_cpu(b->q[1]); if (++v == 0) { b->q[0] = cpu_to_be64(be64_to_cpu(b->q[0]) + 1); b->q[1] = 0; } else b->q[1] = cpu_to_be64(v); } #ifdef IMPL_DEBUG #include static inline void block128_print(block128 *b) { int i; for (i = 0; i < 16; i++) { printf("%02x ", b->b[i]); } printf("\n"); } #endif #endif cryptonite-0.23/cbits/aes/generic.h0000644000000000000000000000352212510177125015470 0ustar0000000000000000/* * Copyright (c) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "cryptonite_aes.h" void cryptonite_aes_generic_encrypt_block(aes_block *output, aes_key *key, aes_block *input); void cryptonite_aes_generic_decrypt_block(aes_block *output, aes_key *key, aes_block *input); void cryptonite_aes_generic_init(aes_key *key, uint8_t *origkey, uint8_t size); cryptonite-0.23/cbits/aes/gf.h0000644000000000000000000000335112541542537014457 0ustar0000000000000000/* * Copyright (c) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef CRYPTONITE_AES_GF128MUL_H #define CRYPTONITE_AES_GF128MUL_H #include "aes/block128.h" void cryptonite_gf_mul(block128 *a, block128 *b); void cryptonite_gf_mulx(block128 *a); #endif cryptonite-0.23/cbits/aes/x86ni.h0000644000000000000000000001000613054074213015021 0ustar0000000000000000/* * Copyright (c) 2012 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef AES_X86NI_H #define AES_X86NI_H #ifdef WITH_AESNI #if defined(__i386__) || defined(__x86_64__) #include #include #include #include #ifdef IMPL_DEBUG static void block128_sse_print(__m128i m) { block128 b; _mm_storeu_si128((__m128i *) &b.b, m); block128_print(&b); } #endif void cryptonite_aesni_init(aes_key *key, uint8_t *origkey, uint8_t size); void cryptonite_aesni_encrypt_block128(aes_block *out, aes_key *key, aes_block *in); void cryptonite_aesni_encrypt_block256(aes_block *out, aes_key *key, aes_block *in); void cryptonite_aesni_decrypt_block128(aes_block *out, aes_key *key, aes_block *in); void cryptonite_aesni_decrypt_block256(aes_block *out, aes_key *key, aes_block *in); void cryptonite_aesni_encrypt_ecb128(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks); void cryptonite_aesni_encrypt_ecb256(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks); void cryptonite_aesni_decrypt_ecb128(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks); void cryptonite_aesni_decrypt_ecb256(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks); void cryptonite_aesni_encrypt_cbc128(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks); void cryptonite_aesni_encrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks); void cryptonite_aesni_decrypt_cbc128(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks); void cryptonite_aesni_decrypt_cbc256(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks); void cryptonite_aesni_encrypt_ctr128(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length); void cryptonite_aesni_encrypt_ctr256(uint8_t *out, aes_key *key, aes_block *_iv, uint8_t *in, uint32_t length); void cryptonite_aesni_encrypt_xts128(aes_block *out, aes_key *key1, aes_key *key2, aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks); void cryptonite_aesni_encrypt_xts256(aes_block *out, aes_key *key1, aes_key *key2, aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks); void cryptonite_aesni_gcm_encrypt128(uint8_t *out, aes_gcm *gcm, aes_key *key, uint8_t *in, uint32_t length); void cryptonite_aesni_gcm_encrypt256(uint8_t *out, aes_gcm *gcm, aes_key *key, uint8_t *in, uint32_t length); void gf_mul_x86ni(block128 *res, block128 *a_, block128 *b_); #endif #endif #endif cryptonite-0.23/cbits/ed25519/curve25519-donna-32bit.h0000644000000000000000000005412612540765174020072 0ustar0000000000000000/* Public domain by Andrew M. See: https://github.com/floodyberry/curve25519-donna 32 bit integer curve25519 implementation */ typedef uint32_t bignum25519[10]; typedef uint32_t bignum25519align16[12]; static const uint32_t reduce_mask_25 = (1 << 25) - 1; static const uint32_t reduce_mask_26 = (1 << 26) - 1; /* out = in */ DONNA_INLINE static void curve25519_copy(bignum25519 out, const bignum25519 in) { out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = in[3]; out[4] = in[4]; out[5] = in[5]; out[6] = in[6]; out[7] = in[7]; out[8] = in[8]; out[9] = in[9]; } /* out = a + b */ DONNA_INLINE static void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; out[8] = a[8] + b[8]; out[9] = a[9] + b[9]; } DONNA_INLINE static void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint32_t c; out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; out[0] += 19 * c; } DONNA_INLINE static void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint32_t c; out[0] = a[0] + b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; out[1] = a[1] + b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; out[2] = a[2] + b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; out[3] = a[3] + b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; out[4] = a[4] + b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; out[5] = a[5] + b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; out[6] = a[6] + b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; out[7] = a[7] + b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; out[8] = a[8] + b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; out[9] = a[9] + b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; out[0] += 19 * c; } /* multiples of p */ static const uint32_t twoP0 = 0x07ffffda; static const uint32_t twoP13579 = 0x03fffffe; static const uint32_t twoP2468 = 0x07fffffe; static const uint32_t fourP0 = 0x0fffffb4; static const uint32_t fourP13579 = 0x07fffffc; static const uint32_t fourP2468 = 0x0ffffffc; /* out = a - b */ DONNA_INLINE static void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint32_t c; out[0] = twoP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; out[1] = twoP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; out[2] = twoP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; out[3] = twoP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; out[4] = twoP2468 + a[4] - b[4] + c; out[5] = twoP13579 + a[5] - b[5] ; out[6] = twoP2468 + a[6] - b[6] ; out[7] = twoP13579 + a[7] - b[7] ; out[8] = twoP2468 + a[8] - b[8] ; out[9] = twoP13579 + a[9] - b[9] ; } /* out = a - b, where a is the result of a basic op (add,sub) */ DONNA_INLINE static void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint32_t c; out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; out[0] += 19 * c; } DONNA_INLINE static void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint32_t c; out[0] = fourP0 + a[0] - b[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; out[1] = fourP13579 + a[1] - b[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; out[2] = fourP2468 + a[2] - b[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; out[3] = fourP13579 + a[3] - b[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; out[4] = fourP2468 + a[4] - b[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; out[5] = fourP13579 + a[5] - b[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; out[6] = fourP2468 + a[6] - b[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; out[7] = fourP13579 + a[7] - b[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; out[8] = fourP2468 + a[8] - b[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; out[9] = fourP13579 + a[9] - b[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; out[0] += 19 * c; } /* out = -a */ DONNA_INLINE static void curve25519_neg(bignum25519 out, const bignum25519 a) { uint32_t c; out[0] = twoP0 - a[0] ; c = (out[0] >> 26); out[0] &= reduce_mask_26; out[1] = twoP13579 - a[1] + c; c = (out[1] >> 25); out[1] &= reduce_mask_25; out[2] = twoP2468 - a[2] + c; c = (out[2] >> 26); out[2] &= reduce_mask_26; out[3] = twoP13579 - a[3] + c; c = (out[3] >> 25); out[3] &= reduce_mask_25; out[4] = twoP2468 - a[4] + c; c = (out[4] >> 26); out[4] &= reduce_mask_26; out[5] = twoP13579 - a[5] + c; c = (out[5] >> 25); out[5] &= reduce_mask_25; out[6] = twoP2468 - a[6] + c; c = (out[6] >> 26); out[6] &= reduce_mask_26; out[7] = twoP13579 - a[7] + c; c = (out[7] >> 25); out[7] &= reduce_mask_25; out[8] = twoP2468 - a[8] + c; c = (out[8] >> 26); out[8] &= reduce_mask_26; out[9] = twoP13579 - a[9] + c; c = (out[9] >> 25); out[9] &= reduce_mask_25; out[0] += 19 * c; } /* out = a * b */ #define curve25519_mul_noinline curve25519_mul static void curve25519_mul(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; uint32_t s0,s1,s2,s3,s4,s5,s6,s7,s8,s9; uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; uint32_t p; r0 = b[0]; r1 = b[1]; r2 = b[2]; r3 = b[3]; r4 = b[4]; r5 = b[5]; r6 = b[6]; r7 = b[7]; r8 = b[8]; r9 = b[9]; s0 = a[0]; s1 = a[1]; s2 = a[2]; s3 = a[3]; s4 = a[4]; s5 = a[5]; s6 = a[6]; s7 = a[7]; s8 = a[8]; s9 = a[9]; m1 = mul32x32_64(r0, s1) + mul32x32_64(r1, s0); m3 = mul32x32_64(r0, s3) + mul32x32_64(r1, s2) + mul32x32_64(r2, s1) + mul32x32_64(r3, s0); m5 = mul32x32_64(r0, s5) + mul32x32_64(r1, s4) + mul32x32_64(r2, s3) + mul32x32_64(r3, s2) + mul32x32_64(r4, s1) + mul32x32_64(r5, s0); m7 = mul32x32_64(r0, s7) + mul32x32_64(r1, s6) + mul32x32_64(r2, s5) + mul32x32_64(r3, s4) + mul32x32_64(r4, s3) + mul32x32_64(r5, s2) + mul32x32_64(r6, s1) + mul32x32_64(r7, s0); m9 = mul32x32_64(r0, s9) + mul32x32_64(r1, s8) + mul32x32_64(r2, s7) + mul32x32_64(r3, s6) + mul32x32_64(r4, s5) + mul32x32_64(r5, s4) + mul32x32_64(r6, s3) + mul32x32_64(r7, s2) + mul32x32_64(r8, s1) + mul32x32_64(r9, s0); r1 *= 2; r3 *= 2; r5 *= 2; r7 *= 2; m0 = mul32x32_64(r0, s0); m2 = mul32x32_64(r0, s2) + mul32x32_64(r1, s1) + mul32x32_64(r2, s0); m4 = mul32x32_64(r0, s4) + mul32x32_64(r1, s3) + mul32x32_64(r2, s2) + mul32x32_64(r3, s1) + mul32x32_64(r4, s0); m6 = mul32x32_64(r0, s6) + mul32x32_64(r1, s5) + mul32x32_64(r2, s4) + mul32x32_64(r3, s3) + mul32x32_64(r4, s2) + mul32x32_64(r5, s1) + mul32x32_64(r6, s0); m8 = mul32x32_64(r0, s8) + mul32x32_64(r1, s7) + mul32x32_64(r2, s6) + mul32x32_64(r3, s5) + mul32x32_64(r4, s4) + mul32x32_64(r5, s3) + mul32x32_64(r6, s2) + mul32x32_64(r7, s1) + mul32x32_64(r8, s0); r1 *= 19; r2 *= 19; r3 = (r3 / 2) * 19; r4 *= 19; r5 = (r5 / 2) * 19; r6 *= 19; r7 = (r7 / 2) * 19; r8 *= 19; r9 *= 19; m1 += (mul32x32_64(r9, s2) + mul32x32_64(r8, s3) + mul32x32_64(r7, s4) + mul32x32_64(r6, s5) + mul32x32_64(r5, s6) + mul32x32_64(r4, s7) + mul32x32_64(r3, s8) + mul32x32_64(r2, s9)); m3 += (mul32x32_64(r9, s4) + mul32x32_64(r8, s5) + mul32x32_64(r7, s6) + mul32x32_64(r6, s7) + mul32x32_64(r5, s8) + mul32x32_64(r4, s9)); m5 += (mul32x32_64(r9, s6) + mul32x32_64(r8, s7) + mul32x32_64(r7, s8) + mul32x32_64(r6, s9)); m7 += (mul32x32_64(r9, s8) + mul32x32_64(r8, s9)); r3 *= 2; r5 *= 2; r7 *= 2; r9 *= 2; m0 += (mul32x32_64(r9, s1) + mul32x32_64(r8, s2) + mul32x32_64(r7, s3) + mul32x32_64(r6, s4) + mul32x32_64(r5, s5) + mul32x32_64(r4, s6) + mul32x32_64(r3, s7) + mul32x32_64(r2, s8) + mul32x32_64(r1, s9)); m2 += (mul32x32_64(r9, s3) + mul32x32_64(r8, s4) + mul32x32_64(r7, s5) + mul32x32_64(r6, s6) + mul32x32_64(r5, s7) + mul32x32_64(r4, s8) + mul32x32_64(r3, s9)); m4 += (mul32x32_64(r9, s5) + mul32x32_64(r8, s6) + mul32x32_64(r7, s7) + mul32x32_64(r6, s8) + mul32x32_64(r5, s9)); m6 += (mul32x32_64(r9, s7) + mul32x32_64(r8, s8) + mul32x32_64(r7, s9)); m8 += (mul32x32_64(r9, s9)); r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); r1 += p; out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; out[5] = r5; out[6] = r6; out[7] = r7; out[8] = r8; out[9] = r9; } /* out = in*in */ static void curve25519_square(bignum25519 out, const bignum25519 in) { uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; uint32_t d6,d7,d8,d9; uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; uint32_t p; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; r5 = in[5]; r6 = in[6]; r7 = in[7]; r8 = in[8]; r9 = in[9]; m0 = mul32x32_64(r0, r0); r0 *= 2; m1 = mul32x32_64(r0, r1); m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); r1 *= 2; m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); r2 *= 2; m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); r3 *= 2; m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); d6 = r6 * 19; d7 = r7 * 2 * 19; d8 = r8 * 19; d9 = r9 * 2 * 19; m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); m7 += (mul32x32_64(d9, r8 )); m8 += (mul32x32_64(d9, r9 )); r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); r1 += p; out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; out[5] = r5; out[6] = r6; out[7] = r7; out[8] = r8; out[9] = r9; } /* out = in ^ (2 * count) */ static void curve25519_square_times(bignum25519 out, const bignum25519 in, int count) { uint32_t r0,r1,r2,r3,r4,r5,r6,r7,r8,r9; uint32_t d6,d7,d8,d9; uint64_t m0,m1,m2,m3,m4,m5,m6,m7,m8,m9,c; uint32_t p; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; r5 = in[5]; r6 = in[6]; r7 = in[7]; r8 = in[8]; r9 = in[9]; do { m0 = mul32x32_64(r0, r0); r0 *= 2; m1 = mul32x32_64(r0, r1); m2 = mul32x32_64(r0, r2) + mul32x32_64(r1, r1 * 2); r1 *= 2; m3 = mul32x32_64(r0, r3) + mul32x32_64(r1, r2 ); m4 = mul32x32_64(r0, r4) + mul32x32_64(r1, r3 * 2) + mul32x32_64(r2, r2); r2 *= 2; m5 = mul32x32_64(r0, r5) + mul32x32_64(r1, r4 ) + mul32x32_64(r2, r3); m6 = mul32x32_64(r0, r6) + mul32x32_64(r1, r5 * 2) + mul32x32_64(r2, r4) + mul32x32_64(r3, r3 * 2); r3 *= 2; m7 = mul32x32_64(r0, r7) + mul32x32_64(r1, r6 ) + mul32x32_64(r2, r5) + mul32x32_64(r3, r4 ); m8 = mul32x32_64(r0, r8) + mul32x32_64(r1, r7 * 2) + mul32x32_64(r2, r6) + mul32x32_64(r3, r5 * 2) + mul32x32_64(r4, r4 ); m9 = mul32x32_64(r0, r9) + mul32x32_64(r1, r8 ) + mul32x32_64(r2, r7) + mul32x32_64(r3, r6 ) + mul32x32_64(r4, r5 * 2); d6 = r6 * 19; d7 = r7 * 2 * 19; d8 = r8 * 19; d9 = r9 * 2 * 19; m0 += (mul32x32_64(d9, r1 ) + mul32x32_64(d8, r2 ) + mul32x32_64(d7, r3 ) + mul32x32_64(d6, r4 * 2) + mul32x32_64(r5, r5 * 2 * 19)); m1 += (mul32x32_64(d9, r2 / 2) + mul32x32_64(d8, r3 ) + mul32x32_64(d7, r4 ) + mul32x32_64(d6, r5 * 2)); m2 += (mul32x32_64(d9, r3 ) + mul32x32_64(d8, r4 * 2) + mul32x32_64(d7, r5 * 2) + mul32x32_64(d6, r6 )); m3 += (mul32x32_64(d9, r4 ) + mul32x32_64(d8, r5 * 2) + mul32x32_64(d7, r6 )); m4 += (mul32x32_64(d9, r5 * 2) + mul32x32_64(d8, r6 * 2) + mul32x32_64(d7, r7 )); m5 += (mul32x32_64(d9, r6 ) + mul32x32_64(d8, r7 * 2)); m6 += (mul32x32_64(d9, r7 * 2) + mul32x32_64(d8, r8 )); m7 += (mul32x32_64(d9, r8 )); m8 += (mul32x32_64(d9, r9 )); r0 = (uint32_t)m0 & reduce_mask_26; c = (m0 >> 26); m1 += c; r1 = (uint32_t)m1 & reduce_mask_25; c = (m1 >> 25); m2 += c; r2 = (uint32_t)m2 & reduce_mask_26; c = (m2 >> 26); m3 += c; r3 = (uint32_t)m3 & reduce_mask_25; c = (m3 >> 25); m4 += c; r4 = (uint32_t)m4 & reduce_mask_26; c = (m4 >> 26); m5 += c; r5 = (uint32_t)m5 & reduce_mask_25; c = (m5 >> 25); m6 += c; r6 = (uint32_t)m6 & reduce_mask_26; c = (m6 >> 26); m7 += c; r7 = (uint32_t)m7 & reduce_mask_25; c = (m7 >> 25); m8 += c; r8 = (uint32_t)m8 & reduce_mask_26; c = (m8 >> 26); m9 += c; r9 = (uint32_t)m9 & reduce_mask_25; p = (uint32_t)(m9 >> 25); m0 = r0 + mul32x32_64(p,19); r0 = (uint32_t)m0 & reduce_mask_26; p = (uint32_t)(m0 >> 26); r1 += p; } while (--count); out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; out[5] = r5; out[6] = r6; out[7] = r7; out[8] = r8; out[9] = r9; } /* Take a little-endian, 32-byte number and expand it into polynomial form */ static void curve25519_expand(bignum25519 out, const unsigned char in[32]) { static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}}; uint32_t x0,x1,x2,x3,x4,x5,x6,x7; if (endian_check.s == 1) { x0 = *(uint32_t *)(in + 0); x1 = *(uint32_t *)(in + 4); x2 = *(uint32_t *)(in + 8); x3 = *(uint32_t *)(in + 12); x4 = *(uint32_t *)(in + 16); x5 = *(uint32_t *)(in + 20); x6 = *(uint32_t *)(in + 24); x7 = *(uint32_t *)(in + 28); } else { #define F(s) \ ((((uint32_t)in[s + 0]) ) | \ (((uint32_t)in[s + 1]) << 8) | \ (((uint32_t)in[s + 2]) << 16) | \ (((uint32_t)in[s + 3]) << 24)) x0 = F(0); x1 = F(4); x2 = F(8); x3 = F(12); x4 = F(16); x5 = F(20); x6 = F(24); x7 = F(28); #undef F } out[0] = ( x0 ) & 0x3ffffff; out[1] = ((((uint64_t)x1 << 32) | x0) >> 26) & 0x1ffffff; out[2] = ((((uint64_t)x2 << 32) | x1) >> 19) & 0x3ffffff; out[3] = ((((uint64_t)x3 << 32) | x2) >> 13) & 0x1ffffff; out[4] = (( x3) >> 6) & 0x3ffffff; out[5] = ( x4 ) & 0x1ffffff; out[6] = ((((uint64_t)x5 << 32) | x4) >> 25) & 0x3ffffff; out[7] = ((((uint64_t)x6 << 32) | x5) >> 19) & 0x1ffffff; out[8] = ((((uint64_t)x7 << 32) | x6) >> 12) & 0x3ffffff; out[9] = (( x7) >> 6) & 0x1ffffff; } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array */ static void curve25519_contract(unsigned char out[32], const bignum25519 in) { bignum25519 f; curve25519_copy(f, in); #define carry_pass() \ f[1] += f[0] >> 26; f[0] &= reduce_mask_26; \ f[2] += f[1] >> 25; f[1] &= reduce_mask_25; \ f[3] += f[2] >> 26; f[2] &= reduce_mask_26; \ f[4] += f[3] >> 25; f[3] &= reduce_mask_25; \ f[5] += f[4] >> 26; f[4] &= reduce_mask_26; \ f[6] += f[5] >> 25; f[5] &= reduce_mask_25; \ f[7] += f[6] >> 26; f[6] &= reduce_mask_26; \ f[8] += f[7] >> 25; f[7] &= reduce_mask_25; \ f[9] += f[8] >> 26; f[8] &= reduce_mask_26; #define carry_pass_full() \ carry_pass() \ f[0] += 19 * (f[9] >> 25); f[9] &= reduce_mask_25; #define carry_pass_final() \ carry_pass() \ f[9] &= reduce_mask_25; carry_pass_full() carry_pass_full() /* now t is between 0 and 2^255-1, properly carried. */ /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ f[0] += 19; carry_pass_full() /* now between 19 and 2^255-1 in both cases, and offset by 19. */ f[0] += (reduce_mask_26 + 1) - 19; f[1] += (reduce_mask_25 + 1) - 1; f[2] += (reduce_mask_26 + 1) - 1; f[3] += (reduce_mask_25 + 1) - 1; f[4] += (reduce_mask_26 + 1) - 1; f[5] += (reduce_mask_25 + 1) - 1; f[6] += (reduce_mask_26 + 1) - 1; f[7] += (reduce_mask_25 + 1) - 1; f[8] += (reduce_mask_26 + 1) - 1; f[9] += (reduce_mask_25 + 1) - 1; /* now between 2^255 and 2^256-20, and offset by 2^255. */ carry_pass_final() #undef carry_pass #undef carry_full #undef carry_final f[1] <<= 2; f[2] <<= 3; f[3] <<= 5; f[4] <<= 6; f[6] <<= 1; f[7] <<= 3; f[8] <<= 4; f[9] <<= 6; #define F(i, s) \ out[s+0] |= (unsigned char )(f[i] & 0xff); \ out[s+1] = (unsigned char )((f[i] >> 8) & 0xff); \ out[s+2] = (unsigned char )((f[i] >> 16) & 0xff); \ out[s+3] = (unsigned char )((f[i] >> 24) & 0xff); out[0] = 0; out[16] = 0; F(0,0); F(1,3); F(2,6); F(3,9); F(4,12); F(5,16); F(6,19); F(7,22); F(8,25); F(9,28); #undef F } /* out = (flag) ? in : out */ DONNA_INLINE static void curve25519_move_conditional_bytes(uint8_t out[96], const uint8_t in[96], uint32_t flag) { const uint32_t nb = flag - 1, b = ~nb; const uint32_t *inl = (const uint32_t *)in; uint32_t *outl = (uint32_t *)out; outl[0] = (outl[0] & nb) | (inl[0] & b); outl[1] = (outl[1] & nb) | (inl[1] & b); outl[2] = (outl[2] & nb) | (inl[2] & b); outl[3] = (outl[3] & nb) | (inl[3] & b); outl[4] = (outl[4] & nb) | (inl[4] & b); outl[5] = (outl[5] & nb) | (inl[5] & b); outl[6] = (outl[6] & nb) | (inl[6] & b); outl[7] = (outl[7] & nb) | (inl[7] & b); outl[8] = (outl[8] & nb) | (inl[8] & b); outl[9] = (outl[9] & nb) | (inl[9] & b); outl[10] = (outl[10] & nb) | (inl[10] & b); outl[11] = (outl[11] & nb) | (inl[11] & b); outl[12] = (outl[12] & nb) | (inl[12] & b); outl[13] = (outl[13] & nb) | (inl[13] & b); outl[14] = (outl[14] & nb) | (inl[14] & b); outl[15] = (outl[15] & nb) | (inl[15] & b); outl[16] = (outl[16] & nb) | (inl[16] & b); outl[17] = (outl[17] & nb) | (inl[17] & b); outl[18] = (outl[18] & nb) | (inl[18] & b); outl[19] = (outl[19] & nb) | (inl[19] & b); outl[20] = (outl[20] & nb) | (inl[20] & b); outl[21] = (outl[21] & nb) | (inl[21] & b); outl[22] = (outl[22] & nb) | (inl[22] & b); outl[23] = (outl[23] & nb) | (inl[23] & b); } /* if (iswap) swap(a, b) */ DONNA_INLINE static void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint32_t iswap) { const uint32_t swap = (uint32_t)(-(int32_t)iswap); uint32_t x0,x1,x2,x3,x4,x5,x6,x7,x8,x9; x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; x5 = swap & (a[5] ^ b[5]); a[5] ^= x5; b[5] ^= x5; x6 = swap & (a[6] ^ b[6]); a[6] ^= x6; b[6] ^= x6; x7 = swap & (a[7] ^ b[7]); a[7] ^= x7; b[7] ^= x7; x8 = swap & (a[8] ^ b[8]); a[8] ^= x8; b[8] ^= x8; x9 = swap & (a[9] ^ b[9]); a[9] ^= x9; b[9] ^= x9; } cryptonite-0.23/cbits/ed25519/curve25519-donna-64bit.h0000644000000000000000000003502512514663134020066 0ustar0000000000000000/* Public domain by Adam Langley & Andrew M. See: https://github.com/floodyberry/curve25519-donna 64bit integer curve25519 implementation */ typedef uint64_t bignum25519[5]; static const uint64_t reduce_mask_40 = ((uint64_t)1 << 40) - 1; static const uint64_t reduce_mask_51 = ((uint64_t)1 << 51) - 1; static const uint64_t reduce_mask_56 = ((uint64_t)1 << 56) - 1; /* out = in */ DONNA_INLINE static void curve25519_copy(bignum25519 out, const bignum25519 in) { out[0] = in[0]; out[1] = in[1]; out[2] = in[2]; out[3] = in[3]; out[4] = in[4]; } /* out = a + b */ DONNA_INLINE static void curve25519_add(bignum25519 out, const bignum25519 a, const bignum25519 b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; } /* out = a + b, where a and/or b are the result of a basic op (add,sub) */ DONNA_INLINE static void curve25519_add_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; } DONNA_INLINE static void curve25519_add_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint64_t c; out[0] = a[0] + b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; out[1] = a[1] + b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; out[2] = a[2] + b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; out[3] = a[3] + b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; out[4] = a[4] + b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; out[0] += c * 19; } /* multiples of p */ static const uint64_t twoP0 = 0x0fffffffffffda; static const uint64_t twoP1234 = 0x0ffffffffffffe; static const uint64_t fourP0 = 0x1fffffffffffb4; static const uint64_t fourP1234 = 0x1ffffffffffffc; /* out = a - b */ DONNA_INLINE static void curve25519_sub(bignum25519 out, const bignum25519 a, const bignum25519 b) { out[0] = a[0] + twoP0 - b[0]; out[1] = a[1] + twoP1234 - b[1]; out[2] = a[2] + twoP1234 - b[2]; out[3] = a[3] + twoP1234 - b[3]; out[4] = a[4] + twoP1234 - b[4]; } /* out = a - b, where a and/or b are the result of a basic op (add,sub) */ DONNA_INLINE static void curve25519_sub_after_basic(bignum25519 out, const bignum25519 a, const bignum25519 b) { out[0] = a[0] + fourP0 - b[0]; out[1] = a[1] + fourP1234 - b[1]; out[2] = a[2] + fourP1234 - b[2]; out[3] = a[3] + fourP1234 - b[3]; out[4] = a[4] + fourP1234 - b[4]; } DONNA_INLINE static void curve25519_sub_reduce(bignum25519 out, const bignum25519 a, const bignum25519 b) { uint64_t c; out[0] = a[0] + fourP0 - b[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; out[1] = a[1] + fourP1234 - b[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; out[2] = a[2] + fourP1234 - b[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; out[3] = a[3] + fourP1234 - b[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; out[4] = a[4] + fourP1234 - b[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; out[0] += c * 19; } /* out = -a */ DONNA_INLINE static void curve25519_neg(bignum25519 out, const bignum25519 a) { uint64_t c; out[0] = twoP0 - a[0] ; c = (out[0] >> 51); out[0] &= reduce_mask_51; out[1] = twoP1234 - a[1] + c; c = (out[1] >> 51); out[1] &= reduce_mask_51; out[2] = twoP1234 - a[2] + c; c = (out[2] >> 51); out[2] &= reduce_mask_51; out[3] = twoP1234 - a[3] + c; c = (out[3] >> 51); out[3] &= reduce_mask_51; out[4] = twoP1234 - a[4] + c; c = (out[4] >> 51); out[4] &= reduce_mask_51; out[0] += c * 19; } /* out = a * b */ DONNA_INLINE static void curve25519_mul(bignum25519 out, const bignum25519 in2, const bignum25519 in) { #if !defined(HAVE_NATIVE_UINT128) uint128_t mul; #endif uint128_t t[5]; uint64_t r0,r1,r2,r3,r4,s0,s1,s2,s3,s4,c; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; s0 = in2[0]; s1 = in2[1]; s2 = in2[2]; s3 = in2[3]; s4 = in2[4]; #if defined(HAVE_NATIVE_UINT128) t[0] = ((uint128_t) r0) * s0; t[1] = ((uint128_t) r0) * s1 + ((uint128_t) r1) * s0; t[2] = ((uint128_t) r0) * s2 + ((uint128_t) r2) * s0 + ((uint128_t) r1) * s1; t[3] = ((uint128_t) r0) * s3 + ((uint128_t) r3) * s0 + ((uint128_t) r1) * s2 + ((uint128_t) r2) * s1; t[4] = ((uint128_t) r0) * s4 + ((uint128_t) r4) * s0 + ((uint128_t) r3) * s1 + ((uint128_t) r1) * s3 + ((uint128_t) r2) * s2; #else mul64x64_128(t[0], r0, s0) mul64x64_128(t[1], r0, s1) mul64x64_128(mul, r1, s0) add128(t[1], mul) mul64x64_128(t[2], r0, s2) mul64x64_128(mul, r2, s0) add128(t[2], mul) mul64x64_128(mul, r1, s1) add128(t[2], mul) mul64x64_128(t[3], r0, s3) mul64x64_128(mul, r3, s0) add128(t[3], mul) mul64x64_128(mul, r1, s2) add128(t[3], mul) mul64x64_128(mul, r2, s1) add128(t[3], mul) mul64x64_128(t[4], r0, s4) mul64x64_128(mul, r4, s0) add128(t[4], mul) mul64x64_128(mul, r3, s1) add128(t[4], mul) mul64x64_128(mul, r1, s3) add128(t[4], mul) mul64x64_128(mul, r2, s2) add128(t[4], mul) #endif r1 *= 19; r2 *= 19; r3 *= 19; r4 *= 19; #if defined(HAVE_NATIVE_UINT128) t[0] += ((uint128_t) r4) * s1 + ((uint128_t) r1) * s4 + ((uint128_t) r2) * s3 + ((uint128_t) r3) * s2; t[1] += ((uint128_t) r4) * s2 + ((uint128_t) r2) * s4 + ((uint128_t) r3) * s3; t[2] += ((uint128_t) r4) * s3 + ((uint128_t) r3) * s4; t[3] += ((uint128_t) r4) * s4; #else mul64x64_128(mul, r4, s1) add128(t[0], mul) mul64x64_128(mul, r1, s4) add128(t[0], mul) mul64x64_128(mul, r2, s3) add128(t[0], mul) mul64x64_128(mul, r3, s2) add128(t[0], mul) mul64x64_128(mul, r4, s2) add128(t[1], mul) mul64x64_128(mul, r2, s4) add128(t[1], mul) mul64x64_128(mul, r3, s3) add128(t[1], mul) mul64x64_128(mul, r4, s3) add128(t[2], mul) mul64x64_128(mul, r3, s4) add128(t[2], mul) mul64x64_128(mul, r4, s4) add128(t[3], mul) #endif r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51); add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51); add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51); add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51); add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51); r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; r1 += c; out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; } DONNA_NOINLINE static void curve25519_mul_noinline(bignum25519 out, const bignum25519 in2, const bignum25519 in) { curve25519_mul(out, in2, in); } /* out = in^(2 * count) */ DONNA_NOINLINE static void curve25519_square_times(bignum25519 out, const bignum25519 in, uint64_t count) { #if !defined(HAVE_NATIVE_UINT128) uint128_t mul; #endif uint128_t t[5]; uint64_t r0,r1,r2,r3,r4,c; uint64_t d0,d1,d2,d4,d419; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; do { d0 = r0 * 2; d1 = r1 * 2; d2 = r2 * 2 * 19; d419 = r4 * 19; d4 = d419 * 2; #if defined(HAVE_NATIVE_UINT128) t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 )); t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19)); t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 )); t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 )); t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 )); #else mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul) mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul) mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul) mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul) mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul) #endif r0 = lo128(t[0]) & reduce_mask_51; r1 = lo128(t[1]) & reduce_mask_51; shl128(c, t[0], 13); r1 += c; r2 = lo128(t[2]) & reduce_mask_51; shl128(c, t[1], 13); r2 += c; r3 = lo128(t[3]) & reduce_mask_51; shl128(c, t[2], 13); r3 += c; r4 = lo128(t[4]) & reduce_mask_51; shl128(c, t[3], 13); r4 += c; shl128(c, t[4], 13); r0 += c * 19; c = r0 >> 51; r0 &= reduce_mask_51; r1 += c ; c = r1 >> 51; r1 &= reduce_mask_51; r2 += c ; c = r2 >> 51; r2 &= reduce_mask_51; r3 += c ; c = r3 >> 51; r3 &= reduce_mask_51; r4 += c ; c = r4 >> 51; r4 &= reduce_mask_51; r0 += c * 19; } while(--count); out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; } DONNA_INLINE static void curve25519_square(bignum25519 out, const bignum25519 in) { #if !defined(HAVE_NATIVE_UINT128) uint128_t mul; #endif uint128_t t[5]; uint64_t r0,r1,r2,r3,r4,c; uint64_t d0,d1,d2,d4,d419; r0 = in[0]; r1 = in[1]; r2 = in[2]; r3 = in[3]; r4 = in[4]; d0 = r0 * 2; d1 = r1 * 2; d2 = r2 * 2 * 19; d419 = r4 * 19; d4 = d419 * 2; #if defined(HAVE_NATIVE_UINT128) t[0] = ((uint128_t) r0) * r0 + ((uint128_t) d4) * r1 + (((uint128_t) d2) * (r3 )); t[1] = ((uint128_t) d0) * r1 + ((uint128_t) d4) * r2 + (((uint128_t) r3) * (r3 * 19)); t[2] = ((uint128_t) d0) * r2 + ((uint128_t) r1) * r1 + (((uint128_t) d4) * (r3 )); t[3] = ((uint128_t) d0) * r3 + ((uint128_t) d1) * r2 + (((uint128_t) r4) * (d419 )); t[4] = ((uint128_t) d0) * r4 + ((uint128_t) d1) * r3 + (((uint128_t) r2) * (r2 )); #else mul64x64_128(t[0], r0, r0) mul64x64_128(mul, d4, r1) add128(t[0], mul) mul64x64_128(mul, d2, r3) add128(t[0], mul) mul64x64_128(t[1], d0, r1) mul64x64_128(mul, d4, r2) add128(t[1], mul) mul64x64_128(mul, r3, r3 * 19) add128(t[1], mul) mul64x64_128(t[2], d0, r2) mul64x64_128(mul, r1, r1) add128(t[2], mul) mul64x64_128(mul, d4, r3) add128(t[2], mul) mul64x64_128(t[3], d0, r3) mul64x64_128(mul, d1, r2) add128(t[3], mul) mul64x64_128(mul, r4, d419) add128(t[3], mul) mul64x64_128(t[4], d0, r4) mul64x64_128(mul, d1, r3) add128(t[4], mul) mul64x64_128(mul, r2, r2) add128(t[4], mul) #endif r0 = lo128(t[0]) & reduce_mask_51; shr128(c, t[0], 51); add128_64(t[1], c) r1 = lo128(t[1]) & reduce_mask_51; shr128(c, t[1], 51); add128_64(t[2], c) r2 = lo128(t[2]) & reduce_mask_51; shr128(c, t[2], 51); add128_64(t[3], c) r3 = lo128(t[3]) & reduce_mask_51; shr128(c, t[3], 51); add128_64(t[4], c) r4 = lo128(t[4]) & reduce_mask_51; shr128(c, t[4], 51); r0 += c * 19; c = r0 >> 51; r0 = r0 & reduce_mask_51; r1 += c; out[0] = r0; out[1] = r1; out[2] = r2; out[3] = r3; out[4] = r4; } /* Take a little-endian, 32-byte number and expand it into polynomial form */ DONNA_INLINE static void curve25519_expand(bignum25519 out, const unsigned char *in) { static const union { uint8_t b[2]; uint16_t s; } endian_check = {{1,0}}; uint64_t x0,x1,x2,x3; if (endian_check.s == 1) { x0 = *(uint64_t *)(in + 0); x1 = *(uint64_t *)(in + 8); x2 = *(uint64_t *)(in + 16); x3 = *(uint64_t *)(in + 24); } else { #define F(s) \ ((((uint64_t)in[s + 0]) ) | \ (((uint64_t)in[s + 1]) << 8) | \ (((uint64_t)in[s + 2]) << 16) | \ (((uint64_t)in[s + 3]) << 24) | \ (((uint64_t)in[s + 4]) << 32) | \ (((uint64_t)in[s + 5]) << 40) | \ (((uint64_t)in[s + 6]) << 48) | \ (((uint64_t)in[s + 7]) << 56)) x0 = F(0); x1 = F(8); x2 = F(16); x3 = F(24); } out[0] = x0 & reduce_mask_51; x0 = (x0 >> 51) | (x1 << 13); out[1] = x0 & reduce_mask_51; x1 = (x1 >> 38) | (x2 << 26); out[2] = x1 & reduce_mask_51; x2 = (x2 >> 25) | (x3 << 39); out[3] = x2 & reduce_mask_51; x3 = (x3 >> 12); out[4] = x3 & reduce_mask_51; } /* Take a fully reduced polynomial form number and contract it into a * little-endian, 32-byte array */ DONNA_INLINE static void curve25519_contract(unsigned char *out, const bignum25519 input) { uint64_t t[5]; uint64_t f, i; t[0] = input[0]; t[1] = input[1]; t[2] = input[2]; t[3] = input[3]; t[4] = input[4]; #define curve25519_contract_carry() \ t[1] += t[0] >> 51; t[0] &= reduce_mask_51; \ t[2] += t[1] >> 51; t[1] &= reduce_mask_51; \ t[3] += t[2] >> 51; t[2] &= reduce_mask_51; \ t[4] += t[3] >> 51; t[3] &= reduce_mask_51; #define curve25519_contract_carry_full() curve25519_contract_carry() \ t[0] += 19 * (t[4] >> 51); t[4] &= reduce_mask_51; #define curve25519_contract_carry_final() curve25519_contract_carry() \ t[4] &= reduce_mask_51; curve25519_contract_carry_full() curve25519_contract_carry_full() /* now t is between 0 and 2^255-1, properly carried. */ /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ t[0] += 19; curve25519_contract_carry_full() /* now between 19 and 2^255-1 in both cases, and offset by 19. */ t[0] += (reduce_mask_51 + 1) - 19; t[1] += (reduce_mask_51 + 1) - 1; t[2] += (reduce_mask_51 + 1) - 1; t[3] += (reduce_mask_51 + 1) - 1; t[4] += (reduce_mask_51 + 1) - 1; /* now between 2^255 and 2^256-20, and offset by 2^255. */ curve25519_contract_carry_final() #define write51full(n,shift) \ f = ((t[n] >> shift) | (t[n+1] << (51 - shift))); \ for (i = 0; i < 8; i++, f >>= 8) *out++ = (unsigned char)f; #define write51(n) write51full(n,13*n) write51(0) write51(1) write51(2) write51(3) } #if !defined(ED25519_GCC_64BIT_CHOOSE) /* out = (flag) ? in : out */ DONNA_INLINE static void curve25519_move_conditional_bytes(uint8_t out[96], const uint8_t in[96], uint64_t flag) { const uint64_t nb = flag - 1, b = ~nb; const uint64_t *inq = (const uint64_t *)in; uint64_t *outq = (uint64_t *)out; outq[0] = (outq[0] & nb) | (inq[0] & b); outq[1] = (outq[1] & nb) | (inq[1] & b); outq[2] = (outq[2] & nb) | (inq[2] & b); outq[3] = (outq[3] & nb) | (inq[3] & b); outq[4] = (outq[4] & nb) | (inq[4] & b); outq[5] = (outq[5] & nb) | (inq[5] & b); outq[6] = (outq[6] & nb) | (inq[6] & b); outq[7] = (outq[7] & nb) | (inq[7] & b); outq[8] = (outq[8] & nb) | (inq[8] & b); outq[9] = (outq[9] & nb) | (inq[9] & b); outq[10] = (outq[10] & nb) | (inq[10] & b); outq[11] = (outq[11] & nb) | (inq[11] & b); } /* if (iswap) swap(a, b) */ DONNA_INLINE static void curve25519_swap_conditional(bignum25519 a, bignum25519 b, uint64_t iswap) { const uint64_t swap = (uint64_t)(-(int64_t)iswap); uint64_t x0,x1,x2,x3,x4; x0 = swap & (a[0] ^ b[0]); a[0] ^= x0; b[0] ^= x0; x1 = swap & (a[1] ^ b[1]); a[1] ^= x1; b[1] ^= x1; x2 = swap & (a[2] ^ b[2]); a[2] ^= x2; b[2] ^= x2; x3 = swap & (a[3] ^ b[3]); a[3] ^= x3; b[3] ^= x3; x4 = swap & (a[4] ^ b[4]); a[4] ^= x4; b[4] ^= x4; } #endif /* ED25519_GCC_64BIT_CHOOSE */ #define ED25519_64BIT_TABLES cryptonite-0.23/cbits/ed25519/curve25519-donna-helpers.h0000644000000000000000000000450612514663134020600 0ustar0000000000000000/* Public domain by Andrew M. See: https://github.com/floodyberry/curve25519-donna Curve25519 implementation agnostic helpers */ /* * In: b = 2^5 - 2^0 * Out: b = 2^250 - 2^0 */ static void curve25519_pow_two5mtwo0_two250mtwo0(bignum25519 b) { bignum25519 ALIGN(16) t0,c; /* 2^5 - 2^0 */ /* b */ /* 2^10 - 2^5 */ curve25519_square_times(t0, b, 5); /* 2^10 - 2^0 */ curve25519_mul_noinline(b, t0, b); /* 2^20 - 2^10 */ curve25519_square_times(t0, b, 10); /* 2^20 - 2^0 */ curve25519_mul_noinline(c, t0, b); /* 2^40 - 2^20 */ curve25519_square_times(t0, c, 20); /* 2^40 - 2^0 */ curve25519_mul_noinline(t0, t0, c); /* 2^50 - 2^10 */ curve25519_square_times(t0, t0, 10); /* 2^50 - 2^0 */ curve25519_mul_noinline(b, t0, b); /* 2^100 - 2^50 */ curve25519_square_times(t0, b, 50); /* 2^100 - 2^0 */ curve25519_mul_noinline(c, t0, b); /* 2^200 - 2^100 */ curve25519_square_times(t0, c, 100); /* 2^200 - 2^0 */ curve25519_mul_noinline(t0, t0, c); /* 2^250 - 2^50 */ curve25519_square_times(t0, t0, 50); /* 2^250 - 2^0 */ curve25519_mul_noinline(b, t0, b); } /* * z^(p - 2) = z(2^255 - 21) */ static void curve25519_recip(bignum25519 out, const bignum25519 z) { bignum25519 ALIGN(16) a,t0,b; /* 2 */ curve25519_square_times(a, z, 1); /* a = 2 */ /* 8 */ curve25519_square_times(t0, a, 2); /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ /* 11 */ curve25519_mul_noinline(a, b, a); /* a = 11 */ /* 22 */ curve25519_square_times(t0, a, 1); /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); /* 2^255 - 2^5 */ curve25519_square_times(b, b, 5); /* 2^255 - 21 */ curve25519_mul_noinline(out, b, a); } /* * z^((p-5)/8) = z^(2^252 - 3) */ static void curve25519_pow_two252m3(bignum25519 two252m3, const bignum25519 z) { bignum25519 ALIGN(16) b,c,t0; /* 2 */ curve25519_square_times(c, z, 1); /* c = 2 */ /* 8 */ curve25519_square_times(t0, c, 2); /* t0 = 8 */ /* 9 */ curve25519_mul_noinline(b, t0, z); /* b = 9 */ /* 11 */ curve25519_mul_noinline(c, b, c); /* c = 11 */ /* 22 */ curve25519_square_times(t0, c, 1); /* 2^5 - 2^0 = 31 */ curve25519_mul_noinline(b, t0, b); /* 2^250 - 2^0 */ curve25519_pow_two5mtwo0_two250mtwo0(b); /* 2^252 - 2^2 */ curve25519_square_times(b, b, 2); /* 2^252 - 3 */ curve25519_mul_noinline(two252m3, b, z); } cryptonite-0.23/cbits/ed25519/ed25519-donna-32bit-sse2.h0000644000000000000000000004432012540765526020204 0ustar0000000000000000#if defined(ED25519_GCC_32BIT_SSE_CHOOSE) #define HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS DONNA_NOINLINE static void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { int32_t breg = (int32_t)b; uint32_t sign = (uint32_t)breg >> 31; uint32_t mask = ~(sign - 1); uint32_t u = (breg + mask) ^ mask; __asm__ __volatile__ ( /* ysubx+xaddy */ "movl %0, %%eax ;\n" "movd %%eax, %%xmm6 ;\n" "pshufd $0x00, %%xmm6, %%xmm6 ;\n" "pxor %%xmm0, %%xmm0 ;\n" "pxor %%xmm1, %%xmm1 ;\n" "pxor %%xmm2, %%xmm2 ;\n" "pxor %%xmm3, %%xmm3 ;\n" /* 0 */ "movl $0, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movl $1, %%ecx ;\n" "movd %%ecx, %%xmm4 ;\n" "pxor %%xmm5, %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 1 */ "movl $1, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 0(%1), %%xmm4 ;\n" "movdqa 16(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 32(%1), %%xmm4 ;\n" "movdqa 48(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 2 */ "movl $2, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 96(%1), %%xmm4 ;\n" "movdqa 112(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 128(%1), %%xmm4 ;\n" "movdqa 144(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 3 */ "movl $3, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 192(%1), %%xmm4 ;\n" "movdqa 208(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 224(%1), %%xmm4 ;\n" "movdqa 240(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 4 */ "movl $4, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 288(%1), %%xmm4 ;\n" "movdqa 304(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 320(%1), %%xmm4 ;\n" "movdqa 336(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 5 */ "movl $5, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 384(%1), %%xmm4 ;\n" "movdqa 400(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 416(%1), %%xmm4 ;\n" "movdqa 432(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 6 */ "movl $6, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 480(%1), %%xmm4 ;\n" "movdqa 496(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 512(%1), %%xmm4 ;\n" "movdqa 528(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 7 */ "movl $7, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 576(%1), %%xmm4 ;\n" "movdqa 592(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 608(%1), %%xmm4 ;\n" "movdqa 624(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* 8 */ "movl $8, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 672(%1), %%xmm4 ;\n" "movdqa 688(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm0 ;\n" "por %%xmm5, %%xmm1 ;\n" "movdqa 704(%1), %%xmm4 ;\n" "movdqa 720(%1), %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "por %%xmm4, %%xmm2 ;\n" "por %%xmm5, %%xmm3 ;\n" /* conditional swap based on sign */ "movl %3, %%ecx ;\n" "movl %2, %%eax ;\n" "xorl $1, %%ecx ;\n" "movd %%ecx, %%xmm6 ;\n" "pxor %%xmm7, %%xmm7 ;\n" "pshufd $0x00, %%xmm6, %%xmm6 ;\n" "pxor %%xmm0, %%xmm2 ;\n" "pxor %%xmm1, %%xmm3 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa %%xmm2, %%xmm4 ;\n" "movdqa %%xmm3, %%xmm5 ;\n" "pand %%xmm7, %%xmm4 ;\n" "pand %%xmm7, %%xmm5 ;\n" "pxor %%xmm4, %%xmm0 ;\n" "pxor %%xmm5, %%xmm1 ;\n" "pxor %%xmm0, %%xmm2 ;\n" "pxor %%xmm1, %%xmm3 ;\n" /* store ysubx */ "movd %%xmm0, %%ecx ;\n" "movl %%ecx, %%edx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 0(%%eax) ;\n" "movd %%xmm0, %%ecx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "shrdl $26, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 4(%%eax) ;\n" "movd %%xmm0, %%edx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "shrdl $19, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 8(%%eax) ;\n" "movd %%xmm0, %%ecx ;\n" "shrdl $13, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 12(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrl $6, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 16(%%eax) ;\n" "movl %%edx, %%ecx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 20(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrdl $25, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 24(%%eax) ;\n" "movd %%xmm1, %%ecx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrdl $19, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 28(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "shrdl $12, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 32(%%eax) ;\n" "shrl $6, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "xorl %%ecx, %%ecx ;\n" "movl %%edx, 36(%%eax) ;\n" "movl %%ecx, 40(%%eax) ;\n" "movl %%ecx, 44(%%eax) ;\n" /* store xaddy */ "addl $48, %%eax ;\n" "movdqa %%xmm2, %%xmm0 ;\n" "movdqa %%xmm3, %%xmm1 ;\n" "movd %%xmm0, %%ecx ;\n" "movl %%ecx, %%edx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 0(%%eax) ;\n" "movd %%xmm0, %%ecx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "shrdl $26, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 4(%%eax) ;\n" "movd %%xmm0, %%edx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "shrdl $19, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 8(%%eax) ;\n" "movd %%xmm0, %%ecx ;\n" "shrdl $13, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 12(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrl $6, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 16(%%eax) ;\n" "movl %%edx, %%ecx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 20(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrdl $25, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 24(%%eax) ;\n" "movd %%xmm1, %%ecx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrdl $19, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 28(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "shrdl $12, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 32(%%eax) ;\n" "shrl $6, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "xorl %%ecx, %%ecx ;\n" "movl %%edx, 36(%%eax) ;\n" "movl %%ecx, 40(%%eax) ;\n" "movl %%ecx, 44(%%eax) ;\n" /* t2d */ "movl %0, %%eax ;\n" "movd %%eax, %%xmm6 ;\n" "pshufd $0x00, %%xmm6, %%xmm6 ;\n" "pxor %%xmm0, %%xmm0 ;\n" "pxor %%xmm1, %%xmm1 ;\n" /* 0 */ "movl $0, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "pxor %%xmm0, %%xmm0 ;\n" "pxor %%xmm1, %%xmm1 ;\n" /* 1 */ "movl $1, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 64(%1), %%xmm3 ;\n" "movdqa 80(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* 2 */ "movl $2, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 160(%1), %%xmm3 ;\n" "movdqa 176(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* 3 */ "movl $3, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 256(%1), %%xmm3 ;\n" "movdqa 272(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* 4 */ "movl $4, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 352(%1), %%xmm3 ;\n" "movdqa 368(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* 5 */ "movl $5, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 448(%1), %%xmm3 ;\n" "movdqa 464(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* 6 */ "movl $6, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 544(%1), %%xmm3 ;\n" "movdqa 560(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* 7 */ "movl $7, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 640(%1), %%xmm3 ;\n" "movdqa 656(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* 8 */ "movl $8, %%eax ;\n" "movd %%eax, %%xmm7 ;\n" "pshufd $0x00, %%xmm7, %%xmm7 ;\n" "pcmpeqd %%xmm6, %%xmm7 ;\n" "movdqa 736(%1), %%xmm3 ;\n" "movdqa 752(%1), %%xmm4 ;\n" "pand %%xmm7, %%xmm3 ;\n" "pand %%xmm7, %%xmm4 ;\n" "por %%xmm3, %%xmm0 ;\n" "por %%xmm4, %%xmm1 ;\n" /* store t2d */ "movl %2, %%eax ;\n" "addl $96, %%eax ;\n" "movd %%xmm0, %%ecx ;\n" "movl %%ecx, %%edx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 0(%%eax) ;\n" "movd %%xmm0, %%ecx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "shrdl $26, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 4(%%eax) ;\n" "movd %%xmm0, %%edx ;\n" "pshufd $0x39, %%xmm0, %%xmm0 ;\n" "shrdl $19, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 8(%%eax) ;\n" "movd %%xmm0, %%ecx ;\n" "shrdl $13, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 12(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrl $6, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 16(%%eax) ;\n" "movl %%edx, %%ecx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 20(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrdl $25, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 24(%%eax) ;\n" "movd %%xmm1, %%ecx ;\n" "pshufd $0x39, %%xmm1, %%xmm1 ;\n" "shrdl $19, %%ecx, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "movl %%edx, 28(%%eax) ;\n" "movd %%xmm1, %%edx ;\n" "movd %%xmm1, %%edx ;\n" "shrdl $12, %%edx, %%ecx ;\n" "andl $0x3ffffff, %%ecx ;\n" "movl %%ecx, 32(%%eax) ;\n" "shrl $6, %%edx ;\n" "andl $0x1ffffff, %%edx ;\n" "xorl %%ecx, %%ecx ;\n" "movl %%edx, 36(%%eax) ;\n" "movl %%ecx, 40(%%eax) ;\n" "movl %%ecx, 44(%%eax) ;\n" "movdqa 0(%%eax), %%xmm0 ;\n" "movdqa 16(%%eax), %%xmm1 ;\n" "movdqa 32(%%eax), %%xmm2 ;\n" /* conditionally negate t2d */ /* set up 2p in to 3/4 */ "movl $0x7ffffda, %%ecx ;\n" "movl $0x3fffffe, %%edx ;\n" "movd %%ecx, %%xmm3 ;\n" "movd %%edx, %%xmm5 ;\n" "movl $0x7fffffe, %%ecx ;\n" "movd %%ecx, %%xmm4 ;\n" "punpckldq %%xmm5, %%xmm3 ;\n" "punpckldq %%xmm5, %%xmm4 ;\n" "punpcklqdq %%xmm4, %%xmm3 ;\n" "movdqa %%xmm4, %%xmm5 ;\n" "punpcklqdq %%xmm4, %%xmm4 ;\n" /* subtract and conditionally move */ "movl %3, %%ecx ;\n" "sub $1, %%ecx ;\n" "movd %%ecx, %%xmm6 ;\n" "pshufd $0x00, %%xmm6, %%xmm6 ;\n" "movdqa %%xmm6, %%xmm7 ;\n" "psubd %%xmm0, %%xmm3 ;\n" "psubd %%xmm1, %%xmm4 ;\n" "psubd %%xmm2, %%xmm5 ;\n" "pand %%xmm6, %%xmm0 ;\n" "pand %%xmm6, %%xmm1 ;\n" "pand %%xmm6, %%xmm2 ;\n" "pandn %%xmm3, %%xmm6 ;\n" "movdqa %%xmm7, %%xmm3 ;\n" "pandn %%xmm4, %%xmm7 ;\n" "pandn %%xmm5, %%xmm3 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm3, %%xmm2 ;\n" /* store */ "movdqa %%xmm0, 0(%%eax) ;\n" "movdqa %%xmm1, 16(%%eax) ;\n" "movdqa %%xmm2, 32(%%eax) ;\n" : : "m"(u), "r"(&table[pos * 8]), "m"(t), "m"(sign) /* %0 = u, %1 = table, %2 = t, %3 = sign */ : "%eax", "%ecx", "%edx", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "cc", "memory" ); } #endif /* defined(ED25519_GCC_32BIT_SSE_CHOOSE) */ cryptonite-0.23/cbits/ed25519/ed25519-donna-32bit-tables.h0000644000000000000000000002734212540765247020607 0ustar0000000000000000static const ge25519 ALIGN(16) ge25519_basepoint = { {0x0325d51a,0x018b5823,0x00f6592a,0x0104a92d,0x01a4b31d,0x01d6dc5c,0x027118fe,0x007fd814,0x013cd6e5,0x0085a4db}, {0x02666658,0x01999999,0x00cccccc,0x01333333,0x01999999,0x00666666,0x03333333,0x00cccccc,0x02666666,0x01999999}, {0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000}, {0x01b7dda3,0x01a2ace9,0x025eadbb,0x0003ba8a,0x0083c27e,0x00abe37d,0x01274732,0x00ccacdd,0x00fd78b7,0x019e1d7c} }; /* d */ static const bignum25519 ALIGN(16) ge25519_ecd = { 0x035978a3,0x00d37284,0x03156ebd,0x006a0a0e,0x0001c029,0x0179e898,0x03a03cbb,0x01ce7198,0x02e2b6ff,0x01480db3 }; static const bignum25519 ALIGN(16) ge25519_ec2d = { 0x02b2f159,0x01a6e509,0x022add7a,0x00d4141d,0x00038052,0x00f3d130,0x03407977,0x019ce331,0x01c56dff,0x00901b67 }; /* sqrt(-1) */ static const bignum25519 ALIGN(16) ge25519_sqrtneg1 = { 0x020ea0b0,0x0186c9d2,0x008f189d,0x0035697f,0x00bd0c60,0x01fbd7a7,0x02804c9e,0x01e16569,0x0004fc1d,0x00ae0c92 }; static const ge25519_niels ALIGN(16) ge25519_niels_sliding_multiples[32] = { {{0x0340913e,0x000e4175,0x03d673a2,0x002e8a05,0x03f4e67c,0x008f8a09,0x00c21a34,0x004cf4b8,0x01298f81,0x0113f4be},{0x018c3b85,0x0124f1bd,0x01c325f7,0x0037dc60,0x033e4cb7,0x003d42c2,0x01a44c32,0x014ca4e1,0x03a33d4b,0x001f3e74},{0x037aaa68,0x00448161,0x0093d579,0x011e6556,0x009b67a0,0x0143598c,0x01bee5ee,0x00b50b43,0x0289f0c6,0x01bc45ed}}, {{0x00fcd265,0x0047fa29,0x034faacc,0x01ef2e0d,0x00ef4d4f,0x014bd6bd,0x00f98d10,0x014c5026,0x007555bd,0x00aae456},{0x00ee9730,0x016c2a13,0x017155e4,0x01874432,0x00096a10,0x01016732,0x01a8014f,0x011e9823,0x01b9a80f,0x01e85938},{0x01d0d889,0x01a4cfc3,0x034c4295,0x0110e1ae,0x0162508c,0x00f2db4c,0x0072a2c6,0x0098da2e,0x02f12b9b,0x0168a09a}}, {{0x0047d6ba,0x0060b0e9,0x0136eff2,0x008a5939,0x03540053,0x0064a087,0x02788e5c,0x00be7c67,0x033eb1b5,0x005529f9},{0x00a5bb33,0x00af1102,0x01a05442,0x001e3af7,0x02354123,0x00bfec44,0x01f5862d,0x00dd7ba3,0x03146e20,0x00a51733},{0x012a8285,0x00f6fc60,0x023f9797,0x003e85ee,0x009c3820,0x01bda72d,0x01b3858d,0x00d35683,0x0296b3bb,0x010eaaf9}}, {{0x023221b1,0x01cb26aa,0x0074f74d,0x0099ddd1,0x01b28085,0x00192c3a,0x013b27c9,0x00fc13bd,0x01d2e531,0x0075bb75},{0x004ea3bf,0x00973425,0x001a4d63,0x01d59cee,0x01d1c0d4,0x00542e49,0x01294114,0x004fce36,0x029283c9,0x01186fa9},{0x01b8b3a2,0x00db7200,0x00935e30,0x003829f5,0x02cc0d7d,0x0077adf3,0x0220dd2c,0x0014ea53,0x01c6a0f9,0x01ea7eec}}, {{0x039d8064,0x01885f80,0x00337e6d,0x01b7a902,0x02628206,0x015eb044,0x01e30473,0x0191f2d9,0x011fadc9,0x01270169},{0x02a8632f,0x0199e2a9,0x00d8b365,0x017a8de2,0x02994279,0x0086f5b5,0x0119e4e3,0x01eb39d6,0x0338add7,0x00d2e7b4},{0x0045af1b,0x013a2fe4,0x0245e0d6,0x014538ce,0x038bfe0f,0x01d4cf16,0x037e14c9,0x0160d55e,0x0021b008,0x01cf05c8}}, {{0x01864348,0x01d6c092,0x0070262b,0x014bb844,0x00fb5acd,0x008deb95,0x003aaab5,0x00eff474,0x00029d5c,0x0062ad66},{0x02802ade,0x01c02122,0x01c4e5f7,0x00781181,0x039767fb,0x01703406,0x0342388b,0x01f5e227,0x022546d8,0x0109d6ab},{0x016089e9,0x00cb317f,0x00949b05,0x01099417,0x000c7ad2,0x011a8622,0x0088ccda,0x01290886,0x022b53df,0x00f71954}}, {{0x027fbf93,0x01c04ecc,0x01ed6a0d,0x004cdbbb,0x02bbf3af,0x00ad5968,0x01591955,0x0094f3a2,0x02d17602,0x00099e20},{0x02007f6d,0x003088a8,0x03db77ee,0x00d5ade6,0x02fe12ce,0x0107ba07,0x0107097d,0x00482a6f,0x02ec346f,0x008d3f5f},{0x032ea378,0x0028465c,0x028e2a6c,0x018efc6e,0x0090df9a,0x01a7e533,0x039bfc48,0x010c745d,0x03daa097,0x0125ee9b}}, {{0x028ccf0b,0x00f36191,0x021ac081,0x012154c8,0x034e0a6e,0x01b25192,0x00180403,0x01d7eea1,0x00218d05,0x010ed735},{0x03cfeaa0,0x01b300c4,0x008da499,0x0068c4e1,0x0219230a,0x01f2d4d0,0x02defd60,0x00e565b7,0x017f12de,0x018788a4},{0x03d0b516,0x009d8be6,0x03ddcbb3,0x0071b9fe,0x03ace2bd,0x01d64270,0x032d3ec9,0x01084065,0x0210ae4d,0x01447584}}, {{0x0020de87,0x00e19211,0x01b68102,0x00b5ac97,0x022873c0,0x01942d25,0x01271394,0x0102073f,0x02fe2482,0x01c69ff9},{0x010e9d81,0x019dbbe5,0x0089f258,0x006e06b8,0x02951883,0x018f1248,0x019b3237,0x00bc7553,0x024ddb85,0x01b4c964},{0x01c8c854,0x0060ae29,0x01406d8e,0x01cff2f9,0x00cff451,0x01778d0c,0x03ac8c41,0x01552e59,0x036559ee,0x011d1b12}}, {{0x00741147,0x0151b219,0x01092690,0x00e877e6,0x01f4d6bb,0x0072a332,0x01cd3b03,0x00dadff2,0x0097db5e,0x0086598d},{0x01c69a2b,0x01decf1b,0x02c2fa6e,0x013b7c4f,0x037beac8,0x013a16b5,0x028e7bda,0x01f6e8ac,0x01e34fe9,0x01726947},{0x01f10e67,0x003c73de,0x022b7ea2,0x010f32c2,0x03ff776a,0x00142277,0x01d38b88,0x00776138,0x03c60822,0x01201140}}, {{0x0236d175,0x0008748e,0x03c6476d,0x013f4cdc,0x02eed02a,0x00838a47,0x032e7210,0x018bcbb3,0x00858de4,0x01dc7826},{0x00a37fc7,0x0127b40b,0x01957884,0x011d30ad,0x02816683,0x016e0e23,0x00b76be4,0x012db115,0x02516506,0x0154ce62},{0x00451edf,0x00bd749e,0x03997342,0x01cc2c4c,0x00eb6975,0x01a59508,0x03a516cf,0x00c228ef,0x0168ff5a,0x01697b47}}, {{0x00527359,0x01783156,0x03afd75c,0x00ce56dc,0x00e4b970,0x001cabe9,0x029e0f6d,0x0188850c,0x0135fefd,0x00066d80},{0x02150e83,0x01448abf,0x02bb0232,0x012bf259,0x033c8268,0x00711e20,0x03fc148f,0x005e0e70,0x017d8bf9,0x0112b2e2},{0x02134b83,0x001a0517,0x0182c3cc,0x00792182,0x0313d799,0x001a3ed7,0x0344547e,0x01f24a0d,0x03de6ad2,0x00543127}}, {{0x00dca868,0x00618f27,0x015a1709,0x00ddc38a,0x0320fd13,0x0036168d,0x0371ab06,0x01783fc7,0x0391e05f,0x01e29b5d},{0x01471138,0x00fca542,0x00ca31cf,0x01ca7bad,0x0175bfbc,0x01a708ad,0x03bce212,0x01244215,0x0075bb99,0x01acad68},{0x03a0b976,0x01dc12d1,0x011aab17,0x00aba0ba,0x029806cd,0x0142f590,0x018fd8ea,0x01a01545,0x03c4ad55,0x01c971ff}}, {{0x00d098c0,0x000afdc7,0x006cd230,0x01276af3,0x03f905b2,0x0102994c,0x002eb8a4,0x015cfbeb,0x025f855f,0x01335518},{0x01cf99b2,0x0099c574,0x01a69c88,0x00881510,0x01cd4b54,0x0112109f,0x008abdc5,0x0074647a,0x0277cb1f,0x01e53324},{0x02ac5053,0x01b109b0,0x024b095e,0x016997b3,0x02f26bb6,0x00311021,0x00197885,0x01d0a55a,0x03b6fcc8,0x01c020d5}}, {{0x02584a34,0x00e7eee0,0x03257a03,0x011e95a3,0x011ead91,0x00536202,0x00b1ce24,0x008516c6,0x03669d6d,0x004ea4a8},{0x00773f01,0x0019c9ce,0x019f6171,0x01d4afde,0x02e33323,0x01ad29b6,0x02ead1dc,0x01ed51a5,0x01851ad0,0x001bbdfa},{0x00577de5,0x00ddc730,0x038b9952,0x00f281ae,0x01d50390,0x0002e071,0x000780ec,0x010d448d,0x01f8a2af,0x00f0a5b7}}, {{0x031f2541,0x00d34bae,0x0323ff9d,0x003a056d,0x02e25443,0x00a1ad05,0x00d1bee8,0x002f7f8e,0x03007477,0x002a24b1},{0x0114a713,0x01457e76,0x032255d5,0x01cc647f,0x02a4bdef,0x0153d730,0x00118bcf,0x00f755ff,0x013490c7,0x01ea674e},{0x02bda3e8,0x00bb490d,0x00f291ea,0x000abf40,0x01dea321,0x002f9ce0,0x00b2b193,0x00fa54b5,0x0128302f,0x00a19d8b}}, {{0x022ef5bd,0x01638af3,0x038c6f8a,0x01a33a3d,0x039261b2,0x01bb89b8,0x010bcf9d,0x00cf42a9,0x023d6f17,0x01da1bca},{0x00e35b25,0x000d824f,0x0152e9cf,0x00ed935d,0x020b8460,0x01c7b83f,0x00c969e5,0x01a74198,0x0046a9d9,0x00cbc768},{0x01597c6a,0x0144a99b,0x00a57551,0x0018269c,0x023c464c,0x0009b022,0x00ee39e1,0x0114c7f2,0x038a9ad2,0x01584c17}}, {{0x03b0c0d5,0x00b30a39,0x038a6ce4,0x01ded83a,0x01c277a6,0x01010a61,0x0346d3eb,0x018d995e,0x02f2c57c,0x000c286b},{0x0092aed1,0x0125e37b,0x027ca201,0x001a6b6b,0x03290f55,0x0047ba48,0x018d916c,0x01a59062,0x013e35d4,0x0002abb1},{0x003ad2aa,0x007ddcc0,0x00c10f76,0x0001590b,0x002cfca6,0x000ed23e,0x00ee4329,0x00900f04,0x01c24065,0x0082fa70}}, {{0x02025e60,0x003912b8,0x0327041c,0x017e5ee5,0x02c0ecec,0x015a0d1c,0x02b1ce7c,0x0062220b,0x0145067e,0x01a5d931},{0x009673a6,0x00e1f609,0x00927c2a,0x016faa37,0x01650ef0,0x016f63b5,0x03cd40e1,0x003bc38f,0x0361f0ac,0x01d42acc},{0x02f81037,0x008ca0e8,0x017e23d1,0x011debfe,0x01bcbb68,0x002e2563,0x03e8add6,0x000816e5,0x03fb7075,0x0153e5ac}}, {{0x02b11ecd,0x016bf185,0x008f22ef,0x00e7d2bb,0x0225d92e,0x00ece785,0x00508873,0x017e16f5,0x01fbe85d,0x01e39a0e},{0x01669279,0x017c810a,0x024941f5,0x0023ebeb,0x00eb7688,0x005760f1,0x02ca4146,0x0073cde7,0x0052bb75,0x00f5ffa7},{0x03b8856b,0x00cb7dcd,0x02f14e06,0x001820d0,0x01d74175,0x00e59e22,0x03fba550,0x00484641,0x03350088,0x01c3c9a3}}, {{0x00dcf355,0x0104481c,0x0022e464,0x01f73fe7,0x00e03325,0x0152b698,0x02ef769a,0x00973663,0x00039b8c,0x0101395b},{0x01805f47,0x019160ec,0x03832cd0,0x008b06eb,0x03d4d717,0x004cb006,0x03a75b8f,0x013b3d30,0x01cfad88,0x01f034d1},{0x0078338a,0x01c7d2e3,0x02bc2b23,0x018b3f05,0x0280d9aa,0x005f3d44,0x0220a95a,0x00eeeb97,0x0362aaec,0x00835d51}}, {{0x01b9f543,0x013fac4d,0x02ad93ae,0x018ef464,0x0212cdf7,0x01138ba9,0x011583ab,0x019c3d26,0x028790b4,0x00e2e2b6},{0x033bb758,0x01f0dbf1,0x03734bd1,0x0129b1e5,0x02b3950e,0x003bc922,0x01a53ec8,0x018c5532,0x006f3cee,0x00ae3c79},{0x0351f95d,0x0012a737,0x03d596b8,0x017658fe,0x00ace54a,0x008b66da,0x0036c599,0x012a63a2,0x032ceba1,0x00126bac}}, {{0x03dcfe7e,0x019f4f18,0x01c81aee,0x0044bc2b,0x00827165,0x014f7c13,0x03b430f0,0x00bf96cc,0x020c8d62,0x01471997},{0x01fc7931,0x001f42dd,0x00ba754a,0x005bd339,0x003fbe49,0x016b3930,0x012a159c,0x009f83b0,0x03530f67,0x01e57b85},{0x02ecbd81,0x0096c294,0x01fce4a9,0x017701a5,0x0175047d,0x00ee4a31,0x012686e5,0x008efcd4,0x0349dc54,0x01b3466f}}, {{0x02179ca3,0x01d86414,0x03f0afd0,0x00305964,0x015c7428,0x0099711e,0x015d5442,0x00c71014,0x01b40b2e,0x01d483cf},{0x01afc386,0x01984859,0x036203ff,0x0045c6a8,0x0020a8aa,0x00990baa,0x03313f10,0x007ceede,0x027429e4,0x017806ce},{0x039357a1,0x0142f8f4,0x0294a7b6,0x00eaccf4,0x0259edb3,0x01311e6e,0x004d326f,0x0130c346,0x01ccef3c,0x01c424b2}}, {{0x0364918c,0x00148fc0,0x01638a7b,0x01a1fd5b,0x028ad013,0x0081e5a4,0x01a54f33,0x0174e101,0x003d0257,0x003a856c},{0x00051dcf,0x00f62b1d,0x0143d0ad,0x0042adbd,0x000fda90,0x01743ceb,0x0173e5e4,0x017bc749,0x03b7137a,0x0105ce96},{0x00f9218a,0x015b8c7c,0x00e102f8,0x0158d7e2,0x0169a5b8,0x00b2f176,0x018b347a,0x014cfef2,0x0214a4e3,0x017f1595}}, {{0x006d7ae5,0x0195c371,0x0391e26d,0x0062a7c6,0x003f42ab,0x010dad86,0x024f8198,0x01542b2a,0x0014c454,0x0189c471},{0x0390988e,0x00b8799d,0x02e44912,0x0078e2e6,0x00075654,0x01923eed,0x0040cd72,0x00a37c76,0x0009d466,0x00c8531d},{0x02651770,0x00609d01,0x0286c265,0x0134513c,0x00ee9281,0x005d223c,0x035c760c,0x00679b36,0x0073ecb8,0x016faa50}}, {{0x02c89be4,0x016fc244,0x02f38c83,0x018beb72,0x02b3ce2c,0x0097b065,0x034f017b,0x01dd957f,0x00148f61,0x00eab357},{0x0343d2f8,0x003398fc,0x011e368e,0x00782a1f,0x00019eea,0x00117b6f,0x0128d0d1,0x01a5e6bb,0x01944f1b,0x012b41e1},{0x03318301,0x018ecd30,0x0104d0b1,0x0038398b,0x03726701,0x019da88c,0x002d9769,0x00a7a681,0x031d9028,0x00ebfc32}}, {{0x0220405e,0x0171face,0x02d930f8,0x017f6d6a,0x023b8c47,0x0129d5f9,0x02972456,0x00a3a524,0x006f4cd2,0x004439fa},{0x00c53505,0x0190c2fd,0x00507244,0x009930f9,0x01a39270,0x01d327c6,0x0399bc47,0x01cfe13d,0x0332bd99,0x00b33e7d},{0x0203f5e4,0x003627b5,0x00018af8,0x01478581,0x004a2218,0x002e3bb7,0x039384d0,0x0146ea62,0x020b9693,0x0017155f}}, {{0x03c97e6f,0x00738c47,0x03b5db1f,0x01808fcf,0x01e8fc98,0x01ed25dd,0x01bf5045,0x00eb5c2b,0x0178fe98,0x01b85530},{0x01c20eb0,0x01aeec22,0x030b9eee,0x01b7d07e,0x0187e16f,0x014421fb,0x009fa731,0x0040b6d7,0x00841861,0x00a27fbc},{0x02d69abf,0x0058cdbf,0x0129f9ec,0x013c19ae,0x026c5b93,0x013a7fe7,0x004bb2ba,0x0063226f,0x002a95ca,0x01abefd9}}, {{0x02f5d2c1,0x00378318,0x03734fb5,0x01258073,0x0263f0f6,0x01ad70e0,0x01b56d06,0x01188fbd,0x011b9503,0x0036d2e1},{0x0113a8cc,0x01541c3e,0x02ac2bbc,0x01d95867,0x01f47459,0x00ead489,0x00ab5b48,0x01db3b45,0x00edb801,0x004b024f},{0x00b8190f,0x011fe4c2,0x00621f82,0x010508d7,0x001a5a76,0x00c7d7fd,0x03aab96d,0x019cd9dc,0x019c6635,0x00ceaa1e}}, {{0x01085cf2,0x01fd47af,0x03e3f5e1,0x004b3e99,0x01e3d46a,0x0060033c,0x015ff0a8,0x0150cdd8,0x029e8e21,0x008cf1bc},{0x00156cb1,0x003d623f,0x01a4f069,0x00d8d053,0x01b68aea,0x01ca5ab6,0x0316ae43,0x0134dc44,0x001c8d58,0x0084b343},{0x0318c781,0x0135441f,0x03a51a5e,0x019293f4,0x0048bb37,0x013d3341,0x0143151e,0x019c74e1,0x00911914,0x0076ddde}}, {{0x006bc26f,0x00d48e5f,0x00227bbe,0x00629ea8,0x01ea5f8b,0x0179a330,0x027a1d5f,0x01bf8f8e,0x02d26e2a,0x00c6b65e},{0x01701ab6,0x0051da77,0x01b4b667,0x00a0ce7c,0x038ae37b,0x012ac852,0x03a0b0fe,0x0097c2bb,0x00a017d2,0x01eb8b2a},{0x0120b962,0x0005fb42,0x0353b6fd,0x0061f8ce,0x007a1463,0x01560a64,0x00e0a792,0x01907c92,0x013a6622,0x007b47f1}} }; cryptonite-0.23/cbits/ed25519/ed25519-donna-64bit-tables.h0000644000000000000000000002421412514663134020600 0ustar0000000000000000static const ge25519 ge25519_basepoint = { {0x00062d608f25d51a,0x000412a4b4f6592a,0x00075b7171a4b31d,0x0001ff60527118fe,0x000216936d3cd6e5}, {0x0006666666666658,0x0004cccccccccccc,0x0001999999999999,0x0003333333333333,0x0006666666666666}, {0x0000000000000001,0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000}, {0x00068ab3a5b7dda3,0x00000eea2a5eadbb,0x0002af8df483c27e,0x000332b375274732,0x00067875f0fd78b7} }; static const bignum25519 ge25519_ecd = { 0x00034dca135978a3,0x0001a8283b156ebd,0x0005e7a26001c029,0x000739c663a03cbb,0x00052036cee2b6ff }; static const bignum25519 ge25519_ec2d = { 0x00069b9426b2f159,0x00035050762add7a,0x0003cf44c0038052,0x0006738cc7407977,0x0002406d9dc56dff }; static const bignum25519 ge25519_sqrtneg1 = { 0x00061b274a0ea0b0,0x0000d5a5fc8f189d,0x0007ef5e9cbd0c60,0x00078595a6804c9e,0x0002b8324804fc1d }; static const ge25519_niels ge25519_niels_sliding_multiples[32] = { {{0x00003905d740913e,0x0000ba2817d673a2,0x00023e2827f4e67c,0x000133d2e0c21a34,0x00044fd2f9298f81},{0x000493c6f58c3b85,0x0000df7181c325f7,0x0000f50b0b3e4cb7,0x0005329385a44c32,0x00007cf9d3a33d4b},{0x00011205877aaa68,0x000479955893d579,0x00050d66309b67a0,0x0002d42d0dbee5ee,0x0006f117b689f0c6}}, {{0x00011fe8a4fcd265,0x0007bcb8374faacc,0x00052f5af4ef4d4f,0x0005314098f98d10,0x0002ab91587555bd},{0x0005b0a84cee9730,0x00061d10c97155e4,0x0004059cc8096a10,0x00047a608da8014f,0x0007a164e1b9a80f},{0x0006933f0dd0d889,0x00044386bb4c4295,0x0003cb6d3162508c,0x00026368b872a2c6,0x0005a2826af12b9b}}, {{0x000182c3a447d6ba,0x00022964e536eff2,0x000192821f540053,0x0002f9f19e788e5c,0x000154a7e73eb1b5},{0x0002bc4408a5bb33,0x000078ebdda05442,0x0002ffb112354123,0x000375ee8df5862d,0x0002945ccf146e20},{0x0003dbf1812a8285,0x0000fa17ba3f9797,0x0006f69cb49c3820,0x00034d5a0db3858d,0x00043aabe696b3bb}}, {{0x00072c9aaa3221b1,0x000267774474f74d,0x000064b0e9b28085,0x0003f04ef53b27c9,0x0001d6edd5d2e531},{0x00025cd0944ea3bf,0x00075673b81a4d63,0x000150b925d1c0d4,0x00013f38d9294114,0x000461bea69283c9},{0x00036dc801b8b3a2,0x0000e0a7d4935e30,0x0001deb7cecc0d7d,0x000053a94e20dd2c,0x0007a9fbb1c6a0f9}}, {{0x0006217e039d8064,0x0006dea408337e6d,0x00057ac112628206,0x000647cb65e30473,0x00049c05a51fadc9},{0x0006678aa6a8632f,0x0005ea3788d8b365,0x00021bd6d6994279,0x0007ace75919e4e3,0x00034b9ed338add7},{0x0004e8bf9045af1b,0x000514e33a45e0d6,0x0007533c5b8bfe0f,0x000583557b7e14c9,0x00073c172021b008}}, {{0x00075b0249864348,0x00052ee11070262b,0x000237ae54fb5acd,0x0003bfd1d03aaab5,0x00018ab598029d5c},{0x000700848a802ade,0x0001e04605c4e5f7,0x0005c0d01b9767fb,0x0007d7889f42388b,0x0004275aae2546d8},{0x00032cc5fd6089e9,0x000426505c949b05,0x00046a18880c7ad2,0x0004a4221888ccda,0x0003dc65522b53df}}, {{0x0007013b327fbf93,0x0001336eeded6a0d,0x0002b565a2bbf3af,0x000253ce89591955,0x0000267882d17602},{0x0000c222a2007f6d,0x000356b79bdb77ee,0x00041ee81efe12ce,0x000120a9bd07097d,0x000234fd7eec346f},{0x0000a119732ea378,0x00063bf1ba8e2a6c,0x00069f94cc90df9a,0x000431d1779bfc48,0x000497ba6fdaa097}}, {{0x0003cd86468ccf0b,0x00048553221ac081,0x0006c9464b4e0a6e,0x00075fba84180403,0x00043b5cd4218d05},{0x0006cc0313cfeaa0,0x0001a313848da499,0x0007cb534219230a,0x00039596dedefd60,0x00061e22917f12de},{0x0002762f9bd0b516,0x0001c6e7fbddcbb3,0x00075909c3ace2bd,0x00042101972d3ec9,0x000511d61210ae4d}}, {{0x000386484420de87,0x0002d6b25db68102,0x000650b4962873c0,0x0004081cfd271394,0x00071a7fe6fe2482},{0x000676ef950e9d81,0x0001b81ae089f258,0x00063c4922951883,0x0002f1d54d9b3237,0x0006d325924ddb85},{0x000182b8a5c8c854,0x00073fcbe5406d8e,0x0005de3430cff451,0x000554b967ac8c41,0x0004746c4b6559ee}}, {{0x000546c864741147,0x0003a1df99092690,0x0001ca8cc9f4d6bb,0x00036b7fc9cd3b03,0x000219663497db5e},{0x00077b3c6dc69a2b,0x0004edf13ec2fa6e,0x0004e85ad77beac8,0x0007dba2b28e7bda,0x0005c9a51de34fe9},{0x0000f1cf79f10e67,0x00043ccb0a2b7ea2,0x00005089dfff776a,0x0001dd84e1d38b88,0x0004804503c60822}}, {{0x000021d23a36d175,0x0004fd3373c6476d,0x00020e291eeed02a,0x00062f2ecf2e7210,0x000771e098858de4},{0x00049ed02ca37fc7,0x000474c2b5957884,0x0005b8388e816683,0x0004b6c454b76be4,0x000553398a516506},{0x0002f5d278451edf,0x000730b133997342,0x0006965420eb6975,0x000308a3bfa516cf,0x0005a5ed1d68ff5a}}, {{0x0005e0c558527359,0x0003395b73afd75c,0x000072afa4e4b970,0x00062214329e0f6d,0x000019b60135fefd},{0x0005122afe150e83,0x0004afc966bb0232,0x0001c478833c8268,0x00017839c3fc148f,0x00044acb897d8bf9},{0x000068145e134b83,0x0001e4860982c3cc,0x000068fb5f13d799,0x0007c9283744547e,0x000150c49fde6ad2}}, {{0x0001863c9cdca868,0x0003770e295a1709,0x0000d85a3720fd13,0x0005e0ff1f71ab06,0x00078a6d7791e05f},{0x0003f29509471138,0x000729eeb4ca31cf,0x00069c22b575bfbc,0x0004910857bce212,0x0006b2b5a075bb99},{0x0007704b47a0b976,0x0002ae82e91aab17,0x00050bd6429806cd,0x00068055158fd8ea,0x000725c7ffc4ad55}}, {{0x00002bf71cd098c0,0x00049dabcc6cd230,0x00040a6533f905b2,0x000573efac2eb8a4,0x0004cd54625f855f},{0x00026715d1cf99b2,0x0002205441a69c88,0x000448427dcd4b54,0x0001d191e88abdc5,0x000794cc9277cb1f},{0x0006c426c2ac5053,0x0005a65ece4b095e,0x0000c44086f26bb6,0x0007429568197885,0x0007008357b6fcc8}}, {{0x00039fbb82584a34,0x00047a568f257a03,0x00014d88091ead91,0x0002145b18b1ce24,0x00013a92a3669d6d},{0x0000672738773f01,0x000752bf799f6171,0x0006b4a6dae33323,0x0007b54696ead1dc,0x00006ef7e9851ad0},{0x0003771cc0577de5,0x0003ca06bb8b9952,0x00000b81c5d50390,0x00043512340780ec,0x0003c296ddf8a2af}}, {{0x00034d2ebb1f2541,0x0000e815b723ff9d,0x000286b416e25443,0x0000bdfe38d1bee8,0x0000a892c7007477},{0x000515f9d914a713,0x00073191ff2255d5,0x00054f5cc2a4bdef,0x0003dd57fc118bcf,0x0007a99d393490c7},{0x0002ed2436bda3e8,0x00002afd00f291ea,0x0000be7381dea321,0x0003e952d4b2b193,0x000286762d28302f}}, {{0x00058e2bce2ef5bd,0x00068ce8f78c6f8a,0x0006ee26e39261b2,0x00033d0aa50bcf9d,0x0007686f2a3d6f17},{0x000036093ce35b25,0x0003b64d7552e9cf,0x00071ee0fe0b8460,0x00069d0660c969e5,0x00032f1da046a9d9},{0x000512a66d597c6a,0x0000609a70a57551,0x000026c08a3c464c,0x0004531fc8ee39e1,0x000561305f8a9ad2}}, {{0x0002cc28e7b0c0d5,0x00077b60eb8a6ce4,0x0004042985c277a6,0x000636657b46d3eb,0x000030a1aef2c57c},{0x0004978dec92aed1,0x000069adae7ca201,0x00011ee923290f55,0x00069641898d916c,0x00000aaec53e35d4},{0x0001f773003ad2aa,0x000005642cc10f76,0x00003b48f82cfca6,0x0002403c10ee4329,0x00020be9c1c24065}}, {{0x0000e44ae2025e60,0x0005f97b9727041c,0x0005683472c0ecec,0x000188882eb1ce7c,0x00069764c545067e},{0x000387d8249673a6,0x0005bea8dc927c2a,0x0005bd8ed5650ef0,0x0000ef0e3fcd40e1,0x000750ab3361f0ac},{0x00023283a2f81037,0x000477aff97e23d1,0x0000b8958dbcbb68,0x0000205b97e8add6,0x00054f96b3fb7075}}, {{0x0005afc616b11ecd,0x00039f4aec8f22ef,0x0003b39e1625d92e,0x0005f85bd4508873,0x00078e6839fbe85d},{0x0005f20429669279,0x00008fafae4941f5,0x00015d83c4eb7688,0x0001cf379eca4146,0x0003d7fe9c52bb75},{0x00032df737b8856b,0x0000608342f14e06,0x0003967889d74175,0x0001211907fba550,0x00070f268f350088}}, {{0x0004112070dcf355,0x0007dcff9c22e464,0x00054ada60e03325,0x00025cd98eef769a,0x000404e56c039b8c},{0x00064583b1805f47,0x00022c1baf832cd0,0x000132c01bd4d717,0x0004ecf4c3a75b8f,0x0007c0d345cfad88},{0x00071f4b8c78338a,0x00062cfc16bc2b23,0x00017cf51280d9aa,0x0003bbae5e20a95a,0x00020d754762aaec}}, {{0x0004feb135b9f543,0x00063bd192ad93ae,0x00044e2ea612cdf7,0x000670f4991583ab,0x00038b8ada8790b4},{0x0007c36fc73bb758,0x0004a6c797734bd1,0x0000ef248ab3950e,0x00063154c9a53ec8,0x0002b8f1e46f3cee},{0x00004a9cdf51f95d,0x0005d963fbd596b8,0x00022d9b68ace54a,0x0004a98e8836c599,0x000049aeb32ceba1}}, {{0x00067d3c63dcfe7e,0x000112f0adc81aee,0x00053df04c827165,0x0002fe5b33b430f0,0x00051c665e0c8d62},{0x00007d0b75fc7931,0x00016f4ce4ba754a,0x0005ace4c03fbe49,0x00027e0ec12a159c,0x000795ee17530f67},{0x00025b0a52ecbd81,0x0005dc0695fce4a9,0x0003b928c575047d,0x00023bf3512686e5,0x0006cd19bf49dc54}}, {{0x0007619052179ca3,0x0000c16593f0afd0,0x000265c4795c7428,0x00031c40515d5442,0x0007520f3db40b2e},{0x0006612165afc386,0x0001171aa36203ff,0x0002642ea820a8aa,0x0001f3bb7b313f10,0x0005e01b3a7429e4},{0x00050be3d39357a1,0x0003ab33d294a7b6,0x0004c479ba59edb3,0x0004c30d184d326f,0x00071092c9ccef3c}}, {{0x0000523f0364918c,0x000687f56d638a7b,0x00020796928ad013,0x0005d38405a54f33,0x0000ea15b03d0257},{0x0003d8ac74051dcf,0x00010ab6f543d0ad,0x0005d0f3ac0fda90,0x0005ef1d2573e5e4,0x0004173a5bb7137a},{0x00056e31f0f9218a,0x0005635f88e102f8,0x0002cbc5d969a5b8,0x000533fbc98b347a,0x0005fc565614a4e3}}, {{0x0006570dc46d7ae5,0x00018a9f1b91e26d,0x000436b6183f42ab,0x000550acaa4f8198,0x00062711c414c454},{0x0002e1e67790988e,0x0001e38b9ae44912,0x000648fbb4075654,0x00028df1d840cd72,0x0003214c7409d466},{0x0001827406651770,0x0004d144f286c265,0x00017488f0ee9281,0x00019e6cdb5c760c,0x0005bea94073ecb8}}, {{0x0005bf0912c89be4,0x00062fadcaf38c83,0x00025ec196b3ce2c,0x00077655ff4f017b,0x0003aacd5c148f61},{0x0000ce63f343d2f8,0x0001e0a87d1e368e,0x000045edbc019eea,0x0006979aed28d0d1,0x0004ad0785944f1b},{0x00063b34c3318301,0x0000e0e62d04d0b1,0x000676a233726701,0x00029e9a042d9769,0x0003aff0cb1d9028}}, {{0x0005c7eb3a20405e,0x0005fdb5aad930f8,0x0004a757e63b8c47,0x00028e9492972456,0x000110e7e86f4cd2},{0x0006430bf4c53505,0x000264c3e4507244,0x00074c9f19a39270,0x00073f84f799bc47,0x0002ccf9f732bd99},{0x0000d89ed603f5e4,0x00051e1604018af8,0x0000b8eedc4a2218,0x00051ba98b9384d0,0x00005c557e0b9693}}, {{0x0001ce311fc97e6f,0x0006023f3fb5db1f,0x0007b49775e8fc98,0x0003ad70adbf5045,0x0006e154c178fe98},{0x0006bbb089c20eb0,0x0006df41fb0b9eee,0x00051087ed87e16f,0x000102db5c9fa731,0x000289fef0841861},{0x00016336fed69abf,0x0004f066b929f9ec,0x0004e9ff9e6c5b93,0x00018c89bc4bb2ba,0x0006afbf642a95ca}}, {{0x0000de0c62f5d2c1,0x00049601cf734fb5,0x0006b5c38263f0f6,0x0004623ef5b56d06,0x0000db4b851b9503},{0x00055070f913a8cc,0x000765619eac2bbc,0x0003ab5225f47459,0x00076ced14ab5b48,0x00012c093cedb801},{0x00047f9308b8190f,0x000414235c621f82,0x00031f5ff41a5a76,0x0006736773aab96d,0x00033aa8799c6635}}, {{0x0007f51ebd085cf2,0x00012cfa67e3f5e1,0x0001800cf1e3d46a,0x00054337615ff0a8,0x000233c6f29e8e21},{0x0000f588fc156cb1,0x000363414da4f069,0x0007296ad9b68aea,0x0004d3711316ae43,0x000212cd0c1c8d58},{0x0004d5107f18c781,0x00064a4fd3a51a5e,0x0004f4cd0448bb37,0x000671d38543151e,0x0001db7778911914}}, {{0x000352397c6bc26f,0x00018a7aa0227bbe,0x0005e68cc1ea5f8b,0x0006fe3e3a7a1d5f,0x00031ad97ad26e2a},{0x00014769dd701ab6,0x00028339f1b4b667,0x0004ab214b8ae37b,0x00025f0aefa0b0fe,0x0007ae2ca8a017d2},{0x000017ed0920b962,0x000187e33b53b6fd,0x00055829907a1463,0x000641f248e0a792,0x0001ed1fc53a6622}} }; cryptonite-0.23/cbits/ed25519/ed25519-donna-64bit-x86-32bit.h0000644000000000000000000003763112540765477020717 0ustar0000000000000000#if defined(ED25519_GCC_64BIT_32BIT_CHOOSE) #define HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS DONNA_NOINLINE static void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { int64_t breg = (int64_t)b; uint64_t sign = (uint64_t)breg >> 63; uint64_t mask = ~(sign - 1); uint64_t u = (breg + mask) ^ mask; __asm__ __volatile__ ( /* ysubx+xaddy+t2d */ "movq %0, %%rax ;\n" "movd %%rax, %%xmm14 ;\n" "pshufd $0x00, %%xmm14, %%xmm14 ;\n" "pxor %%xmm0, %%xmm0 ;\n" "pxor %%xmm1, %%xmm1 ;\n" "pxor %%xmm2, %%xmm2 ;\n" "pxor %%xmm3, %%xmm3 ;\n" "pxor %%xmm4, %%xmm4 ;\n" "pxor %%xmm5, %%xmm5 ;\n" /* 0 */ "movq $0, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movq $1, %%rax ;\n" "movd %%rax, %%xmm6 ;\n" "pxor %%xmm7, %%xmm7 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm6, %%xmm2 ;\n" "por %%xmm7, %%xmm3 ;\n" /* 1 */ "movq $1, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 0(%1), %%xmm6 ;\n" "movdqa 16(%1), %%xmm7 ;\n" "movdqa 32(%1), %%xmm8 ;\n" "movdqa 48(%1), %%xmm9 ;\n" "movdqa 64(%1), %%xmm10 ;\n" "movdqa 80(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 2 */ "movq $2, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 96(%1), %%xmm6 ;\n" "movdqa 112(%1), %%xmm7 ;\n" "movdqa 128(%1), %%xmm8 ;\n" "movdqa 144(%1), %%xmm9 ;\n" "movdqa 160(%1), %%xmm10 ;\n" "movdqa 176(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 3 */ "movq $3, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 192(%1), %%xmm6 ;\n" "movdqa 208(%1), %%xmm7 ;\n" "movdqa 224(%1), %%xmm8 ;\n" "movdqa 240(%1), %%xmm9 ;\n" "movdqa 256(%1), %%xmm10 ;\n" "movdqa 272(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 4 */ "movq $4, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 288(%1), %%xmm6 ;\n" "movdqa 304(%1), %%xmm7 ;\n" "movdqa 320(%1), %%xmm8 ;\n" "movdqa 336(%1), %%xmm9 ;\n" "movdqa 352(%1), %%xmm10 ;\n" "movdqa 368(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 5 */ "movq $5, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 384(%1), %%xmm6 ;\n" "movdqa 400(%1), %%xmm7 ;\n" "movdqa 416(%1), %%xmm8 ;\n" "movdqa 432(%1), %%xmm9 ;\n" "movdqa 448(%1), %%xmm10 ;\n" "movdqa 464(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 6 */ "movq $6, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 480(%1), %%xmm6 ;\n" "movdqa 496(%1), %%xmm7 ;\n" "movdqa 512(%1), %%xmm8 ;\n" "movdqa 528(%1), %%xmm9 ;\n" "movdqa 544(%1), %%xmm10 ;\n" "movdqa 560(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 7 */ "movq $7, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 576(%1), %%xmm6 ;\n" "movdqa 592(%1), %%xmm7 ;\n" "movdqa 608(%1), %%xmm8 ;\n" "movdqa 624(%1), %%xmm9 ;\n" "movdqa 640(%1), %%xmm10 ;\n" "movdqa 656(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 8 */ "movq $8, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 672(%1), %%xmm6 ;\n" "movdqa 688(%1), %%xmm7 ;\n" "movdqa 704(%1), %%xmm8 ;\n" "movdqa 720(%1), %%xmm9 ;\n" "movdqa 736(%1), %%xmm10 ;\n" "movdqa 752(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* conditionally swap ysubx and xaddy */ "movq %3, %%rax ;\n" "xorq $1, %%rax ;\n" "movd %%rax, %%xmm14 ;\n" "pxor %%xmm15, %%xmm15 ;\n" "pshufd $0x00, %%xmm14, %%xmm14 ;\n" "pxor %%xmm0, %%xmm2 ;\n" "pxor %%xmm1, %%xmm3 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa %%xmm2, %%xmm6 ;\n" "movdqa %%xmm3, %%xmm7 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pxor %%xmm6, %%xmm0 ;\n" "pxor %%xmm7, %%xmm1 ;\n" "pxor %%xmm0, %%xmm2 ;\n" "pxor %%xmm1, %%xmm3 ;\n" /* store ysubx */ "xorq %%rax, %%rax ;\n" "movd %%xmm0, %%rcx ;\n" "movd %%xmm0, %%r8 ;\n" "movd %%xmm1, %%rsi ;\n" "pshufd $0xee, %%xmm0, %%xmm0 ;\n" "pshufd $0xee, %%xmm1, %%xmm1 ;\n" "movd %%xmm0, %%rdx ;\n" "movd %%xmm1, %%rdi ;\n" "shrdq $51, %%rdx, %%r8 ;\n" "shrdq $38, %%rsi, %%rdx ;\n" "shrdq $25, %%rdi, %%rsi ;\n" "shrq $12, %%rdi ;\n" "movq %%rcx, %%r9 ;\n" "movq %%r8, %%r10 ;\n" "movq %%rdx, %%r11 ;\n" "movq %%rsi, %%r12 ;\n" "movq %%rdi, %%r13 ;\n" "shrq $26, %%r9 ;\n" "shrq $26, %%r10 ;\n" "shrq $26, %%r11 ;\n" "shrq $26, %%r12 ;\n" "shrq $26, %%r13 ;\n" "andl $0x3ffffff, %%ecx ;\n" "andl $0x1ffffff, %%r9d ;\n" "andl $0x3ffffff, %%r8d ;\n" "andl $0x1ffffff, %%r10d ;\n" "andl $0x3ffffff, %%edx ;\n" "andl $0x1ffffff, %%r11d ;\n" "andl $0x3ffffff, %%esi ;\n" "andl $0x1ffffff, %%r12d ;\n" "andl $0x3ffffff, %%edi ;\n" "andl $0x1ffffff, %%r13d ;\n" "movl %%ecx, 0(%2) ;\n" "movl %%r9d, 4(%2) ;\n" "movl %%r8d, 8(%2) ;\n" "movl %%r10d, 12(%2) ;\n" "movl %%edx, 16(%2) ;\n" "movl %%r11d, 20(%2) ;\n" "movl %%esi, 24(%2) ;\n" "movl %%r12d, 28(%2) ;\n" "movl %%edi, 32(%2) ;\n" "movl %%r13d, 36(%2) ;\n" /* store xaddy */ "movd %%xmm2, %%rcx ;\n" "movd %%xmm2, %%r8 ;\n" "movd %%xmm3, %%rsi ;\n" "pshufd $0xee, %%xmm2, %%xmm2 ;\n" "pshufd $0xee, %%xmm3, %%xmm3 ;\n" "movd %%xmm2, %%rdx ;\n" "movd %%xmm3, %%rdi ;\n" "shrdq $51, %%rdx, %%r8 ;\n" "shrdq $38, %%rsi, %%rdx ;\n" "shrdq $25, %%rdi, %%rsi ;\n" "shrq $12, %%rdi ;\n" "movq %%rcx, %%r9 ;\n" "movq %%r8, %%r10 ;\n" "movq %%rdx, %%r11 ;\n" "movq %%rsi, %%r12 ;\n" "movq %%rdi, %%r13 ;\n" "shrq $26, %%r9 ;\n" "shrq $26, %%r10 ;\n" "shrq $26, %%r11 ;\n" "shrq $26, %%r12 ;\n" "shrq $26, %%r13 ;\n" "andl $0x3ffffff, %%ecx ;\n" "andl $0x1ffffff, %%r9d ;\n" "andl $0x3ffffff, %%r8d ;\n" "andl $0x1ffffff, %%r10d ;\n" "andl $0x3ffffff, %%edx ;\n" "andl $0x1ffffff, %%r11d ;\n" "andl $0x3ffffff, %%esi ;\n" "andl $0x1ffffff, %%r12d ;\n" "andl $0x3ffffff, %%edi ;\n" "andl $0x1ffffff, %%r13d ;\n" "movl %%ecx, 40(%2) ;\n" "movl %%r9d, 44(%2) ;\n" "movl %%r8d, 48(%2) ;\n" "movl %%r10d, 52(%2) ;\n" "movl %%edx, 56(%2) ;\n" "movl %%r11d, 60(%2) ;\n" "movl %%esi, 64(%2) ;\n" "movl %%r12d, 68(%2) ;\n" "movl %%edi, 72(%2) ;\n" "movl %%r13d, 76(%2) ;\n" /* extract t2d */ "xorq %%rax, %%rax ;\n" "movd %%xmm4, %%rcx ;\n" "movd %%xmm4, %%r8 ;\n" "movd %%xmm5, %%rsi ;\n" "pshufd $0xee, %%xmm4, %%xmm4 ;\n" "pshufd $0xee, %%xmm5, %%xmm5 ;\n" "movd %%xmm4, %%rdx ;\n" "movd %%xmm5, %%rdi ;\n" "shrdq $51, %%rdx, %%r8 ;\n" "shrdq $38, %%rsi, %%rdx ;\n" "shrdq $25, %%rdi, %%rsi ;\n" "shrq $12, %%rdi ;\n" "movq %%rcx, %%r9 ;\n" "movq %%r8, %%r10 ;\n" "movq %%rdx, %%r11 ;\n" "movq %%rsi, %%r12 ;\n" "movq %%rdi, %%r13 ;\n" "shrq $26, %%r9 ;\n" "shrq $26, %%r10 ;\n" "shrq $26, %%r11 ;\n" "shrq $26, %%r12 ;\n" "shrq $26, %%r13 ;\n" "andl $0x3ffffff, %%ecx ;\n" "andl $0x1ffffff, %%r9d ;\n" "andl $0x3ffffff, %%r8d ;\n" "andl $0x1ffffff, %%r10d ;\n" "andl $0x3ffffff, %%edx ;\n" "andl $0x1ffffff, %%r11d ;\n" "andl $0x3ffffff, %%esi ;\n" "andl $0x1ffffff, %%r12d ;\n" "andl $0x3ffffff, %%edi ;\n" "andl $0x1ffffff, %%r13d ;\n" "movd %%ecx, %%xmm0 ;\n" "movd %%r9d, %%xmm4 ;\n" "movd %%r8d, %%xmm8 ;\n" "movd %%r10d, %%xmm3 ;\n" "movd %%edx, %%xmm1 ;\n" "movd %%r11d, %%xmm5 ;\n" "movd %%esi, %%xmm6 ;\n" "movd %%r12d, %%xmm7 ;\n" "movd %%edi, %%xmm2 ;\n" "movd %%r13d, %%xmm9 ;\n" "punpckldq %%xmm4, %%xmm0 ;\n" "punpckldq %%xmm3, %%xmm8 ;\n" "punpckldq %%xmm5, %%xmm1 ;\n" "punpckldq %%xmm7, %%xmm6 ;\n" "punpckldq %%xmm9, %%xmm2 ;\n" "punpcklqdq %%xmm8, %%xmm0 ;\n" "punpcklqdq %%xmm6, %%xmm1 ;\n" /* set up 2p in to 3/4 */ "movl $0x7ffffda, %%ecx ;\n" "movl $0x3fffffe, %%edx ;\n" "movl $0x7fffffe, %%eax ;\n" "movd %%ecx, %%xmm3 ;\n" "movd %%edx, %%xmm5 ;\n" "movd %%eax, %%xmm4 ;\n" "punpckldq %%xmm5, %%xmm3 ;\n" "punpckldq %%xmm5, %%xmm4 ;\n" "punpcklqdq %%xmm4, %%xmm3 ;\n" "movdqa %%xmm4, %%xmm5 ;\n" "punpcklqdq %%xmm4, %%xmm4 ;\n" /* subtract and conditionally move */ "movl %3, %%ecx ;\n" "sub $1, %%ecx ;\n" "movd %%ecx, %%xmm6 ;\n" "pshufd $0x00, %%xmm6, %%xmm6 ;\n" "movdqa %%xmm6, %%xmm7 ;\n" "psubd %%xmm0, %%xmm3 ;\n" "psubd %%xmm1, %%xmm4 ;\n" "psubd %%xmm2, %%xmm5 ;\n" "pand %%xmm6, %%xmm0 ;\n" "pand %%xmm6, %%xmm1 ;\n" "pand %%xmm6, %%xmm2 ;\n" "pandn %%xmm3, %%xmm6 ;\n" "movdqa %%xmm7, %%xmm3 ;\n" "pandn %%xmm4, %%xmm7 ;\n" "pandn %%xmm5, %%xmm3 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm3, %%xmm2 ;\n" /* store t2d */ "movdqa %%xmm0, 80(%2) ;\n" "movdqa %%xmm1, 96(%2) ;\n" "movd %%xmm2, %%rax ;\n" "movq %%rax, 112(%2) ;\n" : : "m"(u), "r"(&table[pos * 8]), "r"(t), "m"(sign) /* %0 = u, %1 = table, %2 = t, %3 = sign */ : "%rax", "%rcx", "%rdx", "%rdi", "%rsi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm14", "%xmm14", "cc", "memory" ); } #endif /* defined(ED25519_GCC_64BIT_32BIT_CHOOSE) */ cryptonite-0.23/cbits/ed25519/ed25519-donna-64bit-x86.h0000644000000000000000000003124212514663134017752 0ustar0000000000000000#if defined(ED25519_GCC_64BIT_X86_CHOOSE) #define HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS DONNA_NOINLINE static void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { int64_t breg = (int64_t)b; uint64_t sign = (uint64_t)breg >> 63; uint64_t mask = ~(sign - 1); uint64_t u = (breg + mask) ^ mask; __asm__ __volatile__ ( /* ysubx+xaddy+t2d */ "movq %0, %%rax ;\n" "movd %%rax, %%xmm14 ;\n" "pshufd $0x00, %%xmm14, %%xmm14 ;\n" "pxor %%xmm0, %%xmm0 ;\n" "pxor %%xmm1, %%xmm1 ;\n" "pxor %%xmm2, %%xmm2 ;\n" "pxor %%xmm3, %%xmm3 ;\n" "pxor %%xmm4, %%xmm4 ;\n" "pxor %%xmm5, %%xmm5 ;\n" /* 0 */ "movq $0, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movq $1, %%rax ;\n" "movd %%rax, %%xmm6 ;\n" "pxor %%xmm7, %%xmm7 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm6, %%xmm2 ;\n" "por %%xmm7, %%xmm3 ;\n" /* 1 */ "movq $1, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 0(%1), %%xmm6 ;\n" "movdqa 16(%1), %%xmm7 ;\n" "movdqa 32(%1), %%xmm8 ;\n" "movdqa 48(%1), %%xmm9 ;\n" "movdqa 64(%1), %%xmm10 ;\n" "movdqa 80(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 2 */ "movq $2, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 96(%1), %%xmm6 ;\n" "movdqa 112(%1), %%xmm7 ;\n" "movdqa 128(%1), %%xmm8 ;\n" "movdqa 144(%1), %%xmm9 ;\n" "movdqa 160(%1), %%xmm10 ;\n" "movdqa 176(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 3 */ "movq $3, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 192(%1), %%xmm6 ;\n" "movdqa 208(%1), %%xmm7 ;\n" "movdqa 224(%1), %%xmm8 ;\n" "movdqa 240(%1), %%xmm9 ;\n" "movdqa 256(%1), %%xmm10 ;\n" "movdqa 272(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 4 */ "movq $4, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 288(%1), %%xmm6 ;\n" "movdqa 304(%1), %%xmm7 ;\n" "movdqa 320(%1), %%xmm8 ;\n" "movdqa 336(%1), %%xmm9 ;\n" "movdqa 352(%1), %%xmm10 ;\n" "movdqa 368(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 5 */ "movq $5, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 384(%1), %%xmm6 ;\n" "movdqa 400(%1), %%xmm7 ;\n" "movdqa 416(%1), %%xmm8 ;\n" "movdqa 432(%1), %%xmm9 ;\n" "movdqa 448(%1), %%xmm10 ;\n" "movdqa 464(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 6 */ "movq $6, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 480(%1), %%xmm6 ;\n" "movdqa 496(%1), %%xmm7 ;\n" "movdqa 512(%1), %%xmm8 ;\n" "movdqa 528(%1), %%xmm9 ;\n" "movdqa 544(%1), %%xmm10 ;\n" "movdqa 560(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 7 */ "movq $7, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 576(%1), %%xmm6 ;\n" "movdqa 592(%1), %%xmm7 ;\n" "movdqa 608(%1), %%xmm8 ;\n" "movdqa 624(%1), %%xmm9 ;\n" "movdqa 640(%1), %%xmm10 ;\n" "movdqa 656(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* 8 */ "movq $8, %%rax ;\n" "movd %%rax, %%xmm15 ;\n" "pshufd $0x00, %%xmm15, %%xmm15 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa 672(%1), %%xmm6 ;\n" "movdqa 688(%1), %%xmm7 ;\n" "movdqa 704(%1), %%xmm8 ;\n" "movdqa 720(%1), %%xmm9 ;\n" "movdqa 736(%1), %%xmm10 ;\n" "movdqa 752(%1), %%xmm11 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pand %%xmm15, %%xmm8 ;\n" "pand %%xmm15, %%xmm9 ;\n" "pand %%xmm15, %%xmm10 ;\n" "pand %%xmm15, %%xmm11 ;\n" "por %%xmm6, %%xmm0 ;\n" "por %%xmm7, %%xmm1 ;\n" "por %%xmm8, %%xmm2 ;\n" "por %%xmm9, %%xmm3 ;\n" "por %%xmm10, %%xmm4 ;\n" "por %%xmm11, %%xmm5 ;\n" /* conditionally swap ysubx and xaddy */ "movq %3, %%rax ;\n" "xorq $1, %%rax ;\n" "movd %%rax, %%xmm14 ;\n" "pxor %%xmm15, %%xmm15 ;\n" "pshufd $0x00, %%xmm14, %%xmm14 ;\n" "pxor %%xmm0, %%xmm2 ;\n" "pxor %%xmm1, %%xmm3 ;\n" "pcmpeqd %%xmm14, %%xmm15 ;\n" "movdqa %%xmm2, %%xmm6 ;\n" "movdqa %%xmm3, %%xmm7 ;\n" "pand %%xmm15, %%xmm6 ;\n" "pand %%xmm15, %%xmm7 ;\n" "pxor %%xmm6, %%xmm0 ;\n" "pxor %%xmm7, %%xmm1 ;\n" "pxor %%xmm0, %%xmm2 ;\n" "pxor %%xmm1, %%xmm3 ;\n" /* store ysubx */ "movq $0x7ffffffffffff, %%rax ;\n" "movd %%xmm0, %%rcx ;\n" "movd %%xmm0, %%r8 ;\n" "movd %%xmm1, %%rsi ;\n" "pshufd $0xee, %%xmm0, %%xmm0 ;\n" "pshufd $0xee, %%xmm1, %%xmm1 ;\n" "movd %%xmm0, %%rdx ;\n" "movd %%xmm1, %%rdi ;\n" "shrdq $51, %%rdx, %%r8 ;\n" "shrdq $38, %%rsi, %%rdx ;\n" "shrdq $25, %%rdi, %%rsi ;\n" "shrq $12, %%rdi ;\n" "andq %%rax, %%rcx ;\n" "andq %%rax, %%r8 ;\n" "andq %%rax, %%rdx ;\n" "andq %%rax, %%rsi ;\n" "andq %%rax, %%rdi ;\n" "movq %%rcx, 0(%2) ;\n" "movq %%r8, 8(%2) ;\n" "movq %%rdx, 16(%2) ;\n" "movq %%rsi, 24(%2) ;\n" "movq %%rdi, 32(%2) ;\n" /* store xaddy */ "movq $0x7ffffffffffff, %%rax ;\n" "movd %%xmm2, %%rcx ;\n" "movd %%xmm2, %%r8 ;\n" "movd %%xmm3, %%rsi ;\n" "pshufd $0xee, %%xmm2, %%xmm2 ;\n" "pshufd $0xee, %%xmm3, %%xmm3 ;\n" "movd %%xmm2, %%rdx ;\n" "movd %%xmm3, %%rdi ;\n" "shrdq $51, %%rdx, %%r8 ;\n" "shrdq $38, %%rsi, %%rdx ;\n" "shrdq $25, %%rdi, %%rsi ;\n" "shrq $12, %%rdi ;\n" "andq %%rax, %%rcx ;\n" "andq %%rax, %%r8 ;\n" "andq %%rax, %%rdx ;\n" "andq %%rax, %%rsi ;\n" "andq %%rax, %%rdi ;\n" "movq %%rcx, 40(%2) ;\n" "movq %%r8, 48(%2) ;\n" "movq %%rdx, 56(%2) ;\n" "movq %%rsi, 64(%2) ;\n" "movq %%rdi, 72(%2) ;\n" /* extract t2d */ "movq $0x7ffffffffffff, %%rax ;\n" "movd %%xmm4, %%rcx ;\n" "movd %%xmm4, %%r8 ;\n" "movd %%xmm5, %%rsi ;\n" "pshufd $0xee, %%xmm4, %%xmm4 ;\n" "pshufd $0xee, %%xmm5, %%xmm5 ;\n" "movd %%xmm4, %%rdx ;\n" "movd %%xmm5, %%rdi ;\n" "shrdq $51, %%rdx, %%r8 ;\n" "shrdq $38, %%rsi, %%rdx ;\n" "shrdq $25, %%rdi, %%rsi ;\n" "shrq $12, %%rdi ;\n" "andq %%rax, %%rcx ;\n" "andq %%rax, %%r8 ;\n" "andq %%rax, %%rdx ;\n" "andq %%rax, %%rsi ;\n" "andq %%rax, %%rdi ;\n" /* conditionally negate t2d */ "movq %3, %%rax ;\n" "movq $0xfffffffffffda, %%r9 ;\n" "movq $0xffffffffffffe, %%r10 ;\n" "movq %%r10, %%r11 ;\n" "movq %%r10, %%r12 ;\n" "movq %%r10, %%r13 ;\n" "subq %%rcx, %%r9 ;\n" "subq %%r8, %%r10 ;\n" "subq %%rdx, %%r11 ;\n" "subq %%rsi, %%r12 ;\n" "subq %%rdi, %%r13 ;\n" "cmpq $1, %%rax ;\n" "cmove %%r9, %%rcx ;\n" "cmove %%r10, %%r8 ;\n" "cmove %%r11, %%rdx ;\n" "cmove %%r12, %%rsi ;\n" "cmove %%r13, %%rdi ;\n" /* store t2d */ "movq %%rcx, 80(%2) ;\n" "movq %%r8, 88(%2) ;\n" "movq %%rdx, 96(%2) ;\n" "movq %%rsi, 104(%2) ;\n" "movq %%rdi, 112(%2) ;\n" : : "m"(u), "r"(&table[pos * 8]), "r"(t), "m"(sign) /* %0 = u, %1 = table, %2 = t, %3 = sign */ : "%rax", "%rcx", "%rdx", "%rdi", "%rsi", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm14", "%xmm14", "cc", "memory" ); } #endif /* defined(ED25519_GCC_64BIT_X86_CHOOSE) */ cryptonite-0.23/cbits/ed25519/ed25519-donna-basepoint-table.h0000644000000000000000000036222012514663134021453 0ustar0000000000000000/* multiples of the base point in packed {ysubx, xaddy, t2d} form */ static const uint8_t ALIGN(16) ge25519_niels_base_multiples[256][96] = { {0x3e,0x91,0x40,0xd7,0x05,0x39,0x10,0x9d,0xb3,0xbe,0x40,0xd1,0x05,0x9f,0x39,0xfd,0x09,0x8a,0x8f,0x68,0x34,0x84,0xc1,0xa5,0x67,0x12,0xf8,0x98,0x92,0x2f,0xfd,0x44,0x85,0x3b,0x8c,0xf5,0xc6,0x93,0xbc,0x2f,0x19,0x0e,0x8c,0xfb,0xc6,0x2d,0x93,0xcf,0xc2,0x42,0x3d,0x64,0x98,0x48,0x0b,0x27,0x65,0xba,0xd4,0x33,0x3a,0x9d,0xcf,0x07,0x59,0xbb,0x6f,0x4b,0x67,0x15,0xbd,0xdb,0xea,0xa5,0xa2,0xee,0x00,0x3f,0xe1,0x41,0xfa,0xc6,0x57,0xc9,0x1c,0x9d,0xd4,0xcd,0xca,0xec,0x16,0xaf,0x1f,0xbe,0x0e,0x4f}, {0xa8,0xd5,0xb4,0x42,0x60,0xa5,0x99,0x8a,0xf6,0xac,0x60,0x4e,0x0c,0x81,0x2b,0x8f,0xaa,0x37,0x6e,0xb1,0x6b,0x23,0x9e,0xe0,0x55,0x25,0xc9,0x69,0xa6,0x95,0xb5,0x6b,0xd7,0x71,0x3c,0x93,0xfc,0xe7,0x24,0x92,0xb5,0xf5,0x0f,0x7a,0x96,0x9d,0x46,0x9f,0x02,0x07,0xd6,0xe1,0x65,0x9a,0xa6,0x5a,0x2e,0x2e,0x7d,0xa8,0x3f,0x06,0x0c,0x59,0x02,0x68,0xd3,0xda,0xaa,0x7e,0x34,0x6e,0x05,0x48,0xee,0x83,0x93,0x59,0xf3,0xba,0x26,0x68,0x07,0xe6,0x10,0xbe,0xca,0x3b,0xb8,0xd1,0x5e,0x16,0x0a,0x4f,0x31,0x49}, {0x65,0xd2,0xfc,0xa4,0xe8,0x1f,0x61,0x56,0x7d,0xba,0xc1,0xe5,0xfd,0x53,0xd3,0x3b,0xbd,0xd6,0x4b,0x21,0x1a,0xf3,0x31,0x81,0x62,0xda,0x5b,0x55,0x87,0x15,0xb9,0x2a,0x30,0x97,0xee,0x4c,0xa8,0xb0,0x25,0xaf,0x8a,0x4b,0x86,0xe8,0x30,0x84,0x5a,0x02,0x32,0x67,0x01,0x9f,0x02,0x50,0x1b,0xc1,0xf4,0xf8,0x80,0x9a,0x1b,0x4e,0x16,0x7a,0x34,0x48,0x67,0xf1,0xf4,0x11,0xf2,0x9b,0x95,0xf8,0x2d,0xf6,0x17,0x6b,0x4e,0xb8,0x4e,0x2a,0x72,0x5b,0x07,0x6f,0xde,0xd7,0x21,0x2a,0xbb,0x63,0xb9,0x04,0x9a,0x54}, {0xbf,0x18,0x68,0x05,0x0a,0x05,0xfe,0x95,0xa9,0xfa,0x60,0x56,0x71,0x89,0x7e,0x32,0x73,0x50,0xa0,0x06,0xcd,0xe3,0xe8,0xc3,0x9a,0xa4,0x45,0x74,0x4c,0x3f,0x93,0x27,0x9f,0x09,0xfc,0x8e,0xb9,0x51,0x73,0x28,0x38,0x25,0xfd,0x7d,0xf4,0xc6,0x65,0x67,0x65,0x92,0x0a,0xfb,0x3d,0x8d,0x34,0xca,0x27,0x87,0xe5,0x21,0x03,0x91,0x0e,0x68,0xb0,0x26,0x14,0xe5,0xec,0x45,0x1e,0xbf,0x94,0x0f,0xba,0x6d,0x3d,0xc6,0x2b,0xe3,0xc0,0x52,0xf8,0x8c,0xd5,0x74,0x29,0xe4,0x18,0x4c,0xe6,0xb0,0xb1,0x79,0xf0,0x44}, {0xba,0xd6,0x47,0xa4,0xc3,0x82,0x91,0x7f,0xb7,0x29,0x27,0x4b,0xd1,0x14,0x00,0xd5,0x87,0xa0,0x64,0xb8,0x1c,0xf1,0x3c,0xe3,0xf3,0x55,0x1b,0xeb,0x73,0x7e,0x4a,0x15,0x33,0xbb,0xa5,0x08,0x44,0xbc,0x12,0xa2,0x02,0xed,0x5e,0xc7,0xc3,0x48,0x50,0x8d,0x44,0xec,0xbf,0x5a,0x0c,0xeb,0x1b,0xdd,0xeb,0x06,0xe2,0x46,0xf1,0xcc,0x45,0x29,0xb3,0x03,0xd0,0xe7,0x79,0xa1,0x32,0xc8,0x7e,0x4d,0x12,0x00,0x0a,0x9d,0x72,0x5f,0xf3,0x8f,0x6d,0x0e,0xa1,0xd4,0xc1,0x62,0x98,0x7a,0xb2,0x38,0x59,0xac,0xb8,0x68}, {0xa4,0x8c,0x7d,0x7b,0xb6,0x06,0x98,0x49,0x39,0x27,0xd2,0x27,0x84,0xe2,0x5b,0x57,0xb9,0x53,0x45,0x20,0xe7,0x5c,0x08,0xbb,0x84,0x78,0x41,0xae,0x41,0x4c,0xb6,0x38,0x31,0x71,0x15,0x77,0xeb,0xee,0x0c,0x3a,0x88,0xaf,0xc8,0x00,0x89,0x15,0x27,0x9b,0x36,0xa7,0x59,0xda,0x68,0xb6,0x65,0x80,0xbd,0x38,0xcc,0xa2,0xb6,0x7b,0xe5,0x51,0xa4,0xe3,0x9d,0x68,0x91,0xad,0x9d,0x8f,0x37,0x91,0xfb,0xf8,0x28,0x24,0x5f,0x17,0x88,0xb9,0xcf,0x9f,0x32,0xb5,0x0a,0x05,0x9f,0xc0,0x54,0x13,0xa2,0xdf,0x65,0x78}, {0xb1,0x21,0x32,0xaa,0x9a,0x2c,0x6f,0xba,0xa7,0x23,0xba,0x3b,0x53,0x21,0xa0,0x6c,0x3a,0x2c,0x19,0x92,0x4f,0x76,0xea,0x9d,0xe0,0x17,0x53,0x2e,0x5d,0xdd,0x6e,0x1d,0xbf,0xa3,0x4e,0x94,0xd0,0x5c,0x1a,0x6b,0xd2,0xc0,0x9d,0xb3,0x3a,0x35,0x70,0x74,0x49,0x2e,0x54,0x28,0x82,0x52,0xb2,0x71,0x7e,0x92,0x3c,0x28,0x69,0xea,0x1b,0x46,0x36,0xda,0x0f,0xab,0xac,0x8a,0x7a,0x21,0xc8,0x49,0x35,0x3d,0x54,0xc6,0x28,0xa5,0x68,0x75,0xab,0x13,0x8b,0x5b,0xd0,0x37,0x37,0xbc,0x2c,0x3a,0x62,0xef,0x3c,0x23}, {0xd9,0x34,0x92,0xf3,0xed,0x5d,0xa7,0xe2,0xf9,0x58,0xb5,0xe1,0x80,0x76,0x3d,0x96,0xfb,0x23,0x3c,0x6e,0xac,0x41,0x27,0x2c,0xc3,0x01,0x0e,0x32,0xa1,0x24,0x90,0x3a,0x8f,0x3e,0xdd,0x04,0x66,0x59,0xb7,0x59,0x2c,0x70,0x88,0xe2,0x77,0x03,0xb3,0x6c,0x23,0xc3,0xd9,0x5e,0x66,0x9c,0x33,0xb1,0x2f,0xe5,0xbc,0x61,0x60,0xe7,0x15,0x09,0x7e,0xa3,0x34,0xa8,0x35,0xe8,0x7d,0xdf,0xea,0x57,0x98,0x68,0xda,0x9c,0xe1,0x8b,0x26,0xb3,0x67,0x71,0x36,0x85,0x11,0x2c,0xc2,0xd5,0xef,0xdb,0xd9,0xb3,0x9e,0x58}, {0x5e,0x51,0xaa,0x49,0x54,0x63,0x5b,0xed,0x3a,0x82,0xc6,0x0b,0x9f,0xc4,0x65,0xa8,0xc4,0xd1,0x42,0x5b,0xe9,0x1f,0x0c,0x85,0xb9,0x15,0xd3,0x03,0x6f,0x6d,0xd7,0x30,0x1d,0x9c,0x2f,0x63,0x0e,0xdd,0xcc,0x2e,0x15,0x31,0x89,0x76,0x96,0xb6,0xd0,0x51,0x58,0x7a,0x63,0xa8,0x6b,0xb7,0xdf,0x52,0x39,0xef,0x0e,0xa0,0x49,0x7d,0xd3,0x6d,0xc7,0xe4,0x06,0x21,0x17,0x44,0x44,0x6c,0x69,0x7f,0x8d,0x92,0x80,0xd6,0x53,0xfb,0x26,0x3f,0x4d,0x69,0xa4,0x9e,0x73,0xb4,0xb0,0x4b,0x86,0x2e,0x11,0x97,0xc6,0x10}, {0xde,0x5f,0xbe,0x7d,0x27,0xc4,0x93,0x64,0xa2,0x7e,0xad,0x19,0xad,0x4f,0x5d,0x26,0x90,0x45,0x30,0x46,0xc8,0xdf,0x00,0x0e,0x09,0xfe,0x66,0xed,0xab,0x1c,0xe6,0x25,0x05,0xc8,0x58,0x83,0xa0,0x2a,0xa6,0x0c,0x47,0x42,0x20,0x7a,0xe3,0x4a,0x3d,0x6a,0xdc,0xed,0x11,0x3b,0xa6,0xd3,0x64,0x74,0xef,0x06,0x08,0x55,0xaf,0x9b,0xbf,0x03,0x04,0x66,0x58,0xcc,0x28,0xe1,0x13,0x3f,0x7e,0x74,0x59,0xb4,0xec,0x73,0x58,0x6f,0xf5,0x68,0x12,0xcc,0xed,0x3d,0xb6,0xa0,0x2c,0xe2,0x86,0x45,0x63,0x78,0x6d,0x56}, {0x34,0x08,0xc1,0x9c,0x9f,0xa4,0x37,0x16,0x51,0xc4,0x9b,0xa8,0xd5,0x56,0x8e,0xbc,0xdb,0xd2,0x7f,0x7f,0x0f,0xec,0xb5,0x1c,0xd9,0x35,0xcc,0x5e,0xca,0x5b,0x97,0x33,0xd0,0x2f,0x5a,0xc6,0x85,0x42,0x05,0xa1,0xc3,0x67,0x16,0xf3,0x2a,0x11,0x64,0x6c,0x58,0xee,0x1a,0x73,0x40,0xe2,0x0a,0x68,0x2a,0xb2,0x93,0x47,0xf3,0xa5,0xfb,0x14,0xd4,0xf7,0x85,0x69,0x16,0x46,0xd7,0x3c,0x57,0x00,0xc8,0xc9,0x84,0x5e,0x3e,0x59,0x1e,0x13,0x61,0x7b,0xb6,0xf2,0xc3,0x2f,0x6c,0x52,0xfc,0x83,0xea,0x9c,0x82,0x14}, {0xc2,0x95,0xdd,0x97,0x84,0x7b,0x43,0xff,0xa7,0xb5,0x4e,0xaa,0x30,0x4e,0x74,0x6c,0x8b,0xe8,0x85,0x3c,0x61,0x5d,0x0c,0x9e,0x73,0x81,0x75,0x5f,0x1e,0xc7,0xd9,0x2f,0xb8,0xec,0x71,0x4e,0x2f,0x0b,0xe7,0x21,0xe3,0x77,0xa4,0x40,0xb9,0xdd,0x56,0xe6,0x80,0x4f,0x1d,0xce,0xce,0x56,0x65,0xbf,0x7e,0x7b,0x5d,0x53,0xc4,0x3b,0xfc,0x05,0xdd,0xde,0xaf,0x52,0xae,0xb3,0xb8,0x24,0xcf,0x30,0x3b,0xed,0x8c,0x63,0x95,0x34,0x95,0x81,0xbe,0xa9,0x83,0xbc,0xa4,0x33,0x04,0x1f,0x65,0x5c,0x47,0x67,0x37,0x37}, {0xd9,0xad,0xd1,0x40,0xfd,0x99,0xba,0x2f,0x27,0xd0,0xf4,0x96,0x6f,0x16,0x07,0xb3,0xae,0x3b,0xf0,0x15,0x52,0xf0,0x63,0x43,0x99,0xf9,0x18,0x3b,0x6c,0xa5,0xbe,0x1f,0x90,0x65,0x24,0x14,0xcb,0x95,0x40,0x63,0x35,0x55,0xc1,0x16,0x40,0x14,0x12,0xef,0x60,0xbc,0x10,0x89,0x0c,0x14,0x38,0x9e,0x8c,0x7c,0x90,0x30,0x57,0x90,0xf5,0x6b,0x8a,0x5b,0x41,0xe1,0xf1,0x78,0xa7,0x0f,0x7e,0xa7,0xc3,0xba,0xf7,0x9f,0x40,0x06,0x50,0x9a,0xa2,0x9a,0xb8,0xd7,0x52,0x6f,0x56,0x5a,0x63,0x7a,0xf6,0x1c,0x52,0x02}, {0x94,0x52,0x9d,0x0a,0x0b,0xee,0x3f,0x51,0x66,0x5a,0xdf,0x0f,0x5c,0xe7,0x98,0x8f,0xce,0x07,0xe1,0xbf,0x88,0x86,0x61,0xd4,0xed,0x2c,0x38,0x71,0x7e,0x0a,0xa0,0x3f,0xe4,0x5e,0x2f,0x77,0x20,0x67,0x14,0xb1,0xce,0x9a,0x07,0x96,0xb1,0x94,0xf8,0xe8,0x4a,0x82,0xac,0x00,0x4d,0x22,0xf8,0x4a,0xc4,0x6c,0xcd,0xf7,0xd9,0x53,0x17,0x00,0x34,0xdb,0x3d,0x96,0x2d,0x23,0x69,0x3c,0x58,0x38,0x97,0xb4,0xda,0x87,0xde,0x1d,0x85,0xf2,0x91,0xa0,0xf9,0xd1,0xd7,0xaa,0xb6,0xed,0x48,0xa0,0x2f,0xfe,0xb5,0x12}, {0x4d,0xe3,0xfc,0x96,0xc4,0xfb,0xf0,0x71,0xed,0x5b,0xf3,0xad,0x6b,0x82,0xb9,0x73,0x61,0xc5,0x28,0xff,0x61,0x72,0x04,0xd2,0x6f,0x20,0xb1,0x6f,0xf9,0x76,0x9b,0x74,0x92,0x1e,0x6f,0xad,0x26,0x7c,0x2b,0xdf,0x13,0x89,0x4b,0x50,0x23,0xd3,0x66,0x4b,0xc3,0x8b,0x1c,0x75,0xc0,0x9d,0x40,0x8c,0xb8,0xc7,0x96,0x07,0xc2,0x93,0x7e,0x6f,0x05,0xae,0xa6,0xae,0x04,0xf6,0x5a,0x1f,0x99,0x9c,0xe4,0xbe,0xf1,0x51,0x23,0xc1,0x66,0x6b,0xff,0xee,0xb5,0x08,0xa8,0x61,0x51,0x21,0xe0,0x01,0x0f,0xc1,0xce,0x0f}, {0x44,0x1e,0xfe,0x49,0xa6,0x58,0x4d,0x64,0x7e,0x77,0xad,0x31,0xa2,0xae,0xfc,0x21,0xd2,0xd0,0x7f,0x88,0x5a,0x1c,0x44,0x02,0xf3,0x11,0xc5,0x83,0x71,0xaa,0x01,0x49,0x45,0x4e,0x24,0xc4,0x9d,0xd2,0xf2,0x3d,0x0a,0xde,0xd8,0x93,0x74,0x0e,0x02,0x2b,0x4d,0x21,0x0c,0x82,0x7e,0x06,0xc8,0x6c,0x0a,0xb9,0xea,0x6f,0x16,0x79,0x37,0x41,0xf0,0xf8,0x1a,0x8c,0x54,0xb7,0xb1,0x08,0xb4,0x99,0x62,0x24,0x7c,0x7a,0x0f,0xce,0x39,0xd9,0x06,0x1e,0xf9,0xb0,0x60,0xf7,0x13,0x12,0x6d,0x72,0x7b,0x88,0xbb,0x41}, {0xbe,0x46,0x43,0x74,0x44,0x7d,0xe8,0x40,0x25,0x2b,0xb5,0x15,0xd4,0xda,0x48,0x1d,0x3e,0x60,0x3b,0xa1,0x18,0x8a,0x3a,0x7c,0xf7,0xbd,0xcd,0x2f,0xc1,0x28,0xb7,0x4e,0xae,0x91,0x66,0x7c,0x59,0x4c,0x23,0x7e,0xc8,0xb4,0x85,0x0a,0x3d,0x9d,0x88,0x64,0xe7,0xfa,0x4a,0x35,0x0c,0xc9,0xe2,0xda,0x1d,0x9e,0x6a,0x0c,0x07,0x1e,0x87,0x0a,0x89,0x89,0xbc,0x4b,0x99,0xb5,0x01,0x33,0x60,0x42,0xdd,0x5b,0x3a,0xae,0x6b,0x73,0x3c,0x9e,0xd5,0x19,0xe2,0xad,0x61,0x0d,0x64,0xd4,0x85,0x26,0x0f,0x30,0xe7,0x3e}, {0xb7,0xd6,0x7d,0x9e,0xe4,0x55,0xd2,0xf5,0xac,0x1e,0x0b,0x61,0x5c,0x11,0x16,0x80,0xca,0x87,0xe1,0x92,0x5d,0x97,0x99,0x3c,0xc2,0x25,0x91,0x97,0x62,0x57,0x81,0x13,0x18,0x75,0x1e,0x84,0x47,0x79,0xfa,0x43,0xd7,0x46,0x9c,0x63,0x59,0xfa,0xc6,0xe5,0x74,0x2b,0x05,0xe3,0x1d,0x5e,0x06,0xa1,0x30,0x90,0xb8,0xcf,0xa2,0xc6,0x47,0x7d,0xe0,0xd6,0xf0,0x8e,0x14,0xd0,0xda,0x3f,0x3c,0x6f,0x54,0x91,0x9a,0x74,0x3e,0x9d,0x57,0x81,0xbb,0x26,0x10,0x62,0xec,0x71,0x80,0xec,0xc9,0x34,0x8d,0xf5,0x8c,0x14}, {0x27,0xf0,0x34,0x79,0xf6,0x92,0xa4,0x46,0xa9,0x0a,0x84,0xf6,0xbe,0x84,0x99,0x46,0x54,0x18,0x61,0x89,0x2a,0xbc,0xa1,0x5c,0xd4,0xbb,0x5d,0xbd,0x1e,0xfa,0xf2,0x3f,0x6d,0x75,0xe4,0x9a,0x7d,0x2f,0x57,0xe2,0x7f,0x48,0xf3,0x88,0xbb,0x45,0xc3,0x56,0x8d,0xa8,0x60,0x69,0x6d,0x0b,0xd1,0x9f,0xb9,0xa1,0xae,0x4e,0xad,0xeb,0x8f,0x27,0x66,0x39,0x93,0x8c,0x1f,0x68,0xaa,0xb1,0x98,0x0c,0x29,0x20,0x9c,0x94,0x21,0x8c,0x52,0x3c,0x9d,0x21,0x91,0x52,0x11,0x39,0x7b,0x67,0x9c,0xfe,0x02,0xdd,0x04,0x41}, {0x2a,0x42,0x24,0x11,0x5e,0xbf,0xb2,0x72,0xb5,0x3a,0xa3,0x98,0x33,0x0c,0xfa,0xa1,0x66,0xb6,0x52,0xfa,0x01,0x61,0xcb,0x94,0xd5,0x53,0xaf,0xaf,0x00,0x3b,0x86,0x2c,0xb8,0x6a,0x09,0xdb,0x06,0x4e,0x21,0x81,0x35,0x4f,0xe4,0x0c,0xc9,0xb6,0xa8,0x21,0xf5,0x2a,0x9e,0x40,0x2a,0xc1,0x24,0x65,0x81,0xa4,0xfc,0x8e,0xa4,0xb5,0x65,0x01,0x76,0x6a,0x84,0xa0,0x74,0xa4,0x90,0xf1,0xc0,0x7c,0x2f,0xcd,0x84,0xf9,0xef,0x12,0x8f,0x2b,0xaa,0x58,0x06,0x29,0x5e,0x69,0xb8,0xc8,0xfe,0xbf,0xd9,0x67,0x1b,0x59}, {0xfa,0x9b,0xb4,0x80,0x1c,0x0d,0x2f,0x31,0x8a,0xec,0xf3,0xab,0x5e,0x51,0x79,0x59,0x88,0x1c,0xf0,0x9e,0xc0,0x33,0x70,0x72,0xcb,0x7b,0x8f,0xca,0xc7,0x2e,0xe0,0x3d,0x5d,0xb5,0x18,0x9f,0x71,0xb3,0xb9,0x99,0x1e,0x64,0x8c,0xa1,0xfa,0xe5,0x65,0xe4,0xed,0x05,0x9f,0xc2,0x36,0x11,0x08,0x61,0x8b,0x12,0x30,0x70,0x86,0x4f,0x9b,0x48,0xef,0x92,0xeb,0x3a,0x2d,0x10,0x32,0xd2,0x61,0xa8,0x16,0x61,0xb4,0x53,0x62,0xe1,0x24,0xaa,0x0b,0x19,0xe7,0xab,0x7e,0x3d,0xbf,0xbe,0x6c,0x49,0xba,0xfb,0xf5,0x49}, {0xd4,0xcf,0x5b,0x8a,0x10,0x9a,0x94,0x30,0xeb,0x73,0x64,0xbc,0x70,0xdd,0x40,0xdc,0x1c,0x0d,0x7c,0x30,0xc1,0x94,0xc2,0x92,0x74,0x6e,0xfa,0xcb,0x6d,0xa8,0x04,0x56,0x2e,0x57,0x9c,0x1e,0x8c,0x62,0x5d,0x15,0x41,0x47,0x88,0xc5,0xac,0x86,0x4d,0x8a,0xeb,0x63,0x57,0x51,0xf6,0x52,0xa3,0x91,0x5b,0x51,0x67,0x88,0xc2,0xa6,0xa1,0x06,0xb6,0x64,0x17,0x7c,0xd4,0xd1,0x88,0x72,0x51,0x8b,0x41,0xe0,0x40,0x11,0x54,0x72,0xd1,0xf6,0xac,0x18,0x60,0x1a,0x03,0x9f,0xc6,0x42,0x27,0xfe,0x89,0x9e,0x98,0x20}, {0x7f,0xcc,0x2d,0x3a,0xfd,0x77,0x97,0x49,0x92,0xd8,0x4f,0xa5,0x2c,0x7c,0x85,0x32,0xa0,0xe3,0x07,0xd2,0x64,0xd8,0x79,0xa2,0x29,0x7e,0xa6,0x0c,0x1d,0xed,0x03,0x04,0x2e,0xec,0xea,0x85,0x8b,0x27,0x74,0x16,0xdf,0x2b,0xcb,0x7a,0x07,0xdc,0x21,0x56,0x5a,0xf4,0xcb,0x61,0x16,0x4c,0x0a,0x64,0xd3,0x95,0x05,0xf7,0x50,0x99,0x0b,0x73,0x52,0xc5,0x4e,0x87,0x35,0x2d,0x4b,0xc9,0x8d,0x6f,0x24,0x98,0xcf,0xc8,0xe6,0xc5,0xce,0x35,0xc0,0x16,0xfa,0x46,0xcb,0xf7,0xcc,0x3d,0x30,0x08,0x43,0x45,0xd7,0x5b}, {0xc2,0x4c,0xb2,0x28,0x95,0xd1,0x9a,0x7f,0x81,0xc1,0x35,0x63,0x65,0x54,0x6b,0x7f,0x36,0x72,0xc0,0x4f,0x6e,0xb6,0xb8,0x66,0x83,0xad,0x80,0x73,0x00,0x78,0x3a,0x13,0x2a,0x79,0xe7,0x15,0x21,0x93,0xc4,0x85,0xc9,0xdd,0xcd,0xbd,0xa2,0x89,0x4c,0xc6,0x62,0xd7,0xa3,0xad,0xa8,0x3d,0x1e,0x9d,0x2c,0xf8,0x67,0x30,0x12,0xdb,0xb7,0x5b,0xbe,0x62,0xca,0xc6,0x67,0xf4,0x61,0x09,0xee,0x52,0x19,0x21,0xd6,0x21,0xec,0x04,0x70,0x47,0xd5,0x9b,0x77,0x60,0x23,0x18,0xd2,0xe0,0xf0,0x58,0x6d,0xca,0x0d,0x74}, {0x4e,0xce,0xcf,0x52,0x07,0xee,0x48,0xdf,0xb7,0x08,0xec,0x06,0xf3,0xfa,0xff,0xc3,0xc4,0x59,0x54,0xb9,0x2a,0x0b,0x71,0x05,0x8d,0xa3,0x3e,0x96,0xfa,0x25,0x1d,0x16,0x3c,0x43,0x78,0x04,0x57,0x8c,0x1a,0x23,0x9d,0x43,0x81,0xc2,0x0e,0x27,0xb5,0xb7,0x9f,0x07,0xd9,0xe3,0xea,0x99,0xaa,0xdb,0xd9,0x03,0x2b,0x6c,0x25,0xf5,0x03,0x2c,0x7d,0xa4,0x53,0x7b,0x75,0x18,0x0f,0x79,0x79,0x58,0x0c,0xcf,0x30,0x01,0x7b,0x30,0xf9,0xf7,0x7e,0x25,0x77,0x3d,0x90,0x31,0xaf,0xbb,0x96,0xbd,0xbd,0x68,0x94,0x69}, {0xcf,0xfe,0xda,0xf4,0x46,0x2f,0x1f,0xbd,0xf7,0xd6,0x7f,0xa4,0x14,0x01,0xef,0x7c,0x7f,0xb3,0x47,0x4a,0xda,0xfd,0x1f,0xd3,0x85,0x57,0x90,0x73,0xa4,0x19,0x52,0x52,0x48,0x19,0xa9,0x6a,0xe6,0x3d,0xdd,0xd8,0xcc,0xd2,0xc0,0x2f,0xc2,0x64,0x50,0x48,0x2f,0xea,0xfd,0x34,0x66,0x24,0x48,0x9b,0x3a,0x2e,0x4a,0x6c,0x4e,0x1c,0x3e,0x29,0xe1,0x12,0x51,0x92,0x4b,0x13,0x6e,0x37,0xa0,0x5d,0xa1,0xdc,0xb5,0x78,0x37,0x70,0x11,0x31,0x1c,0x46,0xaf,0x89,0x45,0xb0,0x23,0x28,0x03,0x7f,0x44,0x5c,0x60,0x5b}, {0x89,0x7c,0xc4,0x20,0x59,0x80,0x65,0xb9,0xcc,0x8f,0x3b,0x92,0x0c,0x10,0xf0,0xe7,0x77,0xef,0xe2,0x02,0x65,0x25,0x01,0x00,0xee,0xb3,0xae,0xa8,0xce,0x6d,0xa7,0x24,0x4c,0xf0,0xe7,0xf0,0xc6,0xfe,0xe9,0x3b,0x62,0x49,0xe3,0x75,0x9e,0x57,0x6a,0x86,0x1a,0xe6,0x1d,0x1e,0x16,0xef,0x42,0x55,0xd5,0xbd,0x5a,0xcc,0xf4,0xfe,0x12,0x2f,0x40,0xc7,0xc0,0xdf,0xb2,0x22,0x45,0x0a,0x07,0xa4,0xc9,0x40,0x7f,0x6e,0xd0,0x10,0x68,0xf6,0xcf,0x78,0x41,0x14,0xcf,0xc6,0x90,0x37,0xa4,0x18,0x25,0x7b,0x60,0x5e}, {0x18,0x18,0xdf,0x6c,0x8f,0x1d,0xb3,0x58,0xa2,0x58,0x62,0xc3,0x4f,0xa7,0xcf,0x35,0x6e,0x1d,0xe6,0x66,0x4f,0xff,0xb3,0xe1,0xf7,0xd5,0xcd,0x6c,0xab,0xac,0x67,0x50,0x14,0xcf,0x96,0xa5,0x1c,0x43,0x2c,0xa0,0x00,0xe4,0xd3,0xae,0x40,0x2d,0xc4,0xe3,0xdb,0x26,0x0f,0x2e,0x80,0x26,0x45,0xd2,0x68,0x70,0x45,0x9e,0x13,0x33,0x1f,0x20,0x51,0x9d,0x03,0x08,0x6b,0x7f,0x52,0xfd,0x06,0x00,0x7c,0x01,0x64,0x49,0xb1,0x18,0xa8,0xa4,0x25,0x2e,0xb0,0x0e,0x22,0xd5,0x75,0x03,0x46,0x62,0x88,0xba,0x7c,0x39}, {0xb2,0x59,0x59,0xf0,0x93,0x30,0xc1,0x30,0x76,0x79,0xa9,0xe9,0x8d,0xa1,0x3a,0xe2,0x26,0x5e,0x1d,0x72,0x91,0xd4,0x2f,0x22,0x3a,0x6c,0x6e,0x76,0x20,0xd3,0x39,0x23,0xe7,0x79,0x13,0xc8,0xfb,0xc3,0x15,0x78,0xf1,0x2a,0xe1,0xdd,0x20,0x94,0x61,0xa6,0xd5,0xfd,0xa8,0x85,0xf8,0xc0,0xa9,0xff,0x52,0xc2,0xe1,0xc1,0x22,0x40,0x1b,0x77,0xa7,0x2f,0x3a,0x51,0x86,0xd9,0x7d,0xd8,0x08,0xcf,0xd4,0xf9,0x71,0x9b,0xac,0xf5,0xb3,0x83,0xa2,0x1e,0x1b,0xc3,0x6b,0xd0,0x76,0x1a,0x97,0x19,0x92,0x18,0x1a,0x33}, {0xc6,0x80,0x4f,0xfb,0x45,0x6f,0x16,0xf5,0xcf,0x75,0xc7,0x61,0xde,0xc7,0x36,0x9c,0x1c,0xd9,0x41,0x90,0x1b,0xe8,0xd4,0xe3,0x21,0xfe,0xbd,0x83,0x6b,0x7c,0x16,0x31,0xaf,0x72,0x75,0x9d,0x3a,0x2f,0x51,0x26,0x9e,0x4a,0x07,0x68,0x88,0xe2,0xcb,0x5b,0xc4,0xf7,0x80,0x11,0xc1,0xc1,0xed,0x84,0x7b,0xa6,0x49,0xf6,0x9f,0x61,0xc9,0x1a,0x68,0x10,0x4b,0x52,0x42,0x38,0x2b,0xf2,0x87,0xe9,0x9c,0xee,0x3b,0x34,0x68,0x50,0xc8,0x50,0x62,0x4a,0x84,0x71,0x9d,0xfc,0x11,0xb1,0x08,0x1f,0x34,0x36,0x24,0x61}, {0x8d,0x89,0x4e,0x87,0xdb,0x41,0x9d,0xd9,0x20,0xdc,0x07,0x6c,0xf1,0xa5,0xfe,0x09,0xbc,0x9b,0x0f,0xd0,0x67,0x2c,0x3d,0x79,0x40,0xff,0x5e,0x9e,0x30,0xe2,0xeb,0x46,0x38,0x26,0x2d,0x1a,0xe3,0x49,0x63,0x8b,0x35,0xfd,0xd3,0x9b,0x00,0xb7,0xdf,0x9d,0xa4,0x6b,0xa0,0xa3,0xb8,0xf1,0x8b,0x7f,0x45,0x04,0xd9,0x78,0x31,0xaa,0x22,0x15,0x38,0x49,0x61,0x69,0x53,0x2f,0x38,0x2c,0x10,0x6d,0x2d,0xb7,0x9a,0x40,0xfe,0xda,0x27,0xf2,0x46,0xb6,0x91,0x33,0xc8,0xe8,0x6c,0x30,0x24,0x05,0xf5,0x70,0xfe,0x45}, {0x8c,0x0b,0x0c,0x96,0xa6,0x75,0x48,0xda,0x20,0x2f,0x0e,0xef,0x76,0xd0,0x68,0x5b,0xd4,0x8f,0x0b,0x3d,0xcf,0x51,0xfb,0x07,0xd4,0x92,0xe3,0xa0,0x23,0x16,0x8d,0x42,0x91,0x14,0x95,0xc8,0x20,0x49,0xf2,0x62,0xa2,0x0c,0x63,0x3f,0xc8,0x07,0xf0,0x05,0xb8,0xd4,0xc9,0xf5,0xd2,0x45,0xbb,0x6f,0x45,0x22,0x7a,0xb5,0x6d,0x9f,0x61,0x16,0xfd,0x08,0xa3,0x01,0x44,0x4a,0x4f,0x08,0xac,0xca,0xa5,0x76,0xc3,0x19,0x22,0xa8,0x7d,0xbc,0xd1,0x43,0x46,0xde,0xb8,0xde,0xc6,0x38,0xbd,0x60,0x2d,0x59,0x81,0x1d}, {0x5f,0xac,0x0d,0xa6,0x56,0x87,0x36,0x61,0x57,0xdc,0xab,0xeb,0x6a,0x2f,0xe0,0x17,0x7d,0x0f,0xce,0x4c,0x2d,0x3f,0x19,0x7f,0xf0,0xdc,0xec,0x89,0x77,0x4a,0x23,0x20,0xe8,0xc5,0x85,0x7b,0x9f,0xb6,0x65,0x87,0xb2,0xba,0x68,0xd1,0x8b,0x67,0xf0,0x6f,0x9b,0x0f,0x33,0x1d,0x7c,0xe7,0x70,0x3a,0x7c,0x8e,0xaf,0xb0,0x51,0x6d,0x5f,0x3a,0x52,0xb2,0x78,0x71,0xb6,0x0d,0xd2,0x76,0x60,0xd1,0x1e,0xd5,0xf9,0x34,0x1c,0x07,0x70,0x11,0xe4,0xb3,0x20,0x4a,0x2a,0xf6,0x66,0xe3,0xff,0x3c,0x35,0x82,0xd6,0x7c}, {0xb6,0xfa,0x87,0xd8,0x5b,0xa4,0xe1,0x0b,0x6e,0x3b,0x40,0xba,0x32,0x6a,0x84,0x2a,0x00,0x60,0x6e,0xe9,0x12,0x10,0x92,0xd9,0x43,0x09,0xdc,0x3b,0x86,0xc8,0x38,0x28,0xf3,0xf4,0xac,0x68,0x60,0xcd,0x65,0xa6,0xd3,0xe3,0xd7,0x3c,0x18,0x2d,0xd9,0x42,0xd9,0x25,0x60,0x33,0x9d,0x38,0x59,0x57,0xff,0xd8,0x2c,0x2b,0x3b,0x25,0xf0,0x3e,0x30,0x50,0x46,0x4a,0xcf,0xb0,0x6b,0xd1,0xab,0x77,0xc5,0x15,0x41,0x6b,0x49,0xfa,0x9d,0x41,0xab,0xf4,0x8a,0xae,0xcf,0x82,0x12,0x28,0xa8,0x06,0xa6,0xb8,0xdc,0x21}, {0xc8,0x9f,0x9d,0x8c,0x46,0x04,0x60,0x5c,0xcb,0xa3,0x2a,0xd4,0x6e,0x09,0x40,0x25,0x9c,0x2f,0xee,0x12,0x4c,0x4d,0x5b,0x12,0xab,0x1d,0xa3,0x94,0x81,0xd0,0xc3,0x0b,0xba,0x31,0x77,0xbe,0xfa,0x00,0x8d,0x9a,0x89,0x18,0x9e,0x62,0x7e,0x60,0x03,0x82,0x7f,0xd9,0xf3,0x43,0x37,0x02,0xcc,0xb2,0x8b,0x67,0x6f,0x6c,0xbf,0x0d,0x84,0x5d,0x8b,0xe1,0x9f,0x30,0x0d,0x38,0x6e,0x70,0xc7,0x65,0xe1,0xb9,0xa6,0x2d,0xb0,0x6e,0xab,0x20,0xae,0x7d,0x99,0xba,0xbb,0x57,0xdd,0x96,0xc1,0x2a,0x23,0x76,0x42,0x3a}, {0xfa,0x84,0x70,0x8a,0x2c,0x43,0x42,0x4b,0x45,0xe5,0xb9,0xdf,0xe3,0x19,0x8a,0x89,0x5d,0xe4,0x58,0x9c,0x21,0x00,0x9f,0xbe,0xd1,0xeb,0x6d,0xa1,0xce,0x77,0xf1,0x1f,0xcb,0x7e,0x44,0xdb,0x72,0xc1,0xf8,0x3b,0xbd,0x2d,0x28,0xc6,0x1f,0xc4,0xcf,0x5f,0xfe,0x15,0xaa,0x75,0xc0,0xff,0xac,0x80,0xf9,0xa9,0xe1,0x24,0xe8,0xc9,0x70,0x07,0xfd,0xb5,0xb5,0x45,0x9a,0xd9,0x61,0xcf,0x24,0x79,0x3a,0x1b,0xe9,0x84,0x09,0x86,0x89,0x3e,0x3e,0x30,0x19,0x09,0x30,0xe7,0x1e,0x0b,0x50,0x41,0xfd,0x64,0xf2,0x39}, {0x9c,0xe2,0xe7,0xdb,0x17,0x34,0xad,0xa7,0x9c,0x13,0x9c,0x2b,0x6a,0x37,0x94,0xbd,0xa9,0x7b,0x59,0x93,0x8e,0x1b,0xe9,0xa0,0x40,0x98,0x88,0x68,0x34,0xd7,0x12,0x17,0xe1,0x7b,0x09,0xfe,0xab,0x4a,0x9b,0xd1,0x29,0x19,0xe0,0xdf,0xe1,0xfc,0x6d,0xa4,0xff,0xf1,0xa6,0x2c,0x94,0x08,0xc9,0xc3,0x4e,0xf1,0x35,0x2c,0x27,0x21,0xc6,0x65,0xdd,0x93,0x31,0xce,0xf8,0x89,0x2b,0xe7,0xbb,0xc0,0x25,0xa1,0x56,0x33,0x10,0x4d,0x83,0xfe,0x1c,0x2e,0x3d,0xa9,0x19,0x04,0x72,0xe2,0x9c,0xb1,0x0a,0x80,0xf9,0x22}, {0xcb,0xf8,0x9e,0x3e,0x8a,0x36,0x5a,0x60,0x15,0x47,0x50,0xa5,0x22,0xc0,0xe9,0xe3,0x8f,0x24,0x24,0x5f,0xb0,0x48,0x3d,0x55,0xe5,0x26,0x76,0x64,0xcd,0x16,0xf4,0x13,0xac,0xfd,0x6e,0x9a,0xdd,0x9f,0x02,0x42,0x41,0x49,0xa5,0x34,0xbe,0xce,0x12,0xb9,0x7b,0xf3,0xbd,0x87,0xb9,0x64,0x0f,0x64,0xb4,0xca,0x98,0x85,0xd3,0xa4,0x71,0x41,0x8c,0x4c,0xc9,0x99,0xaa,0x58,0x27,0xfa,0x07,0xb8,0x00,0xb0,0x6f,0x6f,0x00,0x23,0x92,0x53,0xda,0xad,0xdd,0x91,0xd2,0xfb,0xab,0xd1,0x4b,0x57,0xfa,0x14,0x82,0x50}, {0x4b,0xfe,0xd6,0x3e,0x15,0x69,0x02,0xc2,0xc4,0x77,0x1d,0x51,0x39,0x67,0x5a,0xa6,0x94,0xaf,0x14,0x2c,0x46,0x26,0xde,0xcb,0x4b,0xa7,0xab,0x6f,0xec,0x60,0xf9,0x22,0xd6,0x03,0xd0,0x53,0xbb,0x15,0x1a,0x46,0x65,0xc9,0xf3,0xbc,0x88,0x28,0x10,0xb2,0x5a,0x3a,0x68,0x6c,0x75,0x76,0xc5,0x27,0x47,0xb4,0x6c,0xc8,0xa4,0x58,0x77,0x3a,0x76,0x50,0xae,0x93,0xf6,0x11,0x81,0x54,0xa6,0x54,0xfd,0x1d,0xdf,0x21,0xae,0x1d,0x65,0x5e,0x11,0xf3,0x90,0x8c,0x24,0x12,0x94,0xf4,0xe7,0x8d,0x5f,0xd1,0x9f,0x5d}, {0x7f,0x72,0x63,0x6d,0xd3,0x08,0x14,0x03,0x33,0xb5,0xc7,0xd7,0xef,0x9a,0x37,0x6a,0x4b,0xe2,0xae,0xcc,0xc5,0x8f,0xe1,0xa9,0xd3,0xbe,0x8f,0x4f,0x91,0x35,0x2f,0x33,0x1e,0x52,0xd7,0xee,0x2a,0x4d,0x24,0x3f,0x15,0x96,0x2e,0x43,0x28,0x90,0x3a,0x8e,0xd4,0x16,0x9c,0x2e,0x77,0xba,0x64,0xe1,0xd8,0x98,0xeb,0x47,0xfa,0x87,0xc1,0x3b,0x0c,0xc2,0x86,0xea,0x15,0x01,0x47,0x6d,0x25,0xd1,0x46,0x6c,0xcb,0xb7,0x8a,0x99,0x88,0x01,0x66,0x3a,0xb5,0x32,0x78,0xd7,0x03,0xba,0x6f,0x90,0xce,0x81,0x0d,0x45}, {0x75,0x52,0x20,0xa6,0xa1,0xb6,0x7b,0x6e,0x83,0x8e,0x3c,0x41,0xd7,0x21,0x4f,0xaa,0xb2,0x5c,0x8f,0xe8,0x55,0xd1,0x56,0x6f,0xe1,0x5b,0x34,0xa6,0x4b,0x5d,0xe2,0x2d,0x3f,0x74,0xae,0x1c,0x96,0xd8,0x74,0xd0,0xed,0x63,0x1c,0xee,0xf5,0x18,0x6d,0xf8,0x29,0xed,0xf4,0xe7,0x5b,0xc5,0xbd,0x97,0x08,0xb1,0x3a,0x66,0x79,0xd2,0xba,0x4c,0xcd,0x1f,0xd7,0xa0,0x24,0x90,0xd1,0x80,0xf8,0x8a,0x28,0xfb,0x0a,0xc2,0x25,0xc5,0x19,0x64,0x3a,0x5f,0x4b,0x97,0xa3,0xb1,0x33,0x72,0x00,0xe2,0xef,0xbc,0x7f,0x7d}, {0x01,0x28,0x6b,0x26,0x6a,0x1e,0xef,0xfa,0x16,0x9f,0x73,0xd5,0xc4,0x68,0x6c,0x86,0x2c,0x76,0x03,0x1b,0xbc,0x2f,0x8a,0xf6,0x8d,0x5a,0xb7,0x87,0x5e,0x43,0x75,0x59,0x94,0x90,0xc2,0xf3,0xc5,0x5d,0x7c,0xcd,0xab,0x05,0x91,0x2a,0x9a,0xa2,0x81,0xc7,0x58,0x30,0x1c,0x42,0x36,0x1d,0xc6,0x80,0xd7,0xd4,0xd8,0xdc,0x96,0xd1,0x9c,0x4f,0x68,0x37,0x7b,0x6a,0xd8,0x97,0x92,0x19,0x63,0x7a,0xd1,0x1a,0x24,0x58,0xd0,0xd0,0x17,0x0c,0x1c,0x5c,0xad,0x9c,0x02,0xba,0x07,0x03,0x7a,0x38,0x84,0xd0,0xcd,0x7c}, {0x17,0x04,0x26,0x6d,0x2c,0x42,0xa6,0xdc,0xbd,0x40,0x82,0x94,0x50,0x3d,0x15,0xae,0x77,0xc6,0x68,0xfb,0xb4,0xc1,0xc0,0xa9,0x53,0xcf,0xd0,0x61,0xed,0xd0,0x8b,0x42,0x93,0xcc,0x60,0x67,0x18,0x84,0x0c,0x9b,0x99,0x2a,0xb3,0x1a,0x7a,0x00,0xae,0xcd,0x18,0xda,0x0b,0x62,0x86,0xec,0x8d,0xa8,0x44,0xca,0x90,0x81,0x84,0xca,0x93,0x35,0xa7,0x9a,0x84,0x5e,0x9a,0x18,0x13,0x92,0xcd,0xfa,0xd8,0x65,0x35,0xc3,0xd8,0xd4,0xd1,0xbb,0xfd,0x53,0x5b,0x54,0x52,0x8c,0xe6,0x63,0x2d,0xda,0x08,0x83,0x39,0x27}, {0x13,0xd4,0x5e,0x43,0x28,0x8d,0xc3,0x42,0xc9,0xcc,0x78,0x32,0x60,0xf3,0x50,0xbd,0xef,0x03,0xda,0x79,0x1a,0xab,0x07,0xbb,0x55,0x33,0x8c,0xbe,0xae,0x97,0x95,0x26,0x53,0x24,0x70,0x0a,0x4c,0x0e,0xa1,0xb9,0xde,0x1b,0x7d,0xd5,0x66,0x58,0xa2,0x0f,0xf7,0xda,0x27,0xcd,0xb5,0xd9,0xb9,0xff,0xfd,0x33,0x2c,0x49,0x45,0x29,0x2c,0x57,0xbe,0x30,0xcd,0xd6,0x45,0xc7,0x7f,0xc7,0xfb,0xae,0xba,0xe3,0xd3,0xe8,0xdf,0xe4,0x0c,0xda,0x5d,0xaa,0x30,0x88,0x2c,0xa2,0x80,0xca,0x5b,0xc0,0x98,0x54,0x98,0x7f}, {0x17,0xe1,0x0b,0x9f,0x88,0xce,0x49,0x38,0x88,0xa2,0x54,0x7b,0x1b,0xad,0x05,0x80,0x1c,0x92,0xfc,0x23,0x9f,0xc3,0xa3,0x3d,0x04,0xf3,0x31,0x0a,0x47,0xec,0xc2,0x76,0x63,0x63,0xbf,0x0f,0x52,0x15,0x56,0xd3,0xa6,0xfb,0x4d,0xcf,0x45,0x5a,0x04,0x08,0xc2,0xa0,0x3f,0x87,0xbc,0x4f,0xc2,0xee,0xe7,0x12,0x9b,0xd6,0x3c,0x65,0xf2,0x30,0x85,0x0c,0xc1,0xaa,0x38,0xc9,0x08,0x8a,0xcb,0x6b,0x27,0xdb,0x60,0x9b,0x17,0x46,0x70,0xac,0x6f,0x0e,0x1e,0xc0,0x20,0xa9,0xda,0x73,0x64,0x59,0xf1,0x73,0x12,0x2f}, {0x11,0x1e,0xe0,0x8a,0x7c,0xfc,0x39,0x47,0x9f,0xab,0x6a,0x4a,0x90,0x74,0x52,0xfd,0x2e,0x8f,0x72,0x87,0x82,0x8a,0xd9,0x41,0xf2,0x69,0x5b,0xd8,0x2a,0x57,0x9e,0x5d,0xc0,0x0b,0xa7,0x55,0xd7,0x8b,0x48,0x30,0xe7,0x42,0xd4,0xf1,0xa4,0xb5,0xd6,0x06,0x62,0x61,0x59,0xbc,0x9e,0xa6,0xd1,0xea,0x84,0xf7,0xc5,0xed,0x97,0x19,0xac,0x38,0x3b,0xb1,0x51,0xa7,0x17,0xb5,0x66,0x06,0x8c,0x85,0x9b,0x7e,0x86,0x06,0x7d,0x74,0x49,0xde,0x4d,0x45,0x11,0xc0,0xac,0xac,0x9c,0xe6,0xe9,0xbf,0x9c,0xcd,0xdf,0x22}, {0xd9,0x0c,0x0d,0xc3,0xe0,0xd2,0xdb,0x8d,0x33,0x43,0xbb,0xac,0x5f,0x66,0x8e,0xad,0x1f,0x96,0x2a,0x32,0x8c,0x25,0x6b,0x8f,0xc7,0xc1,0x48,0x54,0xc0,0x16,0x29,0x6b,0xa1,0xe0,0x3b,0x10,0xb4,0x59,0xec,0x56,0x69,0xf9,0x59,0xd2,0xec,0xba,0xe3,0x2e,0x32,0xcd,0xf5,0x13,0x94,0xb2,0x7c,0x79,0x72,0xe4,0xcd,0x24,0x78,0x87,0xe9,0x0f,0x3b,0x91,0xba,0x0a,0xd1,0x34,0xdb,0x7e,0x0e,0xac,0x6d,0x2e,0x82,0xcd,0xa3,0x4e,0x15,0xf8,0x78,0x65,0xff,0x3d,0x08,0x66,0x17,0x0a,0xf0,0x7f,0x30,0x3f,0x30,0x4c}, {0x85,0x8c,0xb2,0x17,0xd6,0x3b,0x0a,0xd3,0xea,0x3b,0x77,0x39,0xb7,0x77,0xd3,0xc5,0xbf,0x5c,0x6a,0x1e,0x8c,0xe7,0xc6,0xc6,0xc4,0xb7,0x2a,0x8b,0xf7,0xb8,0x61,0x0d,0x00,0x45,0xd9,0x0d,0x58,0x03,0xfc,0x29,0x93,0xec,0xbb,0x6f,0xa4,0x7a,0xd2,0xec,0xf8,0xa7,0xe2,0xc2,0x5f,0x15,0x0a,0x13,0xd5,0xa1,0x06,0xb7,0x1a,0x15,0x6b,0x41,0xb0,0x36,0xc1,0xe9,0xef,0xd7,0xa8,0x56,0x20,0x4b,0xe4,0x58,0xcd,0xe5,0x07,0xbd,0xab,0xe0,0x57,0x1b,0xda,0x2f,0xe6,0xaf,0xd2,0xe8,0x77,0x42,0xf7,0x2a,0x1a,0x19}, {0x31,0x14,0x3c,0xc5,0x4b,0xf7,0x16,0xce,0xde,0xed,0x72,0x20,0xce,0x25,0x97,0x2b,0xe7,0x3e,0xb2,0xb5,0x6f,0xc3,0xb9,0xb8,0x08,0xc9,0x5c,0x0b,0x45,0x0e,0x2e,0x7e,0xfb,0x0e,0x46,0x4f,0x43,0x2b,0xe6,0x9f,0xd6,0x07,0x36,0xa6,0xd4,0x03,0xd3,0xde,0x24,0xda,0xa0,0xb7,0x0e,0x21,0x52,0xf0,0x93,0x5b,0x54,0x00,0xbe,0x7d,0x7e,0x23,0x30,0xb4,0x01,0x67,0xed,0x75,0x35,0x01,0x10,0xfd,0x0b,0x9f,0xe6,0x94,0x10,0x23,0x22,0x7f,0xe4,0x83,0x15,0x0f,0x32,0x75,0xe3,0x55,0x11,0xb1,0x99,0xa6,0xaf,0x71}, {0x1d,0xb6,0x53,0x39,0x9b,0x6f,0xce,0x65,0xe6,0x41,0xa1,0xaf,0xea,0x39,0x58,0xc6,0xfe,0x59,0xf7,0xa9,0xfd,0x5f,0x43,0x0f,0x8e,0xc2,0xb1,0xc2,0xe9,0x42,0x11,0x02,0xd6,0x50,0x3b,0x47,0x1c,0x3c,0x42,0xea,0x10,0xef,0x38,0x3b,0x1f,0x7a,0xe8,0x51,0x95,0xbe,0xc9,0xb2,0x5f,0xbf,0x84,0x9b,0x1c,0x9a,0xf8,0x78,0xbc,0x1f,0x73,0x00,0x80,0x18,0xf8,0x48,0x18,0xc7,0x30,0xe4,0x19,0xc1,0xce,0x5e,0x22,0x0c,0x96,0xbf,0xe3,0x15,0xba,0x6b,0x83,0xe0,0xda,0xb6,0x08,0x58,0xe1,0x47,0x33,0x6f,0x4d,0x4c}, {0xc9,0x1f,0x7d,0xc1,0xcf,0xec,0xf7,0x18,0x14,0x3c,0x40,0x51,0xa6,0xf5,0x75,0x6c,0xdf,0x0c,0xee,0xf7,0x2b,0x71,0xde,0xdb,0x22,0x7a,0xe4,0xa7,0xaa,0xdd,0x3f,0x19,0x70,0x19,0x8f,0x98,0xfc,0xdd,0x0c,0x2f,0x1b,0xf5,0xb9,0xb0,0x27,0x62,0x91,0x6b,0xbe,0x76,0x91,0x77,0xc4,0xb6,0xc7,0x6e,0xa8,0x9f,0x8f,0xa8,0x00,0x95,0xbf,0x38,0x6f,0x87,0xe8,0x37,0x3c,0xc9,0xd2,0x1f,0x2c,0x46,0xd1,0x18,0x5a,0x1e,0xf6,0xa2,0x76,0x12,0x24,0x39,0x82,0xf5,0x80,0x50,0x69,0x49,0x0d,0xbf,0x9e,0xb9,0x6f,0x6a}, {0xeb,0x55,0x08,0x56,0xbb,0xc1,0x46,0x6a,0x9d,0xf0,0x93,0xf8,0x38,0xbb,0x16,0x24,0xc1,0xac,0x71,0x8f,0x37,0x11,0x1d,0xd7,0xea,0x96,0x18,0xa3,0x14,0x69,0xf7,0x75,0xc6,0x23,0xe4,0xb6,0xb5,0x22,0xb1,0xee,0x8e,0xff,0x86,0xf2,0x10,0x70,0x9d,0x93,0x8c,0x5d,0xcf,0x1d,0x83,0x2a,0xa9,0x90,0x10,0xeb,0xc5,0x42,0x9f,0xda,0x6f,0x13,0xd1,0xbd,0x05,0xa3,0xb1,0xdf,0x4c,0xf9,0x08,0x2c,0xf8,0x9f,0x9d,0x4b,0x36,0x0f,0x8a,0x58,0xbb,0xc3,0xa5,0xd8,0x87,0x2a,0xba,0xdc,0xe8,0x0b,0x51,0x83,0x21,0x02}, {0x14,0x2d,0xad,0x5e,0x38,0x66,0xf7,0x4a,0x30,0x58,0x7c,0xca,0x80,0xd8,0x8e,0xa0,0x3d,0x1e,0x21,0x10,0xe6,0xa6,0x13,0x0d,0x03,0x6c,0x80,0x7b,0xe1,0x1c,0x07,0x6a,0x7f,0x7a,0x30,0x43,0x01,0x71,0x5a,0x9d,0x5f,0xa4,0x7d,0xc4,0x9e,0xde,0x63,0xb0,0xd3,0x7a,0x92,0xbe,0x52,0xfe,0xbb,0x22,0x6c,0x42,0x40,0xfd,0x41,0xc4,0x87,0x13,0xf8,0x8a,0x97,0x87,0xd1,0xc3,0xd3,0xb5,0x13,0x44,0x0e,0x7f,0x3d,0x5a,0x2b,0x72,0xa0,0x7c,0x47,0xbb,0x48,0x48,0x7b,0x0d,0x92,0xdc,0x1e,0xaf,0x6a,0xb2,0x71,0x31}, {0xa8,0x4c,0x56,0x97,0x90,0x31,0x2f,0xa9,0x19,0xe1,0x75,0x22,0x4c,0xb8,0x7b,0xff,0x50,0x51,0x87,0xa4,0x37,0xfe,0x55,0x4f,0x5a,0x83,0xf0,0x3c,0x87,0xd4,0x1f,0x22,0xd1,0x47,0x8a,0xb2,0xd8,0xb7,0x0d,0xa6,0xf1,0xa4,0x70,0x17,0xd6,0x14,0xbf,0xa6,0x58,0xbd,0xdd,0x53,0x93,0xf8,0xa1,0xd4,0xe9,0x43,0x42,0x34,0x63,0x4a,0x51,0x6c,0x41,0x63,0x15,0x3a,0x4f,0x20,0x22,0x23,0x2d,0x03,0x0a,0xba,0xe9,0xe0,0x73,0xfb,0x0e,0x03,0x0f,0x41,0x4c,0xdd,0xe0,0xfc,0xaa,0x4a,0x92,0xfb,0x96,0xa5,0xda,0x48}, {0xc7,0x9c,0xa5,0x5c,0x66,0x8e,0xca,0x6e,0xa0,0xac,0x38,0x2e,0x4b,0x25,0x47,0xa8,0xce,0x17,0x1e,0xd2,0x08,0xc7,0xaf,0x31,0xf7,0x4a,0xd8,0xca,0xfc,0xd6,0x6d,0x67,0x93,0x97,0x4c,0xc8,0x5d,0x1d,0xf6,0x14,0x06,0x82,0x41,0xef,0xe3,0xf9,0x41,0x99,0xac,0x77,0x62,0x34,0x8f,0xb8,0xf5,0xcd,0xa9,0x79,0x8a,0x0e,0xfa,0x37,0xc8,0x58,0x58,0x90,0xfc,0x96,0x85,0x68,0xf9,0x0c,0x1b,0xa0,0x56,0x7b,0xf3,0xbb,0xdc,0x1d,0x6a,0xd6,0x35,0x49,0x7d,0xe7,0xc2,0xdc,0x0a,0x7f,0xa5,0xc6,0xf2,0x73,0x4f,0x1c}, {0xbb,0xa0,0x5f,0x30,0xbd,0x4f,0x7a,0x0e,0xad,0x63,0xc6,0x54,0xe0,0x4c,0x9d,0x82,0x48,0x38,0xe3,0x2f,0x83,0xc3,0x21,0xf4,0x42,0x4c,0xf6,0x1b,0x0d,0xc8,0x5a,0x79,0x84,0x34,0x7c,0xfc,0x6e,0x70,0x6e,0xb3,0x61,0xcf,0xc1,0xc3,0xb4,0xc9,0xdf,0x73,0xe5,0xc7,0x1c,0x78,0xc9,0x79,0x1d,0xeb,0x5c,0x67,0xaf,0x7d,0xdb,0x9a,0x45,0x70,0xb3,0x2b,0xb4,0x91,0x49,0xdb,0x91,0x1b,0xca,0xdc,0x02,0x4b,0x23,0x96,0x26,0x57,0xdc,0x78,0x8c,0x1f,0xe5,0x9e,0xdf,0x9f,0xd3,0x1f,0xe2,0x8c,0x84,0x62,0xe1,0x5f}, {0x1a,0x96,0x94,0xe1,0x4f,0x21,0x59,0x4e,0x4f,0xcd,0x71,0x0d,0xc7,0x7d,0xbe,0x49,0x2d,0xf2,0x50,0x3b,0xd2,0xcf,0x00,0x93,0x32,0x72,0x91,0xfc,0x46,0xd4,0x89,0x47,0x08,0xb2,0x7c,0x5d,0x2d,0x85,0x79,0x28,0xe7,0xf2,0x7d,0x68,0x70,0xdd,0xde,0xb8,0x91,0x78,0x68,0x21,0xab,0xff,0x0b,0xdc,0x35,0xaa,0x7d,0x67,0x43,0xc0,0x44,0x2b,0x8e,0xb7,0x4e,0x07,0xab,0x87,0x1c,0x1a,0x67,0xf4,0xda,0x99,0x8e,0xd1,0xc6,0xfa,0x67,0x90,0x4f,0x48,0xcd,0xbb,0xac,0x3e,0xe4,0xa4,0xb9,0x2b,0xef,0x2e,0xc5,0x60}, {0xf1,0x8b,0xfd,0x3b,0xbc,0x89,0x5d,0x0b,0x1a,0x55,0xf3,0xc9,0x37,0x92,0x6b,0xb0,0xf5,0x28,0x30,0xd5,0xb0,0x16,0x4c,0x0e,0xab,0xca,0xcf,0x2c,0x31,0x9c,0xbc,0x10,0x11,0x6d,0xae,0x7c,0xc2,0xc5,0x2b,0x70,0xab,0x8c,0xa4,0x54,0x9b,0x69,0xc7,0x44,0xb2,0x2e,0x49,0xba,0x56,0x40,0xbc,0xef,0x6d,0x67,0xb6,0xd9,0x48,0x72,0xd7,0x70,0x5b,0xa0,0xc2,0x3e,0x4b,0xe8,0x8a,0xaa,0xe0,0x81,0x17,0xed,0xf4,0x9e,0x69,0x98,0xd1,0x85,0x8e,0x70,0xe4,0x13,0x45,0x79,0x13,0xf4,0x76,0xa9,0xd3,0x5b,0x75,0x63}, {0x53,0x08,0xd1,0x2a,0x3e,0xa0,0x5f,0xb5,0x69,0x35,0xe6,0x9e,0x90,0x75,0x6f,0x35,0x90,0xb8,0x69,0xbe,0xfd,0xf1,0xf9,0x9f,0x84,0x6f,0xc1,0x8b,0xc4,0xc1,0x8c,0x0d,0xb7,0xac,0xf1,0x97,0x18,0x10,0xc7,0x3d,0xd8,0xbb,0x65,0xc1,0x5e,0x7d,0xda,0x5d,0x0f,0x02,0xa1,0x0f,0x9c,0x5b,0x8e,0x50,0x56,0x2a,0xc5,0x37,0x17,0x75,0x63,0x27,0xa9,0x19,0xb4,0x6e,0xd3,0x02,0x94,0x02,0xa5,0x60,0xb4,0x77,0x7e,0x4e,0xb4,0xf0,0x56,0x49,0x3c,0xd4,0x30,0x62,0xa8,0xcf,0xe7,0x66,0xd1,0x7a,0x8a,0xdd,0xc2,0x70}, {0x0e,0xec,0x6f,0x9f,0x50,0x94,0x61,0x65,0x8d,0x51,0xc6,0x46,0xa9,0x7e,0x2e,0xee,0x5c,0x9b,0xe0,0x67,0xf3,0xc1,0x33,0x97,0x95,0x84,0x94,0x63,0x63,0xac,0x0f,0x2e,0x13,0x7e,0xed,0xb8,0x7d,0x96,0xd4,0x91,0x7a,0x81,0x76,0xd7,0x0a,0x2f,0x25,0x74,0x64,0x25,0x85,0x0d,0xe0,0x82,0x09,0xe4,0xe5,0x3c,0xa5,0x16,0x38,0x61,0xb8,0x32,0x64,0xcd,0x48,0xe4,0xbe,0xf7,0xe7,0x79,0xd0,0x86,0x78,0x08,0x67,0x3a,0xc8,0x6a,0x2e,0xdb,0xe4,0xa0,0xd9,0xd4,0x9f,0xf8,0x41,0x4f,0x5a,0x73,0x5c,0x21,0x79,0x41}, {0x2a,0xed,0xdc,0xd7,0xe7,0x94,0x70,0x8c,0x70,0x9c,0xd3,0x47,0xc3,0x8a,0xfb,0x97,0x02,0xd9,0x06,0xa9,0x33,0xe0,0x3b,0xe1,0x76,0x9d,0xd9,0x0c,0xa3,0x44,0x03,0x70,0x34,0xcd,0x6b,0x28,0xb9,0x33,0xae,0xe4,0xdc,0xd6,0x9d,0x55,0xb6,0x7e,0xef,0xb7,0x1f,0x8e,0xd3,0xb3,0x1f,0x14,0x8b,0x27,0x86,0xc2,0x41,0x22,0x66,0x85,0xfa,0x31,0xf4,0x22,0x36,0x2e,0x42,0x6c,0x82,0xaf,0x2d,0x50,0x33,0x98,0x87,0x29,0x20,0xc1,0x23,0x91,0x38,0x2b,0xe1,0xb7,0xc1,0x9b,0x89,0x24,0x95,0xa9,0x12,0x23,0xbb,0x24}, {0xc3,0x67,0xde,0x32,0x17,0xed,0xa8,0xb1,0x48,0x49,0x1b,0x46,0x18,0x94,0xb4,0x3c,0xd2,0xbc,0xcf,0x76,0x43,0x43,0xbd,0x8e,0x08,0x80,0x18,0x1e,0x87,0x3e,0xee,0x0f,0x6b,0x5c,0xf8,0xf5,0x2a,0x0c,0xf8,0x41,0x94,0x67,0xfa,0x04,0xc3,0x84,0x72,0x68,0xad,0x1b,0xba,0xa3,0x99,0xdf,0x45,0x89,0x16,0x5d,0xeb,0xff,0xf9,0x2a,0x1d,0x0d,0xdf,0x1e,0x62,0x32,0xa1,0x8a,0xda,0xa9,0x79,0x65,0x22,0x59,0xa1,0x22,0xb8,0x30,0x93,0xc1,0x9a,0xa7,0x7b,0x19,0x04,0x40,0x76,0x1d,0x53,0x18,0x97,0xd7,0xac,0x16}, {0x3d,0x1d,0x9b,0x2d,0xaf,0x72,0xdf,0x72,0x5a,0x24,0x32,0xa4,0x36,0x2a,0x46,0x63,0x37,0x96,0xb3,0x16,0x79,0xa0,0xce,0x3e,0x09,0x23,0x30,0xb9,0xf6,0x0e,0x3e,0x12,0xad,0xb6,0x87,0x78,0xc5,0xc6,0x59,0xc9,0xba,0xfe,0x90,0x5f,0xad,0x9e,0xe1,0x94,0x04,0xf5,0x42,0xa3,0x62,0x4e,0xe2,0x16,0x00,0x17,0x16,0x18,0x4b,0xd3,0x4e,0x16,0x9a,0xe6,0x2f,0x19,0x4c,0xd9,0x7e,0x48,0x13,0x15,0x91,0x3a,0xea,0x2c,0xae,0x61,0x27,0xde,0xa4,0xb9,0xd3,0xf6,0x7b,0x87,0xeb,0xf3,0x73,0x10,0xc6,0x0f,0xda,0x78}, {0x6a,0xc6,0x2b,0xe5,0x28,0x5d,0xf1,0x5b,0x8e,0x1a,0xf0,0x70,0x18,0xe3,0x47,0x2c,0xdd,0x8b,0xc2,0x06,0xbc,0xaf,0x19,0x24,0x3a,0x17,0x6b,0x25,0xeb,0xde,0x25,0x2d,0x94,0x3a,0x0c,0x68,0xf1,0x80,0x9f,0xa2,0xe6,0xe7,0xe9,0x1a,0x15,0x7e,0xf7,0x71,0x73,0x79,0x01,0x48,0x58,0xf1,0x00,0x11,0xdd,0x8d,0xb3,0x16,0xb3,0xa4,0x4a,0x05,0xb8,0x7c,0x26,0x19,0x8d,0x46,0xc8,0xdf,0xaf,0x4d,0xe5,0x66,0x9c,0x78,0x28,0x0b,0x17,0xec,0x6e,0x66,0x2a,0x1d,0xeb,0x2a,0x60,0xa7,0x7d,0xab,0xa6,0x10,0x46,0x13}, {0xfe,0xb0,0xf6,0x8d,0xc7,0x8e,0x13,0x51,0x1b,0xf5,0x75,0xe5,0x89,0xda,0x97,0x53,0xb9,0xf1,0x7a,0x71,0x1d,0x7a,0x20,0x09,0x50,0xd6,0x20,0x2b,0xba,0xfd,0x02,0x21,0x15,0xf5,0xd1,0x77,0xe7,0x65,0x2a,0xcd,0xf1,0x60,0xaa,0x8f,0x87,0x91,0x89,0x54,0xe5,0x06,0xbc,0xda,0xbc,0x3b,0xb7,0xb1,0xfb,0xc9,0x7c,0xa9,0xcb,0x78,0x48,0x65,0xa1,0xe6,0x5c,0x05,0x05,0xe4,0x9e,0x96,0x29,0xad,0x51,0x12,0x68,0xa7,0xbc,0x36,0x15,0xa4,0x7d,0xaa,0x17,0xf5,0x1a,0x3a,0xba,0xb2,0xec,0x29,0xdb,0x25,0xd7,0x0a}, {0x57,0x24,0x4e,0x83,0xb1,0x67,0x42,0xdc,0xc5,0x1b,0xce,0x70,0xb5,0x44,0x75,0xb6,0xd7,0x5e,0xd1,0xf7,0x0b,0x7a,0xf0,0x1a,0x50,0x36,0xa0,0x71,0xfb,0xcf,0xef,0x4a,0x85,0x6f,0x05,0x9b,0x0c,0xbc,0xc7,0xfe,0xd7,0xff,0xf5,0xe7,0x68,0x52,0x7d,0x53,0xfa,0xae,0x12,0x43,0x62,0xc6,0xaf,0x77,0xd9,0x9f,0x39,0x02,0x53,0x5f,0x67,0x4f,0x1e,0x17,0x15,0x04,0x36,0x36,0x2d,0xc3,0x3b,0x48,0x98,0x89,0x11,0xef,0x2b,0xcd,0x10,0x51,0x94,0xd0,0xad,0x6e,0x0a,0x87,0x61,0x65,0xa8,0xa2,0x72,0xbb,0xcc,0x0b}, {0xc8,0xa9,0xb1,0xea,0x2f,0x96,0x5e,0x18,0xcd,0x7d,0x14,0x65,0x35,0xe6,0xe7,0x86,0xf2,0x6d,0x5b,0xbb,0x31,0xe0,0x92,0xb0,0x3e,0xb7,0xd6,0x59,0xab,0xf0,0x24,0x40,0x96,0x12,0xfe,0x50,0x4c,0x5e,0x6d,0x18,0x7e,0x9f,0xe8,0xfe,0x82,0x7b,0x39,0xe0,0xb0,0x31,0x70,0x50,0xc5,0xf6,0xc7,0x3b,0xc2,0x37,0x8f,0x10,0x69,0xfd,0x78,0x66,0xc2,0x63,0x68,0x63,0x31,0xfa,0x86,0x15,0xf2,0x33,0x2d,0x57,0x48,0x8c,0xf6,0x07,0xfc,0xae,0x9e,0x78,0x9f,0xcc,0x73,0x4f,0x01,0x47,0xad,0x8e,0x10,0xe2,0x42,0x2d}, {0x9b,0xd2,0xdf,0x94,0x15,0x13,0xf5,0x97,0x6a,0x4c,0x3f,0x31,0x5d,0x98,0x55,0x61,0x10,0x50,0x45,0x08,0x07,0x3f,0xa1,0xeb,0x22,0xd3,0xd2,0xb8,0x08,0x26,0x6b,0x67,0x93,0x75,0x53,0x0f,0x0d,0x7b,0x71,0x21,0x4c,0x06,0x1e,0x13,0x0b,0x69,0x4e,0x91,0x9f,0xe0,0x2a,0x75,0xae,0x87,0xb6,0x1b,0x6e,0x3c,0x42,0x9b,0xa7,0xf3,0x0b,0x42,0x47,0x2b,0x5b,0x1c,0x65,0xba,0x38,0x81,0x80,0x1b,0x1b,0x31,0xec,0xb6,0x71,0x86,0xb0,0x35,0x31,0xbc,0xb1,0x0c,0xff,0x7b,0xe0,0xf1,0x0c,0x9c,0xfa,0x2f,0x5d,0x74}, {0xbd,0xc8,0xc9,0x2b,0x1e,0x5a,0x52,0xbf,0x81,0x9d,0x47,0x26,0x08,0x26,0x5b,0xea,0xdb,0x55,0x01,0xdf,0x0e,0xc7,0x11,0xd5,0xd0,0xf5,0x0c,0x96,0xeb,0x3c,0xe2,0x1a,0x6a,0x4e,0xd3,0x21,0x57,0xdf,0x36,0x60,0xd0,0xb3,0x7b,0x99,0x27,0x88,0xdb,0xb1,0xfa,0x6a,0x75,0xc8,0xc3,0x09,0xc2,0xd3,0x39,0xc8,0x1d,0x4c,0xe5,0x5b,0xe1,0x06,0x4a,0x99,0x32,0x19,0x87,0x5d,0x72,0x5b,0xb0,0xda,0xb1,0xce,0xb5,0x1c,0x35,0x32,0x05,0xca,0xb7,0xda,0x49,0x15,0xc4,0x7d,0xf7,0xc1,0x8e,0x27,0x61,0xd8,0xde,0x58}, {0x5c,0xc5,0x66,0xf2,0x93,0x37,0x17,0xd8,0x49,0x4e,0x45,0xcc,0xc5,0x76,0xc9,0xc8,0xa8,0xc3,0x26,0xbc,0xf8,0x82,0xe3,0x5c,0xf9,0xf6,0x85,0x54,0xe8,0x9d,0xf3,0x2f,0xa8,0xc9,0xc2,0xb6,0xa8,0x5b,0xfb,0x2d,0x8c,0x59,0x2c,0xf5,0x8e,0xef,0xee,0x48,0x73,0x15,0x2d,0xf1,0x07,0x91,0x80,0x33,0xd8,0x5b,0x1d,0x53,0x6b,0x69,0xba,0x08,0x7a,0xc5,0xef,0xc3,0xee,0x3e,0xed,0x77,0x11,0x48,0xff,0xd4,0x17,0x55,0xe0,0x04,0xcb,0x71,0xa6,0xf1,0x3f,0x7a,0x3d,0xea,0x54,0xfe,0x7c,0x94,0xb4,0x33,0x06,0x12}, {0x42,0x00,0x61,0x91,0x78,0x98,0x94,0x0b,0xe8,0xfa,0xeb,0xec,0x3c,0xb1,0xe7,0x4e,0xc0,0xa4,0xf0,0x94,0x95,0x73,0xbe,0x70,0x85,0x91,0xd5,0xb4,0x99,0x0a,0xd3,0x35,0x0a,0x10,0x12,0x49,0x47,0x31,0xbd,0x82,0x06,0xbe,0x6f,0x7e,0x6d,0x7b,0x23,0xde,0xc6,0x79,0xea,0x11,0x19,0x76,0x1e,0xe1,0xde,0x3b,0x39,0xcb,0xe3,0x3b,0x43,0x07,0xf4,0x97,0xe9,0x5c,0xc0,0x44,0x79,0xff,0xa3,0x51,0x5c,0xb0,0xe4,0x3d,0x5d,0x57,0x7c,0x84,0x76,0x5a,0xfd,0x81,0x33,0x58,0x9f,0xda,0xf6,0x7a,0xde,0x3e,0x87,0x2d}, {0x09,0x34,0x37,0x43,0x64,0x31,0x7a,0x15,0xd9,0x81,0xaa,0xf4,0xee,0xb7,0xb8,0xfa,0x06,0x48,0xa6,0xf5,0xe6,0xfe,0x93,0xb0,0xb6,0xa7,0x7f,0x70,0x54,0x36,0x77,0x2e,0x81,0xf9,0x5d,0x4e,0xe1,0x02,0x62,0xaa,0xf5,0xe1,0x15,0x50,0x17,0x59,0x0d,0xa2,0x6c,0x1d,0xe2,0xba,0xd3,0x75,0xa2,0x18,0x53,0x02,0x60,0x01,0x8a,0x61,0x43,0x05,0xc1,0x23,0x4c,0x97,0xf4,0xbd,0xea,0x0d,0x93,0x46,0xce,0x9d,0x25,0x0a,0x6f,0xaa,0x2c,0xba,0x9a,0xa2,0xb8,0x2c,0x20,0x04,0x0d,0x96,0x07,0x2d,0x36,0x43,0x14,0x4b}, {0x7a,0x1f,0x6e,0xb6,0xc7,0xb7,0xc4,0xcc,0x7e,0x2f,0x0c,0xf5,0x25,0x7e,0x15,0x44,0x1c,0xaf,0x3e,0x71,0xfc,0x6d,0xf0,0x3e,0xf7,0x63,0xda,0x52,0x67,0x44,0x2f,0x58,0xcb,0x9c,0x52,0x1c,0xe9,0x54,0x7c,0x96,0xfb,0x35,0xc6,0x64,0x92,0x26,0xf6,0x30,0x65,0x19,0x12,0x78,0xf4,0xaf,0x47,0x27,0x5c,0x6f,0xf6,0xea,0x18,0x84,0x03,0x17,0xe4,0x4c,0x32,0x20,0xd3,0x7b,0x31,0xc6,0xc4,0x8b,0x48,0xa4,0xe8,0x42,0x10,0xa8,0x64,0x13,0x5a,0x4e,0x8b,0xf1,0x1e,0xb2,0xc9,0x8d,0xa2,0xcd,0x4b,0x1c,0x2a,0x0c}, {0x47,0x04,0x1f,0x6f,0xd0,0xc7,0x4d,0xd2,0x59,0xc0,0x87,0xdb,0x3e,0x9e,0x26,0xb2,0x8f,0xd2,0xb2,0xfb,0x72,0x02,0x5b,0xd1,0x77,0x48,0xf6,0xc6,0xd1,0x8b,0x55,0x7c,0x45,0x69,0xbd,0x69,0x48,0x81,0xc4,0xed,0x22,0x8d,0x1c,0xbe,0x7d,0x90,0x6d,0x0d,0xab,0xc5,0x5c,0xd5,0x12,0xd2,0x3b,0xc6,0x83,0xdc,0x14,0xa3,0x30,0x9b,0x6a,0x5a,0x3d,0x46,0x96,0xd3,0x24,0x15,0xec,0xd0,0xf0,0x24,0x5a,0xc3,0x8a,0x62,0xbb,0x12,0xa4,0x5f,0xbc,0x1c,0x79,0x3a,0x0c,0xa5,0xc3,0xaf,0xfb,0x0a,0xca,0xa5,0x04,0x04}, {0xd6,0x43,0xa7,0x0a,0x07,0x40,0x1f,0x8c,0xe8,0x5e,0x26,0x5b,0xcb,0xd0,0xba,0xcc,0xde,0xd2,0x8f,0x66,0x6b,0x04,0x4b,0x57,0x33,0x96,0xdd,0xca,0xfd,0x5b,0x39,0x46,0xd1,0x6f,0x41,0x2a,0x1b,0x9e,0xbc,0x62,0x8b,0x59,0x50,0xe3,0x28,0xf7,0xc6,0xb5,0x67,0x69,0x5d,0x3d,0xd8,0x3f,0x34,0x04,0x98,0xee,0xf8,0xe7,0x16,0x75,0x52,0x39,0x9c,0x9a,0x5d,0x1a,0x2d,0xdb,0x7f,0x11,0x2a,0x5c,0x00,0xd1,0xbc,0x45,0x77,0x9c,0xea,0x6f,0xd5,0x54,0xf1,0xbe,0xd4,0xef,0x16,0xd0,0x22,0xe8,0x29,0x9a,0x57,0x76}, {0x17,0x2a,0xc0,0x49,0x7e,0x8e,0xb6,0x45,0x7f,0xa3,0xa9,0xbc,0xa2,0x51,0xcd,0x23,0x1b,0x4c,0x22,0xec,0x11,0x5f,0xd6,0x3e,0xb1,0xbd,0x05,0x9e,0xdc,0x84,0xa3,0x43,0xf2,0x34,0xb4,0x52,0x13,0xb5,0x3c,0x33,0xe1,0x80,0xde,0x93,0x49,0x28,0x32,0xd8,0xce,0x35,0x0d,0x75,0x87,0x28,0x51,0xb5,0xc1,0x77,0x27,0x2a,0xbb,0x14,0xc5,0x02,0x45,0xb6,0xf1,0x8b,0xda,0xd5,0x4b,0x68,0x53,0x4b,0xb5,0xf6,0x7e,0xd3,0x8b,0xfb,0x53,0xd2,0xb0,0xa9,0xd7,0x16,0x39,0x31,0x59,0x80,0x54,0x61,0x09,0x92,0x60,0x11}, {0xaa,0xcf,0xda,0x29,0x69,0x16,0x4d,0xb4,0x8f,0x59,0x13,0x84,0x4c,0x9f,0x52,0xda,0x59,0x55,0x3d,0x45,0xca,0x63,0xef,0xe9,0x0b,0x8e,0x69,0xc5,0x5b,0x12,0x1e,0x35,0xcd,0x4d,0x9b,0x36,0x16,0x56,0x38,0x7a,0x63,0x35,0x5c,0x65,0xa7,0x2c,0xc0,0x75,0x21,0x80,0xf1,0xd4,0xf9,0x1b,0xc2,0x7d,0x42,0xe0,0xe6,0x91,0x74,0x7d,0x63,0x2f,0xbe,0x7b,0xf6,0x1a,0x46,0x9b,0xb4,0xd4,0x61,0x89,0xab,0xc8,0x7a,0x03,0x03,0xd6,0xfb,0x99,0xa6,0xf9,0x9f,0xe1,0xde,0x71,0x9a,0x2a,0xce,0xe7,0x06,0x2d,0x18,0x7f}, {0xec,0x68,0x01,0xab,0x64,0x8e,0x7c,0x7a,0x43,0xc5,0xed,0x15,0x55,0x4a,0x5a,0xcb,0xda,0x0e,0xcd,0x47,0xd3,0x19,0x55,0x09,0xb0,0x93,0x3e,0x34,0x8c,0xac,0xd4,0x67,0x22,0x75,0x21,0x8e,0x72,0x4b,0x45,0x09,0xd8,0xb8,0x84,0xd4,0xf4,0xe8,0x58,0xaa,0x3c,0x90,0x46,0x7f,0x4d,0x25,0x58,0xd3,0x17,0x52,0x1c,0x24,0x43,0xc0,0xac,0x44,0x77,0x57,0x7a,0x4f,0xbb,0x6b,0x7d,0x1c,0xe1,0x13,0x83,0x91,0xd4,0xfe,0x35,0x8b,0x84,0x46,0x6b,0xc9,0xc6,0xa1,0xdc,0x4a,0xbd,0x71,0xad,0x12,0x83,0x1c,0x6d,0x55}, {0x82,0x39,0x8d,0x0c,0xe3,0x40,0xef,0x17,0x34,0xfa,0xa3,0x15,0x3e,0x07,0xf7,0x31,0x6e,0x64,0x73,0x07,0xcb,0xf3,0x21,0x4f,0xff,0x4e,0x82,0x1d,0x6d,0x6c,0x6c,0x74,0x21,0xe8,0x1b,0xb1,0x56,0x67,0xf0,0x81,0xdd,0xf3,0xa3,0x10,0x23,0xf8,0xaf,0x0f,0x5d,0x46,0x99,0x6a,0x55,0xd0,0xb2,0xf8,0x05,0x7f,0x8c,0xcc,0x38,0xbe,0x7a,0x09,0xa4,0x2d,0xa5,0x7e,0x87,0xc9,0x49,0x0c,0x43,0x1d,0xdc,0x9b,0x55,0x69,0x43,0x4c,0xd2,0xeb,0xcc,0xf7,0x09,0x38,0x2c,0x02,0xbd,0x84,0xee,0x4b,0xa3,0x14,0x7e,0x57}, {0x0a,0x3b,0xa7,0x61,0xac,0x68,0xe2,0xf0,0xf5,0xa5,0x91,0x37,0x10,0xfa,0xfa,0xf2,0xe9,0x00,0x6d,0x6b,0x82,0x3e,0xe1,0xc1,0x42,0x8f,0xd7,0x6f,0xe9,0x7e,0xfa,0x60,0x2b,0xd7,0x4d,0xbd,0xbe,0xce,0xfe,0x94,0x11,0x22,0x0f,0x06,0xda,0x4f,0x6a,0xf4,0xff,0xd1,0xc8,0xc0,0x77,0x59,0x4a,0x12,0x95,0x92,0x00,0xfb,0xb8,0x04,0x53,0x70,0xc6,0x6e,0x29,0x4d,0x35,0x1d,0x3d,0xb6,0xd8,0x31,0xad,0x5f,0x3e,0x05,0xc3,0xf3,0xec,0x42,0xbd,0xb4,0x8c,0x95,0x0b,0x67,0xfd,0x53,0x63,0xa1,0x0c,0x8e,0x39,0x21}, {0xf3,0x33,0x2b,0x38,0x8a,0x05,0xf5,0x89,0xb4,0xc0,0x48,0xad,0x0b,0xba,0xe2,0x5a,0x6e,0xb3,0x3d,0xa5,0x03,0xb5,0x93,0x8f,0xe6,0x32,0xa2,0x95,0x9d,0xed,0xa3,0x5a,0x01,0x56,0xb7,0xb4,0xf9,0xaa,0x98,0x27,0x72,0xad,0x8d,0x5c,0x13,0x72,0xac,0x5e,0x23,0xa0,0xb7,0x61,0x61,0xaa,0xce,0xd2,0x4e,0x7d,0x8f,0xe9,0x84,0xb2,0xbf,0x1b,0x61,0x65,0xd9,0xc7,0xe9,0x77,0x67,0x65,0x36,0x80,0xc7,0x72,0x54,0x12,0x2b,0xcb,0xee,0x6e,0x50,0xd9,0x99,0x32,0x05,0x65,0xcc,0x57,0x89,0x5e,0x4e,0xe1,0x07,0x4a}, {0x99,0xf9,0x0d,0x98,0xcb,0x12,0xe4,0x4e,0x71,0xc7,0x6e,0x3c,0x6f,0xd7,0x15,0xa3,0xfd,0x77,0x5c,0x92,0xde,0xed,0xa5,0xbb,0x02,0x34,0x31,0x1d,0x39,0xac,0x0b,0x3f,0x9b,0xa4,0x77,0xc4,0xcd,0x58,0x0b,0x24,0x17,0xf0,0x47,0x64,0xde,0xda,0x38,0xfd,0xad,0x6a,0xc8,0xa7,0x32,0x8d,0x92,0x19,0x81,0xa0,0xaf,0x84,0xed,0x7a,0xaf,0x50,0xe5,0x5b,0xf6,0x15,0x01,0xde,0x4f,0x6e,0xb2,0x09,0x61,0x21,0x21,0x26,0x98,0x29,0xd9,0xd6,0xad,0x0b,0x81,0x05,0x02,0x78,0x06,0xd0,0xeb,0xba,0x16,0xa3,0x21,0x19}, {0xfc,0x70,0xb8,0xdf,0x7e,0x2f,0x42,0x89,0xbd,0xb3,0x76,0x4f,0xeb,0x6b,0x29,0x2c,0xf7,0x4d,0xc2,0x36,0xd4,0xf1,0x38,0x07,0xb0,0xae,0x73,0xe2,0x41,0xdf,0x58,0x64,0x8b,0xc1,0xf3,0xd9,0x9a,0xad,0x5a,0xd7,0x9c,0xc1,0xb1,0x60,0xef,0x0e,0x6a,0x56,0xd9,0x0e,0x5c,0x25,0xac,0x0b,0x9a,0x3e,0xf5,0xc7,0x62,0xa0,0xec,0x9d,0x04,0x7b,0x83,0x44,0x44,0x35,0x7a,0xe3,0xcb,0xdc,0x93,0xbe,0xed,0x0f,0x33,0x79,0x88,0x75,0x87,0xdd,0xc5,0x12,0xc3,0x04,0x60,0x78,0x64,0x0e,0x95,0xc2,0xcb,0xdc,0x93,0x60}, {0x6d,0x70,0xe0,0x85,0x85,0x9a,0xf3,0x1f,0x33,0x39,0xe7,0xb3,0xd8,0xa5,0xd0,0x36,0x3b,0x45,0x8f,0x71,0xe1,0xf2,0xb9,0x43,0x7c,0xa9,0x27,0x48,0x08,0xea,0xd1,0x57,0x4b,0x03,0x84,0x60,0xbe,0xee,0xde,0x6b,0x54,0xb8,0x0f,0x78,0xb6,0xc2,0x99,0x31,0x95,0x06,0x2d,0xb6,0xab,0x76,0x33,0x97,0x90,0x7d,0x64,0x8b,0xc9,0x80,0x31,0x6e,0x71,0xb0,0x28,0xa1,0xe7,0xb6,0x7a,0xee,0xaa,0x8b,0xa8,0x93,0x6d,0x59,0xc1,0xa4,0x30,0x61,0x21,0xb2,0x82,0xde,0xb4,0xf7,0x18,0xbd,0x97,0xdd,0x9d,0x99,0x3e,0x36}, {0xc4,0x1f,0xee,0x35,0xc1,0x43,0xa8,0x96,0xcf,0xc8,0xe4,0x08,0x55,0xb3,0x6e,0x97,0x30,0xd3,0x8c,0xb5,0x01,0x68,0x2f,0xb4,0x2b,0x05,0x3a,0x69,0x78,0x9b,0xee,0x48,0xc6,0xae,0x4b,0xe2,0xdc,0x48,0x18,0x2f,0x60,0xaf,0xbc,0xba,0x55,0x72,0x9b,0x76,0x31,0xe9,0xef,0x3c,0x6e,0x3c,0xcb,0x90,0x55,0xb3,0xf9,0xc6,0x9b,0x97,0x1f,0x23,0xc6,0xf3,0x2a,0xcc,0x4b,0xde,0x31,0x5c,0x1f,0x8d,0x20,0xfe,0x30,0xb0,0x4b,0xb0,0x66,0xb4,0x4f,0xc1,0x09,0x70,0x8d,0xb7,0x13,0x24,0x79,0x08,0x9b,0xfa,0x9b,0x07}, {0xf4,0x0d,0x30,0xda,0x51,0x3a,0x90,0xe3,0xb0,0x5a,0xa9,0x3d,0x23,0x64,0x39,0x84,0x80,0x64,0x35,0x0b,0x2d,0xf1,0x3c,0xed,0x94,0x71,0x81,0x84,0xf6,0x77,0x8c,0x03,0x45,0x42,0xd5,0xa2,0x80,0xed,0xc9,0xf3,0x52,0x39,0xf6,0x77,0x78,0x8b,0xa0,0x0a,0x75,0x54,0x08,0xd1,0x63,0xac,0x6d,0xd7,0x6b,0x63,0x70,0x94,0x15,0xfb,0xf4,0x1e,0xec,0x7b,0x16,0x5b,0xe6,0x5e,0x4e,0x85,0xc2,0xcd,0xd0,0x96,0x42,0x0a,0x59,0x59,0x99,0x21,0x10,0x98,0x34,0xdf,0xb2,0x72,0x56,0xff,0x0b,0x4a,0x2a,0xe9,0x5e,0x57}, {0xcf,0x2f,0x18,0x8a,0x90,0x80,0xc0,0xd4,0xbd,0x9d,0x48,0x99,0xc2,0x70,0xe1,0x30,0xde,0x33,0xf7,0x52,0x57,0xbd,0xba,0x05,0x00,0xfd,0xd3,0x2c,0x11,0xe7,0xd4,0x43,0x01,0xd8,0xa4,0x0a,0x45,0xbc,0x46,0x5d,0xd8,0xb9,0x33,0xa5,0x27,0x12,0xaf,0xc3,0xc2,0x06,0x89,0x2b,0x26,0x3b,0x9e,0x38,0x1b,0x58,0x2f,0x38,0x7e,0x1e,0x0a,0x20,0xc5,0x3a,0xf9,0xea,0x67,0xb9,0x8d,0x51,0xc0,0x52,0x66,0x05,0x9b,0x98,0xbc,0x71,0xf5,0x97,0x71,0x56,0xd9,0x85,0x2b,0xfe,0x38,0x4e,0x1e,0x65,0x52,0xca,0x0e,0x05}, {0x9c,0x0c,0x3f,0x45,0xde,0x1a,0x43,0xc3,0x9b,0x3b,0x70,0xff,0x5e,0x04,0xf5,0xe9,0x3d,0x7b,0x84,0xed,0xc9,0x7a,0xd9,0xfc,0xc6,0xf4,0x58,0x1c,0xc2,0xe6,0x0e,0x4b,0xea,0x68,0xe6,0x60,0x76,0x39,0xac,0x97,0x97,0xb4,0x3a,0x15,0xfe,0xbb,0x19,0x9b,0x9f,0xa7,0xec,0x34,0xb5,0x79,0xb1,0x4c,0x57,0xae,0x31,0xa1,0x9f,0xc0,0x51,0x61,0x96,0x5d,0xf0,0xfd,0x0d,0x5c,0xf5,0x3a,0x7a,0xee,0xb4,0x2a,0xe0,0x2e,0x26,0xdd,0x09,0x17,0x17,0x12,0x87,0xbb,0xb2,0x11,0x0b,0x03,0x0f,0x80,0xfa,0x24,0xef,0x1f}, {0x96,0x31,0xa7,0x1a,0xfb,0x53,0xd6,0x37,0x18,0x64,0xd7,0x3f,0x30,0x95,0x94,0x0f,0xb2,0x17,0x3a,0xfb,0x09,0x0b,0x20,0xad,0x3e,0x61,0xc8,0x2f,0x29,0x49,0x4d,0x54,0x86,0x6b,0x97,0x30,0xf5,0xaf,0xd2,0x22,0x04,0x46,0xd2,0xc2,0x06,0xb8,0x90,0x8d,0xe5,0xba,0xe5,0x4d,0x6c,0x89,0xa1,0xdc,0x17,0x0c,0x34,0xc8,0xe6,0x5f,0x00,0x28,0x88,0x86,0x52,0x34,0x9f,0xba,0xef,0x6a,0xa1,0x7d,0x10,0x25,0x94,0xff,0x1b,0x5c,0x36,0x4b,0xd9,0x66,0xcd,0xbb,0x5b,0xf7,0xfa,0x6d,0x31,0x0f,0x93,0x72,0xe4,0x72}, {0x4f,0x08,0x81,0x97,0x8c,0x20,0x95,0x26,0xe1,0x0e,0x45,0x23,0x0b,0x2a,0x50,0xb1,0x02,0xde,0xef,0x03,0xa6,0xae,0x9d,0xfd,0x4c,0xa3,0x33,0x27,0x8c,0x2e,0x9d,0x5a,0x27,0x76,0x2a,0xd3,0x35,0xf6,0xf3,0x07,0xf0,0x66,0x65,0x5f,0x86,0x4d,0xaa,0x7a,0x50,0x44,0xd0,0x28,0x97,0xe7,0x85,0x3c,0x38,0x64,0xe0,0x0f,0x00,0x7f,0xee,0x1f,0xe5,0xf7,0xdb,0x03,0xda,0x05,0x53,0x76,0xbd,0xcd,0x34,0x14,0x49,0xf2,0xda,0xa4,0xec,0x88,0x4a,0xd2,0xcd,0xd5,0x4a,0x7b,0x43,0x05,0x04,0xee,0x51,0x40,0xf9,0x00}, {0xb2,0x30,0xd3,0xc3,0x23,0x6b,0x35,0x8d,0x06,0x1b,0x47,0xb0,0x9b,0x8b,0x1c,0xf2,0x3c,0xb8,0x42,0x6e,0x6c,0x31,0x6c,0xb3,0x0d,0xb1,0xea,0x8b,0x7e,0x9c,0xd7,0x07,0x53,0x97,0xaf,0x07,0xbb,0x93,0xef,0xd7,0xa7,0x66,0xb7,0x3d,0xcf,0xd0,0x3e,0x58,0xc5,0x1e,0x0b,0x6e,0xbf,0x98,0x69,0xce,0x52,0x04,0xd4,0x5d,0xd2,0xff,0xb7,0x47,0x12,0xdd,0x08,0xbc,0x9c,0xfb,0xfb,0x87,0x9b,0xc2,0xee,0xe1,0x3a,0x6b,0x06,0x8a,0xbf,0xc1,0x1f,0xdb,0x2b,0x24,0x57,0x0d,0xb6,0x4b,0xa6,0x5e,0xa3,0x20,0x35,0x1c}, {0x4a,0xa3,0xcb,0xbc,0xa6,0x53,0xd2,0x80,0x9b,0x21,0x38,0x38,0xa1,0xc3,0x61,0x3e,0x96,0xe3,0x82,0x98,0x01,0xb6,0xc3,0x90,0x6f,0xe6,0x0e,0x5d,0x77,0x05,0x3d,0x1c,0x59,0xc0,0x6b,0x21,0x40,0x6f,0xa8,0xcd,0x7e,0xd8,0xbc,0x12,0x1d,0x23,0xbb,0x1f,0x90,0x09,0xc7,0x17,0x9e,0x6a,0x95,0xb4,0x55,0x2e,0xd1,0x66,0x3b,0x0c,0x75,0x38,0x1a,0xe5,0x22,0x94,0x40,0xf1,0x2e,0x69,0x71,0xf6,0x5d,0x2b,0x3c,0xc7,0xc0,0xcb,0x29,0xe0,0x4c,0x74,0xe7,0x4f,0x01,0x21,0x7c,0x48,0x30,0xd3,0xc7,0xe2,0x21,0x06}, {0x8d,0x83,0x59,0x82,0xcc,0x60,0x98,0xaf,0xdc,0x9a,0x9f,0xc6,0xc1,0x48,0xea,0x90,0x30,0x1e,0x58,0x65,0x37,0x48,0x26,0x65,0xbc,0xa5,0xd3,0x7b,0x09,0xd6,0x07,0x00,0xf3,0xf0,0xdb,0xb0,0x96,0x17,0xae,0xb7,0x96,0xe1,0x7c,0xe1,0xb9,0xaf,0xdf,0x54,0xb4,0xa3,0xaa,0xe9,0x71,0x30,0x92,0x25,0x9d,0x2e,0x00,0xa1,0x9c,0x58,0x8e,0x5d,0x4b,0xa9,0x42,0x08,0x95,0x1d,0xbf,0xc0,0x3e,0x2e,0x8f,0x58,0x63,0xc3,0xd3,0xb2,0xef,0xe2,0x51,0xbb,0x38,0x14,0x96,0x0a,0x86,0xbf,0x1c,0x3c,0x78,0xd7,0x83,0x15}, {0xe1,0x7a,0xa2,0x5d,0xef,0xa2,0xee,0xec,0x74,0x01,0x67,0x55,0x14,0x3a,0x7c,0x59,0x7a,0x16,0x09,0x66,0x12,0x2a,0xa6,0xc9,0x70,0x8f,0xed,0x81,0x2e,0x5f,0x2a,0x25,0xc7,0x28,0x9d,0xcc,0x04,0x47,0x03,0x90,0x8f,0xc5,0x2c,0xf7,0x9e,0x67,0x1b,0x1d,0x26,0x87,0x5b,0xbe,0x5f,0x2b,0xe1,0x16,0x0a,0x58,0xc5,0x83,0x4e,0x06,0x58,0x49,0x0d,0xe8,0x66,0x50,0x26,0x94,0x28,0x0d,0x6b,0x8c,0x7c,0x30,0x85,0xf7,0xc3,0xfc,0xfd,0x12,0x11,0x0c,0x78,0xda,0x53,0x1b,0x88,0xb3,0x43,0xd8,0x0b,0x17,0x9c,0x07}, {0xff,0x6f,0xfa,0x64,0xe4,0xec,0x06,0x05,0x23,0xe5,0x05,0x62,0x1e,0x43,0xe3,0xbe,0x42,0xea,0xb8,0x51,0x24,0x42,0x79,0x35,0x00,0xfb,0xc9,0x4a,0xe3,0x05,0xec,0x6d,0x56,0xd0,0xd5,0xc0,0x50,0xcd,0xd6,0xcd,0x3b,0x57,0x03,0xbb,0x6d,0x68,0xf7,0x9a,0x48,0xef,0xc3,0xf3,0x3f,0x72,0xa6,0x3c,0xcc,0x8a,0x7b,0x31,0xd7,0xc0,0x68,0x67,0xb3,0xc1,0x55,0xf1,0xe5,0x25,0xb6,0x94,0x91,0x7b,0x7b,0x99,0xa7,0xf3,0x7b,0x41,0x00,0x26,0x6b,0x6d,0xdc,0xbd,0x2c,0xc2,0xf4,0x52,0xcd,0xdd,0x14,0x5e,0x44,0x51}, {0x51,0x49,0x14,0x3b,0x4b,0x2b,0x50,0x57,0xb3,0xbc,0x4b,0x44,0x6b,0xff,0x67,0x8e,0xdb,0x85,0x63,0x16,0x27,0x69,0xbd,0xb8,0xc8,0x95,0x92,0xe3,0x31,0x6f,0x18,0x13,0x55,0xa4,0xbe,0x2b,0xab,0x47,0x31,0x89,0x29,0x91,0x07,0x92,0x4f,0xa2,0x53,0x8c,0xa7,0xf7,0x30,0xbe,0x48,0xf9,0x49,0x4b,0x3d,0xd4,0x4f,0x6e,0x08,0x90,0xe9,0x12,0x2e,0xbb,0xdf,0x7f,0xb3,0x96,0x0c,0xf1,0xf9,0xea,0x1c,0x12,0x5e,0x93,0x9a,0x9f,0x3f,0x98,0x5b,0x3a,0xc4,0x36,0x11,0xdf,0xaf,0x99,0x3e,0x5d,0xf0,0xe3,0xb2,0x77}, {0xde,0xc4,0x2e,0x9c,0xc5,0xa9,0x6f,0x29,0xcb,0xf3,0x84,0x4f,0xbf,0x61,0x8b,0xbc,0x08,0xf9,0xa8,0x17,0xd9,0x06,0x77,0x1c,0x5d,0x25,0xd3,0x7a,0xfc,0x95,0xb7,0x63,0xa4,0xb0,0xdd,0x12,0x9c,0x63,0x98,0xd5,0x6b,0x86,0x24,0xc0,0x30,0x9f,0xd1,0xa5,0x60,0xe4,0xfc,0x58,0x03,0x2f,0x7c,0xd1,0x8a,0x5e,0x09,0x2e,0x15,0x95,0xa1,0x07,0xc8,0x5f,0x9e,0x38,0x02,0x8f,0x36,0xa8,0x3b,0xe4,0x8d,0xcf,0x02,0x3b,0x43,0x90,0x43,0x26,0x41,0xc5,0x5d,0xfd,0xa1,0xaf,0x37,0x01,0x2f,0x03,0x3d,0xe8,0x8f,0x3e}, {0x94,0xa2,0x70,0x05,0xb9,0x15,0x8b,0x2f,0x49,0x45,0x08,0x67,0x70,0x42,0xf2,0x94,0x84,0xfd,0xbb,0x61,0xe1,0x5a,0x1c,0xde,0x07,0x40,0xac,0x7f,0x79,0x3b,0xba,0x75,0x3c,0xd1,0xef,0xe8,0x8d,0x4c,0x70,0x08,0x31,0x37,0xe0,0x33,0x8e,0x1a,0xc5,0xdf,0xe3,0xcd,0x60,0x12,0xa5,0x5d,0x9d,0xa5,0x86,0x8c,0x25,0xa6,0x99,0x08,0xd6,0x22,0x96,0xd1,0xcd,0x70,0xc0,0xdb,0x39,0x62,0x9a,0x8a,0x7d,0x6c,0x8b,0x8a,0xfe,0x60,0x60,0x12,0x40,0xeb,0xbc,0x47,0x88,0xb3,0x5e,0x9e,0x77,0x87,0x7b,0xd0,0x04,0x09}, {0x9c,0x91,0xba,0xdd,0xd4,0x1f,0xce,0xb4,0xaa,0x8d,0x4c,0xc7,0x3e,0xdb,0x31,0xcf,0x51,0xcc,0x86,0xad,0x63,0xcc,0x63,0x2c,0x07,0xde,0x1d,0xbc,0x3f,0x14,0xe2,0x43,0xb9,0x40,0xf9,0x48,0x66,0x2d,0x32,0xf4,0x39,0x0c,0x2d,0xbd,0x0c,0x2f,0x95,0x06,0x31,0xf9,0x81,0xa0,0xad,0x97,0x76,0x16,0x6c,0x2a,0xf7,0xba,0xce,0xaa,0x40,0x62,0xa0,0x95,0xa2,0x5b,0x9c,0x74,0x34,0xf8,0x5a,0xd2,0x37,0xca,0x5b,0x7c,0x94,0xd6,0x6a,0x31,0xc9,0xe7,0xa7,0x3b,0xf1,0x66,0xac,0x0c,0xb4,0x8d,0x23,0xaf,0xbd,0x56}, {0xeb,0x33,0x35,0xf5,0xe3,0xb9,0x2a,0x36,0x40,0x3d,0xb9,0x6e,0xd5,0x68,0x85,0x33,0x72,0x55,0x5a,0x1d,0x52,0x14,0x0e,0x9e,0x18,0x13,0x74,0x83,0x6d,0xa8,0x24,0x1d,0xb2,0x3b,0x9d,0xc1,0x6c,0xd3,0x10,0x13,0xb9,0x86,0x23,0x62,0xb7,0x6b,0x2a,0x06,0x5c,0x4f,0xa1,0xd7,0x91,0x85,0x9b,0x7c,0x54,0x57,0x1e,0x7e,0x50,0x31,0xaa,0x03,0x1f,0xce,0xd4,0xff,0x48,0x76,0xec,0xf4,0x1c,0x8c,0xac,0x54,0xf0,0xea,0x45,0xe0,0x7c,0x35,0x09,0x1d,0x82,0x25,0xd2,0x88,0x59,0x48,0xeb,0x9a,0xdc,0x61,0xb2,0x43}, {0xbb,0x79,0xbb,0x88,0x19,0x1e,0x5b,0xe5,0x9d,0x35,0x7a,0xc1,0x7d,0xd0,0x9e,0xa0,0x33,0xea,0x3d,0x60,0xe2,0x2e,0x2c,0xb0,0xc2,0x6b,0x27,0x5b,0xcf,0x55,0x60,0x32,0x64,0x13,0x95,0x6c,0x8b,0x3d,0x51,0x19,0x7b,0xf4,0x0b,0x00,0x26,0x71,0xfe,0x94,0x67,0x95,0x4f,0xd5,0xdd,0x10,0x8d,0x02,0x64,0x09,0x94,0x42,0xe2,0xd5,0xb4,0x02,0xf2,0x8d,0xd1,0x28,0xcb,0x55,0xa1,0xb4,0x08,0xe5,0x6c,0x18,0x46,0x46,0xcc,0xea,0x89,0x43,0x82,0x6c,0x93,0xf4,0x9c,0xc4,0x10,0x34,0x5d,0xae,0x09,0xc8,0xa6,0x27}, {0x88,0xb1,0x0d,0x1f,0xcd,0xeb,0xa6,0x8b,0xe8,0x5b,0x5a,0x67,0x3a,0xd7,0xd3,0x37,0x5a,0x58,0xf5,0x15,0xa3,0xdf,0x2e,0xf2,0x7e,0xa1,0x60,0xff,0x74,0x71,0xb6,0x2c,0x54,0x69,0x3d,0xc4,0x0a,0x27,0x2c,0xcd,0xb2,0xca,0x66,0x6a,0x57,0x3e,0x4a,0xdd,0x6c,0x03,0xd7,0x69,0x24,0x59,0xfa,0x79,0x99,0x25,0x8c,0x3d,0x60,0x03,0x15,0x22,0xd0,0xe1,0x0b,0x39,0xf9,0xcd,0xee,0x59,0xf1,0xe3,0x8c,0x72,0x44,0x20,0x42,0xa9,0xf4,0xf0,0x94,0x7a,0x66,0x1c,0x89,0x82,0x36,0xf4,0x90,0x38,0xb7,0xf4,0x1d,0x7b}, {0x24,0xa2,0xb2,0xb3,0xe0,0xf2,0x92,0xe4,0x60,0x11,0x55,0x2b,0x06,0x9e,0x6c,0x7c,0x0e,0x7b,0x7f,0x0d,0xe2,0x8f,0xeb,0x15,0x92,0x59,0xfc,0x58,0x26,0xef,0xfc,0x61,0x8c,0xf5,0xf8,0x07,0x18,0x22,0x2e,0x5f,0xd4,0x09,0x94,0xd4,0x9f,0x5c,0x55,0xe3,0x30,0xa6,0xb6,0x1f,0x8d,0xa8,0xaa,0xb2,0x3d,0xe0,0x52,0xd3,0x45,0x82,0x69,0x68,0x7a,0x18,0x18,0x2a,0x85,0x5d,0xb1,0xdb,0xd7,0xac,0xdd,0x86,0xd3,0xaa,0xe4,0xf3,0x82,0xc4,0xf6,0x0f,0x81,0xe2,0xba,0x44,0xcf,0x01,0xaf,0x3d,0x47,0x4c,0xcf,0x46}, {0xf9,0xe5,0xc4,0x9e,0xed,0x25,0x65,0x42,0x03,0x33,0x90,0x16,0x01,0xda,0x5e,0x0e,0xdc,0xca,0xe5,0xcb,0xf2,0xa7,0xb1,0x72,0x40,0x5f,0xeb,0x14,0xcd,0x7b,0x38,0x29,0x40,0x81,0x49,0xf1,0xa7,0x6e,0x3c,0x21,0x54,0x48,0x2b,0x39,0xf8,0x7e,0x1e,0x7c,0xba,0xce,0x29,0x56,0x8c,0xc3,0x88,0x24,0xbb,0xc5,0x8c,0x0d,0xe5,0xaa,0x65,0x10,0x57,0x0d,0x20,0xdf,0x25,0x45,0x2c,0x1c,0x4a,0x67,0xca,0xbf,0xd6,0x2d,0x3b,0x5c,0x30,0x40,0x83,0xe1,0xb1,0xe7,0x07,0x0a,0x16,0xe7,0x1c,0x4f,0xe6,0x98,0xa1,0x69}, {0xbc,0x78,0x1a,0xd9,0xe0,0xb2,0x62,0x90,0x67,0x96,0x50,0xc8,0x9c,0x88,0xc9,0x47,0xb8,0x70,0x50,0x40,0x66,0x4a,0xf5,0x9d,0xbf,0xa1,0x93,0x24,0xa9,0xe6,0x69,0x73,0xed,0xca,0xc5,0xdc,0x34,0x44,0x01,0xe1,0x33,0xfb,0x84,0x3c,0x96,0x5d,0xed,0x47,0xe7,0xa0,0x86,0xed,0x76,0x95,0x01,0x70,0xe4,0xf9,0x67,0xd2,0x7b,0x69,0xb2,0x25,0x64,0x68,0x98,0x13,0xfb,0x3f,0x67,0x9d,0xb8,0xc7,0x5d,0x41,0xd9,0xfb,0xa5,0x3c,0x5e,0x3b,0x27,0xdf,0x3b,0xcc,0x4e,0xe0,0xd2,0x4c,0x4e,0xb5,0x3d,0x68,0x20,0x14}, {0x97,0xd1,0x9d,0x24,0x1e,0xbd,0x78,0xb4,0x02,0xc1,0x58,0x5e,0x00,0x35,0x0c,0x62,0x5c,0xac,0xba,0xcc,0x2f,0xd3,0x02,0xfb,0x2d,0xa7,0x08,0xf5,0xeb,0x3b,0xb6,0x60,0xd0,0x5a,0xcc,0xc1,0x6f,0xbb,0xee,0x34,0x8b,0xac,0x46,0x96,0xe9,0x0c,0x1b,0x6a,0x53,0xde,0x6b,0xa6,0x49,0xda,0xb0,0xd3,0xc1,0x81,0xd0,0x61,0x41,0x3b,0xe8,0x31,0x4f,0x2b,0x06,0x9e,0x12,0xc7,0xe8,0x97,0xd8,0x0a,0x32,0x29,0x4f,0x8f,0xe4,0x49,0x3f,0x68,0x18,0x6f,0x4b,0xe1,0xec,0x5b,0x17,0x03,0x55,0x2d,0xb6,0x1e,0xcf,0x55}, {0x58,0x3d,0xc2,0x65,0x10,0x10,0x79,0x58,0x9c,0x81,0x94,0x50,0x6d,0x08,0x9d,0x8b,0xa7,0x5f,0xc5,0x12,0xa9,0x2f,0x40,0xe2,0xd4,0x91,0x08,0x57,0x64,0x65,0x9a,0x66,0x52,0x8c,0xf5,0x7d,0xe3,0xb5,0x76,0x30,0x36,0xcc,0x99,0xe7,0xdd,0xb9,0x3a,0xd7,0x20,0xee,0x13,0x49,0xe3,0x1c,0x83,0xbd,0x33,0x01,0xba,0x62,0xaa,0xfb,0x56,0x1a,0xec,0xc9,0x9d,0x5c,0x50,0x6b,0x3e,0x94,0x1a,0x37,0x7c,0xa7,0xbb,0x57,0x25,0x30,0x51,0x76,0x34,0x41,0x56,0xae,0x73,0x98,0x5c,0x8a,0xc5,0x99,0x67,0x83,0xc4,0x13}, {0xb9,0xe1,0xb3,0x5a,0x46,0x5d,0x3a,0x42,0x61,0x3f,0xf1,0xc7,0x87,0xc1,0x13,0xfc,0xb6,0xb9,0xb5,0xec,0x64,0x36,0xf8,0x19,0x07,0xb6,0x37,0xa6,0x93,0x0c,0xf8,0x66,0x80,0xd0,0x8b,0x5d,0x6a,0xfb,0xdc,0xc4,0x42,0x48,0x1a,0x57,0xec,0xc4,0xeb,0xde,0x65,0x53,0xe5,0xb8,0x83,0xe8,0xb2,0xd4,0x27,0xb8,0xe5,0xc8,0x7d,0xc8,0xbd,0x50,0x11,0xe1,0xdf,0x6e,0x83,0x37,0x6d,0x60,0xd9,0xab,0x11,0xf0,0x15,0x3e,0x35,0x32,0x96,0x3b,0xb7,0x25,0xc3,0x3a,0xb0,0x64,0xae,0xd5,0x5f,0x72,0x44,0x64,0xd5,0x1d}, {0x7d,0x12,0x62,0x33,0xf8,0x7f,0xa4,0x8f,0x15,0x7c,0xcd,0x71,0xc4,0x6a,0x9f,0xbc,0x8b,0x0c,0x22,0x49,0x43,0x45,0x71,0x6e,0x2e,0x73,0x9f,0x21,0x12,0x59,0x64,0x0e,0x9a,0xc8,0xba,0x08,0x00,0xe6,0x97,0xc2,0xe0,0xc3,0xe1,0xea,0x11,0xea,0x4c,0x7d,0x7c,0x97,0xe7,0x9f,0xe1,0x8b,0xe3,0xf3,0xcd,0x05,0xa3,0x63,0x0f,0x45,0x3a,0x3a,0x27,0x46,0x39,0xd8,0x31,0x2f,0x8f,0x07,0x10,0xa5,0x94,0xde,0x83,0x31,0x9d,0x38,0x80,0x6f,0x99,0x17,0x6d,0x6c,0xe3,0xd1,0x7b,0xa8,0xa9,0x93,0x93,0x8d,0x8c,0x31}, {0x19,0xfe,0xff,0x2a,0x03,0x5d,0x74,0xf2,0x66,0xdb,0x24,0x7f,0x49,0x3c,0x9f,0x0c,0xef,0x98,0x85,0xba,0xe3,0xd3,0x98,0xbc,0x14,0x53,0x1d,0x9a,0x67,0x7c,0x4c,0x22,0x98,0xd3,0x1d,0xab,0x29,0x9e,0x66,0x5d,0x3b,0x9e,0x2d,0x34,0x58,0x16,0x92,0xfc,0xcd,0x73,0x59,0xf3,0xfd,0x1d,0x85,0x55,0xf6,0x0a,0x95,0x25,0xc3,0x41,0x9a,0x50,0xe9,0x25,0xf9,0xa6,0xdc,0x6e,0xc0,0xbd,0x33,0x1f,0x1b,0x64,0xf4,0xf3,0x3e,0x79,0x89,0x3e,0x83,0x9d,0x80,0x12,0xec,0x82,0x89,0x13,0xa1,0x28,0x23,0xf0,0xbf,0x05}, {0x0b,0xe0,0xca,0x23,0x70,0x13,0x32,0x36,0x59,0xcf,0xac,0xd1,0x0a,0xcf,0x4a,0x54,0x88,0x1c,0x1a,0xd2,0x49,0x10,0x74,0x96,0xa7,0x44,0x2a,0xfa,0xc3,0x8c,0x0b,0x78,0xe4,0x12,0xc5,0x0d,0xdd,0xa0,0x81,0x68,0xfe,0xfa,0xa5,0x44,0xc8,0x0d,0xe7,0x4f,0x40,0x52,0x4a,0x8f,0x6b,0x8e,0x74,0x1f,0xea,0xa3,0x01,0xee,0xcd,0x77,0x62,0x57,0x5f,0x30,0x4f,0x23,0xbc,0x8a,0xf3,0x1e,0x08,0xde,0x05,0x14,0xbd,0x7f,0x57,0x9a,0x0d,0x2a,0xe6,0x34,0x14,0xa5,0x82,0x5e,0xa1,0xb7,0x71,0x62,0x72,0x18,0xf4,0x5f}, {0x9d,0xdb,0x89,0x17,0x0c,0x08,0x8e,0x39,0xf5,0x78,0xe7,0xf3,0x25,0x20,0x60,0xa7,0x5d,0x03,0xbd,0x06,0x4c,0x89,0x98,0xfa,0xbe,0x66,0xa9,0x25,0xdc,0x03,0x6a,0x10,0x40,0x95,0xb6,0x13,0xe8,0x47,0xdb,0xe5,0xe1,0x10,0x26,0x43,0x3b,0x2a,0x5d,0xf3,0x76,0x12,0x78,0x38,0xe9,0x26,0x1f,0xac,0x69,0xcb,0xa0,0xa0,0x8c,0xdb,0xd4,0x29,0xd0,0x53,0x33,0x33,0xaf,0x0a,0xad,0xd9,0xe5,0x09,0xd3,0xac,0xa5,0x9d,0x66,0x38,0xf0,0xf7,0x88,0xc8,0x8a,0x65,0x57,0x3c,0xfa,0xbe,0x2c,0x05,0x51,0x8a,0xb3,0x4a}, {0x93,0xd5,0x68,0x67,0x25,0x2b,0x7c,0xda,0x13,0xca,0x22,0x44,0x57,0xc0,0xc1,0x98,0x1d,0xce,0x0a,0xca,0xd5,0x0b,0xa8,0xf1,0x90,0xa6,0x88,0xc0,0xad,0xd1,0xcd,0x29,0x9c,0xc0,0xdd,0x5f,0xef,0xd1,0xcf,0xd6,0xce,0x5d,0x57,0xf7,0xfd,0x3e,0x2b,0xe8,0xc2,0x34,0x16,0x20,0x5d,0x6b,0xd5,0x25,0x9b,0x2b,0xed,0x04,0xbb,0xc6,0x41,0x30,0x48,0xe1,0x56,0xd9,0xf9,0xf2,0xf2,0x0f,0x2e,0x6b,0x35,0x9f,0x75,0x97,0xe7,0xad,0x5c,0x02,0x6c,0x5f,0xbb,0x98,0x46,0x1a,0x7b,0x9a,0x04,0x14,0x68,0xbd,0x4b,0x10}, {0x67,0xed,0xf1,0x68,0x31,0xfd,0xf0,0x51,0xc2,0x3b,0x6f,0xd8,0xcd,0x1d,0x81,0x2c,0xde,0xf2,0xd2,0x04,0x43,0x5c,0xdc,0x44,0x49,0x71,0x2a,0x09,0x57,0xcc,0xe8,0x5b,0x63,0xf1,0x7f,0xd6,0x5f,0x9a,0x5d,0xa9,0x81,0x56,0xc7,0x4c,0x9d,0xe6,0x2b,0xe9,0x57,0xf2,0x20,0xde,0x4c,0x02,0xf8,0xb7,0xf5,0x2d,0x07,0xfb,0x20,0x2a,0x4f,0x20,0x79,0xb0,0xeb,0x30,0x3d,0x3b,0x14,0xc8,0x30,0x2e,0x65,0xbd,0x5a,0x15,0x89,0x75,0x31,0x5c,0x6d,0x8f,0x31,0x3c,0x3c,0x65,0x1f,0x16,0x79,0xc2,0x17,0xfb,0x70,0x25}, {0x75,0x15,0xb6,0x2c,0x7f,0x36,0xfa,0x3e,0x6c,0x02,0xd6,0x1c,0x76,0x6f,0xf9,0xf5,0x62,0x25,0xb5,0x65,0x2a,0x14,0xc7,0xe8,0xcd,0x0a,0x03,0x53,0xea,0x65,0xcb,0x3d,0x5a,0x24,0xb8,0x0b,0x55,0xa9,0x2e,0x19,0xd1,0x50,0x90,0x8f,0xa8,0xfb,0xe6,0xc8,0x35,0xc9,0xa4,0x88,0x2d,0xea,0x86,0x79,0x68,0x86,0x01,0xde,0x91,0x5f,0x1c,0x24,0xaa,0x6c,0xde,0x40,0x29,0x17,0xd8,0x28,0x3a,0x73,0xd9,0x22,0xf0,0x2c,0xbf,0x8f,0xd1,0x01,0x5b,0x23,0xdd,0xfc,0xd7,0x16,0xe5,0xf0,0xcd,0x5f,0xdd,0x0e,0x42,0x08}, {0x4a,0xfa,0x62,0x83,0xab,0x20,0xff,0xcd,0x6e,0x3e,0x1a,0xe2,0xd4,0x18,0xe1,0x57,0x2b,0xe6,0x39,0xfc,0x17,0x96,0x17,0xe3,0xfd,0x69,0x17,0xbc,0xef,0x53,0x9a,0x0d,0xce,0x10,0xf4,0x04,0x4e,0xc3,0x58,0x03,0x85,0x06,0x6e,0x27,0x5a,0x5b,0x13,0xb6,0x21,0x15,0xb9,0xeb,0xc7,0x70,0x96,0x5d,0x9c,0x88,0xdb,0x21,0xf3,0x54,0xd6,0x04,0xd5,0xb5,0xbd,0xdd,0x16,0xc1,0x7d,0x5e,0x2d,0xdd,0xa5,0x8d,0xb6,0xde,0x54,0x29,0x92,0xa2,0x34,0x33,0x17,0x08,0xb6,0x1c,0xd7,0x1a,0x99,0x18,0x26,0x4f,0x7a,0x4a}, {0x95,0x5f,0xb1,0x5f,0x02,0x18,0xa7,0xf4,0x8f,0x1b,0x5c,0x6b,0x34,0x5f,0xf6,0x3d,0x12,0x11,0xe0,0x00,0x85,0xf0,0xfc,0xcd,0x48,0x18,0xd3,0xdd,0x4c,0x0c,0xb5,0x11,0x4b,0x2a,0x37,0xaf,0x91,0xb2,0xc3,0x24,0xf2,0x47,0x81,0x71,0x70,0x82,0xda,0x93,0xf2,0x9e,0x89,0x86,0x64,0x85,0x84,0xdd,0x33,0xee,0xe0,0x23,0x42,0x31,0x96,0x4a,0xd6,0xff,0xa4,0x08,0x44,0x27,0xe8,0xa6,0xd9,0x76,0x15,0x9c,0x7e,0x17,0x8e,0x73,0xf2,0xb3,0x02,0x3d,0xb6,0x48,0x33,0x77,0x51,0xcc,0x6b,0xce,0x4d,0xce,0x4b,0x4f}, {0x84,0x25,0x24,0xe2,0x5a,0xce,0x1f,0xa7,0x9e,0x8a,0xf5,0x92,0x56,0x72,0xea,0x26,0xf4,0x3c,0xea,0x1c,0xd7,0x09,0x1a,0xd2,0xe6,0x01,0x1c,0xb7,0x14,0xdd,0xfc,0x73,0x6f,0x0b,0x9d,0xc4,0x6e,0x61,0xe2,0x30,0x17,0x23,0xec,0xca,0x8f,0x71,0x56,0xe4,0xa6,0x4f,0x6b,0xf2,0x9b,0x40,0xeb,0x48,0x37,0x5f,0x59,0x61,0xe5,0xce,0x42,0x30,0x41,0xac,0x9b,0x44,0x79,0x70,0x7e,0x42,0x0a,0x31,0xe2,0xbc,0x6d,0xe3,0x5a,0x85,0x7c,0x1a,0x84,0x5f,0x21,0x76,0xae,0x4c,0xd6,0xe1,0x9c,0x9a,0x0c,0x74,0x9e,0x38}, {0xce,0xb9,0xdc,0x34,0xae,0xb3,0xfc,0x64,0xad,0xd0,0x48,0xe3,0x23,0x03,0x50,0x97,0x1b,0x38,0xc6,0x62,0x7d,0xf0,0xb3,0x45,0x88,0x67,0x5a,0x46,0x79,0x53,0x54,0x61,0x28,0xac,0x0e,0x57,0xf6,0x78,0xbd,0xc9,0xe1,0x9c,0x91,0x27,0x32,0x0b,0x5b,0xe5,0xed,0x91,0x9b,0xa1,0xab,0x3e,0xfc,0x65,0x90,0x36,0x26,0xd6,0xe5,0x25,0xc4,0x25,0x6e,0xde,0xd7,0xf1,0xa6,0x06,0x3e,0x3f,0x08,0x23,0x06,0x8e,0x27,0x76,0xf9,0x3e,0x77,0x6c,0x8a,0x4e,0x26,0xf6,0x14,0x8c,0x59,0x47,0x48,0x15,0x89,0xa0,0x39,0x65}, {0x73,0xf7,0xd2,0xc3,0x74,0x1f,0xd2,0xe9,0x45,0x68,0xc4,0x25,0x41,0x54,0x50,0xc1,0x33,0x9e,0xb9,0xf9,0xe8,0x5c,0x4e,0x62,0x6c,0x18,0xcd,0xc5,0xaa,0xe4,0xc5,0x11,0x19,0x4a,0xbb,0x14,0xd4,0xdb,0xc4,0xdd,0x8e,0x4f,0x42,0x98,0x3c,0xbc,0xb2,0x19,0x69,0x71,0xca,0x36,0xd7,0x9f,0xa8,0x48,0x90,0xbd,0x19,0xf0,0x0e,0x32,0x65,0x0f,0xc6,0xe0,0xfd,0xca,0xb1,0xd1,0x86,0xd4,0x81,0x51,0x3b,0x16,0xe3,0xe6,0x3f,0x4f,0x9a,0x93,0xf2,0xfa,0x0d,0xaf,0xa8,0x59,0x2a,0x07,0x33,0xec,0xbd,0xc7,0xab,0x4c}, {0x2e,0x0a,0x9c,0x08,0x24,0x96,0x9e,0x23,0x38,0x47,0xfe,0x3a,0xc0,0xc4,0x48,0xc7,0x2a,0xa1,0x4f,0x76,0x2a,0xed,0xdb,0x17,0x82,0x85,0x1c,0x32,0xf0,0x93,0x9b,0x63,0x89,0xd2,0x78,0x3f,0x8f,0x78,0x8f,0xc0,0x9f,0x4d,0x40,0xa1,0x2c,0xa7,0x30,0xfe,0x9d,0xcc,0x65,0xcf,0xfc,0x8b,0x77,0xf2,0x21,0x20,0xcb,0x5a,0x16,0x98,0xe4,0x7e,0xc3,0xa1,0x11,0x91,0xe3,0x08,0xd5,0x7b,0x89,0x74,0x90,0x80,0xd4,0x90,0x2b,0x2b,0x19,0xfd,0x72,0xae,0xc2,0xae,0xd2,0xe7,0xa6,0x02,0xb6,0x85,0x3c,0x49,0xdf,0x0e}, {0x68,0x5a,0x9b,0x59,0x58,0x81,0xcc,0xae,0x0e,0xe2,0xad,0xeb,0x0f,0x4f,0x57,0xea,0x07,0x7f,0xb6,0x22,0x74,0x1d,0xe4,0x4f,0xb4,0x4f,0x9d,0x01,0xe3,0x92,0x3b,0x40,0x13,0x41,0x76,0x84,0xd2,0xc4,0x67,0x67,0x35,0xf8,0xf5,0xf7,0x3f,0x40,0x90,0xa0,0xde,0xbe,0xe6,0xca,0xfa,0xcf,0x8f,0x1c,0x69,0xa3,0xdf,0xd1,0x54,0x0c,0xc0,0x04,0xf8,0x5c,0x46,0x8b,0x81,0x2f,0xc2,0x4d,0xf8,0xef,0x80,0x14,0x5a,0xf3,0xa0,0x71,0x57,0xd6,0xc7,0x04,0xad,0xbf,0xe8,0xae,0xf4,0x76,0x61,0xb2,0x2a,0xb1,0x5b,0x35}, {0xf4,0xbb,0x93,0x74,0xcc,0x64,0x1e,0xa7,0xc3,0xb0,0xa3,0xec,0xd9,0x84,0xbd,0xe5,0x85,0xe7,0x05,0xfa,0x0c,0xc5,0x6b,0x0a,0x12,0xc3,0x2e,0x18,0x32,0x81,0x9b,0x0f,0x18,0x73,0x8c,0x5a,0xc7,0xda,0x01,0xa3,0x11,0xaa,0xce,0xb3,0x9d,0x03,0x90,0xed,0x2d,0x3f,0xae,0x3b,0xbf,0x7c,0x07,0x6f,0x8e,0xad,0x52,0xe0,0xf8,0xea,0x18,0x75,0x32,0x6c,0x7f,0x1b,0xc4,0x59,0x88,0xa4,0x98,0x32,0x38,0xf4,0xbc,0x60,0x2d,0x0f,0xd9,0xd1,0xb1,0xc9,0x29,0xa9,0x15,0x18,0xc4,0x55,0x17,0xbb,0x1b,0x87,0xc3,0x47}, {0x48,0x4f,0xec,0x71,0x97,0x53,0x44,0x51,0x6e,0x5d,0x8c,0xc9,0x7d,0xb1,0x05,0xf8,0x6b,0xc6,0xc3,0x47,0x1a,0xc1,0x62,0xf7,0xdc,0x99,0x46,0x76,0x85,0x9b,0xb8,0x00,0xb0,0x66,0x50,0xc8,0x50,0x5d,0xe6,0xfb,0xb0,0x99,0xa2,0xb3,0xb0,0xc4,0xec,0x62,0xe0,0xe8,0x1a,0x44,0xea,0x54,0x37,0xe5,0x5f,0x8d,0xd4,0xe8,0x2c,0xa0,0xfe,0x08,0xd0,0xea,0xde,0x68,0x76,0xdd,0x4d,0x82,0x23,0x5d,0x68,0x4b,0x20,0x45,0x64,0xc8,0x65,0xd6,0x89,0x5d,0xcd,0xcf,0x14,0xb5,0x37,0xd5,0x75,0x4f,0xa7,0x29,0x38,0x47}, {0x18,0xc4,0x79,0x46,0x75,0xda,0xd2,0x82,0xf0,0x8d,0x61,0xb2,0xd8,0xd7,0x3b,0xe6,0x0a,0xeb,0x47,0xac,0x24,0xef,0x5e,0x35,0xb4,0xc6,0x33,0x48,0x4c,0x68,0x78,0x20,0xc9,0x02,0x39,0xad,0x3a,0x53,0xd9,0x23,0x8f,0x58,0x03,0xef,0xce,0xdd,0xc2,0x64,0xb4,0x2f,0xe1,0xcf,0x90,0x73,0x25,0x15,0x90,0xd3,0xe4,0x44,0x4d,0x8b,0x66,0x6c,0x0c,0x82,0x78,0x7a,0x21,0xcf,0x48,0x3b,0x97,0x3e,0x27,0x81,0xb2,0x0a,0x6a,0xf7,0x7b,0xed,0x8e,0x8c,0xa7,0x65,0x6c,0xa9,0x3f,0x43,0x8a,0x4f,0x05,0xa6,0x11,0x74}, {0x6d,0xc8,0x9d,0xb9,0x32,0x9d,0x65,0x4d,0x15,0xf1,0x3a,0x60,0x75,0xdc,0x4c,0x04,0x88,0xe4,0xc2,0xdc,0x2c,0x71,0x4c,0xb3,0xff,0x34,0x81,0xfb,0x74,0x65,0x13,0x7c,0xb4,0x75,0xb1,0x18,0x3d,0xe5,0x9a,0x57,0x02,0xa1,0x92,0xf3,0x59,0x31,0x71,0x68,0xf5,0x35,0xef,0x1e,0xba,0xec,0x55,0x84,0x8f,0x39,0x8c,0x45,0x72,0xa8,0xc9,0x1e,0x9b,0x50,0xa2,0x00,0xd4,0xa4,0xe6,0xb8,0xb4,0x82,0xc8,0x0b,0x02,0xd7,0x81,0x9b,0x61,0x75,0x95,0xf1,0x9b,0xcc,0xe7,0x57,0x60,0x64,0xcd,0xc7,0xa5,0x88,0xdd,0x3a}, {0xf2,0xdc,0x35,0xb6,0x70,0x57,0x89,0xab,0xbc,0x1f,0x6c,0xf6,0x6c,0xef,0xdf,0x02,0x87,0xd1,0xb6,0xbe,0x68,0x02,0x53,0x85,0x74,0x9e,0x87,0xcc,0xfc,0x29,0x99,0x24,0x46,0x30,0x39,0x59,0xd4,0x98,0xc2,0x85,0xec,0x59,0xf6,0x5f,0x98,0x35,0x7e,0x8f,0x3a,0x6e,0xf6,0xf2,0x2a,0xa2,0x2c,0x1d,0x20,0xa7,0x06,0xa4,0x31,0x11,0xba,0x61,0x29,0x90,0x95,0x16,0xf1,0xa0,0xd0,0xa3,0x89,0xbd,0x7e,0xba,0x6c,0x6b,0x3b,0x02,0x07,0x33,0x78,0x26,0x3e,0x5a,0xf1,0x7b,0xe7,0xec,0xd8,0xbb,0x0c,0x31,0x20,0x56}, {0x43,0xd6,0x34,0x49,0x43,0x93,0x89,0x52,0xf5,0x22,0x12,0xa5,0x06,0xf8,0xdb,0xb9,0x22,0x1c,0xf4,0xc3,0x8f,0x87,0x6d,0x8f,0x30,0x97,0x9d,0x4d,0x2a,0x6a,0x67,0x37,0xd6,0x85,0xe2,0x77,0xf4,0xb5,0x46,0x66,0x93,0x61,0x8f,0x6c,0x67,0xff,0xe8,0x40,0xdd,0x94,0xb5,0xab,0x11,0x73,0xec,0xa6,0x4d,0xec,0x8c,0x65,0xf3,0x46,0xc8,0x7e,0xc7,0x2e,0xa2,0x1d,0x3f,0x8f,0x5e,0x9b,0x13,0xcd,0x01,0x6c,0x77,0x1d,0x0f,0x13,0xb8,0x9f,0x98,0xa2,0xcf,0x8f,0x4c,0x21,0xd5,0x9d,0x9b,0x39,0x23,0xf7,0xaa,0x6d}, {0x47,0xbe,0x3d,0xeb,0x62,0x75,0x3a,0x5f,0xb8,0xa0,0xbd,0x8e,0x54,0x38,0xea,0xf7,0x99,0x72,0x74,0x45,0x31,0xe5,0xc3,0x00,0x51,0xd5,0x27,0x16,0xe7,0xe9,0x04,0x13,0xa2,0x8e,0xad,0xac,0xbf,0x04,0x3b,0x58,0x84,0xe8,0x8b,0x14,0xe8,0x43,0xb7,0x29,0xdb,0xc5,0x10,0x08,0x3b,0x58,0x1e,0x2b,0xaa,0xbb,0xb3,0x8e,0xe5,0x49,0x54,0x2b,0xfe,0x9c,0xdc,0x6a,0xd2,0x14,0x98,0x78,0x0b,0xdd,0x48,0x8b,0x3f,0xab,0x1b,0x3c,0x0a,0xc6,0x79,0xf9,0xff,0xe1,0x0f,0xda,0x93,0xd6,0x2d,0x7c,0x2d,0xde,0x68,0x44}, {0x9e,0x46,0x19,0x94,0x5e,0x35,0xbb,0x51,0x54,0xc7,0xdd,0x23,0x4c,0xdc,0xe6,0x33,0x62,0x99,0x7f,0x44,0xd6,0xb6,0xa5,0x93,0x63,0xbd,0x44,0xfb,0x6f,0x7c,0xce,0x6c,0xce,0x07,0x63,0xf8,0xc6,0xd8,0x9a,0x4b,0x28,0x0c,0x5d,0x43,0x31,0x35,0x11,0x21,0x2c,0x77,0x7a,0x65,0xc5,0x66,0xa8,0xd4,0x52,0x73,0x24,0x63,0x7e,0x42,0xa6,0x5d,0xca,0x22,0xac,0xde,0x88,0xc6,0x94,0x1a,0xf8,0x1f,0xae,0xbb,0xf7,0x6e,0x06,0xb9,0x0f,0x58,0x59,0x8d,0x38,0x8c,0xad,0x88,0xa8,0x2c,0x9f,0xe7,0xbf,0x9a,0xf2,0x58}, {0x68,0x3e,0xe7,0x8d,0xab,0xcf,0x0e,0xe9,0xa5,0x76,0x7e,0x37,0x9f,0x6f,0x03,0x54,0x82,0x59,0x01,0xbe,0x0b,0x5b,0x49,0xf0,0x36,0x1e,0xf4,0xa7,0xc4,0x29,0x76,0x57,0xf6,0xcd,0x0e,0x71,0xbf,0x64,0x5a,0x4b,0x3c,0x29,0x2c,0x46,0x38,0xe5,0x4c,0xb1,0xb9,0x3a,0x0b,0xd5,0x56,0xd0,0x43,0x36,0x70,0x48,0x5b,0x18,0x24,0x37,0xf9,0x6a,0x88,0xa8,0xc6,0x09,0x45,0x02,0x20,0x32,0x73,0x89,0x55,0x4b,0x13,0x36,0xe0,0xd2,0x9f,0x28,0x33,0x3c,0x23,0x36,0xe2,0x83,0x8f,0xc1,0xae,0x0c,0xbb,0x25,0x1f,0x70}, {0xed,0x6c,0x61,0xe4,0xf8,0xb0,0xa8,0xc3,0x7d,0xa8,0x25,0x9e,0x0e,0x66,0x00,0xf7,0x9c,0xa5,0xbc,0xf4,0x1f,0x06,0xe3,0x61,0xe9,0x0b,0xc4,0xbd,0xbf,0x92,0x0c,0x2e,0x13,0xc1,0xbe,0x7c,0xd9,0xf6,0x18,0x9d,0xe4,0xdb,0xbf,0x74,0xe6,0x06,0x4a,0x84,0xd6,0x60,0x4e,0xac,0x22,0xb5,0xf5,0x20,0x51,0x5e,0x95,0x50,0xc0,0x5b,0x0a,0x72,0x35,0x5a,0x80,0x9b,0x43,0x09,0x3f,0x0c,0xfc,0xab,0x42,0x62,0x37,0x8b,0x4e,0xe8,0x46,0x93,0x22,0x5c,0xf3,0x17,0x14,0x69,0xec,0xf0,0x4e,0x14,0xbb,0x9c,0x9b,0x0e}, {0xad,0x20,0x57,0xfb,0x8f,0xd4,0xba,0xfb,0x0e,0x0d,0xf9,0xdb,0x6b,0x91,0x81,0xee,0xbf,0x43,0x55,0x63,0x52,0x31,0x81,0xd4,0xd8,0x7b,0x33,0x3f,0xeb,0x04,0x11,0x22,0xee,0xbe,0xb1,0x5d,0xd5,0x9b,0xee,0x8d,0xb9,0x3f,0x72,0x0a,0x37,0xab,0xc3,0xc9,0x91,0xd7,0x68,0x1c,0xbf,0xf1,0xa8,0x44,0xde,0x3c,0xfd,0x1c,0x19,0x44,0x6d,0x36,0x14,0x8c,0xbc,0xf2,0x43,0x17,0x3c,0x9e,0x3b,0x6c,0x85,0xb5,0xfc,0x26,0xda,0x2e,0x97,0xfb,0xa7,0x68,0x0e,0x2f,0xb8,0xcc,0x44,0x32,0x59,0xbc,0xe6,0xa4,0x67,0x41}, {0x00,0x27,0xf6,0x76,0x28,0x9d,0x3b,0x64,0xeb,0x68,0x76,0x0e,0x40,0x9d,0x1d,0x5d,0x84,0x06,0xfc,0x21,0x03,0x43,0x4b,0x1b,0x6a,0x24,0x55,0x22,0x7e,0xbb,0x38,0x79,0xee,0x8f,0xce,0xf8,0x65,0x26,0xbe,0xc2,0x2c,0xd6,0x80,0xe8,0x14,0xff,0x67,0xe9,0xee,0x4e,0x36,0x2f,0x7e,0x6e,0x2e,0xf1,0xf6,0xd2,0x7e,0xcb,0x70,0x33,0xb3,0x34,0xcc,0xd6,0x81,0x86,0xee,0x91,0xc5,0xcd,0x53,0xa7,0x85,0xed,0x9c,0x10,0x02,0xce,0x83,0x88,0x80,0x58,0xc1,0x85,0x74,0xed,0xe4,0x65,0xfe,0x2d,0x6e,0xfc,0x76,0x11}, {0x9b,0x61,0x9c,0x5b,0xd0,0x6c,0xaf,0xb4,0x80,0x84,0xa5,0xb2,0xf4,0xc9,0xdf,0x2d,0xc4,0x4d,0xe9,0xeb,0x02,0xa5,0x4f,0x3d,0x34,0x5f,0x7d,0x67,0x4c,0x3a,0xfc,0x08,0xb8,0x0e,0x77,0x49,0x89,0xe2,0x90,0xdb,0xa3,0x40,0xf4,0xac,0x2a,0xcc,0xfb,0x98,0x9b,0x87,0xd7,0xde,0xfe,0x4f,0x35,0x21,0xb6,0x06,0x69,0xf2,0x54,0x3e,0x6a,0x1f,0xea,0x34,0x07,0xd3,0x99,0xc1,0xa4,0x60,0xd6,0x5c,0x16,0x31,0xb6,0x85,0xc0,0x40,0x95,0x82,0x59,0xf7,0x23,0x3e,0x33,0xe2,0xd1,0x00,0xb9,0x16,0x01,0xad,0x2f,0x4f}, {0x54,0x4e,0xae,0x94,0x41,0xb2,0xbe,0x44,0x6c,0xef,0x57,0x18,0x51,0x1c,0x54,0x5f,0x98,0x04,0x8d,0x36,0x2d,0x6b,0x1e,0xa6,0xab,0xf7,0x2e,0x97,0xa4,0x84,0x54,0x44,0x38,0xb6,0x3b,0xb7,0x1d,0xd9,0x2c,0x96,0x08,0x9c,0x12,0xfc,0xaa,0x77,0x05,0xe6,0x89,0x16,0xb6,0xf3,0x39,0x9b,0x61,0x6f,0x81,0xee,0x44,0x29,0x5f,0x99,0x51,0x34,0x7c,0x7d,0xea,0x9f,0xd0,0xfc,0x52,0x91,0xf6,0x5c,0x93,0xb0,0x94,0x6c,0x81,0x4a,0x40,0x5c,0x28,0x47,0xaa,0x9a,0x8e,0x25,0xb7,0x93,0x28,0x04,0xa6,0x9c,0xb8,0x10}, {0x9c,0x28,0x18,0x97,0x49,0x47,0x59,0x3d,0x26,0x3f,0x53,0x24,0xc5,0xf8,0xeb,0x12,0x15,0xef,0xc3,0x14,0xcb,0xbf,0x62,0x02,0x8e,0x51,0xb7,0x77,0xd5,0x78,0xb8,0x20,0x6e,0xf0,0x45,0x5a,0xbe,0x41,0x39,0x75,0x65,0x5f,0x9c,0x6d,0xed,0xae,0x7c,0xd0,0xb6,0x51,0xff,0x72,0x9c,0x6b,0x77,0x11,0xa9,0x4d,0x0d,0xef,0xd9,0xd1,0xd2,0x17,0x6a,0x3e,0x3f,0x07,0x18,0xaf,0xf2,0x27,0x69,0x10,0x52,0xd7,0x19,0xe5,0x3f,0xfd,0x22,0x00,0xa6,0x3c,0x2c,0xb7,0xe3,0x22,0xa7,0xc6,0x65,0xcc,0x63,0x4f,0x21,0x72}, {0x93,0xa6,0x07,0x53,0x40,0x7f,0xe3,0xb4,0x95,0x67,0x33,0x2f,0xd7,0x14,0xa7,0xab,0x99,0x10,0x76,0x73,0xa7,0xd0,0xfb,0xd6,0xc9,0xcb,0x71,0x81,0xc5,0x48,0xdf,0x5f,0xc9,0x29,0x3b,0xf4,0xb9,0xb7,0x9d,0x1d,0x75,0x8f,0x51,0x4f,0x4a,0x82,0x05,0xd6,0xc4,0x9d,0x2f,0x31,0xbd,0x72,0xc0,0xf2,0xb0,0x45,0x15,0x5a,0x85,0xac,0x24,0x1f,0xaa,0x05,0x95,0x8e,0x32,0x08,0xd6,0x24,0xee,0x20,0x14,0x0c,0xd1,0xc1,0x48,0x47,0xa2,0x25,0xfb,0x06,0x5c,0xe4,0xff,0xc7,0xe6,0x95,0xe3,0x2a,0x9e,0x73,0xba,0x00}, {0xd6,0x90,0x87,0x5c,0xde,0x98,0x2e,0x59,0xdf,0xa2,0xc2,0x45,0xd3,0xb7,0xbf,0xe5,0x22,0x99,0xb4,0xf9,0x60,0x3b,0x5a,0x11,0xf3,0x78,0xad,0x67,0x3e,0x3a,0x28,0x03,0x26,0xbb,0x88,0xea,0xf5,0x26,0x44,0xae,0xfb,0x3b,0x97,0x84,0xd9,0x79,0x06,0x36,0x50,0x4e,0x69,0x26,0x0c,0x03,0x9f,0x5c,0x26,0xd2,0x18,0xd5,0xe7,0x7d,0x29,0x72,0x39,0xb9,0x0c,0xbe,0xc7,0x1d,0x24,0x48,0x80,0x30,0x63,0x8b,0x4d,0x9b,0xf1,0x32,0x08,0x93,0x28,0x02,0x0d,0xc9,0xdf,0xd3,0x45,0x19,0x27,0x46,0x68,0x29,0xe1,0x05}, {0x5a,0x49,0x9c,0x2d,0xb3,0xee,0x82,0xba,0x7c,0xb9,0x2b,0xf1,0xfc,0xc8,0xef,0xce,0xe0,0xd1,0xb5,0x93,0xae,0xab,0x2d,0xb0,0x9b,0x8d,0x69,0x13,0x9c,0x0c,0xc0,0x39,0x50,0x45,0x2c,0x24,0xc8,0xbb,0xbf,0xad,0xd9,0x81,0x30,0xd0,0xec,0x0c,0xc8,0xbc,0x92,0xdf,0xc8,0xf5,0xa6,0x66,0x35,0x84,0x4c,0xce,0x58,0x82,0xd3,0x25,0xcf,0x78,0x68,0x9d,0x48,0x31,0x8e,0x6b,0xae,0x15,0x87,0xf0,0x2b,0x9c,0xab,0x1c,0x85,0xaa,0x05,0xfa,0x4e,0xf0,0x97,0x5a,0xa7,0xc9,0x32,0xf8,0x3f,0x6b,0x07,0x52,0x6b,0x00}, {0x1c,0x78,0x95,0x9d,0xe1,0xcf,0xe0,0x29,0xe2,0x10,0x63,0x96,0x18,0xdf,0x81,0xb6,0x39,0x6b,0x51,0x70,0xd3,0x39,0xdf,0x57,0x22,0x61,0xc7,0x3b,0x44,0xe3,0x57,0x4d,0x2d,0x08,0xce,0xb9,0x16,0x7e,0xcb,0xf5,0x29,0xbc,0x7a,0x41,0x4c,0xf1,0x07,0x34,0xab,0xa7,0xf4,0x2b,0xce,0x6b,0xb3,0xd4,0xce,0x75,0x9f,0x1a,0x56,0xe9,0xe2,0x7d,0xcb,0x5e,0xa5,0xb6,0xf4,0xd4,0x70,0xde,0x99,0xdb,0x85,0x5d,0x7f,0x52,0x01,0x48,0x81,0x9a,0xee,0xd3,0x40,0xc4,0xc9,0xdb,0xed,0x29,0x60,0x1a,0xaf,0x90,0x2a,0x6b}, {0x97,0x1e,0xe6,0x9a,0xfc,0xf4,0x23,0x69,0xd1,0x5f,0x3f,0xe0,0x1d,0x28,0x35,0x57,0x2d,0xd1,0xed,0xe6,0x43,0xae,0x64,0xa7,0x4a,0x3e,0x2d,0xd1,0xe9,0xf4,0xd8,0x5f,0x0a,0xd8,0xb2,0x5b,0x24,0xf3,0xeb,0x77,0x9b,0x07,0xb9,0x2f,0x47,0x1b,0x30,0xd8,0x33,0x73,0xee,0x4c,0xf2,0xe6,0x47,0xc6,0x09,0x21,0x6c,0x27,0xc8,0x12,0x58,0x46,0xd9,0x62,0x10,0x2a,0xb2,0xbe,0x43,0x4d,0x16,0xdc,0x31,0x38,0x75,0xfb,0x65,0x70,0xd7,0x68,0x29,0xde,0x7b,0x4a,0x0d,0x18,0x90,0x67,0xb1,0x1c,0x2b,0x2c,0xb3,0x05}, {0xfd,0xa8,0x4d,0xd2,0xcc,0x5e,0xc0,0xc8,0x83,0xef,0xdf,0x05,0xac,0x1a,0xcf,0xa1,0x61,0xcd,0xf9,0x7d,0xf2,0xef,0xbe,0xdb,0x99,0x1e,0x47,0x7b,0xa3,0x56,0x55,0x3b,0x95,0x81,0xd5,0x7a,0x2c,0xa4,0xfc,0xf7,0xcc,0xf3,0x33,0x43,0x6e,0x28,0x14,0x32,0x9d,0x97,0x0b,0x34,0x0d,0x9d,0xc2,0xb6,0xe1,0x07,0x73,0x56,0x48,0x1a,0x77,0x31,0x82,0xd4,0x4d,0xe1,0x24,0xc5,0xb0,0x32,0xb6,0xa4,0x2b,0x1a,0x54,0x51,0xb3,0xed,0xf3,0x5a,0x2b,0x28,0x48,0x60,0xd1,0xa3,0xeb,0x36,0x73,0x7a,0xd2,0x79,0xc0,0x4f}, {0x7f,0x2f,0xbf,0x89,0xb0,0x38,0xc9,0x51,0xa7,0xe9,0xdf,0x02,0x65,0xbd,0x97,0x24,0x53,0xe4,0x80,0x78,0x9c,0xc0,0xff,0xff,0x92,0x8e,0xf9,0xca,0xce,0x67,0x45,0x12,0x0d,0xc5,0x86,0x0c,0x44,0x8b,0x34,0xdc,0x51,0xe6,0x94,0xcc,0xc9,0xcb,0x37,0x13,0xb9,0x3c,0x3e,0x64,0x4d,0xf7,0x22,0x64,0x08,0xcd,0xe3,0xba,0xc2,0x70,0x11,0x24,0xb4,0x73,0xc4,0x0a,0x86,0xab,0xf9,0x3f,0x35,0xe4,0x13,0x01,0xee,0x1d,0x91,0xf0,0xaf,0xc4,0xc6,0xeb,0x60,0x50,0xe7,0x4a,0x0d,0x00,0x87,0x6c,0x96,0x12,0x86,0x3f}, {0xde,0x0d,0x2a,0x78,0xc9,0x0c,0x9a,0x55,0x85,0x83,0x71,0xea,0xb2,0xcd,0x1d,0x55,0x8c,0x23,0xef,0x31,0x5b,0x86,0x62,0x7f,0x3d,0x61,0x73,0x79,0x76,0xa7,0x4a,0x50,0x13,0x8d,0x04,0x36,0xfa,0xfc,0x18,0x9c,0xdd,0x9d,0x89,0x73,0xb3,0x9d,0x15,0x29,0xaa,0xd0,0x92,0x9f,0x0b,0x35,0x9f,0xdc,0xd4,0x19,0x8a,0x87,0xee,0x7e,0xf5,0x26,0xb1,0xef,0x87,0x56,0xd5,0x2c,0xab,0x0c,0x7b,0xf1,0x7a,0x24,0x62,0xd1,0x80,0x51,0x67,0x24,0x5a,0x4f,0x34,0x5a,0xc1,0x85,0x69,0x30,0xba,0x9d,0x3d,0x94,0x41,0x40}, {0x96,0xcc,0xeb,0x43,0xba,0xee,0xc0,0xc3,0xaf,0x9c,0xea,0x26,0x9c,0x9c,0x74,0x8d,0xc6,0xcc,0x77,0x1c,0xee,0x95,0xfa,0xd9,0x0f,0x34,0x84,0x76,0xd9,0xa1,0x20,0x14,0xdd,0xaa,0x6c,0xa2,0x43,0x77,0x21,0x4b,0xce,0xb7,0x8a,0x64,0x24,0xb4,0xa6,0x47,0xe3,0xc9,0xfb,0x03,0x7a,0x4f,0x1d,0xcb,0x19,0xd0,0x00,0x98,0x42,0x31,0xd9,0x12,0x4f,0x59,0x37,0xd3,0x99,0x77,0xc6,0x00,0x7b,0xa4,0x3a,0xb2,0x40,0x51,0x3c,0x5e,0x95,0xf3,0x5f,0xe3,0x54,0x28,0x18,0x44,0x12,0xa0,0x59,0x43,0x31,0x92,0x4f,0x1b}, {0x51,0x09,0x15,0x89,0x9d,0x10,0x5c,0x3e,0x6a,0x69,0xe9,0x2d,0x91,0xfa,0xce,0x39,0x20,0x30,0x5f,0x97,0x3f,0xe4,0xea,0x20,0xae,0x2d,0x13,0x7f,0x2a,0x57,0x9b,0x23,0xb1,0x66,0x98,0xa4,0x30,0x30,0xcf,0x33,0x59,0x48,0x5f,0x21,0xd2,0x73,0x1f,0x25,0xf6,0xf4,0xde,0x51,0x40,0xaa,0x82,0xab,0xf6,0x23,0x9a,0x6f,0xd5,0x91,0xf1,0x5f,0x68,0x90,0x2d,0xac,0x33,0xd4,0x9e,0x81,0x23,0x85,0xc9,0x5f,0x79,0xab,0x83,0x28,0x3d,0xeb,0x93,0x55,0x80,0x72,0x45,0xef,0xcb,0x36,0x8f,0x75,0x6a,0x52,0x0c,0x02}, {0xbc,0xdb,0xd8,0x9e,0xf8,0x34,0x98,0x77,0x6c,0xa4,0x7c,0xdc,0xf9,0xaa,0xf2,0xc8,0x74,0xb0,0xe1,0xa3,0xdc,0x4c,0x52,0xa9,0x77,0x38,0x31,0x15,0x46,0xcc,0xaa,0x02,0x89,0xcc,0x42,0xf0,0x59,0xef,0x31,0xe9,0xb6,0x4b,0x12,0x8e,0x9d,0x9c,0x58,0x2c,0x97,0x59,0xc7,0xae,0x8a,0xe1,0xc8,0xad,0x0c,0xc5,0x02,0x56,0x0a,0xfe,0x2c,0x45,0xdf,0x77,0x78,0x64,0xa0,0xf7,0xa0,0x86,0x9f,0x7c,0x60,0x0e,0x27,0x64,0xc4,0xbb,0xc9,0x11,0xfb,0xf1,0x25,0xea,0x17,0xab,0x7b,0x87,0x4b,0x30,0x7b,0x7d,0xfb,0x4c}, {0xfe,0x75,0x9b,0xb8,0x6c,0x3d,0xb4,0x72,0x80,0xdc,0x6a,0x9c,0xd9,0x94,0xc6,0x54,0x9f,0x4c,0xe3,0x3e,0x37,0xaa,0xc3,0xb8,0x64,0x53,0x07,0x39,0x2b,0x62,0xb4,0x14,0x12,0xef,0x89,0x97,0xc2,0x99,0x86,0xe2,0x0d,0x19,0x57,0xdf,0x71,0xcd,0x6e,0x2b,0xd0,0x70,0xc9,0xec,0x57,0xc8,0x43,0xc3,0xc5,0x3a,0x4d,0x43,0xbc,0x4c,0x1d,0x5b,0x26,0x9f,0x0a,0xcc,0x15,0x26,0xfb,0xb6,0xe5,0xcc,0x8d,0xb8,0x2b,0x0e,0x4f,0x3a,0x05,0xa7,0x69,0x33,0x8b,0x49,0x01,0x13,0xd1,0x2d,0x59,0x58,0x12,0xf7,0x98,0x2f}, {0x56,0x9e,0x0f,0xb5,0x4c,0xa7,0x94,0x0c,0x20,0x13,0x8e,0x8e,0xa9,0xf4,0x1f,0x5b,0x67,0x0f,0x30,0x82,0x21,0xcc,0x2a,0x9a,0xf9,0xaa,0x06,0xd8,0x49,0xe2,0x6a,0x3a,0x01,0xa7,0x54,0x4f,0x44,0xae,0x12,0x2e,0xde,0xd7,0xcb,0xa9,0xf0,0x3e,0xfe,0xfc,0xe0,0x5d,0x83,0x75,0x0d,0x89,0xbf,0xce,0x54,0x45,0x61,0xe7,0xe9,0x62,0x80,0x1d,0x5a,0x7c,0x90,0xa9,0x85,0xda,0x7a,0x65,0x62,0x0f,0xb9,0x91,0xb5,0xa8,0x0e,0x1a,0xe9,0xb4,0x34,0xdf,0xfb,0x1d,0x0e,0x8d,0xf3,0x5f,0xf2,0xae,0xe8,0x8c,0x8b,0x29}, {0xb2,0x0c,0xf7,0xef,0x53,0x79,0x92,0x2a,0x76,0x70,0x15,0x79,0x2a,0xc9,0x89,0x4b,0x6a,0xcf,0xa7,0x30,0x7a,0x45,0x18,0x94,0x85,0xe4,0x5c,0x4d,0x40,0xa8,0xb8,0x34,0xde,0x65,0x21,0x0a,0xea,0x72,0x7a,0x83,0xf6,0x79,0xcf,0x0b,0xb4,0x07,0xab,0x3f,0x70,0xae,0x38,0x77,0xc7,0x36,0x16,0x52,0xdc,0xd7,0xa7,0x03,0x18,0x27,0xa6,0x6b,0x35,0x33,0x69,0x83,0xb5,0xec,0x6e,0xc2,0xfd,0xfe,0xb5,0x63,0xdf,0x13,0xa8,0xd5,0x73,0x25,0xb2,0xa4,0x9a,0xaa,0x93,0xa2,0x6a,0x1c,0x5e,0x46,0xdd,0x2b,0xd6,0x71}, {0x80,0xdf,0x78,0xd3,0x28,0xcc,0x33,0x65,0xb4,0xa4,0x0f,0x0a,0x79,0x43,0xdb,0xf6,0x5a,0xda,0x01,0xf7,0xf9,0x5f,0x64,0xe3,0xa4,0x2b,0x17,0xf3,0x17,0xf3,0xd5,0x74,0xf5,0x5e,0xf7,0xb1,0xda,0xb5,0x2d,0xcd,0xf5,0x65,0xb0,0x16,0xcf,0x95,0x7f,0xd7,0x85,0xf0,0x49,0x3f,0xea,0x1f,0x57,0x14,0x3d,0x2b,0x2b,0x26,0x21,0x36,0x33,0x1c,0x81,0xca,0xd9,0x67,0x54,0xe5,0x6f,0xa8,0x37,0x8c,0x29,0x2b,0x75,0x7c,0x8b,0x39,0x3b,0x62,0xac,0xe3,0x92,0x08,0x6d,0xda,0x8c,0xd9,0xe9,0x47,0x45,0xcc,0xeb,0x4a}, {0xc9,0x01,0x6d,0x27,0x1b,0x07,0xf0,0x12,0x70,0x8c,0xc4,0x86,0xc5,0xba,0xb8,0xe7,0xa9,0xfb,0xd6,0x71,0x9b,0x12,0x08,0x53,0x92,0xb7,0x3d,0x5a,0xf9,0xfb,0x88,0x5d,0x10,0xb6,0x54,0x73,0x9e,0x8d,0x40,0x0b,0x6e,0x5b,0xa8,0x5b,0x53,0x32,0x6b,0x80,0x07,0xa2,0x58,0x4a,0x03,0x3a,0xe6,0xdb,0x2c,0xdf,0xa1,0xc9,0xdd,0xd9,0x3b,0x17,0xdf,0x72,0x58,0xfe,0x1e,0x0f,0x50,0x2b,0xc1,0x18,0x39,0xd4,0x2e,0x58,0xd6,0x58,0xe0,0x3a,0x67,0xc9,0x8e,0x27,0xed,0xe6,0x19,0xa3,0x9e,0xb1,0x13,0xcd,0xe1,0x06}, {0x23,0x6f,0x16,0x6f,0x51,0xad,0xd0,0x40,0xbe,0x6a,0xab,0x1f,0x93,0x32,0x8e,0x11,0x8e,0x08,0x4d,0xa0,0x14,0x5e,0xe3,0x3f,0x66,0x62,0xe1,0x26,0x35,0x60,0x80,0x30,0x53,0x03,0x5b,0x9e,0x62,0xaf,0x2b,0x47,0x47,0x04,0x8d,0x27,0x90,0x0b,0xaa,0x3b,0x27,0xbf,0x43,0x96,0x46,0x5f,0x78,0x0c,0x13,0x7b,0x83,0x8d,0x1a,0x6a,0x3a,0x7f,0x0b,0x80,0x3d,0x5d,0x39,0x44,0xe6,0xf7,0xf6,0xed,0x01,0xc9,0x55,0xd5,0xa8,0x95,0x39,0x63,0x2c,0x59,0x30,0x78,0xcd,0x68,0x7e,0x30,0x51,0x2e,0xed,0xfd,0xd0,0x30}, {0xb3,0x33,0x12,0xf2,0x1a,0x4d,0x59,0xe0,0x9c,0x4d,0xcc,0xf0,0x8e,0xe7,0xdb,0x1b,0x77,0x9a,0x49,0x8f,0x7f,0x18,0x65,0x69,0x68,0x98,0x09,0x2c,0x20,0x14,0x92,0x0a,0x50,0x47,0xb8,0x68,0x1e,0x97,0xb4,0x9c,0xcf,0xbb,0x64,0x66,0x29,0x72,0x95,0xa0,0x2b,0x41,0xfa,0x72,0x26,0xe7,0x8d,0x5c,0xd9,0x89,0xc5,0x51,0x43,0x08,0x15,0x46,0x2e,0xa0,0xb9,0xae,0xc0,0x19,0x90,0xbc,0xae,0x4c,0x03,0x16,0x0d,0x11,0xc7,0x55,0xec,0x32,0x99,0x65,0x01,0xf5,0x6d,0x0e,0xfe,0x5d,0xca,0x95,0x28,0x0d,0xca,0x3b}, {0xa4,0x62,0x5d,0x3c,0xbc,0x31,0xf0,0x40,0x60,0x7a,0xf0,0xcf,0x3e,0x8b,0xfc,0x19,0x45,0xb5,0x0f,0x13,0xa2,0x3d,0x18,0x98,0xcd,0x13,0x8f,0xae,0xdd,0xde,0x31,0x56,0xbf,0x01,0xcc,0x9e,0xb6,0x8e,0x68,0x9c,0x6f,0x89,0x44,0xa6,0xad,0x83,0xbc,0xf0,0xe2,0x9f,0x7a,0x5f,0x5f,0x95,0x2d,0xca,0x41,0x82,0xf2,0x8d,0x03,0xb4,0xa8,0x4e,0x02,0xd2,0xca,0xf1,0x0a,0x46,0xed,0x2a,0x83,0xee,0x8c,0xa4,0x05,0x53,0x30,0x46,0x5f,0x1a,0xf1,0x49,0x45,0x77,0x21,0x91,0x63,0xa4,0x2c,0x54,0x30,0x09,0xce,0x24}, {0x06,0xc1,0x06,0xfd,0xf5,0x90,0xe8,0x1f,0xf2,0x10,0x88,0x5d,0x35,0x68,0xc4,0xb5,0x3e,0xaf,0x8c,0x6e,0xfe,0x08,0x78,0x82,0x4b,0xd7,0x06,0x8a,0xc2,0xe3,0xd4,0x41,0x85,0x0b,0xf3,0xfd,0x55,0xa1,0xcf,0x3f,0xa4,0x2e,0x37,0x36,0x8e,0x16,0xf7,0xd2,0x44,0xf8,0x92,0x64,0xde,0x64,0xe0,0xb2,0x80,0x42,0x4f,0x32,0xa7,0x28,0x99,0x54,0x2e,0x1a,0xee,0x63,0xa7,0x32,0x6e,0xf2,0xea,0xfd,0x5f,0xd2,0xb7,0xe4,0x91,0xae,0x69,0x4d,0x7f,0xd1,0x3b,0xd3,0x3b,0xbc,0x6a,0xff,0xdc,0xc0,0xde,0x66,0x1b,0x49}, {0xa7,0x32,0xea,0xc7,0x3d,0xb1,0xf5,0x98,0x98,0xdb,0x16,0x7e,0xcc,0xf8,0xd5,0xe3,0x47,0xd9,0xf8,0xcb,0x52,0xbf,0x0a,0xac,0xac,0xe4,0x5e,0xc8,0xd0,0x38,0xf3,0x08,0xa1,0x64,0xda,0xd0,0x8e,0x4a,0xf0,0x75,0x4b,0x28,0xe2,0x67,0xaf,0x2c,0x22,0xed,0xa4,0x7b,0x7b,0x1f,0x79,0xa3,0x34,0x82,0x67,0x8b,0x01,0xb7,0xb0,0xb8,0xf6,0x4c,0xbd,0x73,0x1a,0x99,0x21,0xa8,0x83,0xc3,0x7a,0x0c,0x32,0xdf,0x01,0xbc,0x27,0xab,0x63,0x70,0x77,0x84,0x1b,0x33,0x3d,0xc1,0x99,0x8a,0x07,0xeb,0x82,0x4a,0x0d,0x53}, {0x25,0x48,0xf9,0xe1,0x30,0x36,0x4c,0x00,0x5a,0x53,0xab,0x8c,0x26,0x78,0x2d,0x7e,0x8b,0xff,0x84,0xcc,0x23,0x23,0x48,0xc7,0xb9,0x70,0x17,0x10,0x3f,0x75,0xea,0x65,0x9e,0xbf,0x9a,0x6c,0x45,0x73,0x69,0x6d,0x80,0xa8,0x00,0x49,0xfc,0xb2,0x7f,0x25,0x50,0xb8,0xcf,0xc8,0x12,0xf4,0xac,0x2b,0x5b,0xbd,0xbf,0x0c,0xe0,0xe7,0xb3,0x0d,0x63,0x63,0x09,0xe2,0x3e,0xfc,0x66,0x3d,0x6b,0xcb,0xb5,0x61,0x7f,0x2c,0xd6,0x81,0x1a,0x3b,0x44,0x13,0x42,0x04,0xbe,0x0f,0xdb,0xa1,0xe1,0x21,0x19,0xec,0xa4,0x02}, {0xa2,0xb8,0x24,0x3b,0x9a,0x25,0xe6,0x5c,0xb8,0xa0,0xaf,0x45,0xcc,0x7a,0x57,0xb8,0x37,0x70,0xa0,0x8b,0xe8,0xe6,0xcb,0xcc,0xbf,0x09,0x78,0x12,0x51,0x3c,0x14,0x3d,0x5f,0x79,0xcf,0xf1,0x62,0x61,0xc8,0xf5,0xf2,0x57,0xee,0x26,0x19,0x86,0x8c,0x11,0x78,0x35,0x06,0x1c,0x85,0x24,0x21,0x17,0xcf,0x7f,0x06,0xec,0x5d,0x2b,0xd1,0x36,0x57,0x45,0x15,0x79,0x91,0x27,0x6d,0x12,0x0a,0x3a,0x78,0xfc,0x5c,0x8f,0xe4,0xd5,0xac,0x9b,0x17,0xdf,0xe8,0xb6,0xbd,0x36,0x59,0x28,0xa8,0x5b,0x88,0x17,0xf5,0x2e}, {0xdc,0xae,0x58,0x8c,0x4e,0x97,0x37,0x46,0xa4,0x41,0xf0,0xab,0xfb,0x22,0xef,0xb9,0x8a,0x71,0x80,0xe9,0x56,0xd9,0x85,0xe1,0xa6,0xa8,0x43,0xb1,0xfa,0x78,0x1b,0x2f,0x51,0x2f,0x5b,0x30,0xfb,0xbf,0xee,0x96,0xb8,0x96,0x95,0x88,0xad,0x38,0xf9,0xd3,0x25,0xdd,0xd5,0x46,0xc7,0x2d,0xf5,0xf0,0x95,0x00,0x3a,0xbb,0x90,0x82,0x96,0x57,0x01,0xe1,0x20,0x0a,0x43,0xb8,0x1a,0xf7,0x47,0xec,0xf0,0x24,0x8d,0x65,0x93,0xf3,0xd1,0xee,0xe2,0x6e,0xa8,0x09,0x75,0xcf,0xe1,0xa3,0x2a,0xdc,0x35,0x3e,0xc4,0x7d}, {0xc3,0xd9,0x7d,0x88,0x65,0x66,0x96,0x85,0x55,0x53,0xb0,0x4b,0x31,0x9b,0x0f,0xc9,0xb1,0x79,0x20,0xef,0xf8,0x8d,0xe0,0xc6,0x2f,0xc1,0x8c,0x75,0x16,0x20,0xf7,0x7e,0x18,0x97,0x3e,0x27,0x5c,0x2a,0x78,0x5a,0x94,0xfd,0x4e,0x5e,0x99,0xc6,0x76,0x35,0x3e,0x7d,0x23,0x1f,0x05,0xd8,0x2e,0x0f,0x99,0x0a,0xd5,0x82,0x1d,0xb8,0x4f,0x04,0xd9,0xe3,0x07,0xa9,0xc5,0x18,0xdf,0xc1,0x59,0x63,0x4c,0xce,0x1d,0x37,0xb3,0x57,0x49,0xbb,0x01,0xb2,0x34,0x45,0x70,0xca,0x2e,0xdd,0x30,0x9c,0x3f,0x82,0x79,0x7f}, {0xe8,0x13,0xb5,0xa3,0x39,0xd2,0x34,0x83,0xd8,0xa8,0x1f,0xb9,0xd4,0x70,0x36,0xc1,0x33,0xbd,0x90,0xf5,0x36,0x41,0xb5,0x12,0xb4,0xd9,0x84,0xd7,0x73,0x03,0x4e,0x0a,0xba,0x87,0xf5,0x68,0xf0,0x1f,0x9c,0x6a,0xde,0xc8,0x50,0x00,0x4e,0x89,0x27,0x08,0xe7,0x5b,0xed,0x7d,0x55,0x99,0xbf,0x3c,0xf0,0xd6,0x06,0x1c,0x43,0xb0,0xa9,0x64,0x19,0x29,0x7d,0x5b,0xa1,0xd6,0xb3,0x2e,0x35,0x82,0x3a,0xd5,0xa0,0xf6,0xb4,0xb0,0x47,0x5d,0xa4,0x89,0x43,0xce,0x56,0x71,0x6c,0x34,0x18,0xce,0x0a,0x7d,0x1a,0x07}, {0x0b,0xba,0x87,0xc8,0xaa,0x2d,0x07,0xd3,0xee,0x62,0xa5,0xbf,0x05,0x29,0x26,0x01,0x8b,0x76,0xef,0xc0,0x02,0x30,0x54,0xcf,0x9c,0x7e,0xea,0x46,0x71,0xcc,0x3b,0x2c,0x31,0x44,0xe1,0x20,0x52,0x35,0x0c,0xcc,0x41,0x51,0xb1,0x09,0x07,0x95,0x65,0x0d,0x36,0x5f,0x9d,0x20,0x1b,0x62,0xf5,0x9a,0xd3,0x55,0x77,0x61,0xf7,0xbc,0x69,0x7c,0x5f,0x29,0xe8,0x04,0xeb,0xd7,0xf0,0x07,0x7d,0xf3,0x50,0x2f,0x25,0x18,0xdb,0x10,0xd7,0x98,0x17,0x17,0xa3,0xa9,0x51,0xe9,0x1d,0xa5,0xac,0x22,0x73,0x9a,0x5a,0x6f}, {0xc5,0xc6,0x41,0x2f,0x0c,0x00,0xa1,0x8b,0x9b,0xfb,0xfe,0x0c,0xc1,0x79,0x9f,0xc4,0x9f,0x1c,0xc5,0x3c,0x70,0x47,0xfa,0x4e,0xca,0xaf,0x47,0xe1,0xa2,0x21,0x4e,0x49,0xbe,0x44,0xd9,0xa3,0xeb,0xd4,0x29,0xe7,0x9e,0xaf,0x78,0x80,0x40,0x09,0x9e,0x8d,0x03,0x9c,0x86,0x47,0x7a,0x56,0x25,0x45,0x24,0x3b,0x8d,0xee,0x80,0x96,0xab,0x02,0x9a,0x0d,0xe5,0xdd,0x85,0x8a,0xa4,0xef,0x49,0xa2,0xb9,0x0f,0x4e,0x22,0x9a,0x21,0xd9,0xf6,0x1e,0xd9,0x1d,0x1f,0x09,0xfa,0x34,0xbb,0x46,0xea,0xcb,0x76,0x5d,0x6b}, {0x94,0xd9,0x0c,0xec,0x6c,0x55,0x57,0x88,0xba,0x1d,0xd0,0x5c,0x6f,0xdc,0x72,0x64,0x77,0xb4,0x42,0x8f,0x14,0x69,0x01,0xaf,0x54,0x73,0x27,0x85,0xf6,0x33,0xe3,0x0a,0x22,0x25,0x78,0x1e,0x17,0x41,0xf9,0xe0,0xd3,0x36,0x69,0x03,0x74,0xae,0xe6,0xf1,0x46,0xc7,0xfc,0xd0,0xa2,0x3e,0x8b,0x40,0x3e,0x31,0xdd,0x03,0x9c,0x86,0xfb,0x16,0x62,0x09,0xb6,0x33,0x97,0x19,0x8e,0x28,0x33,0xe1,0xab,0xd8,0xb4,0x72,0xfc,0x24,0x3e,0xd0,0x91,0x09,0xed,0xf7,0x11,0x48,0x75,0xd0,0x70,0x8f,0x8b,0xe3,0x81,0x3f}, {0xfe,0xaf,0xd9,0x7e,0xcc,0x0f,0x91,0x7f,0x4b,0x87,0x65,0x24,0xa1,0xb8,0x5c,0x54,0x04,0x47,0x0c,0x4b,0xd2,0x7e,0x39,0xa8,0x93,0x09,0xf5,0x04,0xc1,0x0f,0x51,0x50,0x24,0xc8,0x17,0x5f,0x35,0x7f,0xdb,0x0a,0xa4,0x99,0x42,0xd7,0xc3,0x23,0xb9,0x74,0xf7,0xea,0xf8,0xcb,0x8b,0x3e,0x7c,0xd5,0x3d,0xdc,0xde,0x4c,0xd3,0xe2,0xd3,0x0a,0x9d,0x24,0x6e,0x33,0xc5,0x0f,0x0c,0x6f,0xd9,0xcf,0x31,0xc3,0x19,0xde,0x5e,0x74,0x1c,0xfe,0xee,0x09,0x00,0xfd,0xd6,0xf2,0xbe,0x1e,0xfa,0xf0,0x8b,0x15,0x7c,0x12}, {0xa2,0x79,0x98,0x2e,0x42,0x7c,0x19,0xf6,0x47,0x36,0xca,0x52,0xd4,0xdd,0x4a,0xa4,0xcb,0xac,0x4e,0x4b,0xc1,0x3f,0x41,0x9b,0x68,0x4f,0xef,0x07,0x7d,0xf8,0x4e,0x35,0x74,0xb9,0x51,0xae,0xc4,0x8f,0xa2,0xde,0x96,0xfe,0x4d,0x74,0xd3,0x73,0x99,0x1d,0xa8,0x48,0x38,0x87,0x0b,0x68,0x40,0x62,0x95,0xdf,0x67,0xd1,0x79,0x24,0xd8,0x4e,0x75,0xd9,0xc5,0x60,0x22,0xb5,0xe3,0xfe,0xb8,0xb0,0x41,0xeb,0xfc,0x2e,0x35,0x50,0x3c,0x65,0xf6,0xa9,0x30,0xac,0x08,0x88,0x6d,0x23,0x39,0x05,0xd2,0x92,0x2d,0x30}, {0x3d,0x28,0xa4,0xbc,0xa2,0xc1,0x13,0x78,0xd9,0x3d,0x86,0xa1,0x91,0xf0,0x62,0xed,0x86,0xfa,0x68,0xc2,0xb8,0xbc,0xc7,0xae,0x4c,0xae,0x1c,0x6f,0xb7,0xd3,0xe5,0x10,0x77,0xf1,0xe0,0xe4,0xb6,0x6f,0xbc,0x2d,0x93,0x6a,0xbd,0xa4,0x29,0xbf,0xe1,0x04,0xe8,0xf6,0x7a,0x78,0xd4,0x66,0x19,0x5e,0x60,0xd0,0x26,0xb4,0x5e,0x5f,0xdc,0x0e,0x67,0x8e,0xda,0x53,0xd6,0xbf,0x53,0x54,0x41,0xf6,0xa9,0x24,0xec,0x1e,0xdc,0xe9,0x23,0x8a,0x57,0x03,0x3b,0x26,0x87,0xbf,0x72,0xba,0x1c,0x36,0x51,0x6c,0xb4,0x45}, {0xa1,0x7f,0x4f,0x31,0xbf,0x2a,0x40,0xa9,0x50,0xf4,0x8c,0x8e,0xdc,0xf1,0x57,0xe2,0x84,0xbe,0xa8,0x23,0x4b,0xd5,0xbb,0x1d,0x3b,0x71,0xcb,0x6d,0xa3,0xbf,0x77,0x21,0xe4,0xe3,0x7f,0x8a,0xdd,0x4d,0x9d,0xce,0x30,0x0e,0x62,0x76,0x56,0x64,0x13,0xab,0x58,0x99,0x0e,0xb3,0x7b,0x4f,0x59,0x4b,0xdf,0x29,0x12,0x32,0xef,0x0a,0x1c,0x5c,0x8f,0xdb,0x79,0xfa,0xbc,0x1b,0x08,0x37,0xb3,0x59,0x5f,0xc2,0x1e,0x81,0x48,0x60,0x87,0x24,0x83,0x9c,0x65,0x76,0x7a,0x08,0xbb,0xb5,0x8a,0x7d,0x38,0x19,0xe6,0x4a}, {0x2e,0xa3,0x44,0x53,0xaa,0xf6,0xdb,0x8d,0x78,0x40,0x1b,0xb4,0xb4,0xea,0x88,0x7d,0x60,0x0d,0x13,0x4a,0x97,0xeb,0xb0,0x5e,0x03,0x3e,0xbf,0x17,0x1b,0xd9,0x00,0x1a,0x83,0xfb,0x5b,0x98,0x44,0x7e,0x11,0x61,0x36,0x31,0x96,0x71,0x2a,0x46,0xe0,0xfc,0x4b,0x90,0x25,0xd4,0x48,0x34,0xac,0x83,0x64,0x3d,0xa4,0x5b,0xbe,0x5a,0x68,0x75,0xb2,0xf2,0x61,0xeb,0x33,0x09,0x96,0x6e,0x52,0x49,0xff,0xc9,0xa8,0x0f,0x3d,0x54,0x69,0x65,0xf6,0x7a,0x10,0x75,0x72,0xdf,0xaa,0xe6,0xb0,0x23,0xb6,0x29,0x55,0x13}, {0x18,0xd5,0xd1,0xad,0xd7,0xdb,0xf0,0x18,0x11,0x1f,0xc1,0xcf,0x88,0x78,0x9f,0x97,0x9b,0x75,0x14,0x71,0xf0,0xe1,0x32,0x87,0x01,0x3a,0xca,0x65,0x1a,0xb8,0xb5,0x79,0xfe,0x83,0x2e,0xe2,0xbc,0x16,0xc7,0xf5,0xc1,0x85,0x09,0xe8,0x19,0xeb,0x2b,0xb4,0xae,0x4a,0x25,0x14,0x37,0xa6,0x9d,0xec,0x13,0xa6,0x90,0x15,0x05,0xea,0x72,0x59,0x11,0x78,0x8f,0xdc,0x20,0xac,0xd4,0x0f,0xa8,0x4f,0x4d,0xac,0x94,0xd2,0x9a,0x9a,0x34,0x04,0x36,0xb3,0x64,0x2d,0x1b,0xc0,0xdb,0x3b,0x5f,0x90,0x95,0x9c,0x7e,0x4f}, {0x2e,0x30,0x81,0x57,0xbc,0x4b,0x67,0x62,0x0f,0xdc,0xad,0x89,0x39,0x0f,0x52,0xd8,0xc6,0xd9,0xfb,0x53,0xae,0x99,0x29,0x8c,0x4c,0x8e,0x63,0x2e,0xd9,0x3a,0x99,0x31,0xfe,0x99,0x52,0x35,0x3d,0x44,0xc8,0x71,0xd7,0xea,0xeb,0xdb,0x1c,0x3b,0xcd,0x8b,0x66,0x94,0xa4,0xf1,0x9e,0x49,0x92,0x80,0xc8,0xad,0x44,0xa1,0xc4,0xee,0x42,0x19,0x92,0x49,0x23,0xae,0x19,0x53,0xac,0x7d,0x92,0x3e,0xea,0x0c,0x91,0x3d,0x1b,0x2c,0x22,0x11,0x3c,0x25,0x94,0xe4,0x3c,0x55,0x75,0xca,0xf9,0x4e,0x31,0x65,0x0a,0x2a}, {0xc2,0x27,0xf9,0xf7,0x7f,0x93,0xb7,0x2d,0x35,0xa6,0xd0,0x17,0x06,0x1f,0x74,0xdb,0x76,0xaf,0x55,0x11,0xa2,0xf3,0x82,0x59,0xed,0x2d,0x7c,0x64,0x18,0xe2,0xf6,0x4c,0x3a,0x79,0x1c,0x3c,0xcd,0x1a,0x36,0xcf,0x3b,0xbc,0x35,0x5a,0xac,0xbc,0x9e,0x2f,0xab,0xa6,0xcd,0xa8,0xe9,0x60,0xe8,0x60,0x13,0x1a,0xea,0x6d,0x9b,0xc3,0x5d,0x05,0xb6,0x5b,0x8d,0xc2,0x7c,0x22,0x19,0xb1,0xab,0xff,0x4d,0x77,0xbc,0x4e,0xe2,0x07,0x89,0x2c,0xa3,0xe4,0xce,0x78,0x3c,0xa8,0xb6,0x24,0xaa,0x10,0x77,0x30,0x1a,0x12}, {0x97,0x4a,0x03,0x9f,0x5e,0x5d,0xdb,0xe4,0x2d,0xbc,0x34,0x30,0x09,0xfc,0x53,0xe1,0xb1,0xd3,0x51,0x95,0x91,0x46,0x05,0x46,0x2d,0xe5,0x40,0x7a,0x6c,0xc7,0x3f,0x33,0xc9,0x83,0x74,0xc7,0x3e,0x71,0x59,0xd6,0xaf,0x96,0x2b,0xb8,0x77,0xe0,0xbf,0x88,0xd3,0xbc,0x97,0x10,0x23,0x28,0x9e,0x28,0x9b,0x3a,0xed,0x6c,0x4a,0xb9,0x7b,0x52,0x2e,0x48,0x5b,0x99,0x2a,0x99,0x3d,0x56,0x01,0x38,0x38,0x6e,0x7c,0xd0,0x05,0x34,0xe5,0xd8,0x64,0x2f,0xde,0x35,0x50,0x48,0xf7,0xa9,0xa7,0x20,0x9b,0x06,0x89,0x6b}, {0x0d,0x22,0x70,0x62,0x41,0xa0,0x2a,0x81,0x4e,0x5b,0x24,0xf9,0xfa,0x89,0x5a,0x99,0x05,0xef,0x72,0x50,0xce,0xc4,0xad,0xff,0x73,0xeb,0x73,0xaa,0x03,0x21,0xbc,0x23,0x77,0xdb,0xc7,0xb5,0x8c,0xfa,0x82,0x40,0x55,0xc1,0x34,0xc7,0xf8,0x86,0x86,0x06,0x7e,0xa5,0xe7,0xf6,0xd9,0xc8,0xe6,0x29,0xcf,0x9b,0x63,0xa7,0x08,0xd3,0x73,0x04,0x05,0x9e,0x58,0x03,0x26,0x79,0xee,0xca,0x92,0xc4,0xdc,0x46,0x12,0x42,0x4b,0x2b,0x4f,0xa9,0x01,0xe6,0x74,0xef,0xa1,0x02,0x1a,0x34,0x04,0xde,0xbf,0x73,0x2f,0x10}, {0xc6,0x45,0x57,0x7f,0xab,0xb9,0x18,0xeb,0x90,0xc6,0x87,0x57,0xee,0x8a,0x3a,0x02,0xa9,0xaf,0xf7,0x2d,0xda,0x12,0x27,0xb7,0x3d,0x01,0x5c,0xea,0x25,0x7d,0x59,0x36,0x9a,0x1c,0x51,0xb5,0xe0,0xda,0xb4,0xa2,0x06,0xff,0xff,0x2b,0x29,0x60,0xc8,0x7a,0x34,0x42,0x50,0xf5,0x5d,0x37,0x1f,0x98,0x2d,0xa1,0x4e,0xda,0x25,0xd7,0x6b,0x3f,0xac,0x58,0x60,0x10,0x7b,0x8d,0x4d,0x73,0x5f,0x90,0xc6,0x6f,0x9e,0x57,0x40,0xd9,0x2d,0x93,0x02,0x92,0xf9,0xf8,0x66,0x64,0xd0,0xd6,0x60,0xda,0x19,0xcc,0x7e,0x7b}, {0x0d,0x69,0x5c,0x69,0x3c,0x37,0xc2,0x78,0x6e,0x90,0x42,0x06,0x66,0x2e,0x25,0xdd,0xd2,0x2b,0xe1,0x4a,0x44,0x44,0x1d,0x95,0x56,0x39,0x74,0x01,0x76,0xad,0x35,0x42,0x9b,0xfa,0x7c,0xa7,0x51,0x4a,0xae,0x6d,0x50,0x86,0xa3,0xe7,0x54,0x36,0x26,0x82,0xdb,0x82,0x2d,0x8f,0xcd,0xff,0xbb,0x09,0xba,0xca,0xf5,0x1b,0x66,0xdc,0xbe,0x03,0xf5,0x75,0x89,0x07,0x0d,0xcb,0x58,0x62,0x98,0xf2,0x89,0x91,0x54,0x42,0x29,0x49,0xe4,0x6e,0xe3,0xe2,0x23,0xb4,0xca,0xa0,0xa1,0x66,0xf0,0xcd,0xb0,0xe2,0x7c,0x0e}, {0xa3,0x85,0x8c,0xc4,0x3a,0x64,0x94,0xc4,0xad,0x39,0x61,0x3c,0xf4,0x1d,0x36,0xfd,0x48,0x4d,0xe9,0x3a,0xdd,0x17,0xdb,0x09,0x4a,0x67,0xb4,0x8f,0x5d,0x0a,0x6e,0x66,0xf9,0x70,0x4b,0xd9,0xdf,0xfe,0xa6,0xfe,0x2d,0xba,0xfc,0xc1,0x51,0xc0,0x30,0xf1,0x89,0xab,0x2f,0x7f,0x7e,0xd4,0x82,0x48,0xb5,0xee,0xec,0x8a,0x13,0x56,0x52,0x61,0x0d,0xcb,0x70,0x48,0x4e,0xf6,0xbb,0x2a,0x6b,0x8b,0x45,0xaa,0xf0,0xbc,0x65,0xcd,0x5d,0x98,0xe8,0x75,0xba,0x4e,0xbe,0x9a,0xe4,0xde,0x14,0xd5,0x10,0xc8,0x0b,0x7f}, {0x6f,0x13,0xf4,0x26,0xa4,0x6b,0x00,0xb9,0x35,0x30,0xe0,0x57,0x9e,0x36,0x67,0x8d,0x28,0x3c,0x46,0x4f,0xd9,0xdf,0xc8,0xcb,0xf5,0xdb,0xee,0xf8,0xbc,0x8d,0x1f,0x0d,0xa0,0x13,0x72,0x73,0xad,0x9d,0xac,0x83,0x98,0x2e,0xf7,0x2e,0xba,0xf8,0xf6,0x9f,0x57,0x69,0xec,0x43,0xdd,0x2e,0x1e,0x31,0x75,0xab,0xc5,0xde,0x7d,0x90,0x3a,0x1d,0xdc,0x81,0xd0,0x3e,0x31,0x93,0x16,0xba,0x80,0x34,0x1b,0x85,0xad,0x9f,0x32,0x29,0xcb,0x21,0x03,0x03,0x3c,0x01,0x28,0x01,0xe3,0xfd,0x1b,0xa3,0x44,0x1b,0x01,0x00}, {0x0c,0x6c,0xc6,0x3f,0x6c,0xa0,0xdf,0x3f,0xd2,0x0d,0xd6,0x4d,0x8e,0xe3,0x40,0x5d,0x71,0x4d,0x8e,0x26,0x38,0x8b,0xe3,0x7a,0xe1,0x57,0x83,0x6e,0x91,0x8d,0xc4,0x3a,0x5c,0xa7,0x0a,0x6a,0x69,0x1f,0x56,0x16,0x6a,0xbd,0x52,0x58,0x5c,0x72,0xbf,0xc1,0xad,0x66,0x79,0x9a,0x7f,0xdd,0xa8,0x11,0x26,0x10,0x85,0xd2,0xa2,0x88,0xd9,0x63,0x2e,0x23,0xbd,0xaf,0x53,0x07,0x12,0x00,0x83,0xf6,0xd8,0xfd,0xb8,0xce,0x2b,0xe9,0x91,0x2b,0xe7,0x84,0xb3,0x69,0x16,0xf8,0x66,0xa0,0x68,0x23,0x2b,0xd5,0xfa,0x33}, {0x16,0x1e,0xe4,0xc5,0xc6,0x49,0x06,0x54,0x35,0x77,0x3f,0x33,0x30,0x64,0xf8,0x0a,0x46,0xe7,0x05,0xf3,0xd2,0xfc,0xac,0xb2,0xa7,0xdc,0x56,0xa2,0x29,0xf4,0xc0,0x16,0xe8,0xcf,0x22,0xc4,0xd0,0xc8,0x2c,0x8d,0xcb,0x3a,0xa1,0x05,0x7b,0x4f,0x2b,0x07,0x6f,0xa5,0xf6,0xec,0xe6,0xb6,0xfe,0xa3,0xe2,0x71,0x0a,0xb9,0xcc,0x55,0xc3,0x3c,0x31,0x91,0x3e,0x90,0x43,0x94,0xb6,0xe9,0xce,0x37,0x56,0x7a,0xcb,0x94,0xa4,0xb8,0x44,0x92,0xba,0xba,0xa4,0xd1,0x7c,0xc8,0x68,0x75,0xae,0x6b,0x42,0xaf,0x1e,0x63}, {0x9f,0xfe,0x66,0xda,0x10,0x04,0xe9,0xb3,0xa6,0xe5,0x16,0x6c,0x52,0x4b,0xdd,0x85,0x83,0xbf,0xf9,0x1e,0x61,0x97,0x3d,0xbc,0xb5,0x19,0xa9,0x1e,0x8b,0x64,0x99,0x55,0xe8,0x0d,0x70,0xa3,0xb9,0x75,0xd9,0x47,0x52,0x05,0xf8,0xe2,0xfb,0xc5,0x80,0x72,0xe1,0x5d,0xe4,0x32,0x27,0x8f,0x65,0x53,0xb5,0x80,0x5f,0x66,0x7f,0x2c,0x1f,0x43,0x19,0x7b,0x8f,0x85,0x44,0x63,0x02,0xd6,0x4a,0x51,0xea,0xa1,0x2f,0x35,0xab,0x14,0xd7,0xa9,0x90,0x20,0x1a,0x44,0x00,0x89,0x26,0x3b,0x25,0x91,0x5f,0x71,0x04,0x7b}, {0x43,0xae,0xf6,0xac,0x28,0xbd,0xed,0x83,0xb4,0x7a,0x5c,0x7d,0x8b,0x7c,0x35,0x86,0x44,0x2c,0xeb,0xb7,0x69,0x47,0x40,0xc0,0x3f,0x58,0xf6,0xc2,0xf5,0x7b,0xb3,0x59,0xc6,0xba,0xe6,0xc4,0x80,0xc2,0x76,0xb3,0x0b,0x9b,0x1d,0x6d,0xdd,0xd3,0x0e,0x97,0x44,0xf9,0x0b,0x45,0x58,0x95,0x9a,0xb0,0x23,0xe2,0xcd,0x57,0xfa,0xac,0xd0,0x48,0x71,0xe6,0xab,0x7d,0xe4,0x26,0x0f,0xb6,0x37,0x3a,0x2f,0x62,0x97,0xa1,0xd1,0xf1,0x94,0x03,0x96,0xe9,0x7e,0xce,0x08,0x42,0xdb,0x3b,0x6d,0x33,0x91,0x41,0x23,0x16}, {0xf6,0x7f,0x26,0xf6,0xde,0x99,0xe4,0xb9,0x43,0x08,0x2c,0x74,0x7b,0xca,0x72,0x77,0xb1,0xf2,0xa4,0xe9,0x3f,0x15,0xa0,0x23,0x06,0x50,0xd0,0xd5,0xec,0xdf,0xdf,0x2c,0x40,0x86,0xf3,0x1f,0xd6,0x9c,0x49,0xdd,0xa0,0x25,0x36,0x06,0xc3,0x9b,0xcd,0x29,0xc3,0x3d,0xd7,0x3d,0x02,0xd8,0xe2,0x51,0x31,0x92,0x3b,0x20,0x7a,0x70,0x25,0x4a,0x6a,0xed,0xf6,0x53,0x8a,0x66,0xb7,0x2a,0xa1,0x70,0xd1,0x1d,0x58,0x42,0x42,0x30,0x61,0x01,0xe2,0x3a,0x4c,0x14,0x00,0x40,0xfc,0x49,0x8e,0x24,0x6d,0x89,0x21,0x57}, {0xae,0x1b,0x18,0xfd,0x17,0x55,0x6e,0x0b,0xb4,0x63,0xb9,0x2b,0x9f,0x62,0x22,0x90,0x25,0x46,0x06,0x32,0xe9,0xbc,0x09,0x55,0xda,0x13,0x3c,0xf6,0x74,0xdd,0x8e,0x57,0x4e,0xda,0xd0,0xa1,0x91,0x50,0x5d,0x28,0x08,0x3e,0xfe,0xb5,0xa7,0x6f,0xaa,0x4b,0xb3,0x93,0x93,0xe1,0x7c,0x17,0xe5,0x63,0xfd,0x30,0xb0,0xc4,0xaf,0x35,0xc9,0x03,0x3d,0x0c,0x2b,0x49,0xc6,0x76,0x72,0x99,0xfc,0x05,0xe2,0xdf,0xc4,0xc2,0xcc,0x47,0x3c,0x3a,0x62,0xdd,0x84,0x9b,0xd2,0xdc,0xa2,0xc7,0x88,0x02,0x59,0xab,0xc2,0x3e}, {0xb9,0x7b,0xd8,0xe4,0x7b,0xd2,0xa0,0xa1,0xed,0x1a,0x39,0x61,0xeb,0x4d,0x8b,0xa9,0x83,0x9b,0xcb,0x73,0xd0,0xdd,0xa0,0x99,0xce,0xca,0x0f,0x20,0x5a,0xc2,0xd5,0x2d,0xcb,0xd1,0x32,0xae,0x09,0x3a,0x21,0xa7,0xd5,0xc2,0xf5,0x40,0xdf,0x87,0x2b,0x0f,0x29,0xab,0x1e,0xe8,0xc6,0xa4,0xae,0x0b,0x5e,0xac,0xdb,0x6a,0x6c,0xf6,0x1b,0x0e,0x7e,0x88,0x2c,0x79,0xe9,0xd5,0xab,0xe2,0x5d,0x6d,0x92,0xcb,0x18,0x00,0x02,0x1a,0x1e,0x5f,0xae,0xba,0xcd,0x69,0xba,0xbf,0x5f,0x8f,0xe8,0x5a,0xb3,0x48,0x05,0x73}, {0xee,0xb8,0xa8,0xcb,0xa3,0x51,0x35,0xc4,0x16,0x5f,0x11,0xb2,0x1d,0x6f,0xa2,0x65,0x50,0x38,0x8c,0xab,0x52,0x4f,0x0f,0x76,0xca,0xb8,0x1d,0x41,0x3b,0x44,0x43,0x30,0x34,0xe3,0xd6,0xa1,0x4b,0x09,0x5b,0x80,0x19,0x3f,0x35,0x09,0x77,0xf1,0x3e,0xbf,0x2b,0x70,0x22,0x06,0xcb,0x06,0x3f,0x42,0xdd,0x45,0x78,0xd8,0x77,0x22,0x5a,0x58,0x62,0x89,0xd4,0x33,0x82,0x5f,0x8a,0xa1,0x7f,0x25,0x78,0xec,0xb5,0xc4,0x98,0x66,0xff,0x41,0x3e,0x37,0xa5,0x6f,0x8e,0xa7,0x1f,0x98,0xef,0x50,0x89,0x27,0x56,0x76}, {0xc0,0xc8,0x1f,0xd5,0x59,0xcf,0xc3,0x38,0xf2,0xb6,0x06,0x05,0xfd,0xd2,0xed,0x9b,0x8f,0x0e,0x57,0xab,0x9f,0x10,0xbf,0x26,0xa6,0x46,0xb8,0xc1,0xa8,0x60,0x41,0x3f,0x9d,0xcf,0x86,0xea,0xa3,0x73,0x70,0xe1,0xdc,0x5f,0x15,0x07,0xb7,0xfb,0x8c,0x3a,0x8e,0x8a,0x83,0x31,0xfc,0xe7,0x53,0x48,0x16,0xf6,0x13,0xb6,0x84,0xf4,0xbb,0x28,0x7c,0x6c,0x13,0x6f,0x5c,0x2f,0x61,0xf2,0xbe,0x11,0xdd,0xf6,0x07,0xd1,0xea,0xaf,0x33,0x6f,0xde,0x13,0xd2,0x9a,0x7e,0x52,0x5d,0xf7,0x88,0x81,0x35,0xcb,0x79,0x1e}, {0xf1,0xe3,0xf7,0xee,0xc3,0x36,0x34,0x01,0xf8,0x10,0x9e,0xfe,0x7f,0x6a,0x8b,0x82,0xfc,0xde,0xf9,0xbc,0xe5,0x08,0xf9,0x7f,0x31,0x38,0x3b,0x3a,0x1b,0x95,0xd7,0x65,0x81,0x81,0xe0,0xf5,0xd8,0x53,0xe9,0x77,0xd9,0xde,0x9d,0x29,0x44,0x0c,0xa5,0x84,0xe5,0x25,0x45,0x86,0x0c,0x2d,0x6c,0xdc,0xf4,0xf2,0xd1,0x39,0x2d,0xb5,0x8a,0x47,0x59,0xd1,0x52,0x92,0xd3,0xa4,0xa6,0x66,0x07,0xc8,0x1a,0x87,0xbc,0xe1,0xdd,0xe5,0x6f,0xc9,0xc1,0xa6,0x40,0x6b,0x2c,0xb8,0x14,0x22,0x21,0x1a,0x41,0x7a,0xd8,0x16}, {0x15,0x62,0x06,0x42,0x5a,0x7e,0xbd,0xb3,0xc1,0x24,0x5a,0x0c,0xcd,0xe3,0x9b,0x87,0xb7,0x94,0xf9,0xd6,0xb1,0x5d,0xc0,0x57,0xa6,0x8c,0xf3,0x65,0x81,0x7c,0xf8,0x28,0x83,0x05,0x4e,0xd5,0xe2,0xd5,0xa4,0xfb,0xfa,0x99,0xbd,0x2e,0xd7,0xaf,0x1f,0xe2,0x8f,0x77,0xe9,0x6e,0x73,0xc2,0x7a,0x49,0xde,0x6d,0x5a,0x7a,0x57,0x0b,0x99,0x1f,0xd6,0xf7,0xe8,0x1b,0xad,0x4e,0x34,0xa3,0x8f,0x79,0xea,0xac,0xeb,0x50,0x1e,0x7d,0x52,0xe0,0x0d,0x52,0x9e,0x56,0xc6,0x77,0x3e,0x6d,0x4d,0x53,0xe1,0x2f,0x88,0x45}, {0xd6,0x83,0x79,0x75,0x5d,0x34,0x69,0x66,0xa6,0x11,0xaa,0x17,0x11,0xed,0xb6,0x62,0x8f,0x12,0x5e,0x98,0x57,0x18,0xdd,0x7d,0xdd,0xf6,0x26,0xf6,0xb8,0xe5,0x8f,0x68,0xe4,0x6f,0x3c,0x94,0x29,0x99,0xac,0xd8,0xa2,0x92,0x83,0xa3,0x61,0xf1,0xf9,0xb5,0xf3,0x9a,0xc8,0xbe,0x13,0xdb,0x99,0x26,0x74,0xf0,0x05,0xe4,0x3c,0x84,0xcf,0x7d,0xc0,0x32,0x47,0x4a,0x48,0xd6,0x90,0x6c,0x99,0x32,0x56,0xca,0xfd,0x43,0x21,0xd5,0xe1,0xc6,0x5d,0x91,0xc3,0x28,0xbe,0xb3,0x1b,0x19,0x27,0x73,0x7e,0x68,0x39,0x67}, {0xa6,0x75,0x56,0x38,0x14,0x20,0x78,0xef,0xe8,0xa9,0xfd,0xaa,0x30,0x9f,0x64,0xa2,0xcb,0xa8,0xdf,0x5c,0x50,0xeb,0xd1,0x4c,0xb3,0xc0,0x4d,0x1d,0xba,0x5a,0x11,0x46,0xc0,0x1a,0x0c,0xc8,0x9d,0xcc,0x6d,0xa6,0x36,0xa4,0x38,0x1b,0xf4,0x5c,0xa0,0x97,0xc6,0xd7,0xdb,0x95,0xbe,0xf3,0xeb,0xa7,0xab,0x7d,0x7e,0x8d,0xf6,0xb8,0xa0,0x7d,0x76,0xda,0xb5,0xc3,0x53,0x19,0x0f,0xd4,0x9b,0x9e,0x11,0x21,0x73,0x6f,0xac,0x1d,0x60,0x59,0xb2,0xfe,0x21,0x60,0xcc,0x03,0x4b,0x4b,0x67,0x83,0x7e,0x88,0x5f,0x5a}, {0x11,0x3d,0xa1,0x70,0xcf,0x01,0x63,0x8f,0xc4,0xd0,0x0d,0x35,0x15,0xb8,0xce,0xcf,0x7e,0xa4,0xbc,0xa4,0xd4,0x97,0x02,0xf7,0x34,0x14,0x4d,0xe4,0x56,0xb6,0x69,0x36,0xb9,0x43,0xa6,0xa0,0xd3,0x28,0x96,0x9e,0x64,0x20,0xc3,0xe6,0x00,0xcb,0xc3,0xb5,0x32,0xec,0x2d,0x7c,0x89,0x02,0x53,0x9b,0x0c,0xc7,0xd1,0xd5,0xe2,0x7a,0xe3,0x43,0x33,0xe1,0xa6,0xed,0x06,0x3f,0x7e,0x38,0xc0,0x3a,0xa1,0x99,0x51,0x1d,0x30,0x67,0x11,0x38,0x26,0x36,0xf8,0xd8,0x5a,0xbd,0xbe,0xe9,0xd5,0x4f,0xcd,0xe6,0x21,0x6a}, {0x5f,0xe6,0x46,0x30,0x0a,0x17,0xc6,0xf1,0x24,0x35,0xd2,0x00,0x2a,0x2a,0x71,0x58,0x55,0xb7,0x82,0x8c,0x3c,0xbd,0xdb,0x69,0x57,0xff,0x95,0xa1,0xf1,0xf9,0x6b,0x58,0xe3,0xb2,0x99,0x66,0x12,0x29,0x41,0xef,0x01,0x13,0x8d,0x70,0x47,0x08,0xd3,0x71,0xbd,0xb0,0x82,0x11,0xd0,0x32,0x54,0x32,0x36,0x8b,0x1e,0x00,0x07,0x1b,0x37,0x45,0x0b,0x79,0xf8,0x5e,0x8d,0x08,0xdb,0xa6,0xe5,0x37,0x09,0x61,0xdc,0xf0,0x78,0x52,0xb8,0x6e,0xa1,0x61,0xd2,0x49,0x03,0xac,0x79,0x21,0xe5,0x90,0x37,0xb0,0xaf,0x0e}, {0x2f,0x04,0x48,0x37,0xc1,0x55,0x05,0x96,0x11,0xaa,0x0b,0x82,0xe6,0x41,0x9a,0x21,0x0c,0x6d,0x48,0x73,0x38,0xf7,0x81,0x1c,0x61,0xc6,0x02,0x5a,0x67,0xcc,0x9a,0x30,0x1d,0xae,0x75,0x0f,0x5e,0x80,0x40,0x51,0x30,0xcc,0x62,0x26,0xe3,0xfb,0x02,0xec,0x6d,0x39,0x92,0xea,0x1e,0xdf,0xeb,0x2c,0xb3,0x5b,0x43,0xc5,0x44,0x33,0xae,0x44,0xee,0x43,0xa5,0xbb,0xb9,0x89,0xf2,0x9c,0x42,0x71,0xc9,0x5a,0x9d,0x0e,0x76,0xf3,0xaa,0x60,0x93,0x4f,0xc6,0xe5,0x82,0x1d,0x8f,0x67,0x94,0x7f,0x1b,0x22,0xd5,0x62}, {0x6d,0x93,0xd0,0x18,0x9c,0x29,0x4c,0x52,0x0c,0x1a,0x0c,0x8a,0x6c,0xb5,0x6b,0xc8,0x31,0x86,0x4a,0xdb,0x2e,0x05,0x75,0xa3,0x62,0x45,0x75,0xbc,0xe4,0xfd,0x0e,0x5c,0x3c,0x7a,0xf7,0x3a,0x26,0xd4,0x85,0x75,0x4d,0x14,0xe9,0xfe,0x11,0x7b,0xae,0xdf,0x3d,0x19,0xf7,0x59,0x80,0x70,0x06,0xa5,0x37,0x20,0x92,0x83,0x53,0x9a,0xf2,0x14,0xf5,0xd7,0xb2,0x25,0xdc,0x7e,0x71,0xdf,0x40,0x30,0xb5,0x99,0xdb,0x70,0xf9,0x21,0x62,0x4c,0xed,0xc3,0xb7,0x34,0x92,0xda,0x3e,0x09,0xee,0x7b,0x5c,0x36,0x72,0x5e}, {0x7f,0x21,0x71,0x45,0x07,0xfc,0x5b,0x57,0x5b,0xd9,0x94,0x06,0x5d,0x67,0x79,0x37,0x33,0x1e,0x19,0xf4,0xbb,0x37,0x0a,0x9a,0xbc,0xea,0xb4,0x47,0x4c,0x10,0xf1,0x77,0x3e,0xb3,0x08,0x2f,0x06,0x39,0x93,0x7d,0xbe,0x32,0x9f,0xdf,0xe5,0x59,0x96,0x5b,0xfd,0xbd,0x9e,0x1f,0xad,0x3d,0xff,0xac,0xb7,0x49,0x73,0xcb,0x55,0x05,0xb2,0x70,0x4c,0x2c,0x11,0x55,0xc5,0x13,0x51,0xbe,0xcd,0x1f,0x88,0x9a,0x3a,0x42,0x88,0x66,0x47,0x3b,0x50,0x5e,0x85,0x77,0x66,0x44,0x4a,0x40,0x06,0x4a,0x8f,0x39,0x34,0x0e}, {0xe8,0xbd,0xce,0x3e,0xd9,0x22,0x7d,0xb6,0x07,0x2f,0x82,0x27,0x41,0xe8,0xb3,0x09,0x8d,0x6d,0x5b,0xb0,0x1f,0xa6,0x3f,0x74,0x72,0x23,0x36,0x8a,0x36,0x05,0x54,0x5e,0x28,0x19,0x4b,0x3e,0x09,0x0b,0x93,0x18,0x40,0xf6,0xf3,0x73,0x0e,0xe1,0xe3,0x7d,0x6f,0x5d,0x39,0x73,0xda,0x17,0x32,0xf4,0x3e,0x9c,0x37,0xca,0xd6,0xde,0x8a,0x6f,0x9a,0xb2,0xb7,0xfd,0x3d,0x12,0x40,0xe3,0x91,0xb2,0x1a,0xa2,0xe1,0x97,0x7b,0x48,0x9e,0x94,0xe6,0xfd,0x02,0x7d,0x96,0xf9,0x97,0xde,0xd3,0xc8,0x2e,0xe7,0x0d,0x78}, {0xbc,0xe7,0x9a,0x08,0x45,0x85,0xe2,0x0a,0x06,0x4d,0x7f,0x1c,0xcf,0xde,0x8d,0x38,0xb8,0x11,0x48,0x0a,0x51,0x15,0xac,0x38,0xe4,0x8c,0x92,0x71,0xf6,0x8b,0xb2,0x0e,0x72,0x27,0xf4,0x00,0xf3,0xea,0x1f,0x67,0xaa,0x41,0x8c,0x2a,0x2a,0xeb,0x72,0x8f,0x92,0x32,0x37,0x97,0xd7,0x7f,0xa1,0x29,0xa6,0x87,0xb5,0x32,0xad,0xc6,0xef,0x1d,0xa7,0x95,0x51,0xef,0x1a,0xbe,0x5b,0xaf,0xed,0x15,0x7b,0x91,0x77,0x12,0x8c,0x14,0x2e,0xda,0xe5,0x7a,0xfb,0xf7,0x91,0x29,0x67,0x28,0xdd,0xf8,0x1b,0x20,0x7d,0x46}, {0xad,0x4f,0xef,0x74,0x9a,0x91,0xfe,0x95,0xa2,0x08,0xa3,0xf6,0xec,0x7b,0x82,0x3a,0x01,0x7b,0xa4,0x09,0xd3,0x01,0x4e,0x96,0x97,0xc7,0xa3,0x5b,0x4f,0x3c,0xc4,0x71,0xa9,0xe7,0x7a,0x56,0xbd,0xf4,0x1e,0xbc,0xbd,0x98,0x44,0xd6,0xb2,0x4c,0x62,0x3f,0xc8,0x4e,0x1f,0x2c,0xd2,0x64,0x10,0xe4,0x01,0x40,0x38,0xba,0xa5,0xc5,0xf9,0x2e,0xcd,0x74,0x9e,0xfa,0xf6,0x6d,0xfd,0xb6,0x7a,0x26,0xaf,0xe4,0xbc,0x78,0x82,0xf1,0x0e,0x99,0xef,0xf1,0xd0,0xb3,0x55,0x82,0x93,0xf2,0xc5,0x90,0xa3,0x8c,0x75,0x5a}, {0x95,0x24,0x46,0xd9,0x10,0x27,0xb7,0xa2,0x03,0x50,0x7d,0xd5,0xd2,0xc6,0xa8,0x3a,0xca,0x87,0xb4,0xa0,0xbf,0x00,0xd4,0xe3,0xec,0x72,0xeb,0xb3,0x44,0xe2,0xba,0x2d,0x94,0xdc,0x61,0x1d,0x8b,0x91,0xe0,0x8c,0x66,0x30,0x81,0x9a,0x46,0x36,0xed,0x8d,0xd3,0xaa,0xe8,0xaf,0x29,0xa8,0xe6,0xd4,0x3f,0xd4,0x39,0xf6,0x27,0x80,0x73,0x0a,0xcc,0xe1,0xff,0x57,0x2f,0x4a,0x0f,0x98,0x43,0x98,0x83,0xe1,0x0d,0x0d,0x67,0x00,0xfd,0x15,0xfb,0x49,0x4a,0x3f,0x5c,0x10,0x9c,0xa6,0x26,0x51,0x63,0xca,0x98,0x26}, {0x78,0xba,0xb0,0x32,0x88,0x31,0x65,0xe7,0x8b,0xff,0x5c,0x92,0xf7,0x31,0x18,0x38,0xcc,0x1f,0x29,0xa0,0x91,0x1b,0xa8,0x08,0x07,0xeb,0xca,0x49,0xcc,0x3d,0xb4,0x1f,0x0e,0xd9,0x3d,0x5e,0x2f,0x70,0x3d,0x2e,0x86,0x53,0xd2,0xe4,0x18,0x09,0x3f,0x9e,0x6a,0xa9,0x4d,0x02,0xf6,0x3e,0x77,0x5e,0x32,0x33,0xfa,0x4a,0x0c,0x4b,0x00,0x3c,0x2b,0xb8,0xf4,0x06,0xac,0x46,0xa9,0x9a,0xf3,0xc4,0x06,0xa8,0xa5,0x84,0xa2,0x1c,0x87,0x47,0xcd,0xc6,0x5f,0x26,0xd3,0x3e,0x17,0xd2,0x1f,0xcd,0x01,0xfd,0x43,0x6b}, {0x44,0xc5,0x97,0x46,0x4b,0x5d,0xa7,0xc7,0xbf,0xff,0x0f,0xdf,0x48,0xf8,0xfd,0x15,0x5a,0x78,0x46,0xaa,0xeb,0xb9,0x68,0x28,0x14,0xf7,0x52,0x5b,0x10,0xd7,0x68,0x5a,0xf3,0x0e,0x76,0x3e,0x58,0x42,0xc7,0xb5,0x90,0xb9,0x0a,0xee,0xb9,0x52,0xdc,0x75,0x3f,0x92,0x2b,0x07,0xc2,0x27,0x14,0xbf,0xf0,0xd9,0xf0,0x6f,0x2d,0x0b,0x42,0x73,0x06,0x1e,0x85,0x9e,0xcb,0xf6,0x2c,0xaf,0xc4,0x38,0x22,0xc6,0x13,0x39,0x59,0x8f,0x73,0xf3,0xfb,0x99,0x96,0xb8,0x8a,0xda,0x9e,0xbc,0x34,0xea,0x2f,0x63,0xb5,0x3d}, {0xd8,0xd9,0x5d,0xf7,0x2b,0xee,0x6e,0xf4,0xa5,0x59,0x67,0x39,0xf6,0xb1,0x17,0x0d,0x73,0x72,0x9e,0x49,0x31,0xd1,0xf2,0x1b,0x13,0x5f,0xd7,0x49,0xdf,0x1a,0x32,0x04,0xd5,0x25,0x98,0x82,0xb1,0x90,0x49,0x2e,0x91,0x89,0x9a,0x3e,0x87,0xeb,0xea,0xed,0xf8,0x4a,0x70,0x4c,0x39,0x3d,0xf0,0xee,0x0e,0x2b,0xdf,0x95,0xa4,0x7e,0x19,0x59,0xae,0x5a,0xe5,0xe4,0x19,0x60,0xe1,0x04,0xe9,0x92,0x2f,0x7e,0x7a,0x43,0x7b,0xe7,0xa4,0x9a,0x15,0x6f,0xc1,0x2d,0xce,0xc7,0xc0,0x0c,0xd7,0xf4,0xc1,0xfd,0xea,0x45}, {0x2b,0xd7,0x45,0x80,0x85,0x01,0x84,0x69,0x51,0x06,0x2f,0xcf,0xa2,0xfa,0x22,0x4c,0xc6,0x2d,0x22,0x6b,0x65,0x36,0x1a,0x94,0xde,0xda,0x62,0x03,0xc8,0xeb,0x5e,0x5a,0xed,0xb1,0xcc,0xcf,0x24,0x46,0x0e,0xb6,0x95,0x03,0x5c,0xbd,0x92,0xc2,0xdb,0x59,0xc9,0x81,0x04,0xdc,0x1d,0x9d,0xa0,0x31,0x40,0xd9,0x56,0x5d,0xea,0xce,0x73,0x3f,0xc6,0x8d,0x4e,0x0a,0xd1,0xbf,0xa7,0xb7,0x39,0xb3,0xc9,0x44,0x7e,0x00,0x57,0xbe,0xfa,0xae,0x57,0x15,0x7f,0x20,0xc1,0x60,0xdb,0x18,0x62,0x26,0x91,0x88,0x05,0x26}, {0x04,0xff,0x60,0x83,0xa6,0x04,0xf7,0x59,0xf4,0xe6,0x61,0x76,0xde,0x3f,0xd9,0xc3,0x51,0x35,0x87,0x12,0x73,0x2a,0x1b,0x83,0x57,0x5d,0x61,0x4e,0x2e,0x0c,0xad,0x54,0x42,0xe5,0x76,0xc6,0x3c,0x8e,0x81,0x4c,0xad,0xcc,0xce,0x03,0x93,0x2c,0x42,0x5e,0x08,0x9f,0x12,0xb4,0xca,0xcc,0x07,0xec,0xb8,0x43,0x44,0xb2,0x10,0xfa,0xed,0x0d,0x2a,0x52,0x2b,0xb8,0xd5,0x67,0x3b,0xee,0xeb,0xc1,0xa5,0x9f,0x46,0x63,0xf1,0x36,0xd3,0x9f,0xc1,0x6e,0xf2,0xd2,0xb4,0xa5,0x08,0x94,0x7a,0xa7,0xba,0xb2,0xec,0x62}, {0x3d,0x2b,0x15,0x61,0x52,0x79,0xed,0xe5,0xd1,0xd7,0xdd,0x0e,0x7d,0x35,0x62,0x49,0x71,0x4c,0x6b,0xb9,0xd0,0xc8,0x82,0x74,0xbe,0xd8,0x66,0xa9,0x19,0xf9,0x59,0x2e,0x74,0x28,0xb6,0xaf,0x36,0x28,0x07,0x92,0xa5,0x04,0xe1,0x79,0x85,0x5e,0xcd,0x5f,0x4a,0xa1,0x30,0xc6,0xad,0x01,0xad,0x5a,0x98,0x3f,0x66,0x75,0x50,0x3d,0x91,0x61,0xda,0x31,0x32,0x1a,0x36,0x2d,0xc6,0x0d,0x70,0x02,0x20,0x94,0x32,0x58,0x47,0xfa,0xce,0x94,0x95,0x3f,0x51,0x01,0xd8,0x02,0x5c,0x5d,0xc0,0x31,0xa1,0xc2,0xdb,0x3d}, {0x4b,0xc5,0x5e,0xce,0xf9,0x0f,0xdc,0x9a,0x0d,0x13,0x2f,0x8c,0x6b,0x2a,0x9c,0x03,0x15,0x95,0xf8,0xf0,0xc7,0x07,0x80,0x02,0x6b,0xb3,0x04,0xac,0x14,0x83,0x96,0x78,0x14,0xbb,0x96,0x27,0xa2,0x57,0xaa,0xf3,0x21,0xda,0x07,0x9b,0xb7,0xba,0x3a,0x88,0x1c,0x39,0xa0,0x31,0x18,0xe2,0x4b,0xe5,0xf9,0x05,0x32,0xd8,0x38,0xfb,0xe7,0x5e,0x8e,0x6a,0x44,0x41,0xcb,0xfd,0x8d,0x53,0xf9,0x37,0x49,0x43,0xa9,0xfd,0xac,0xa5,0x78,0x8c,0x3c,0x26,0x8d,0x90,0xaf,0x46,0x09,0x0d,0xca,0x9b,0x3c,0x63,0xd0,0x61}, {0x66,0x25,0xdb,0xff,0x35,0x49,0x74,0x63,0xbb,0x68,0x0b,0x78,0x89,0x6b,0xbd,0xc5,0x03,0xec,0x3e,0x55,0x80,0x32,0x1b,0x6f,0xf5,0xd7,0xae,0x47,0xd8,0x5f,0x96,0x6e,0xdf,0x73,0xfc,0xf8,0xbc,0x28,0xa3,0xad,0xfc,0x37,0xf0,0xa6,0x5d,0x69,0x84,0xee,0x09,0xa9,0xc2,0x38,0xdb,0xb4,0x7f,0x63,0xdc,0x7b,0x06,0xf8,0x2d,0xac,0x23,0x5b,0x7b,0x52,0x80,0xee,0x53,0xb9,0xd2,0x9a,0x8d,0x6d,0xde,0xfa,0xaa,0x19,0x8f,0xe8,0xcf,0x82,0x0e,0x15,0x04,0x17,0x71,0x0e,0xdc,0xde,0x95,0xdd,0xb9,0xbb,0xb9,0x79}, {0xc2,0x26,0x31,0x6a,0x40,0x55,0xb3,0xeb,0x93,0xc3,0xc8,0x68,0xa8,0x83,0x63,0xd2,0x82,0x7a,0xb9,0xe5,0x29,0x64,0x0c,0x6c,0x47,0x21,0xfd,0xc9,0x58,0xf1,0x65,0x50,0x74,0x73,0x9f,0x8e,0xae,0x7d,0x99,0xd1,0x16,0x08,0xbb,0xcf,0xf8,0xa2,0x32,0xa0,0x0a,0x5f,0x44,0x6d,0x12,0xba,0x6c,0xcd,0x34,0xb8,0xcc,0x0a,0x46,0x11,0xa8,0x1b,0x54,0x99,0x42,0x0c,0xfb,0x69,0x81,0x70,0x67,0xcf,0x6e,0xd7,0xac,0x00,0x46,0xe1,0xba,0x45,0xe6,0x70,0x8a,0xb9,0xaa,0x2e,0xf2,0xfa,0xa4,0x58,0x9e,0xf3,0x81,0x39}, {0x93,0x0a,0x23,0x59,0x75,0x8a,0xfb,0x18,0x5d,0xf4,0xe6,0x60,0x69,0x8f,0x16,0x1d,0xb5,0x3c,0xa9,0x14,0x45,0xa9,0x85,0x3a,0xfd,0xd0,0xac,0x05,0x37,0x08,0xdc,0x38,0xde,0x6f,0xe6,0x6d,0xa5,0xdf,0x45,0xc8,0x3a,0x48,0x40,0x2c,0x00,0xa5,0x52,0xe1,0x32,0xf6,0xb4,0xc7,0x63,0xe1,0xd2,0xe9,0x65,0x1b,0xbc,0xdc,0x2e,0x45,0xf4,0x30,0x40,0x97,0x75,0xc5,0x82,0x27,0x6d,0x85,0xcc,0xbe,0x9c,0xf9,0x69,0x45,0x13,0xfa,0x71,0x4e,0xea,0xc0,0x73,0xfc,0x44,0x88,0x69,0x24,0x3f,0x59,0x1a,0x9a,0x2d,0x63}, {0xa6,0xcb,0x07,0xb8,0x15,0x6b,0xbb,0xf6,0xd7,0xf0,0x54,0xbc,0xdf,0xc7,0x23,0x18,0x0b,0x67,0x29,0x6e,0x03,0x97,0x1d,0xbb,0x57,0x4a,0xed,0x47,0x88,0xf4,0x24,0x0b,0xa7,0x84,0x0c,0xed,0x11,0xfd,0x09,0xbf,0x3a,0x69,0x9f,0x0d,0x81,0x71,0xf0,0x63,0x79,0x87,0xcf,0x57,0x2d,0x8c,0x90,0x21,0xa2,0x4b,0xf6,0x8a,0xf2,0x7d,0x5a,0x3a,0xc7,0xea,0x1b,0x51,0xbe,0xd4,0xda,0xdc,0xf2,0xcc,0x26,0xed,0x75,0x80,0x53,0xa4,0x65,0x9a,0x5f,0x00,0x9f,0xff,0x9c,0xe1,0x63,0x1f,0x48,0x75,0x44,0xf7,0xfc,0x34}, {0xca,0x67,0x97,0x78,0x4c,0xe0,0x97,0xc1,0x7d,0x46,0xd9,0x38,0xcb,0x4d,0x71,0xb8,0xa8,0x5f,0xf9,0x83,0x82,0x88,0xde,0x55,0xf7,0x63,0xfa,0x4d,0x16,0xdc,0x3b,0x3d,0x98,0xaa,0xcf,0x78,0xab,0x1d,0xbb,0xa5,0xf2,0x72,0x0b,0x19,0x67,0xa2,0xed,0x5c,0x8e,0x60,0x92,0x0a,0x11,0xc9,0x09,0x93,0xb0,0x74,0xb3,0x2f,0x04,0xa3,0x19,0x01,0x7d,0x17,0xc2,0xe8,0x9c,0xd8,0xa2,0x67,0xc1,0xd0,0x95,0x68,0xf6,0xa5,0x9d,0x66,0xb0,0xa2,0x82,0xb2,0xe5,0x98,0x65,0xf5,0x73,0x0a,0xe2,0xed,0xf1,0x88,0xc0,0x56}, {0x17,0x6e,0xa8,0x10,0x11,0x3d,0x6d,0x33,0xfa,0xb2,0x75,0x0b,0x32,0x88,0xf3,0xd7,0x88,0x29,0x07,0x25,0x76,0x33,0x15,0xf9,0x87,0x8b,0x10,0x99,0x6b,0x4c,0x67,0x09,0x02,0x8f,0xf3,0x24,0xac,0x5f,0x1b,0x58,0xbd,0x0c,0xe3,0xba,0xfe,0xe9,0x0b,0xa9,0xf0,0x92,0xcf,0x8a,0x02,0x69,0x21,0x9a,0x8f,0x03,0x59,0x83,0xa4,0x7e,0x8b,0x03,0xf8,0x6f,0x31,0x99,0x21,0xf8,0x4e,0x9f,0x4f,0x8d,0xa7,0xea,0x82,0xd2,0x49,0x2f,0x74,0x31,0xef,0x5a,0xab,0xa5,0x71,0x09,0x65,0xeb,0x69,0x59,0x02,0x31,0x5e,0x6e}, {0xfb,0x93,0xe5,0x87,0xf5,0x62,0x6c,0xb1,0x71,0x3e,0x5d,0xca,0xde,0xed,0x99,0x49,0x6d,0x3e,0xcc,0x14,0xe0,0xc1,0x91,0xb4,0xa8,0xdb,0xa8,0x89,0x47,0x11,0xf5,0x08,0x22,0x62,0x06,0x63,0x0e,0xfb,0x04,0x33,0x3f,0xba,0xac,0x87,0x89,0x06,0x35,0xfb,0xa3,0x61,0x10,0x8c,0x77,0x24,0x19,0xbd,0x20,0x86,0x83,0xd1,0x43,0xad,0x58,0x30,0xd0,0x63,0x76,0xe5,0xfd,0x0f,0x3c,0x32,0x10,0xa6,0x2e,0xa2,0x38,0xdf,0xc3,0x05,0x9a,0x4f,0x99,0xac,0xbd,0x8a,0xc7,0xbd,0x99,0xdc,0xe3,0xef,0xa4,0x9f,0x54,0x26}, {0xd6,0xf9,0x6b,0x1e,0x46,0x5a,0x1d,0x74,0x81,0xa5,0x77,0x77,0xfc,0xb3,0x05,0x23,0xd9,0xd3,0x74,0x64,0xa2,0x74,0x55,0xd4,0xff,0xe0,0x01,0x64,0xdc,0xe1,0x26,0x19,0x6e,0x66,0x3f,0xaf,0x49,0x85,0x46,0xdb,0xa5,0x0e,0x4a,0xf1,0x04,0xcf,0x7f,0xd7,0x47,0x0c,0xba,0xa4,0xf7,0x3f,0xf2,0x3d,0x85,0x3c,0xce,0x32,0xe1,0xdf,0x10,0x3a,0xa0,0xce,0x17,0xea,0x8a,0x4e,0x7f,0xe0,0xfd,0xc1,0x1f,0x3a,0x46,0x15,0xd5,0x2f,0xf1,0xc0,0xf2,0x31,0xfd,0x22,0x53,0x17,0x15,0x5d,0x1e,0x86,0x1d,0xd0,0xa1,0x1f}, {0x32,0x98,0x59,0x7d,0x94,0x55,0x80,0xcc,0x20,0x55,0xf1,0x37,0xda,0x56,0x46,0x1e,0x20,0x93,0x05,0x4e,0x74,0xf7,0xf6,0x99,0x33,0xcf,0x75,0x6a,0xbc,0x63,0x35,0x77,0xab,0x94,0xdf,0xd1,0x00,0xac,0xdc,0x38,0xe9,0x0d,0x08,0xd1,0xdd,0x2b,0x71,0x2e,0x62,0xe2,0xd5,0xfd,0x3e,0xe9,0x13,0x7f,0xe5,0x01,0x9a,0xee,0x18,0xed,0xfc,0x73,0xb3,0x9c,0x13,0x63,0x08,0xe9,0xb1,0x06,0xcd,0x3e,0xa0,0xc5,0x67,0xda,0x93,0xa4,0x32,0x89,0x63,0xad,0xc8,0xce,0x77,0x8d,0x44,0x4f,0x86,0x1b,0x70,0x6b,0x42,0x1f}, {0x01,0x1c,0x91,0x41,0x4c,0x26,0xc9,0xef,0x25,0x2c,0xa2,0x17,0xb8,0xb7,0xa3,0xf1,0x47,0x14,0x0f,0xf3,0x6b,0xda,0x75,0x58,0x90,0xb0,0x31,0x1d,0x27,0xf5,0x1a,0x4e,0x52,0x25,0xa1,0x91,0xc8,0x35,0x7e,0xf1,0x76,0x9c,0x5e,0x57,0x53,0x81,0x6b,0xb7,0x3e,0x72,0x9b,0x0d,0x6f,0x40,0x83,0xfa,0x38,0xe4,0xa7,0x3f,0x1b,0xbb,0x76,0x0b,0x9b,0x93,0x92,0x7f,0xf9,0xc1,0xb8,0x08,0x6e,0xab,0x44,0xd4,0xcb,0x71,0x67,0xbe,0x17,0x80,0xbb,0x99,0x63,0x64,0xe5,0x22,0x55,0xa9,0x72,0xb7,0x1e,0xd6,0x6d,0x7b}, {0x92,0x3d,0xf3,0x50,0xe8,0xc1,0xad,0xb7,0xcf,0xd5,0x8c,0x60,0x4f,0xfa,0x98,0x79,0xdb,0x5b,0xfc,0x8d,0xbd,0x2d,0x96,0xad,0x4f,0x2f,0x1d,0xaf,0xce,0x9b,0x3e,0x70,0xc7,0xd2,0x01,0xab,0xf9,0xab,0x30,0x57,0x18,0x3b,0x14,0x40,0xdc,0x76,0xfb,0x16,0x81,0xb2,0xcb,0xa0,0x65,0xbe,0x6c,0x86,0xfe,0x6a,0xff,0x9b,0x65,0x9b,0xfa,0x53,0x55,0x54,0x88,0x94,0xe9,0xc8,0x14,0x6c,0xe5,0xd4,0xae,0x65,0x66,0x5d,0x3a,0x84,0xf1,0x5a,0xd6,0xbc,0x3e,0xb7,0x1b,0x18,0x50,0x1f,0xc6,0xc4,0xe5,0x93,0x8d,0x39}, {0xf3,0x48,0xe2,0x33,0x67,0xd1,0x4b,0x1c,0x5f,0x0a,0xbf,0x15,0x87,0x12,0x9e,0xbd,0x76,0x03,0x0b,0xa1,0xf0,0x8c,0x3f,0xd4,0x13,0x1b,0x19,0xdf,0x5d,0x9b,0xb0,0x53,0xf2,0xe3,0xe7,0xd2,0x60,0x7c,0x87,0xc3,0xb1,0x8b,0x82,0x30,0xa0,0xaa,0x34,0x3b,0x38,0xf1,0x9e,0x73,0xe7,0x26,0x3e,0x28,0x77,0x05,0xc3,0x02,0x90,0x9c,0x9c,0x69,0xcc,0xf1,0x46,0x59,0x23,0xa7,0x06,0xf3,0x7d,0xd9,0xe5,0xcc,0xb5,0x18,0x17,0x92,0x75,0xe9,0xb4,0x81,0x47,0xd2,0xcd,0x28,0x07,0xd9,0xcd,0x6f,0x0c,0xf3,0xca,0x51}, {0x0a,0xe0,0x74,0x76,0x42,0xa7,0x0b,0xa6,0xf3,0x7b,0x7a,0xa1,0x70,0x85,0x0e,0x63,0xcc,0x24,0x33,0xcf,0x3d,0x56,0x58,0x37,0xaa,0xfd,0x83,0x23,0x29,0xaa,0x04,0x55,0xc7,0x54,0xac,0x18,0x9a,0xf9,0x7a,0x73,0x0f,0xb3,0x1c,0xc5,0xdc,0x78,0x33,0x90,0xc7,0x0c,0xe1,0x4c,0x33,0xbc,0x89,0x2b,0x9a,0xe9,0xf8,0x89,0xc1,0x29,0xae,0x12,0xcf,0x01,0x0d,0x1f,0xcb,0xc0,0x9e,0xa9,0xae,0xf7,0x34,0x3a,0xcc,0xef,0xd1,0x0d,0x22,0x4e,0x9c,0xd0,0x21,0x75,0xca,0x55,0xea,0xa5,0xeb,0x58,0xe9,0x4f,0xd1,0x5f}, {0x2c,0xab,0x45,0x28,0xdf,0x2d,0xdc,0xb5,0x93,0xe9,0x7f,0x0a,0xb1,0x91,0x94,0x06,0x46,0xe3,0x02,0x40,0xd6,0xf3,0xaa,0x4d,0xd1,0x74,0x64,0x58,0x6e,0xf2,0x3f,0x09,0x8e,0xcb,0x93,0xbf,0x5e,0xfe,0x42,0x3c,0x5f,0x56,0xd4,0x36,0x51,0xa8,0xdf,0xbe,0xe8,0x20,0x42,0x88,0x9e,0x85,0xf0,0xe0,0x28,0xd1,0x25,0x07,0x96,0x3f,0xd7,0x7d,0x29,0x98,0x05,0x68,0xfe,0x24,0x0d,0xb1,0xe5,0x23,0xaf,0xdb,0x72,0x06,0x73,0x75,0x29,0xac,0x57,0xb4,0x3a,0x25,0x67,0x13,0xa4,0x70,0xb4,0x86,0xbc,0xbc,0x59,0x2f}, {0x5f,0x13,0x17,0x99,0x42,0x7d,0x84,0x83,0xd7,0x03,0x7d,0x56,0x1f,0x91,0x1b,0xad,0xd1,0xaa,0x77,0xbe,0xd9,0x48,0x77,0x7e,0x4a,0xaf,0x51,0x2e,0x2e,0xb4,0x58,0x54,0x01,0xc3,0x91,0xb6,0x60,0xd5,0x41,0x70,0x1e,0xe7,0xd7,0xad,0x3f,0x1b,0x20,0x85,0x85,0x55,0x33,0x11,0x63,0xe1,0xc2,0x16,0xb1,0x28,0x08,0x01,0x3d,0x5e,0xa5,0x2a,0x4f,0x44,0x07,0x0c,0xe6,0x92,0x51,0xed,0x10,0x1d,0x42,0x74,0x2d,0x4e,0xc5,0x42,0x64,0xc8,0xb5,0xfd,0x82,0x4c,0x2b,0x35,0x64,0x86,0x76,0x8a,0x4a,0x00,0xe9,0x13}, {0xdb,0xce,0x2f,0x83,0x45,0x88,0x9d,0x73,0x63,0xf8,0x6b,0xae,0xc9,0xd6,0x38,0xfa,0xf7,0xfe,0x4f,0xb7,0xca,0x0d,0xbc,0x32,0x5e,0xe4,0xbc,0x14,0x88,0x7e,0x93,0x73,0x7f,0x87,0x3b,0x19,0xc9,0x00,0x2e,0xbb,0x6b,0x50,0xdc,0xe0,0x90,0xa8,0xe3,0xec,0x9f,0x64,0xde,0x36,0xc0,0xb7,0xf3,0xec,0x1a,0x9e,0xde,0x98,0x08,0x04,0x46,0x5f,0x8d,0xf4,0x7b,0x29,0x16,0x71,0x03,0xb9,0x34,0x68,0xf0,0xd4,0x22,0x3b,0xd1,0xa9,0xc6,0xbd,0x96,0x46,0x57,0x15,0x97,0xe1,0x35,0xe8,0xd5,0x91,0xe8,0xa4,0xf8,0x2c}, {0x67,0x0f,0x11,0x07,0x87,0xfd,0x93,0x6d,0x49,0xb5,0x38,0x7c,0xd3,0x09,0x4c,0xdd,0x86,0x6a,0x73,0xc2,0x4c,0x6a,0xb1,0x7c,0x09,0x2a,0x25,0x58,0x6e,0xbd,0x49,0x20,0xa2,0x6b,0xd0,0x17,0x7e,0x48,0xb5,0x2c,0x6b,0x19,0x50,0x39,0x1c,0x38,0xd2,0x24,0x30,0x8a,0x97,0x85,0x81,0x9c,0x65,0xd7,0xf6,0xa4,0xd6,0x91,0x28,0x7f,0x6f,0x7a,0x49,0xef,0x9a,0x6a,0x8d,0xfd,0x09,0x7d,0x0b,0xb9,0x3d,0x5b,0xbe,0x60,0xee,0xf0,0xd4,0xbf,0x9e,0x51,0x2c,0xb5,0x21,0x4c,0x1d,0x94,0x45,0xc5,0xdf,0xaa,0x11,0x60}, {0x3c,0xf8,0x95,0xcf,0x6d,0x92,0x67,0x5f,0x71,0x90,0x28,0x71,0x61,0x85,0x7e,0x7c,0x5b,0x7a,0x8f,0x99,0xf3,0xe7,0xa1,0xd6,0xe0,0xf9,0x62,0x0b,0x1b,0xcc,0xc5,0x6f,0x90,0xf8,0xcb,0x02,0xc8,0xd0,0xde,0x63,0xaa,0x6a,0xff,0x0d,0xca,0x98,0xd0,0xfb,0x99,0xed,0xb6,0xb9,0xfd,0x0a,0x4d,0x62,0x1e,0x0b,0x34,0x79,0xb7,0x18,0xce,0x69,0xcb,0x79,0x98,0xb2,0x28,0x55,0xef,0xd1,0x92,0x90,0x7e,0xd4,0x3c,0xae,0x1a,0xdd,0x52,0x23,0x9f,0x18,0x42,0x04,0x7e,0x12,0xf1,0x01,0x71,0xe5,0x3a,0x6b,0x59,0x15}, {0xa2,0x79,0x91,0x3f,0xd2,0x39,0x27,0x46,0xcf,0xdd,0xd6,0x97,0x31,0x12,0x83,0xff,0x8a,0x14,0xf2,0x53,0xb5,0xde,0x07,0x13,0xda,0x4d,0x5f,0x7b,0x68,0x37,0x22,0x0d,0xca,0x24,0x51,0x7e,0x16,0x31,0xff,0x09,0xdf,0x45,0xc7,0xd9,0x8b,0x15,0xe4,0x0b,0xe5,0x56,0xf5,0x7e,0x22,0x7d,0x2b,0x29,0x38,0xd1,0xb6,0xaf,0x41,0xe2,0xa4,0x3a,0xf5,0x05,0x33,0x2a,0xbf,0x38,0xc1,0x2c,0xc3,0x26,0xe9,0xa2,0x8f,0x3f,0x58,0x48,0xeb,0xd2,0x49,0x55,0xa2,0xb1,0x3a,0x08,0x6c,0xa3,0x87,0x46,0x6e,0xaa,0xfc,0x32}, {0xf5,0x9a,0x7d,0xc5,0x8d,0x6e,0xc5,0x7b,0xf2,0xbd,0xf0,0x9d,0xed,0xd2,0x0b,0x3e,0xa3,0xe4,0xef,0x22,0xde,0x14,0xc0,0xaa,0x5c,0x6a,0xbd,0xfe,0xce,0xe9,0x27,0x46,0xdf,0xcc,0x87,0x27,0x73,0xa4,0x07,0x32,0xf8,0xe3,0x13,0xf2,0x08,0x19,0xe3,0x17,0x4e,0x96,0x0d,0xf6,0xd7,0xec,0xb2,0xd5,0xe9,0x0b,0x60,0xc2,0x36,0x63,0x6f,0x74,0x1c,0x97,0x6c,0xab,0x45,0xf3,0x4a,0x3f,0x1f,0x73,0x43,0x99,0x72,0xeb,0x88,0xe2,0x6d,0x18,0x44,0x03,0x8a,0x6a,0x59,0x33,0x93,0x62,0xd6,0x7e,0x00,0x17,0x49,0x7b}, {0x64,0xb0,0x84,0xab,0x5c,0xfb,0x85,0x2d,0x14,0xbc,0xf3,0x89,0xd2,0x10,0x78,0x49,0x0c,0xce,0x15,0x7b,0x44,0xdc,0x6a,0x47,0x7b,0xfd,0x44,0xf8,0x76,0xa3,0x2b,0x12,0xdd,0xa2,0x53,0xdd,0x28,0x1b,0x34,0x54,0x3f,0xfc,0x42,0xdf,0x5b,0x90,0x17,0xaa,0xf4,0xf8,0xd2,0x4d,0xd9,0x92,0xf5,0x0f,0x7d,0xd3,0x8c,0xe0,0x0f,0x62,0x03,0x1d,0x54,0xe5,0xb4,0xa2,0xcd,0x32,0x02,0xc2,0x7f,0x18,0x5d,0x11,0x42,0xfd,0xd0,0x9e,0xd9,0x79,0xd4,0x7d,0xbe,0xb4,0xab,0x2e,0x4c,0xec,0x68,0x2b,0xf5,0x0b,0xc7,0x02}, {0xbb,0x2f,0x0b,0x5d,0x4b,0xec,0x87,0xa2,0xca,0x82,0x48,0x07,0x90,0x57,0x5c,0x41,0x5c,0x81,0xd0,0xc1,0x1e,0xa6,0x44,0xe0,0xe0,0xf5,0x9e,0x40,0x0a,0x4f,0x33,0x26,0xe1,0x72,0x8d,0x45,0xbf,0x32,0xe5,0xac,0xb5,0x3c,0xb7,0x7c,0xe0,0x68,0xe7,0x5b,0xe7,0xbd,0x8b,0xee,0x94,0x7d,0xcf,0x56,0x03,0x3a,0xb4,0xfe,0xe3,0x97,0x06,0x6b,0xc0,0xa3,0x62,0xdf,0x4a,0xf0,0xc8,0xb6,0x5d,0xa4,0x6d,0x07,0xef,0x00,0xf0,0x3e,0xa9,0xd2,0xf0,0x49,0x58,0xb9,0x9c,0x9c,0xae,0x2f,0x1b,0x44,0x43,0x7f,0xc3,0x1c}, {0x4f,0x32,0xc7,0x5c,0x5a,0x56,0x8f,0x50,0x22,0xa9,0x06,0xe5,0xc0,0xc4,0x61,0xd0,0x19,0xac,0x45,0x5c,0xdb,0xab,0x18,0xfb,0x4a,0x31,0x80,0x03,0xc1,0x09,0x68,0x6c,0xb9,0xae,0xce,0xc9,0xf1,0x56,0x66,0xd7,0x6a,0x65,0xe5,0x18,0xf8,0x15,0x5b,0x1c,0x34,0x23,0x4c,0x84,0x32,0x28,0xe7,0x26,0x38,0x68,0x19,0x2f,0x77,0x6f,0x34,0x3a,0xc8,0x6a,0xda,0xe2,0x12,0x51,0xd5,0xd2,0xed,0x51,0xe8,0xb1,0x31,0x03,0xbd,0xe9,0x62,0x72,0xc6,0x8e,0xdd,0x46,0x07,0x96,0xd0,0xc5,0xf7,0x6e,0x9f,0x1b,0x91,0x05}, {0xbb,0x0e,0xdf,0xf5,0x83,0x99,0x33,0xc1,0xac,0x4c,0x2c,0x51,0x8f,0x75,0xf3,0xc0,0xe1,0x98,0xb3,0x0b,0x0a,0x13,0xf1,0x2c,0x62,0x0c,0x27,0xaa,0xf9,0xec,0x3c,0x6b,0xef,0xea,0x2e,0x51,0xf3,0xac,0x49,0x53,0x49,0xcb,0xc1,0x1c,0xd3,0x41,0xc1,0x20,0x8d,0x68,0x9a,0xa9,0x07,0x0c,0x18,0x24,0x17,0x2d,0x4b,0xc6,0xd1,0xf9,0x5e,0x55,0x08,0xbd,0x73,0x3b,0xba,0x70,0xa7,0x36,0x0c,0xbf,0xaf,0xa3,0x08,0xef,0x4a,0x62,0xf2,0x46,0x09,0xb4,0x98,0xff,0x37,0x57,0x9d,0x74,0x81,0x33,0xe1,0x4d,0x5f,0x67}, {0xfc,0x82,0x17,0x6b,0x03,0x52,0x2c,0x0e,0xb4,0x83,0xad,0x6c,0x81,0x6c,0x81,0x64,0x3e,0x07,0x64,0x69,0xd9,0xbd,0xdc,0xd0,0x20,0xc5,0x64,0x01,0xf7,0x9d,0xd9,0x13,0x1d,0xb3,0xda,0x3b,0xd9,0xf6,0x2f,0xa1,0xfe,0x2d,0x65,0x9d,0x0f,0xd8,0x25,0x07,0x87,0x94,0xbe,0x9a,0xf3,0x4f,0x9c,0x01,0x43,0x3c,0xcd,0x82,0xb8,0x50,0xf4,0x60,0xca,0xc0,0xe5,0x21,0xc3,0x5e,0x4b,0x01,0xa2,0xbf,0x19,0xd7,0xc9,0x69,0xcb,0x4f,0xa0,0x23,0x00,0x75,0x18,0x1c,0x5f,0x4e,0x80,0xac,0xed,0x55,0x9e,0xde,0x06,0x1c}, {0xe2,0xc4,0x3e,0xa3,0xd6,0x7a,0x0f,0x99,0x8e,0xe0,0x2e,0xbe,0x38,0xf9,0x08,0x66,0x15,0x45,0x28,0x63,0xc5,0x43,0xa1,0x9c,0x0d,0xb6,0x2d,0xec,0x1f,0x8a,0xf3,0x4c,0xaa,0x69,0x6d,0xff,0x40,0x2b,0xd5,0xff,0xbb,0x49,0x40,0xdc,0x18,0x0b,0x53,0x34,0x97,0x98,0x4d,0xa3,0x2f,0x5c,0x4a,0x5e,0x2d,0xba,0x32,0x7d,0x8e,0x6f,0x09,0x78,0xe7,0x5c,0xfa,0x0d,0x65,0xaa,0xaa,0xa0,0x8c,0x47,0xb5,0x48,0x2a,0x9e,0xc4,0xf9,0x5b,0x72,0x03,0x70,0x7d,0xcc,0x09,0x4f,0xbe,0x1a,0x09,0x26,0x3a,0xad,0x3c,0x37}, {0x7c,0xf5,0xc9,0x82,0x4d,0x63,0x94,0xb2,0x36,0x45,0x93,0x24,0xe1,0xfd,0xcb,0x1f,0x5a,0xdb,0x8c,0x41,0xb3,0x4d,0x9c,0x9e,0xfc,0x19,0x44,0x45,0xd9,0xf3,0x40,0x00,0xad,0xbb,0xdd,0x89,0xfb,0xa8,0xbe,0xf1,0xcb,0xae,0xae,0x61,0xbc,0x2c,0xcb,0x3b,0x9d,0x8d,0x9b,0x1f,0xbb,0xa7,0x58,0x8f,0x86,0xa6,0x12,0x51,0xda,0x7e,0x54,0x21,0xd3,0x86,0x59,0xfd,0x39,0xe9,0xfd,0xde,0x0c,0x38,0x0a,0x51,0x89,0x2c,0x27,0xf4,0xb9,0x19,0x31,0xbb,0x07,0xa4,0x2b,0xb7,0xf4,0x4d,0x25,0x4a,0x33,0x0a,0x55,0x63}, {0x37,0xcf,0x69,0xb5,0xed,0xd6,0x07,0x65,0xe1,0x2e,0xa5,0x0c,0xb0,0x29,0x84,0x17,0x5d,0xd6,0x6b,0xeb,0x90,0x00,0x7c,0xea,0x51,0x8f,0xf7,0xda,0xc7,0x62,0xea,0x3e,0x49,0x7b,0x54,0x72,0x45,0x58,0xba,0x9b,0xe0,0x08,0xc4,0xe2,0xfa,0xc6,0x05,0xf3,0x8d,0xf1,0x34,0xc7,0x69,0xfa,0xe8,0x60,0x7a,0x76,0x7d,0xaa,0xaf,0x2b,0xa9,0x39,0x4e,0x27,0x93,0xe6,0x13,0xc7,0x24,0x9d,0x75,0xd3,0xdb,0x68,0x77,0x85,0x63,0x5f,0x9a,0xb3,0x8a,0xeb,0x60,0x55,0x52,0x70,0xcd,0xc4,0xc9,0x65,0x06,0x6a,0x43,0x68}, {0x27,0x3f,0x2f,0x20,0xe8,0x35,0x02,0xbc,0xb0,0x75,0xf9,0x64,0xe2,0x00,0x5c,0xc7,0x16,0x24,0x8c,0xa3,0xd5,0xe9,0xa4,0x91,0xf9,0x89,0xb7,0x8a,0xf6,0xe7,0xb6,0x17,0x7c,0x10,0x20,0xe8,0x17,0xd3,0x56,0x1e,0x65,0xe9,0x0a,0x84,0x44,0x68,0x26,0xc5,0x7a,0xfc,0x0f,0x32,0xc6,0xa1,0xe0,0xc1,0x72,0x14,0x61,0x91,0x9c,0x66,0x73,0x53,0x57,0x52,0x0e,0x9a,0xab,0x14,0x28,0x5d,0xfc,0xb3,0xca,0xc9,0x84,0x20,0x8f,0x90,0xca,0x1e,0x2d,0x5b,0x88,0xf5,0xca,0xaf,0x11,0x7d,0xf8,0x78,0xa6,0xb5,0xb4,0x1c}, {0x6c,0xfc,0x4a,0x39,0x6b,0xc0,0x64,0xb6,0xb1,0x5f,0xda,0x98,0x24,0xde,0x88,0x0c,0x34,0xd8,0xca,0x4b,0x16,0x03,0x8d,0x4f,0xa2,0x34,0x74,0xde,0x78,0xca,0x0b,0x33,0xe7,0x07,0xa0,0xa2,0x62,0xaa,0x74,0x6b,0xb1,0xc7,0x71,0xf0,0xb0,0xe0,0x11,0xf3,0x23,0xe2,0x0b,0x00,0x38,0xe4,0x07,0x57,0xac,0x6e,0xef,0x82,0x2d,0xfd,0xc0,0x2d,0x4e,0x74,0x19,0x11,0x84,0xff,0x2e,0x98,0x24,0x47,0x07,0x2b,0x96,0x5e,0x69,0xf9,0xfb,0x53,0xc9,0xbf,0x4f,0xc1,0x8a,0xc5,0xf5,0x1c,0x9f,0x36,0x1b,0xbe,0x31,0x3c}, {0xee,0x8a,0x94,0x08,0x4d,0x86,0xf4,0xb0,0x6f,0x1c,0xba,0x91,0xee,0x19,0xdc,0x07,0x58,0xa1,0xac,0xa6,0xae,0xcd,0x75,0x79,0xbb,0xd4,0x62,0x42,0x13,0x61,0x0b,0x33,0x72,0x42,0xcb,0xf9,0x93,0xbc,0x68,0xc1,0x98,0xdb,0xce,0xc7,0x1f,0x71,0xb8,0xae,0x7a,0x8d,0xac,0x34,0xaa,0x52,0x0e,0x7f,0xbb,0x55,0x7d,0x7e,0x09,0xc1,0xce,0x41,0x8a,0x80,0x6d,0xa2,0xd7,0x19,0x96,0xf7,0x6d,0x15,0x9e,0x1d,0x9e,0xd4,0x1f,0xbb,0x27,0xdf,0xa1,0xdb,0x6c,0xc3,0xd7,0x73,0x7d,0x77,0x28,0x1f,0xd9,0x4c,0xb4,0x26}, {0x75,0x74,0x38,0x8f,0x47,0x48,0xf0,0x51,0x3c,0xcb,0xbe,0x9c,0xf4,0xbc,0x5d,0xb2,0x55,0x20,0x9f,0xd9,0x44,0x12,0xab,0x9a,0xd6,0xa5,0x10,0x1c,0x6c,0x9e,0x70,0x2c,0x83,0x03,0x73,0x62,0x93,0xf2,0xb7,0xe1,0x2c,0x8a,0xca,0xeb,0xff,0x79,0x52,0x4b,0x14,0x13,0xd4,0xbf,0x8a,0x77,0xfc,0xda,0x0f,0x61,0x72,0x9c,0x14,0x10,0xeb,0x7d,0x7a,0xee,0x66,0x87,0x6a,0xaf,0x62,0xcb,0x0e,0xcd,0x53,0x55,0x04,0xec,0xcb,0x66,0xb5,0xe4,0x0b,0x0f,0x38,0x01,0x80,0x58,0xea,0xe2,0x2c,0xf6,0x9f,0x8e,0xe6,0x08}, {0xad,0x30,0xc1,0x4b,0x0a,0x50,0xad,0x34,0x9c,0xd4,0x0b,0x3d,0x49,0xdb,0x38,0x8d,0xbe,0x89,0x0a,0x50,0x98,0x3d,0x5c,0xa2,0x09,0x3b,0xba,0xee,0x87,0x3f,0x1f,0x2f,0xf9,0xf2,0xb8,0x0a,0xd5,0x09,0x2d,0x2f,0xdf,0x23,0x59,0xc5,0x8d,0x21,0xb9,0xac,0xb9,0x6c,0x76,0x73,0x26,0x34,0x8f,0x4a,0xf5,0x19,0xf7,0x38,0xd7,0x3b,0xb1,0x4c,0x4a,0xb6,0x15,0xe5,0x75,0x8c,0x84,0xf7,0x38,0x90,0x4a,0xdb,0xba,0x01,0x95,0xa5,0x50,0x1b,0x75,0x3f,0x3f,0x31,0x0d,0xc2,0xe8,0x2e,0xae,0xc0,0x53,0xe3,0xa1,0x19}, {0xc3,0x05,0xfa,0xba,0x60,0x75,0x1c,0x7d,0x61,0x5e,0xe5,0xc6,0xa0,0xa0,0xe1,0xb3,0x73,0x64,0xd6,0xc0,0x18,0x97,0x52,0xe3,0x86,0x34,0x0c,0xc2,0x11,0x6b,0x54,0x41,0xbd,0xbd,0x96,0xd5,0xcd,0x72,0x21,0xb4,0x40,0xfc,0xee,0x98,0x43,0x45,0xe0,0x93,0xb5,0x09,0x41,0xb4,0x47,0x53,0xb1,0x9f,0x34,0xae,0x66,0x02,0x99,0xd3,0x6b,0x73,0xb4,0xb3,0x34,0x93,0x50,0x2d,0x53,0x85,0x73,0x65,0x81,0x60,0x4b,0x11,0xfd,0x46,0x75,0x83,0x5c,0x42,0x30,0x5f,0x5f,0xcc,0x5c,0xab,0x7f,0xb8,0xa2,0x95,0x22,0x41}, {0xe9,0xd6,0x7e,0xf5,0x88,0x9b,0xc9,0x19,0x25,0xc8,0xf8,0x6d,0x26,0xcb,0x93,0x53,0x73,0xd2,0x0a,0xb3,0x13,0x32,0xee,0x5c,0x34,0x2e,0x2d,0xb5,0xeb,0x53,0xe1,0x14,0xc6,0xea,0x93,0xe2,0x61,0x52,0x65,0x2e,0xdb,0xac,0x33,0x21,0x03,0x92,0x5a,0x84,0x6b,0x99,0x00,0x79,0xcb,0x75,0x09,0x46,0x80,0xdd,0x5a,0x19,0x8d,0xbb,0x60,0x07,0x8a,0x81,0xe6,0xcd,0x17,0x1a,0x3e,0x41,0x84,0xa0,0x69,0xed,0xa9,0x6d,0x15,0x57,0xb1,0xcc,0xca,0x46,0x8f,0x26,0xbf,0x2c,0xf2,0xc5,0x3a,0xc3,0x9b,0xbe,0x34,0x6b}, {0xb2,0xc0,0x78,0x3a,0x64,0x2f,0xdf,0xf3,0x7c,0x02,0x2e,0xf2,0x1e,0x97,0x3e,0x4c,0xa3,0xb5,0xc1,0x49,0x5e,0x1c,0x7d,0xec,0x2d,0xdd,0x22,0x09,0x8f,0xc1,0x12,0x20,0xd3,0xf2,0x71,0x65,0x65,0x69,0xfc,0x11,0x7a,0x73,0x0e,0x53,0x45,0xe8,0xc9,0xc6,0x35,0x50,0xfe,0xd4,0xa2,0xe7,0x3a,0xe3,0x0b,0xd3,0x6d,0x2e,0xb6,0xc7,0xb9,0x01,0x29,0x9d,0xc8,0x5a,0xe5,0x55,0x0b,0x88,0x63,0xa7,0xa0,0x45,0x1f,0x24,0x83,0x14,0x1f,0x6c,0xe7,0xc2,0xdf,0xef,0x36,0x3d,0xe8,0xad,0x4b,0x4e,0x78,0x5b,0xaf,0x08}, {0x33,0x25,0x1f,0x88,0xdc,0x99,0x34,0x28,0xb6,0x23,0x93,0x77,0xda,0x25,0x05,0x9d,0xf4,0x41,0x34,0x67,0xfb,0xdd,0x7a,0x89,0x8d,0x16,0x3a,0x16,0x71,0x9d,0xb7,0x32,0x4b,0x2c,0xcc,0x89,0xd2,0x14,0x73,0xe2,0x8d,0x17,0x87,0xa2,0x11,0xbd,0xe4,0x4b,0xce,0x64,0x33,0xfa,0xd6,0x28,0xd5,0x18,0x6e,0x82,0xd9,0xaf,0xd5,0xc1,0x23,0x64,0x6a,0xb3,0xfc,0xed,0xd9,0xf8,0x85,0xcc,0xf9,0xe5,0x46,0x37,0x8f,0xc2,0xbc,0x22,0xcd,0xd3,0xe5,0xf9,0x38,0xe3,0x9d,0xe4,0xcc,0x2d,0x3e,0xc1,0xfb,0x5e,0x0a,0x48}, {0x71,0x20,0x62,0x01,0x0b,0xe7,0x51,0x0b,0xc5,0xaf,0x1d,0x8b,0xcf,0x05,0xb5,0x06,0xcd,0xab,0x5a,0xef,0x61,0xb0,0x6b,0x2c,0x31,0xbf,0xb7,0x0c,0x60,0x27,0xaa,0x47,0x1f,0x22,0xce,0x42,0xe4,0x4c,0x61,0xb6,0x28,0x39,0x05,0x4c,0xcc,0x9d,0x19,0x6e,0x03,0xbe,0x1c,0xdc,0xa4,0xb4,0x3f,0x66,0x06,0x8e,0x1c,0x69,0x47,0x1d,0xb3,0x24,0xc3,0xf8,0x15,0xc0,0xed,0x1e,0x54,0x2a,0x7c,0x3f,0x69,0x7c,0x7e,0xfe,0xa4,0x11,0xd6,0x78,0xa2,0x4e,0x13,0x66,0xaf,0xf0,0x94,0xa0,0xdd,0x14,0x5d,0x58,0x5b,0x54}, {0x0f,0x3a,0xd4,0xa0,0x5e,0x27,0xbf,0x67,0xbe,0xee,0x9b,0x08,0x34,0x8e,0xe6,0xad,0x2e,0xe7,0x79,0xd4,0x4c,0x13,0x89,0x42,0x54,0x54,0xba,0x32,0xc3,0xf9,0x62,0x0f,0xe1,0x21,0xb3,0xe3,0xd0,0xe4,0x04,0x62,0x95,0x1e,0xff,0x28,0x7a,0x63,0xaa,0x3b,0x9e,0xbd,0x99,0x5b,0xfd,0xcf,0x0c,0x0b,0x71,0xd0,0xc8,0x64,0x3e,0xdc,0x22,0x4d,0x39,0x5f,0x3b,0xd6,0x89,0x65,0xb4,0xfc,0x61,0xcf,0xcb,0x57,0x3f,0x6a,0xae,0x5c,0x05,0xfa,0x3a,0x95,0xd2,0xc2,0xba,0xfe,0x36,0x14,0x37,0x36,0x1a,0xa0,0x0f,0x1c}, {0xff,0x3d,0x94,0x22,0xb6,0x04,0xc6,0xd2,0xa0,0xb3,0xcf,0x44,0xce,0xbe,0x8c,0xbc,0x78,0x86,0x80,0x97,0xf3,0x4f,0x25,0x5d,0xbf,0xa6,0x1c,0x3b,0x4f,0x61,0xa3,0x0f,0x50,0x6a,0x93,0x8c,0x0e,0x2b,0x08,0x69,0xb6,0xc5,0xda,0xc1,0x35,0xa0,0xc9,0xf9,0x34,0xb6,0xdf,0xc4,0x54,0x3e,0xb7,0x6f,0x40,0xc1,0x2b,0x1d,0x9b,0x41,0x05,0x40,0xf0,0x82,0xbe,0xb9,0xbd,0xfe,0x03,0xa0,0x90,0xac,0x44,0x3a,0xaf,0xc1,0x89,0x20,0x8e,0xfa,0x54,0x19,0x91,0x9f,0x49,0xf8,0x42,0xab,0x40,0xef,0x8a,0x21,0xba,0x1f}, {0x3e,0xf5,0xc8,0xfa,0x48,0x94,0x54,0xab,0x41,0x37,0xa6,0x7b,0x9a,0xe8,0xf6,0x81,0x01,0x5e,0x2b,0x6c,0x7d,0x6c,0xfd,0x74,0x42,0x6e,0xc8,0xa8,0xca,0x3a,0x2e,0x39,0x94,0x01,0x7b,0x3e,0x04,0x57,0x3e,0x4f,0x7f,0xaf,0xda,0x08,0xee,0x3e,0x1d,0xa8,0xf1,0xde,0xdc,0x99,0xab,0xc6,0x39,0xc8,0xd5,0x61,0x77,0xff,0x13,0x5d,0x53,0x6c,0xaf,0x35,0x8a,0x3e,0xe9,0x34,0xbd,0x4c,0x16,0xe8,0x87,0x58,0x44,0x81,0x07,0x2e,0xab,0xb0,0x9a,0xf2,0x76,0x9c,0x31,0x19,0x3b,0xc1,0x0a,0xd5,0xe4,0x7f,0xe1,0x25}, {0x76,0xf6,0x04,0x1e,0xd7,0x9b,0x28,0x0a,0x95,0x0f,0x42,0xd6,0x52,0x1c,0x8e,0x20,0xab,0x1f,0x69,0x34,0xb0,0xd8,0x86,0x51,0x51,0xb3,0x9f,0x2a,0x44,0x51,0x57,0x25,0xa7,0x21,0xf1,0x76,0xf5,0x7f,0x5f,0x91,0xe3,0x87,0xcd,0x2f,0x27,0x32,0x4a,0xc3,0x26,0xe5,0x1b,0x4d,0xde,0x2f,0xba,0xcc,0x9b,0x89,0x69,0x89,0x8f,0x82,0xba,0x6b,0x01,0x39,0xfe,0x90,0x66,0xbc,0xd1,0xe2,0xd5,0x7a,0x99,0xa0,0x18,0x4a,0xb5,0x4c,0xd4,0x60,0x84,0xaf,0x14,0x69,0x1d,0x97,0xe4,0x7b,0x6b,0x7f,0x4f,0x50,0x9d,0x55}, {0xd5,0x54,0xeb,0xb3,0x78,0x83,0x73,0xa7,0x7c,0x3c,0x55,0xa5,0x66,0xd3,0x69,0x1d,0xba,0x00,0x28,0xf9,0x62,0xcf,0x26,0x0a,0x17,0x32,0x7e,0x80,0xd5,0x12,0xab,0x01,0xfd,0x66,0xd2,0xf6,0xe7,0x91,0x48,0x9c,0x1b,0x78,0x07,0x03,0x9b,0xa1,0x44,0x07,0x3b,0xe2,0x61,0x60,0x1d,0x8f,0x38,0x88,0x0e,0xd5,0x4b,0x35,0xa3,0xa6,0x3e,0x12,0x96,0x2d,0xe3,0x41,0x90,0x18,0x8d,0x11,0x48,0x58,0x31,0xd8,0xc2,0xe3,0xed,0xb9,0xd9,0x45,0x32,0xd8,0x71,0x42,0xab,0x1e,0x54,0xa1,0x18,0xc9,0xe2,0x61,0x39,0x4a}, {0xa0,0xbb,0xe6,0xf8,0xe0,0x3b,0xdc,0x71,0x0a,0xe3,0xff,0x7e,0x34,0xf8,0xce,0xd6,0x6a,0x47,0x3a,0xe1,0x5f,0x42,0x92,0xa9,0x63,0xb7,0x1d,0xfb,0xe3,0xbc,0xd6,0x2c,0x1e,0x3f,0x23,0xf3,0x44,0xd6,0x27,0x03,0x16,0xf0,0xfc,0x34,0x0e,0x26,0x9a,0x49,0x79,0xb9,0xda,0xf2,0x16,0xa7,0xb5,0x83,0x1f,0x11,0xd4,0x9b,0xad,0xee,0xac,0x68,0x10,0xc2,0xd7,0xf3,0x0e,0xc9,0xb4,0x38,0x0c,0x04,0xad,0xb7,0x24,0x6e,0x8e,0x30,0x23,0x3e,0xe7,0xb7,0xf1,0xd9,0x60,0x38,0x97,0xf5,0x08,0xb5,0xd5,0x60,0x57,0x59}, {0x97,0x63,0xaa,0x04,0xe1,0xbf,0x29,0x61,0xcb,0xfc,0xa7,0xa4,0x08,0x00,0x96,0x8f,0x58,0x94,0x90,0x7d,0x89,0xc0,0x8b,0x3f,0xa9,0x91,0xb2,0xdc,0x3e,0xa4,0x9f,0x70,0x90,0x27,0x02,0xfd,0xeb,0xcb,0x2a,0x88,0x60,0x57,0x11,0xc4,0x05,0x33,0xaf,0x89,0xf4,0x73,0x34,0x7d,0xe3,0x92,0xf4,0x65,0x2b,0x5a,0x51,0x54,0xdf,0xc5,0xb2,0x2c,0xca,0x2a,0xfd,0x63,0x8c,0x5d,0x0a,0xeb,0xff,0x4e,0x69,0x2e,0x66,0xc1,0x2b,0xd2,0x3a,0xb0,0xcb,0xf8,0x6e,0xf3,0x23,0x27,0x1f,0x13,0xc8,0xf0,0xec,0x29,0xf0,0x70}, {0x33,0x3e,0xed,0x2e,0xb3,0x07,0x13,0x46,0xe7,0x81,0x55,0xa4,0x33,0x2f,0x04,0xae,0x66,0x03,0x5f,0x19,0xd3,0x49,0x44,0xc9,0x58,0x48,0x31,0x6c,0x8a,0x5d,0x7d,0x0b,0xb9,0xb0,0x10,0x5e,0xaa,0xaf,0x6a,0x2a,0xa9,0x1a,0x04,0xef,0x70,0xa3,0xf0,0x78,0x1f,0xd6,0x3a,0xaa,0x77,0xfb,0x3e,0x77,0xe1,0xd9,0x4b,0xa7,0xa2,0xa5,0xec,0x44,0x43,0xd5,0x95,0x7b,0x32,0x48,0xd4,0x25,0x1d,0x0f,0x34,0xa3,0x00,0x83,0xd3,0x70,0x2b,0xc5,0xe1,0x60,0x1c,0x53,0x1c,0xde,0xe4,0xe9,0x7d,0x2c,0x51,0x24,0x22,0x27}, {0x2e,0x34,0xc5,0x49,0xaf,0x92,0xbc,0x1a,0xd0,0xfa,0xe6,0xb2,0x11,0xd8,0xee,0xff,0x29,0x4e,0xc8,0xfc,0x8d,0x8c,0xa2,0xef,0x43,0xc5,0x4c,0xa4,0x18,0xdf,0xb5,0x11,0xfc,0x75,0xa9,0x42,0x8a,0xbb,0x7b,0xbf,0x58,0xa3,0xad,0x96,0x77,0x39,0x5c,0x8c,0x48,0xaa,0xed,0xcd,0x6f,0xc7,0x7f,0xe2,0xa6,0x20,0xbc,0xf6,0xd7,0x5f,0x73,0x19,0x66,0x42,0xc8,0x42,0xd0,0x90,0xab,0xe3,0x7e,0x54,0x19,0x7f,0x0f,0x8e,0x84,0xeb,0xb9,0x97,0xa4,0x65,0xd0,0xa1,0x03,0x25,0x5f,0x89,0xdf,0x91,0x11,0x91,0xef,0x0f} }; cryptonite-0.23/cbits/ed25519/ed25519-donna-batchverify.h0000644000000000000000000001673412514663134020716 0ustar0000000000000000/* Ed25519 batch verification */ #define max_batch_size 64 #define heap_batch_size ((max_batch_size * 2) + 1) /* which limb is the 128th bit in? */ static const size_t limb128bits = (128 + bignum256modm_bits_per_limb - 1) / bignum256modm_bits_per_limb; typedef size_t heap_index_t; typedef struct batch_heap_t { unsigned char r[heap_batch_size][16]; /* 128 bit random values */ ge25519 points[heap_batch_size]; bignum256modm scalars[heap_batch_size]; heap_index_t heap[heap_batch_size]; size_t size; } batch_heap; /* swap two values in the heap */ static void heap_swap(heap_index_t *heap, size_t a, size_t b) { heap_index_t temp; temp = heap[a]; heap[a] = heap[b]; heap[b] = temp; } /* add the scalar at the end of the list to the heap */ static void heap_insert_next(batch_heap *heap) { size_t node = heap->size, parent; heap_index_t *pheap = heap->heap; bignum256modm *scalars = heap->scalars; /* insert at the bottom */ pheap[node] = (heap_index_t)node; /* sift node up to its sorted spot */ parent = (node - 1) / 2; while (node && lt256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], bignum256modm_limb_size - 1)) { heap_swap(pheap, parent, node); node = parent; parent = (node - 1) / 2; } heap->size++; } /* update the heap when the root element is updated */ static void heap_updated_root(batch_heap *heap, size_t limbsize) { size_t node, parent, childr, childl; heap_index_t *pheap = heap->heap; bignum256modm *scalars = heap->scalars; /* sift root to the bottom */ parent = 0; node = 1; childl = 1; childr = 2; while ((childr < heap->size)) { node = lt256_modm_batch(scalars[pheap[childl]], scalars[pheap[childr]], limbsize) ? childr : childl; heap_swap(pheap, parent, node); parent = node; childl = (parent * 2) + 1; childr = childl + 1; } /* sift root back up to its sorted spot */ parent = (node - 1) / 2; while (node && lte256_modm_batch(scalars[pheap[parent]], scalars[pheap[node]], limbsize)) { heap_swap(pheap, parent, node); node = parent; parent = (node - 1) / 2; } } /* build the heap with count elements, count must be >= 3 */ static void heap_build(batch_heap *heap, size_t count) { heap->heap[0] = 0; heap->size = 0; while (heap->size < count) heap_insert_next(heap); } /* extend the heap to contain new_count elements */ static void heap_extend(batch_heap *heap, size_t new_count) { while (heap->size < new_count) heap_insert_next(heap); } /* get the top 2 elements of the heap */ static void heap_get_top2(batch_heap *heap, heap_index_t *max1, heap_index_t *max2, size_t limbsize) { heap_index_t h0 = heap->heap[0], h1 = heap->heap[1], h2 = heap->heap[2]; if (lt256_modm_batch(heap->scalars[h1], heap->scalars[h2], limbsize)) h1 = h2; *max1 = h0; *max2 = h1; } /* */ static void ge25519_multi_scalarmult_vartime_final(ge25519 *r, ge25519 *point, bignum256modm scalar) { const bignum256modm_element_t topbit = ((bignum256modm_element_t)1 << (bignum256modm_bits_per_limb - 1)); size_t limb = limb128bits; bignum256modm_element_t flag; if (isone256_modm_batch(scalar)) { /* this will happen most of the time after bos-carter */ *r = *point; return; } else if (iszero256_modm_batch(scalar)) { /* this will only happen if all scalars == 0 */ memset(r, 0, sizeof(*r)); r->y[0] = 1; r->z[0] = 1; return; } *r = *point; /* find the limb where first bit is set */ while (!scalar[limb]) limb--; /* find the first bit */ flag = topbit; while ((scalar[limb] & flag) == 0) flag >>= 1; /* exponentiate */ for (;;) { ge25519_double(r, r); if (scalar[limb] & flag) ge25519_add(r, r, point); flag >>= 1; if (!flag) { if (!limb--) break; flag = topbit; } } } /* count must be >= 5 */ static void ge25519_multi_scalarmult_vartime(ge25519 *r, batch_heap *heap, size_t count) { heap_index_t max1, max2; /* start with the full limb size */ size_t limbsize = bignum256modm_limb_size - 1; /* whether the heap has been extended to include the 128 bit scalars */ int extended = 0; /* grab an odd number of scalars to build the heap, unknown limb sizes */ heap_build(heap, ((count + 1) / 2) | 1); for (;;) { heap_get_top2(heap, &max1, &max2, limbsize); /* only one scalar remaining, we're done */ if (iszero256_modm_batch(heap->scalars[max2])) break; /* exhausted another limb? */ if (!heap->scalars[max1][limbsize]) limbsize -= 1; /* can we extend to the 128 bit scalars? */ if (!extended && isatmost128bits256_modm_batch(heap->scalars[max1])) { heap_extend(heap, count); heap_get_top2(heap, &max1, &max2, limbsize); extended = 1; } sub256_modm_batch(heap->scalars[max1], heap->scalars[max1], heap->scalars[max2], limbsize); ge25519_add(&heap->points[max2], &heap->points[max2], &heap->points[max1]); heap_updated_root(heap, limbsize); } ge25519_multi_scalarmult_vartime_final(r, &heap->points[max1], heap->scalars[max1]); } /* not actually used for anything other than testing */ unsigned char batch_point_buffer[3][32]; static int ge25519_is_neutral_vartime(const ge25519 *p) { static const unsigned char zero[32] = {0}; unsigned char point_buffer[3][32]; curve25519_contract(point_buffer[0], p->x); curve25519_contract(point_buffer[1], p->y); curve25519_contract(point_buffer[2], p->z); memcpy(batch_point_buffer[1], point_buffer[1], 32); return (memcmp(point_buffer[0], zero, 32) == 0) && (memcmp(point_buffer[1], point_buffer[2], 32) == 0); } int ED25519_FN(ed25519_sign_open_batch) (const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid) { batch_heap ALIGN(16) batch; ge25519 ALIGN(16) p; bignum256modm *r_scalars; size_t i, batchsize; unsigned char hram[64]; int ret = 0; for (i = 0; i < num; i++) valid[i] = 1; while (num > 3) { batchsize = (num > max_batch_size) ? max_batch_size : num; /* generate r (scalars[batchsize+1]..scalars[2*batchsize] */ ED25519_FN(ed25519_randombytes_unsafe) (batch.r, batchsize * 16); r_scalars = &batch.scalars[batchsize + 1]; for (i = 0; i < batchsize; i++) expand256_modm(r_scalars[i], batch.r[i], 16); /* compute scalars[0] = ((r1s1 + r2s2 + ...)) */ for (i = 0; i < batchsize; i++) { expand256_modm(batch.scalars[i], RS[i] + 32, 32); mul256_modm(batch.scalars[i], batch.scalars[i], r_scalars[i]); } for (i = 1; i < batchsize; i++) add256_modm(batch.scalars[0], batch.scalars[0], batch.scalars[i]); /* compute scalars[1]..scalars[batchsize] as r[i]*H(R[i],A[i],m[i]) */ for (i = 0; i < batchsize; i++) { ed25519_hram(hram, RS[i], pk[i], m[i], mlen[i]); expand256_modm(batch.scalars[i+1], hram, 64); mul256_modm(batch.scalars[i+1], batch.scalars[i+1], r_scalars[i]); } /* compute points */ batch.points[0] = ge25519_basepoint; for (i = 0; i < batchsize; i++) if (!ge25519_unpack_negative_vartime(&batch.points[i+1], pk[i])) goto fallback; for (i = 0; i < batchsize; i++) if (!ge25519_unpack_negative_vartime(&batch.points[batchsize+i+1], RS[i])) goto fallback; ge25519_multi_scalarmult_vartime(&p, &batch, (batchsize * 2) + 1); if (!ge25519_is_neutral_vartime(&p)) { ret |= 2; fallback: for (i = 0; i < batchsize; i++) { valid[i] = ED25519_FN(ed25519_sign_open) (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1; ret |= (valid[i] ^ 1); } } m += batchsize; mlen += batchsize; pk += batchsize; RS += batchsize; num -= batchsize; valid += batchsize; } for (i = 0; i < num; i++) { valid[i] = ED25519_FN(ed25519_sign_open) (m[i], mlen[i], pk[i], RS[i]) ? 0 : 1; ret |= (valid[i] ^ 1); } return ret; } cryptonite-0.23/cbits/ed25519/ed25519-donna-impl-base.h0000644000000000000000000002375412514663134020261 0ustar0000000000000000/* conversions */ DONNA_INLINE static void ge25519_p1p1_to_partial(ge25519 *r, const ge25519_p1p1 *p) { curve25519_mul(r->x, p->x, p->t); curve25519_mul(r->y, p->y, p->z); curve25519_mul(r->z, p->z, p->t); } DONNA_INLINE static void ge25519_p1p1_to_full(ge25519 *r, const ge25519_p1p1 *p) { curve25519_mul(r->x, p->x, p->t); curve25519_mul(r->y, p->y, p->z); curve25519_mul(r->z, p->z, p->t); curve25519_mul(r->t, p->x, p->y); } static void ge25519_full_to_pniels(ge25519_pniels *p, const ge25519 *r) { curve25519_sub(p->ysubx, r->y, r->x); curve25519_add(p->xaddy, r->y, r->x); curve25519_copy(p->z, r->z); curve25519_mul(p->t2d, r->t, ge25519_ec2d); } /* adding & doubling */ static void ge25519_add_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519 *q) { bignum25519 a,b,c,d,t,u; curve25519_sub(a, p->y, p->x); curve25519_add(b, p->y, p->x); curve25519_sub(t, q->y, q->x); curve25519_add(u, q->y, q->x); curve25519_mul(a, a, t); curve25519_mul(b, b, u); curve25519_mul(c, p->t, q->t); curve25519_mul(c, c, ge25519_ec2d); curve25519_mul(d, p->z, q->z); curve25519_add(d, d, d); curve25519_sub(r->x, b, a); curve25519_add(r->y, b, a); curve25519_add_after_basic(r->z, d, c); curve25519_sub_after_basic(r->t, d, c); } static void ge25519_double_p1p1(ge25519_p1p1 *r, const ge25519 *p) { bignum25519 a,b,c; curve25519_square(a, p->x); curve25519_square(b, p->y); curve25519_square(c, p->z); curve25519_add_reduce(c, c, c); curve25519_add(r->x, p->x, p->y); curve25519_square(r->x, r->x); curve25519_add(r->y, b, a); curve25519_sub(r->z, b, a); curve25519_sub_after_basic(r->x, r->x, r->y); curve25519_sub_after_basic(r->t, c, r->z); } static void ge25519_nielsadd2_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_niels *q, unsigned char signbit) { const bignum25519 *qb = (const bignum25519 *)q; bignum25519 *rb = (bignum25519 *)r; bignum25519 a,b,c; curve25519_sub(a, p->y, p->x); curve25519_add(b, p->y, p->x); curve25519_mul(a, a, qb[signbit]); /* x for +, y for - */ curve25519_mul(r->x, b, qb[signbit^1]); /* y for +, x for - */ curve25519_add(r->y, r->x, a); curve25519_sub(r->x, r->x, a); curve25519_mul(c, p->t, q->t2d); curve25519_add_reduce(r->t, p->z, p->z); curve25519_copy(r->z, r->t); curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ } static void ge25519_pnielsadd_p1p1(ge25519_p1p1 *r, const ge25519 *p, const ge25519_pniels *q, unsigned char signbit) { const bignum25519 *qb = (const bignum25519 *)q; bignum25519 *rb = (bignum25519 *)r; bignum25519 a,b,c; curve25519_sub(a, p->y, p->x); curve25519_add(b, p->y, p->x); curve25519_mul(a, a, qb[signbit]); /* ysubx for +, xaddy for - */ curve25519_mul(r->x, b, qb[signbit^1]); /* xaddy for +, ysubx for - */ curve25519_add(r->y, r->x, a); curve25519_sub(r->x, r->x, a); curve25519_mul(c, p->t, q->t2d); curve25519_mul(r->t, p->z, q->z); curve25519_add_reduce(r->t, r->t, r->t); curve25519_copy(r->z, r->t); curve25519_add(rb[2+signbit], rb[2+signbit], c); /* z for +, t for - */ curve25519_sub(rb[2+(signbit^1)], rb[2+(signbit^1)], c); /* t for +, z for - */ } static void ge25519_double_partial(ge25519 *r, const ge25519 *p) { ge25519_p1p1 t; ge25519_double_p1p1(&t, p); ge25519_p1p1_to_partial(r, &t); } static void ge25519_double(ge25519 *r, const ge25519 *p) { ge25519_p1p1 t; ge25519_double_p1p1(&t, p); ge25519_p1p1_to_full(r, &t); } static void ge25519_add(ge25519 *r, const ge25519 *p, const ge25519 *q) { ge25519_p1p1 t; ge25519_add_p1p1(&t, p, q); ge25519_p1p1_to_full(r, &t); } static void ge25519_nielsadd2(ge25519 *r, const ge25519_niels *q) { bignum25519 a,b,c,e,f,g,h; curve25519_sub(a, r->y, r->x); curve25519_add(b, r->y, r->x); curve25519_mul(a, a, q->ysubx); curve25519_mul(e, b, q->xaddy); curve25519_add(h, e, a); curve25519_sub(e, e, a); curve25519_mul(c, r->t, q->t2d); curve25519_add(f, r->z, r->z); curve25519_add_after_basic(g, f, c); curve25519_sub_after_basic(f, f, c); curve25519_mul(r->x, e, f); curve25519_mul(r->y, h, g); curve25519_mul(r->z, g, f); curve25519_mul(r->t, e, h); } static void ge25519_pnielsadd(ge25519_pniels *r, const ge25519 *p, const ge25519_pniels *q) { bignum25519 a,b,c,x,y,z,t; curve25519_sub(a, p->y, p->x); curve25519_add(b, p->y, p->x); curve25519_mul(a, a, q->ysubx); curve25519_mul(x, b, q->xaddy); curve25519_add(y, x, a); curve25519_sub(x, x, a); curve25519_mul(c, p->t, q->t2d); curve25519_mul(t, p->z, q->z); curve25519_add(t, t, t); curve25519_add_after_basic(z, t, c); curve25519_sub_after_basic(t, t, c); curve25519_mul(r->xaddy, x, t); curve25519_mul(r->ysubx, y, z); curve25519_mul(r->z, z, t); curve25519_mul(r->t2d, x, y); curve25519_copy(y, r->ysubx); curve25519_sub(r->ysubx, r->ysubx, r->xaddy); curve25519_add(r->xaddy, r->xaddy, y); curve25519_mul(r->t2d, r->t2d, ge25519_ec2d); } /* pack & unpack */ static void ge25519_pack(unsigned char r[32], const ge25519 *p) { bignum25519 tx, ty, zi; unsigned char parity[32]; curve25519_recip(zi, p->z); curve25519_mul(tx, p->x, zi); curve25519_mul(ty, p->y, zi); curve25519_contract(r, ty); curve25519_contract(parity, tx); r[31] ^= ((parity[0] & 1) << 7); } static int ge25519_unpack_negative_vartime(ge25519 *r, const unsigned char p[32]) { static const unsigned char zero[32] = {0}; static const bignum25519 one = {1}; unsigned char parity = p[31] >> 7; unsigned char check[32]; bignum25519 t, root, num, den, d3; curve25519_expand(r->y, p); curve25519_copy(r->z, one); curve25519_square(num, r->y); /* x = y^2 */ curve25519_mul(den, num, ge25519_ecd); /* den = dy^2 */ curve25519_sub_reduce(num, num, r->z); /* x = y^1 - 1 */ curve25519_add(den, den, r->z); /* den = dy^2 + 1 */ /* Computation of sqrt(num/den) */ /* 1.: computation of num^((p-5)/8)*den^((7p-35)/8) = (num*den^7)^((p-5)/8) */ curve25519_square(t, den); curve25519_mul(d3, t, den); curve25519_square(r->x, d3); curve25519_mul(r->x, r->x, den); curve25519_mul(r->x, r->x, num); curve25519_pow_two252m3(r->x, r->x); /* 2. computation of r->x = num * den^3 * (num*den^7)^((p-5)/8) */ curve25519_mul(r->x, r->x, d3); curve25519_mul(r->x, r->x, num); /* 3. Check if either of the roots works: */ curve25519_square(t, r->x); curve25519_mul(t, t, den); curve25519_sub_reduce(root, t, num); curve25519_contract(check, root); if (!ed25519_verify(check, zero, 32)) { curve25519_add_reduce(t, t, num); curve25519_contract(check, t); if (!ed25519_verify(check, zero, 32)) return 0; curve25519_mul(r->x, r->x, ge25519_sqrtneg1); } curve25519_contract(check, r->x); if ((check[0] & 1) == parity) { curve25519_copy(t, r->x); curve25519_neg(r->x, t); } curve25519_mul(r->t, r->x, r->y); return 1; } /* scalarmults */ #define S1_SWINDOWSIZE 5 #define S1_TABLE_SIZE (1<<(S1_SWINDOWSIZE-2)) #define S2_SWINDOWSIZE 7 #define S2_TABLE_SIZE (1<<(S2_SWINDOWSIZE-2)) /* computes [s1]p1 + [s2]basepoint */ static void ge25519_double_scalarmult_vartime(ge25519 *r, const ge25519 *p1, const bignum256modm s1, const bignum256modm s2) { signed char slide1[256], slide2[256]; ge25519_pniels pre1[S1_TABLE_SIZE]; ge25519 d1; ge25519_p1p1 t; int32_t i; contract256_slidingwindow_modm(slide1, s1, S1_SWINDOWSIZE); contract256_slidingwindow_modm(slide2, s2, S2_SWINDOWSIZE); ge25519_double(&d1, p1); ge25519_full_to_pniels(pre1, p1); for (i = 0; i < S1_TABLE_SIZE - 1; i++) ge25519_pnielsadd(&pre1[i+1], &d1, &pre1[i]); /* set neutral */ memset(r, 0, sizeof(ge25519)); r->y[0] = 1; r->z[0] = 1; i = 255; while ((i >= 0) && !(slide1[i] | slide2[i])) i--; for (; i >= 0; i--) { ge25519_double_p1p1(&t, r); if (slide1[i]) { ge25519_p1p1_to_full(r, &t); ge25519_pnielsadd_p1p1(&t, r, &pre1[abs(slide1[i]) / 2], (unsigned char)slide1[i] >> 7); } if (slide2[i]) { ge25519_p1p1_to_full(r, &t); ge25519_nielsadd2_p1p1(&t, r, &ge25519_niels_sliding_multiples[abs(slide2[i]) / 2], (unsigned char)slide2[i] >> 7); } ge25519_p1p1_to_partial(r, &t); } } #if !defined(HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS) static uint32_t ge25519_windowb_equal(uint32_t b, uint32_t c) { return ((b ^ c) - 1) >> 31; } static void ge25519_scalarmult_base_choose_niels(ge25519_niels *t, const uint8_t table[256][96], uint32_t pos, signed char b) { bignum25519 neg; uint32_t sign = (uint32_t)((unsigned char)b >> 7); uint32_t mask = ~(sign - 1); uint32_t u = (b + mask) ^ mask; uint32_t i; /* ysubx, xaddy, t2d in packed form. initialize to ysubx = 1, xaddy = 1, t2d = 0 */ uint8_t packed[96] = {0}; packed[0] = 1; packed[32] = 1; for (i = 0; i < 8; i++) curve25519_move_conditional_bytes(packed, table[(pos * 8) + i], ge25519_windowb_equal(u, i + 1)); /* expand in to t */ curve25519_expand(t->ysubx, packed + 0); curve25519_expand(t->xaddy, packed + 32); curve25519_expand(t->t2d , packed + 64); /* adjust for sign */ curve25519_swap_conditional(t->ysubx, t->xaddy, sign); curve25519_neg(neg, t->t2d); curve25519_swap_conditional(t->t2d, neg, sign); } #endif /* HAVE_GE25519_SCALARMULT_BASE_CHOOSE_NIELS */ /* computes [s]basepoint */ static void ge25519_scalarmult_base_niels(ge25519 *r, const uint8_t basepoint_table[256][96], const bignum256modm s) { signed char b[64]; uint32_t i; ge25519_niels t; contract256_window4_modm(b, s); ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[1]); curve25519_sub_reduce(r->x, t.xaddy, t.ysubx); curve25519_add_reduce(r->y, t.xaddy, t.ysubx); memset(r->z, 0, sizeof(bignum25519)); curve25519_copy(r->t, t.t2d); r->z[0] = 2; for (i = 3; i < 64; i += 2) { ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); ge25519_nielsadd2(r, &t); } ge25519_double_partial(r, r); ge25519_double_partial(r, r); ge25519_double_partial(r, r); ge25519_double(r, r); ge25519_scalarmult_base_choose_niels(&t, basepoint_table, 0, b[0]); curve25519_mul(t.t2d, t.t2d, ge25519_ecd); ge25519_nielsadd2(r, &t); for(i = 2; i < 64; i += 2) { ge25519_scalarmult_base_choose_niels(&t, basepoint_table, i / 2, b[i]); ge25519_nielsadd2(r, &t); } } cryptonite-0.23/cbits/ed25519/ed25519-donna-portable-identify.h0000644000000000000000000000553612514663134022027 0ustar0000000000000000/* os */ #if defined(_WIN32) || defined(_WIN64) || defined(__TOS_WIN__) || defined(__WINDOWS__) #define OS_WINDOWS #elif defined(sun) || defined(__sun) || defined(__SVR4) || defined(__svr4__) #define OS_SOLARIS #else #include /* need this to define BSD */ #define OS_NIX #if defined(__linux__) #define OS_LINUX #elif defined(BSD) #define OS_BSD #if defined(MACOS_X) || (defined(__APPLE__) & defined(__MACH__)) #define OS_OSX #elif defined(macintosh) || defined(Macintosh) #define OS_MAC #elif defined(__OpenBSD__) #define OS_OPENBSD #endif #endif #endif /* compiler */ #if defined(_MSC_VER) #define COMPILER_MSVC #endif #if defined(__ICC) #define COMPILER_INTEL #endif #if defined(__GNUC__) #if (__GNUC__ >= 3) #define COMPILER_GCC ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + (__GNUC_PATCHLEVEL__)) #else #define COMPILER_GCC ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) ) #endif #endif #if defined(__PATHCC__) #define COMPILER_PATHCC #endif #if defined(__clang__) #define COMPILER_CLANG ((__clang_major__ * 10000) + (__clang_minor__ * 100) + (__clang_patchlevel__)) #endif /* cpu */ #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__ ) || defined(_M_X64) #define CPU_X86_64 #elif defined(__i586__) || defined(__i686__) || (defined(_M_IX86) && (_M_IX86 >= 500)) #define CPU_X86 500 #elif defined(__i486__) || (defined(_M_IX86) && (_M_IX86 >= 400)) #define CPU_X86 400 #elif defined(__i386__) || (defined(_M_IX86) && (_M_IX86 >= 300)) || defined(__X86__) || defined(_X86_) || defined(__I86__) #define CPU_X86 300 #elif defined(__ia64__) || defined(_IA64) || defined(__IA64__) || defined(_M_IA64) || defined(__ia64) #define CPU_IA64 #endif #if defined(__sparc__) || defined(__sparc) || defined(__sparcv9) #define CPU_SPARC #if defined(__sparcv9) #define CPU_SPARC64 #endif #endif #if defined(powerpc) || defined(__PPC__) || defined(__ppc__) || defined(_ARCH_PPC) || defined(__powerpc__) || defined(__powerpc) || defined(POWERPC) || defined(_M_PPC) #define CPU_PPC #if defined(_ARCH_PWR7) #define CPU_POWER7 #elif defined(__64BIT__) #define CPU_PPC64 #else #define CPU_PPC32 #endif #endif #if defined(__hppa__) || defined(__hppa) #define CPU_HPPA #endif #if defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) #define CPU_ALPHA #endif /* 64 bit cpu */ #if defined(CPU_X86_64) || defined(CPU_IA64) || defined(CPU_SPARC64) || defined(__64BIT__) || defined(__LP64__) || defined(_LP64) || (defined(_MIPS_SZLONG) && (_MIPS_SZLONG == 64)) #define CPU_64BITS #endif #if defined(COMPILER_MSVC) typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed int int32_t; typedef unsigned int uint32_t; typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; #else #include #endif cryptonite-0.23/cbits/ed25519/ed25519-donna-portable.h0000644000000000000000000001127512514663134020213 0ustar0000000000000000#include "ed25519-donna-portable-identify.h" #define mul32x32_64(a,b) (((uint64_t)(a))*(b)) /* platform */ #if defined(COMPILER_MSVC) #include #if !defined(_DEBUG) #undef mul32x32_64 #define mul32x32_64(a,b) __emulu(a,b) #endif #undef inline #define inline __forceinline #define DONNA_INLINE __forceinline #define DONNA_NOINLINE __declspec(noinline) #define ALIGN(x) __declspec(align(x)) #define ROTL32(a,b) _rotl(a,b) #define ROTR32(a,b) _rotr(a,b) #else #include #define DONNA_INLINE inline __attribute__((always_inline)) #define DONNA_NOINLINE __attribute__((noinline)) #ifdef ALIGN #undef ALIGN #endif #define ALIGN(x) __attribute__((aligned(x))) #define ROTL32(a,b) (((a) << (b)) | ((a) >> (32 - b))) #define ROTR32(a,b) (((a) >> (b)) | ((a) << (32 - b))) #endif /* uint128_t */ #if defined(CPU_64BITS) && !defined(ED25519_FORCE_32BIT) #if defined(COMPILER_CLANG) && (COMPILER_CLANG >= 30100) #define HAVE_NATIVE_UINT128 typedef unsigned __int128 uint128_t; #elif defined(COMPILER_MSVC) #define HAVE_UINT128 typedef struct uint128_t { uint64_t lo, hi; } uint128_t; #define mul64x64_128(out,a,b) out.lo = _umul128(a,b,&out.hi); #define shr128_pair(out,hi,lo,shift) out = __shiftright128(lo, hi, shift); #define shl128_pair(out,hi,lo,shift) out = __shiftleft128(lo, hi, shift); #define shr128(out,in,shift) shr128_pair(out, in.hi, in.lo, shift) #define shl128(out,in,shift) shl128_pair(out, in.hi, in.lo, shift) #define add128(a,b) { uint64_t p = a.lo; a.lo += b.lo; a.hi += b.hi + (a.lo < p); } #define add128_64(a,b) { uint64_t p = a.lo; a.lo += b; a.hi += (a.lo < p); } #define lo128(a) (a.lo) #define hi128(a) (a.hi) #elif defined(COMPILER_GCC) && !defined(HAVE_NATIVE_UINT128) #if defined(__SIZEOF_INT128__) #define HAVE_NATIVE_UINT128 typedef unsigned __int128 uint128_t; #elif (COMPILER_GCC >= 40400) #define HAVE_NATIVE_UINT128 typedef unsigned uint128_t __attribute__((mode(TI))); #elif defined(CPU_X86_64) #define HAVE_UINT128 typedef struct uint128_t { uint64_t lo, hi; } uint128_t; #define mul64x64_128(out,a,b) __asm__ ("mulq %3" : "=a" (out.lo), "=d" (out.hi) : "a" (a), "rm" (b)); #define shr128_pair(out,hi,lo,shift) __asm__ ("shrdq %2,%1,%0" : "+r" (lo) : "r" (hi), "J" (shift)); out = lo; #define shl128_pair(out,hi,lo,shift) __asm__ ("shldq %2,%1,%0" : "+r" (hi) : "r" (lo), "J" (shift)); out = hi; #define shr128(out,in,shift) shr128_pair(out,in.hi, in.lo, shift) #define shl128(out,in,shift) shl128_pair(out,in.hi, in.lo, shift) #define add128(a,b) __asm__ ("addq %4,%2; adcq %5,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b.lo), "rm" (b.hi) : "cc"); #define add128_64(a,b) __asm__ ("addq %4,%2; adcq $0,%3" : "=r" (a.hi), "=r" (a.lo) : "1" (a.lo), "0" (a.hi), "rm" (b) : "cc"); #define lo128(a) (a.lo) #define hi128(a) (a.hi) #endif #endif #if defined(HAVE_NATIVE_UINT128) #define HAVE_UINT128 #define mul64x64_128(out,a,b) out = (uint128_t)a * b; #define shr128_pair(out,hi,lo,shift) out = (uint64_t)((((uint128_t)hi << 64) | lo) >> (shift)); #define shl128_pair(out,hi,lo,shift) out = (uint64_t)(((((uint128_t)hi << 64) | lo) << (shift)) >> 64); #define shr128(out,in,shift) out = (uint64_t)(in >> (shift)); #define shl128(out,in,shift) out = (uint64_t)((in << shift) >> 64); #define add128(a,b) a += b; #define add128_64(a,b) a += (uint64_t)b; #define lo128(a) ((uint64_t)a) #define hi128(a) ((uint64_t)(a >> 64)) #endif #if !defined(HAVE_UINT128) #error Need a uint128_t implementation! #endif #endif /* endian */ #if !defined(ED25519_OPENSSLRNG) static inline void U32TO8_LE(unsigned char *p, const uint32_t v) { p[0] = (unsigned char)(v ); p[1] = (unsigned char)(v >> 8); p[2] = (unsigned char)(v >> 16); p[3] = (unsigned char)(v >> 24); } #endif #if !defined(HAVE_UINT128) static inline uint32_t U8TO32_LE(const unsigned char *p) { return (((uint32_t)(p[0]) ) | ((uint32_t)(p[1]) << 8) | ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24)); } #else static inline uint64_t U8TO64_LE(const unsigned char *p) { return (((uint64_t)(p[0]) ) | ((uint64_t)(p[1]) << 8) | ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) | ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) | ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56)); } static inline void U64TO8_LE(unsigned char *p, const uint64_t v) { p[0] = (unsigned char)(v ); p[1] = (unsigned char)(v >> 8); p[2] = (unsigned char)(v >> 16); p[3] = (unsigned char)(v >> 24); p[4] = (unsigned char)(v >> 32); p[5] = (unsigned char)(v >> 40); p[6] = (unsigned char)(v >> 48); p[7] = (unsigned char)(v >> 56); } #endif #include #include cryptonite-0.23/cbits/ed25519/ed25519-donna.h0000644000000000000000000000531212514663134016400 0ustar0000000000000000/* Public domain by Andrew M. Modified from the amd64-51-30k implementation by Daniel J. Bernstein Niels Duif Tanja Lange Peter Schwabe Bo-Yin Yang */ #include "ed25519-donna-portable.h" #if defined(ED25519_SSE2) #else #if defined(HAVE_UINT128) && !defined(ED25519_FORCE_32BIT) #define ED25519_64BIT #else #define ED25519_32BIT #endif #endif #if !defined(ED25519_NO_INLINE_ASM) /* detect extra features first so un-needed functions can be disabled throughout */ #if defined(ED25519_SSE2) #if defined(COMPILER_GCC) && defined(CPU_X86) #define ED25519_GCC_32BIT_SSE_CHOOSE #elif defined(COMPILER_GCC) && defined(CPU_X86_64) #define ED25519_GCC_64BIT_SSE_CHOOSE #endif #else #if defined(CPU_X86_64) #if defined(COMPILER_GCC) #if defined(ED25519_64BIT) #define ED25519_GCC_64BIT_X86_CHOOSE #else #define ED25519_GCC_64BIT_32BIT_CHOOSE #endif #endif #endif #endif #endif #if defined(ED25519_SSE2) #include "curve25519-donna-sse2.h" #elif defined(ED25519_64BIT) #include "curve25519-donna-64bit.h" #else #include "curve25519-donna-32bit.h" #endif #include "curve25519-donna-helpers.h" /* separate uint128 check for 64 bit sse2 */ #if defined(HAVE_UINT128) && !defined(ED25519_FORCE_32BIT) #include "modm-donna-64bit.h" #else #include "modm-donna-32bit.h" #endif typedef unsigned char hash_512bits[64]; /* Timing safe memory compare */ static int ed25519_verify(const unsigned char *x, const unsigned char *y, size_t len) { size_t differentbits = 0; while (len--) differentbits |= (*x++ ^ *y++); return (int) (1 & ((differentbits - 1) >> 8)); } /* * Arithmetic on the twisted Edwards curve -x^2 + y^2 = 1 + dx^2y^2 * with d = -(121665/121666) = 37095705934669439343138083508754565189542113879843219016388785533085940283555 * Base point: (15112221349535400772501151409588531511454012693041857206046113283949847762202,46316835694926478169428394003475163141307993866256225615783033603165251855960); */ typedef struct ge25519_t { bignum25519 x, y, z, t; } ge25519; typedef struct ge25519_p1p1_t { bignum25519 x, y, z, t; } ge25519_p1p1; typedef struct ge25519_niels_t { bignum25519 ysubx, xaddy, t2d; } ge25519_niels; typedef struct ge25519_pniels_t { bignum25519 ysubx, xaddy, z, t2d; } ge25519_pniels; #include "ed25519-donna-basepoint-table.h" #if defined(ED25519_64BIT) #include "ed25519-donna-64bit-tables.h" #include "ed25519-donna-64bit-x86.h" #else #include "ed25519-donna-32bit-tables.h" #include "ed25519-donna-64bit-x86-32bit.h" #endif #if defined(ED25519_SSE2) #include "ed25519-donna-32bit-sse2.h" #include "ed25519-donna-64bit-sse2.h" #include "ed25519-donna-impl-sse2.h" #else #include "ed25519-donna-impl-base.h" #endif cryptonite-0.23/cbits/ed25519/ed25519-hash.h0000644000000000000000000000125112514663134016222 0ustar0000000000000000#include typedef struct sha512_ctx ed25519_hash_context; static void ed25519_hash_init(ed25519_hash_context *ctx) { cryptonite_sha512_init(ctx); } static void ed25519_hash_update(ed25519_hash_context *ctx, const uint8_t *in, size_t inlen) { cryptonite_sha512_update(ctx, in, inlen); } static void ed25519_hash_final(ed25519_hash_context *ctx, uint8_t *hash) { cryptonite_sha512_finalize(ctx, hash); } static void ed25519_hash(uint8_t *hash, const uint8_t *in, size_t inlen) { ed25519_hash_context ctx; cryptonite_sha512_init(&ctx); cryptonite_sha512_update(&ctx, in, inlen); cryptonite_sha512_finalize(&ctx, hash); memset(&ctx, 0, sizeof(ctx)); } cryptonite-0.23/cbits/ed25519/ed25519-randombytes.h0000644000000000000000000000012012514663134017620 0ustar0000000000000000void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) { exit(1); } cryptonite-0.23/cbits/ed25519/ed25519.h0000644000000000000000000000176212514663134015310 0ustar0000000000000000#ifndef ED25519_H #define ED25519_H #include #if defined(__cplusplus) extern "C" { #endif typedef unsigned char ed25519_signature[64]; typedef unsigned char ed25519_public_key[32]; typedef unsigned char ed25519_secret_key[32]; typedef unsigned char curved25519_key[32]; void cryptonite_ed25519_publickey(const ed25519_secret_key sk, ed25519_public_key pk); int cryptonite_ed25519_sign_open(const unsigned char *m, size_t mlen, const ed25519_public_key pk, const ed25519_signature RS); void cryptonite_ed25519_sign(const unsigned char *m, size_t mlen, const ed25519_secret_key sk, const ed25519_public_key pk, ed25519_signature RS); //int cryptonite_ed25519_sign_open_batch(const unsigned char **m, size_t *mlen, const unsigned char **pk, const unsigned char **RS, size_t num, int *valid); //void ed25519_randombytes_unsafe(void *out, size_t count); //void curved25519_scalarmult_basepoint(curved25519_key pk, const curved25519_key e); #if defined(__cplusplus) } #endif #endif // ED25519_H cryptonite-0.23/cbits/ed25519/modm-donna-32bit.h0000644000000000000000000005121612540765215017265 0ustar0000000000000000/* Public domain by Andrew M. */ /* Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 k = 32 b = 1 << 8 = 256 m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b */ #define bignum256modm_bits_per_limb 30 #define bignum256modm_limb_size 9 typedef uint32_t bignum256modm_element_t; typedef bignum256modm_element_t bignum256modm[9]; static const bignum256modm modm_m = { 0x1cf5d3ed, 0x20498c69, 0x2f79cd65, 0x37be77a8, 0x00000014, 0x00000000, 0x00000000, 0x00000000, 0x00001000 }; static const bignum256modm modm_mu = { 0x0a2c131b, 0x3673968c, 0x06329a7e, 0x01885742, 0x3fffeb21, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x000fffff }; static bignum256modm_element_t lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { return (a - b) >> 31; } /* see HAC, Alg. 14.42 Step 4 */ static void reduce256_modm(bignum256modm r) { bignum256modm t; bignum256modm_element_t b = 0, pb, mask; /* t = r - m */ pb = 0; pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 30)); pb = b; pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 30)); pb = b; pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 30)); pb = b; pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 30)); pb = b; pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 30)); pb = b; pb += modm_m[5]; b = lt_modm(r[5], pb); t[5] = (r[5] - pb + (b << 30)); pb = b; pb += modm_m[6]; b = lt_modm(r[6], pb); t[6] = (r[6] - pb + (b << 30)); pb = b; pb += modm_m[7]; b = lt_modm(r[7], pb); t[7] = (r[7] - pb + (b << 30)); pb = b; pb += modm_m[8]; b = lt_modm(r[8], pb); t[8] = (r[8] - pb + (b << 16)); /* keep r if r was smaller than m */ mask = b - 1; r[0] ^= mask & (r[0] ^ t[0]); r[1] ^= mask & (r[1] ^ t[1]); r[2] ^= mask & (r[2] ^ t[2]); r[3] ^= mask & (r[3] ^ t[3]); r[4] ^= mask & (r[4] ^ t[4]); r[5] ^= mask & (r[5] ^ t[5]); r[6] ^= mask & (r[6] ^ t[6]); r[7] ^= mask & (r[7] ^ t[7]); r[8] ^= mask & (r[8] ^ t[8]); } /* Barrett reduction, see HAC, Alg. 14.42 Instead of passing in x, pre-process in to q1 and r1 for efficiency */ static void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { bignum256modm q3, r2; uint64_t c; bignum256modm_element_t f, b, pb; /* q1 = x >> 248 = 264 bits = 9 30 bit elements q2 = mu * q1 q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */ c = mul32x32_64(modm_mu[0], q1[7]) + mul32x32_64(modm_mu[1], q1[6]) + mul32x32_64(modm_mu[2], q1[5]) + mul32x32_64(modm_mu[3], q1[4]) + mul32x32_64(modm_mu[4], q1[3]) + mul32x32_64(modm_mu[5], q1[2]) + mul32x32_64(modm_mu[6], q1[1]) + mul32x32_64(modm_mu[7], q1[0]); c >>= 30; c += mul32x32_64(modm_mu[0], q1[8]) + mul32x32_64(modm_mu[1], q1[7]) + mul32x32_64(modm_mu[2], q1[6]) + mul32x32_64(modm_mu[3], q1[5]) + mul32x32_64(modm_mu[4], q1[4]) + mul32x32_64(modm_mu[5], q1[3]) + mul32x32_64(modm_mu[6], q1[2]) + mul32x32_64(modm_mu[7], q1[1]) + mul32x32_64(modm_mu[8], q1[0]); f = (bignum256modm_element_t)c; q3[0] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[1], q1[8]) + mul32x32_64(modm_mu[2], q1[7]) + mul32x32_64(modm_mu[3], q1[6]) + mul32x32_64(modm_mu[4], q1[5]) + mul32x32_64(modm_mu[5], q1[4]) + mul32x32_64(modm_mu[6], q1[3]) + mul32x32_64(modm_mu[7], q1[2]) + mul32x32_64(modm_mu[8], q1[1]); f = (bignum256modm_element_t)c; q3[0] |= (f << 6) & 0x3fffffff; q3[1] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[2], q1[8]) + mul32x32_64(modm_mu[3], q1[7]) + mul32x32_64(modm_mu[4], q1[6]) + mul32x32_64(modm_mu[5], q1[5]) + mul32x32_64(modm_mu[6], q1[4]) + mul32x32_64(modm_mu[7], q1[3]) + mul32x32_64(modm_mu[8], q1[2]); f = (bignum256modm_element_t)c; q3[1] |= (f << 6) & 0x3fffffff; q3[2] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[3], q1[8]) + mul32x32_64(modm_mu[4], q1[7]) + mul32x32_64(modm_mu[5], q1[6]) + mul32x32_64(modm_mu[6], q1[5]) + mul32x32_64(modm_mu[7], q1[4]) + mul32x32_64(modm_mu[8], q1[3]); f = (bignum256modm_element_t)c; q3[2] |= (f << 6) & 0x3fffffff; q3[3] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[4], q1[8]) + mul32x32_64(modm_mu[5], q1[7]) + mul32x32_64(modm_mu[6], q1[6]) + mul32x32_64(modm_mu[7], q1[5]) + mul32x32_64(modm_mu[8], q1[4]); f = (bignum256modm_element_t)c; q3[3] |= (f << 6) & 0x3fffffff; q3[4] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[5], q1[8]) + mul32x32_64(modm_mu[6], q1[7]) + mul32x32_64(modm_mu[7], q1[6]) + mul32x32_64(modm_mu[8], q1[5]); f = (bignum256modm_element_t)c; q3[4] |= (f << 6) & 0x3fffffff; q3[5] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[6], q1[8]) + mul32x32_64(modm_mu[7], q1[7]) + mul32x32_64(modm_mu[8], q1[6]); f = (bignum256modm_element_t)c; q3[5] |= (f << 6) & 0x3fffffff; q3[6] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[7], q1[8]) + mul32x32_64(modm_mu[8], q1[7]); f = (bignum256modm_element_t)c; q3[6] |= (f << 6) & 0x3fffffff; q3[7] = (f >> 24) & 0x3f; c >>= 30; c += mul32x32_64(modm_mu[8], q1[8]); f = (bignum256modm_element_t)c; q3[7] |= (f << 6) & 0x3fffffff; q3[8] = (bignum256modm_element_t)(c >> 24); /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) r2 = (q3 * m) mod (256^(32+1)) = (q3 * m) & ((1 << 264) - 1) */ c = mul32x32_64(modm_m[0], q3[0]); r2[0] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[1]) + mul32x32_64(modm_m[1], q3[0]); r2[1] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[2]) + mul32x32_64(modm_m[1], q3[1]) + mul32x32_64(modm_m[2], q3[0]); r2[2] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[3]) + mul32x32_64(modm_m[1], q3[2]) + mul32x32_64(modm_m[2], q3[1]) + mul32x32_64(modm_m[3], q3[0]); r2[3] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[4]) + mul32x32_64(modm_m[1], q3[3]) + mul32x32_64(modm_m[2], q3[2]) + mul32x32_64(modm_m[3], q3[1]) + mul32x32_64(modm_m[4], q3[0]); r2[4] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[5]) + mul32x32_64(modm_m[1], q3[4]) + mul32x32_64(modm_m[2], q3[3]) + mul32x32_64(modm_m[3], q3[2]) + mul32x32_64(modm_m[4], q3[1]) + mul32x32_64(modm_m[5], q3[0]); r2[5] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[6]) + mul32x32_64(modm_m[1], q3[5]) + mul32x32_64(modm_m[2], q3[4]) + mul32x32_64(modm_m[3], q3[3]) + mul32x32_64(modm_m[4], q3[2]) + mul32x32_64(modm_m[5], q3[1]) + mul32x32_64(modm_m[6], q3[0]); r2[6] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[7]) + mul32x32_64(modm_m[1], q3[6]) + mul32x32_64(modm_m[2], q3[5]) + mul32x32_64(modm_m[3], q3[4]) + mul32x32_64(modm_m[4], q3[3]) + mul32x32_64(modm_m[5], q3[2]) + mul32x32_64(modm_m[6], q3[1]) + mul32x32_64(modm_m[7], q3[0]); r2[7] = (bignum256modm_element_t)(c & 0x3fffffff); c >>= 30; c += mul32x32_64(modm_m[0], q3[8]) + mul32x32_64(modm_m[1], q3[7]) + mul32x32_64(modm_m[2], q3[6]) + mul32x32_64(modm_m[3], q3[5]) + mul32x32_64(modm_m[4], q3[4]) + mul32x32_64(modm_m[5], q3[3]) + mul32x32_64(modm_m[6], q3[2]) + mul32x32_64(modm_m[7], q3[1]) + mul32x32_64(modm_m[8], q3[0]); r2[8] = (bignum256modm_element_t)(c & 0xffffff); /* r = r1 - r2 if (r < 0) r += (1 << 264) */ pb = 0; pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 30)); pb = b; pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 30)); pb = b; pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 30)); pb = b; pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 30)); pb = b; pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 30)); pb = b; pb += r2[5]; b = lt_modm(r1[5], pb); r[5] = (r1[5] - pb + (b << 30)); pb = b; pb += r2[6]; b = lt_modm(r1[6], pb); r[6] = (r1[6] - pb + (b << 30)); pb = b; pb += r2[7]; b = lt_modm(r1[7], pb); r[7] = (r1[7] - pb + (b << 30)); pb = b; pb += r2[8]; b = lt_modm(r1[8], pb); r[8] = (r1[8] - pb + (b << 24)); reduce256_modm(r); reduce256_modm(r); } /* addition modulo m */ static void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { bignum256modm_element_t c; c = x[0] + y[0]; r[0] = c & 0x3fffffff; c >>= 30; c += x[1] + y[1]; r[1] = c & 0x3fffffff; c >>= 30; c += x[2] + y[2]; r[2] = c & 0x3fffffff; c >>= 30; c += x[3] + y[3]; r[3] = c & 0x3fffffff; c >>= 30; c += x[4] + y[4]; r[4] = c & 0x3fffffff; c >>= 30; c += x[5] + y[5]; r[5] = c & 0x3fffffff; c >>= 30; c += x[6] + y[6]; r[6] = c & 0x3fffffff; c >>= 30; c += x[7] + y[7]; r[7] = c & 0x3fffffff; c >>= 30; c += x[8] + y[8]; r[8] = c; reduce256_modm(r); } /* multiplication modulo m */ static void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { bignum256modm r1, q1; uint64_t c; bignum256modm_element_t f; /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) q1 = x >> 248 = 264 bits = 9 30 bit elements */ c = mul32x32_64(x[0], y[0]); f = (bignum256modm_element_t)c; r1[0] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[1]) + mul32x32_64(x[1], y[0]); f = (bignum256modm_element_t)c; r1[1] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[2]) + mul32x32_64(x[1], y[1]) + mul32x32_64(x[2], y[0]); f = (bignum256modm_element_t)c; r1[2] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[3]) + mul32x32_64(x[1], y[2]) + mul32x32_64(x[2], y[1]) + mul32x32_64(x[3], y[0]); f = (bignum256modm_element_t)c; r1[3] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[4]) + mul32x32_64(x[1], y[3]) + mul32x32_64(x[2], y[2]) + mul32x32_64(x[3], y[1]) + mul32x32_64(x[4], y[0]); f = (bignum256modm_element_t)c; r1[4] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[5]) + mul32x32_64(x[1], y[4]) + mul32x32_64(x[2], y[3]) + mul32x32_64(x[3], y[2]) + mul32x32_64(x[4], y[1]) + mul32x32_64(x[5], y[0]); f = (bignum256modm_element_t)c; r1[5] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[6]) + mul32x32_64(x[1], y[5]) + mul32x32_64(x[2], y[4]) + mul32x32_64(x[3], y[3]) + mul32x32_64(x[4], y[2]) + mul32x32_64(x[5], y[1]) + mul32x32_64(x[6], y[0]); f = (bignum256modm_element_t)c; r1[6] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[7]) + mul32x32_64(x[1], y[6]) + mul32x32_64(x[2], y[5]) + mul32x32_64(x[3], y[4]) + mul32x32_64(x[4], y[3]) + mul32x32_64(x[5], y[2]) + mul32x32_64(x[6], y[1]) + mul32x32_64(x[7], y[0]); f = (bignum256modm_element_t)c; r1[7] = (f & 0x3fffffff); c >>= 30; c += mul32x32_64(x[0], y[8]) + mul32x32_64(x[1], y[7]) + mul32x32_64(x[2], y[6]) + mul32x32_64(x[3], y[5]) + mul32x32_64(x[4], y[4]) + mul32x32_64(x[5], y[3]) + mul32x32_64(x[6], y[2]) + mul32x32_64(x[7], y[1]) + mul32x32_64(x[8], y[0]); f = (bignum256modm_element_t)c; r1[8] = (f & 0x00ffffff); q1[0] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[1], y[8]) + mul32x32_64(x[2], y[7]) + mul32x32_64(x[3], y[6]) + mul32x32_64(x[4], y[5]) + mul32x32_64(x[5], y[4]) + mul32x32_64(x[6], y[3]) + mul32x32_64(x[7], y[2]) + mul32x32_64(x[8], y[1]); f = (bignum256modm_element_t)c; q1[0] = (q1[0] | (f << 22)) & 0x3fffffff; q1[1] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[2], y[8]) + mul32x32_64(x[3], y[7]) + mul32x32_64(x[4], y[6]) + mul32x32_64(x[5], y[5]) + mul32x32_64(x[6], y[4]) + mul32x32_64(x[7], y[3]) + mul32x32_64(x[8], y[2]); f = (bignum256modm_element_t)c; q1[1] = (q1[1] | (f << 22)) & 0x3fffffff; q1[2] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[3], y[8]) + mul32x32_64(x[4], y[7]) + mul32x32_64(x[5], y[6]) + mul32x32_64(x[6], y[5]) + mul32x32_64(x[7], y[4]) + mul32x32_64(x[8], y[3]); f = (bignum256modm_element_t)c; q1[2] = (q1[2] | (f << 22)) & 0x3fffffff; q1[3] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[4], y[8]) + mul32x32_64(x[5], y[7]) + mul32x32_64(x[6], y[6]) + mul32x32_64(x[7], y[5]) + mul32x32_64(x[8], y[4]); f = (bignum256modm_element_t)c; q1[3] = (q1[3] | (f << 22)) & 0x3fffffff; q1[4] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[5], y[8]) + mul32x32_64(x[6], y[7]) + mul32x32_64(x[7], y[6]) + mul32x32_64(x[8], y[5]); f = (bignum256modm_element_t)c; q1[4] = (q1[4] | (f << 22)) & 0x3fffffff; q1[5] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[6], y[8]) + mul32x32_64(x[7], y[7]) + mul32x32_64(x[8], y[6]); f = (bignum256modm_element_t)c; q1[5] = (q1[5] | (f << 22)) & 0x3fffffff; q1[6] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[7], y[8]) + mul32x32_64(x[8], y[7]); f = (bignum256modm_element_t)c; q1[6] = (q1[6] | (f << 22)) & 0x3fffffff; q1[7] = (f >> 8) & 0x3fffff; c >>= 30; c += mul32x32_64(x[8], y[8]); f = (bignum256modm_element_t)c; q1[7] = (q1[7] | (f << 22)) & 0x3fffffff; q1[8] = (f >> 8) & 0x3fffff; barrett_reduce256_modm(r, q1, r1); } static void expand256_modm(bignum256modm out, const unsigned char *in, size_t len) { unsigned char work[64] = {0}; bignum256modm_element_t x[16]; bignum256modm q1; memcpy(work, in, len); x[0] = U8TO32_LE(work + 0); x[1] = U8TO32_LE(work + 4); x[2] = U8TO32_LE(work + 8); x[3] = U8TO32_LE(work + 12); x[4] = U8TO32_LE(work + 16); x[5] = U8TO32_LE(work + 20); x[6] = U8TO32_LE(work + 24); x[7] = U8TO32_LE(work + 28); x[8] = U8TO32_LE(work + 32); x[9] = U8TO32_LE(work + 36); x[10] = U8TO32_LE(work + 40); x[11] = U8TO32_LE(work + 44); x[12] = U8TO32_LE(work + 48); x[13] = U8TO32_LE(work + 52); x[14] = U8TO32_LE(work + 56); x[15] = U8TO32_LE(work + 60); /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ out[0] = ( x[0]) & 0x3fffffff; out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; out[8] = ((x[ 7] >> 16) | (x[ 8] << 16)) & 0x00ffffff; /* 8*31 = 248 bits, no need to reduce */ if (len < 32) return; /* q1 = x >> 248 = 264 bits = 9 30 bit elements */ q1[0] = ((x[ 7] >> 24) | (x[ 8] << 8)) & 0x3fffffff; q1[1] = ((x[ 8] >> 22) | (x[ 9] << 10)) & 0x3fffffff; q1[2] = ((x[ 9] >> 20) | (x[10] << 12)) & 0x3fffffff; q1[3] = ((x[10] >> 18) | (x[11] << 14)) & 0x3fffffff; q1[4] = ((x[11] >> 16) | (x[12] << 16)) & 0x3fffffff; q1[5] = ((x[12] >> 14) | (x[13] << 18)) & 0x3fffffff; q1[6] = ((x[13] >> 12) | (x[14] << 20)) & 0x3fffffff; q1[7] = ((x[14] >> 10) | (x[15] << 22)) & 0x3fffffff; q1[8] = ((x[15] >> 8) ); barrett_reduce256_modm(out, q1, out); } static void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) { bignum256modm_element_t x[8]; x[0] = U8TO32_LE(in + 0); x[1] = U8TO32_LE(in + 4); x[2] = U8TO32_LE(in + 8); x[3] = U8TO32_LE(in + 12); x[4] = U8TO32_LE(in + 16); x[5] = U8TO32_LE(in + 20); x[6] = U8TO32_LE(in + 24); x[7] = U8TO32_LE(in + 28); out[0] = ( x[0]) & 0x3fffffff; out[1] = ((x[ 0] >> 30) | (x[ 1] << 2)) & 0x3fffffff; out[2] = ((x[ 1] >> 28) | (x[ 2] << 4)) & 0x3fffffff; out[3] = ((x[ 2] >> 26) | (x[ 3] << 6)) & 0x3fffffff; out[4] = ((x[ 3] >> 24) | (x[ 4] << 8)) & 0x3fffffff; out[5] = ((x[ 4] >> 22) | (x[ 5] << 10)) & 0x3fffffff; out[6] = ((x[ 5] >> 20) | (x[ 6] << 12)) & 0x3fffffff; out[7] = ((x[ 6] >> 18) | (x[ 7] << 14)) & 0x3fffffff; out[8] = ((x[ 7] >> 16) ) & 0x0000ffff; } static void contract256_modm(unsigned char out[32], const bignum256modm in) { U32TO8_LE(out + 0, (in[0] ) | (in[1] << 30)); U32TO8_LE(out + 4, (in[1] >> 2) | (in[2] << 28)); U32TO8_LE(out + 8, (in[2] >> 4) | (in[3] << 26)); U32TO8_LE(out + 12, (in[3] >> 6) | (in[4] << 24)); U32TO8_LE(out + 16, (in[4] >> 8) | (in[5] << 22)); U32TO8_LE(out + 20, (in[5] >> 10) | (in[6] << 20)); U32TO8_LE(out + 24, (in[6] >> 12) | (in[7] << 18)); U32TO8_LE(out + 28, (in[7] >> 14) | (in[8] << 16)); } static void contract256_window4_modm(signed char r[64], const bignum256modm in) { char carry; signed char *quads = r; bignum256modm_element_t i, j, v; for (i = 0; i < 8; i += 2) { v = in[i]; for (j = 0; j < 7; j++) { *quads++ = (v & 15); v >>= 4; } v |= (in[i+1] << 2); for (j = 0; j < 8; j++) { *quads++ = (v & 15); v >>= 4; } } v = in[8]; *quads++ = (v & 15); v >>= 4; *quads++ = (v & 15); v >>= 4; *quads++ = (v & 15); v >>= 4; *quads++ = (v & 15); v >>= 4; /* making it signed */ carry = 0; for(i = 0; i < 63; i++) { r[i] += carry; r[i+1] += (r[i] >> 4); r[i] &= 15; carry = (r[i] >> 3); r[i] -= (carry << 4); } r[63] += carry; } static void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { int i,j,k,b; int m = (1 << (windowsize - 1)) - 1, soplen = 256; signed char *bits = r; bignum256modm_element_t v; /* first put the binary expansion into r */ for (i = 0; i < 8; i++) { v = s[i]; for (j = 0; j < 30; j++, v >>= 1) *bits++ = (v & 1); } v = s[8]; for (j = 0; j < 16; j++, v >>= 1) *bits++ = (v & 1); /* Making it sliding window */ for (j = 0; j < soplen; j++) { if (!r[j]) continue; for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { if ((r[j] + (r[j + b] << b)) <= m) { r[j] += r[j + b] << b; r[j + b] = 0; } else if ((r[j] - (r[j + b] << b)) >= -m) { r[j] -= r[j + b] << b; for (k = j + b; k < soplen; k++) { if (!r[k]) { r[k] = 1; break; } r[k] = 0; } } else if (r[j + b]) { break; } } } } /* helpers for batch verifcation, are allowed to be vartime */ /* out = a - b, a must be larger than b */ static void sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) { size_t i = 0; bignum256modm_element_t carry = 0; switch (limbsize) { case 8: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 7: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 6: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 5: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 4: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; case 0: default: out[i] = (a[i] - b[i]) - carry; } } /* is a < b */ static int lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { switch (limbsize) { case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1; } return 0; } /* is a <= b */ static int lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { switch (limbsize) { case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1; } return 1; } /* is a == 0 */ static int iszero256_modm_batch(const bignum256modm a) { size_t i; for (i = 0; i < 9; i++) if (a[i]) return 0; return 1; } /* is a == 1 */ static int isone256_modm_batch(const bignum256modm a) { size_t i; if (a[0] != 1) return 0; for (i = 1; i < 9; i++) if (a[i]) return 0; return 1; } /* can a fit in to (at most) 128 bits */ static int isatmost128bits256_modm_batch(const bignum256modm a) { uint32_t mask = ((a[8] ) | /* 16 */ (a[7] ) | /* 46 */ (a[6] ) | /* 76 */ (a[5] ) | /* 106 */ (a[4] & 0x3fffff00)); /* 128 */ return (mask == 0); } cryptonite-0.23/cbits/ed25519/modm-donna-64bit.h0000644000000000000000000003205212514663134017265 0ustar0000000000000000/* Public domain by Andrew M. */ /* Arithmetic modulo the group order n = 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 k = 32 b = 1 << 8 = 256 m = 2^252 + 27742317777372353535851937790883648493 = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed mu = floor( b^(k*2) / m ) = 0xfffffffffffffffffffffffffffffffeb2106215d086329a7ed9ce5a30a2c131b */ #define bignum256modm_bits_per_limb 56 #define bignum256modm_limb_size 5 typedef uint64_t bignum256modm_element_t; typedef bignum256modm_element_t bignum256modm[5]; static const bignum256modm modm_m = { 0x12631a5cf5d3ed, 0xf9dea2f79cd658, 0x000000000014de, 0x00000000000000, 0x00000010000000 }; static const bignum256modm modm_mu = { 0x9ce5a30a2c131b, 0x215d086329a7ed, 0xffffffffeb2106, 0xffffffffffffff, 0x00000fffffffff }; static bignum256modm_element_t lt_modm(bignum256modm_element_t a, bignum256modm_element_t b) { return (a - b) >> 63; } static void reduce256_modm(bignum256modm r) { bignum256modm t; bignum256modm_element_t b = 0, pb, mask; /* t = r - m */ pb = 0; pb += modm_m[0]; b = lt_modm(r[0], pb); t[0] = (r[0] - pb + (b << 56)); pb = b; pb += modm_m[1]; b = lt_modm(r[1], pb); t[1] = (r[1] - pb + (b << 56)); pb = b; pb += modm_m[2]; b = lt_modm(r[2], pb); t[2] = (r[2] - pb + (b << 56)); pb = b; pb += modm_m[3]; b = lt_modm(r[3], pb); t[3] = (r[3] - pb + (b << 56)); pb = b; pb += modm_m[4]; b = lt_modm(r[4], pb); t[4] = (r[4] - pb + (b << 32)); /* keep r if r was smaller than m */ mask = b - 1; r[0] ^= mask & (r[0] ^ t[0]); r[1] ^= mask & (r[1] ^ t[1]); r[2] ^= mask & (r[2] ^ t[2]); r[3] ^= mask & (r[3] ^ t[3]); r[4] ^= mask & (r[4] ^ t[4]); } static void barrett_reduce256_modm(bignum256modm r, const bignum256modm q1, const bignum256modm r1) { bignum256modm q3, r2; uint128_t c, mul; bignum256modm_element_t f, b, pb; /* q1 = x >> 248 = 264 bits = 5 56 bit elements q2 = mu * q1 q3 = (q2 / 256(32+1)) = q2 / (2^8)^(32+1) = q2 >> 264 */ mul64x64_128(c, modm_mu[0], q1[3]) mul64x64_128(mul, modm_mu[3], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[2]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[1]) add128(c, mul) shr128(f, c, 56); mul64x64_128(c, modm_mu[0], q1[4]) add128_64(c, f) mul64x64_128(mul, modm_mu[4], q1[0]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[1]) add128(c, mul) mul64x64_128(mul, modm_mu[1], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[2]) add128(c, mul) f = lo128(c); q3[0] = (f >> 40) & 0xffff; shr128(f, c, 56); mul64x64_128(c, modm_mu[4], q1[1]) add128_64(c, f) mul64x64_128(mul, modm_mu[1], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[2], q1[3]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[2]) add128(c, mul) f = lo128(c); q3[0] |= (f << 16) & 0xffffffffffffff; q3[1] = (f >> 40) & 0xffff; shr128(f, c, 56); mul64x64_128(c, modm_mu[4], q1[2]) add128_64(c, f) mul64x64_128(mul, modm_mu[2], q1[4]) add128(c, mul) mul64x64_128(mul, modm_mu[3], q1[3]) add128(c, mul) f = lo128(c); q3[1] |= (f << 16) & 0xffffffffffffff; q3[2] = (f >> 40) & 0xffff; shr128(f, c, 56); mul64x64_128(c, modm_mu[4], q1[3]) add128_64(c, f) mul64x64_128(mul, modm_mu[3], q1[4]) add128(c, mul) f = lo128(c); q3[2] |= (f << 16) & 0xffffffffffffff; q3[3] = (f >> 40) & 0xffff; shr128(f, c, 56); mul64x64_128(c, modm_mu[4], q1[4]) add128_64(c, f) f = lo128(c); q3[3] |= (f << 16) & 0xffffffffffffff; q3[4] = (f >> 40) & 0xffff; shr128(f, c, 56); q3[4] |= (f << 16); mul64x64_128(c, modm_m[0], q3[0]) r2[0] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, modm_m[0], q3[1]) add128_64(c, f) mul64x64_128(mul, modm_m[1], q3[0]) add128(c, mul) r2[1] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, modm_m[0], q3[2]) add128_64(c, f) mul64x64_128(mul, modm_m[2], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[1]) add128(c, mul) r2[2] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, modm_m[0], q3[3]) add128_64(c, f) mul64x64_128(mul, modm_m[3], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[2]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[1]) add128(c, mul) r2[3] = lo128(c) & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, modm_m[0], q3[4]) add128_64(c, f) mul64x64_128(mul, modm_m[4], q3[0]) add128(c, mul) mul64x64_128(mul, modm_m[3], q3[1]) add128(c, mul) mul64x64_128(mul, modm_m[1], q3[3]) add128(c, mul) mul64x64_128(mul, modm_m[2], q3[2]) add128(c, mul) r2[4] = lo128(c) & 0x0000ffffffffff; pb = 0; pb += r2[0]; b = lt_modm(r1[0], pb); r[0] = (r1[0] - pb + (b << 56)); pb = b; pb += r2[1]; b = lt_modm(r1[1], pb); r[1] = (r1[1] - pb + (b << 56)); pb = b; pb += r2[2]; b = lt_modm(r1[2], pb); r[2] = (r1[2] - pb + (b << 56)); pb = b; pb += r2[3]; b = lt_modm(r1[3], pb); r[3] = (r1[3] - pb + (b << 56)); pb = b; pb += r2[4]; b = lt_modm(r1[4], pb); r[4] = (r1[4] - pb + (b << 40)); reduce256_modm(r); reduce256_modm(r); } static void add256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { bignum256modm_element_t c; c = x[0] + y[0]; r[0] = c & 0xffffffffffffff; c >>= 56; c += x[1] + y[1]; r[1] = c & 0xffffffffffffff; c >>= 56; c += x[2] + y[2]; r[2] = c & 0xffffffffffffff; c >>= 56; c += x[3] + y[3]; r[3] = c & 0xffffffffffffff; c >>= 56; c += x[4] + y[4]; r[4] = c; reduce256_modm(r); } static void mul256_modm(bignum256modm r, const bignum256modm x, const bignum256modm y) { bignum256modm q1, r1; uint128_t c, mul; bignum256modm_element_t f; mul64x64_128(c, x[0], y[0]) f = lo128(c); r1[0] = f & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, x[0], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[0]) add128(c, mul) f = lo128(c); r1[1] = f & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, x[0], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[1]) add128(c, mul) f = lo128(c); r1[2] = f & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, x[0], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[0]) add128(c, mul) mul64x64_128(mul, x[1], y[2]) add128(c, mul) mul64x64_128(mul, x[2], y[1]) add128(c, mul) f = lo128(c); r1[3] = f & 0xffffffffffffff; shr128(f, c, 56); mul64x64_128(c, x[0], y[4]) add128_64(c, f) mul64x64_128(mul, x[4], y[0]) add128(c, mul) mul64x64_128(mul, x[3], y[1]) add128(c, mul) mul64x64_128(mul, x[1], y[3]) add128(c, mul) mul64x64_128(mul, x[2], y[2]) add128(c, mul) f = lo128(c); r1[4] = f & 0x0000ffffffffff; q1[0] = (f >> 24) & 0xffffffff; shr128(f, c, 56); mul64x64_128(c, x[4], y[1]) add128_64(c, f) mul64x64_128(mul, x[1], y[4]) add128(c, mul) mul64x64_128(mul, x[2], y[3]) add128(c, mul) mul64x64_128(mul, x[3], y[2]) add128(c, mul) f = lo128(c); q1[0] |= (f << 32) & 0xffffffffffffff; q1[1] = (f >> 24) & 0xffffffff; shr128(f, c, 56); mul64x64_128(c, x[4], y[2]) add128_64(c, f) mul64x64_128(mul, x[2], y[4]) add128(c, mul) mul64x64_128(mul, x[3], y[3]) add128(c, mul) f = lo128(c); q1[1] |= (f << 32) & 0xffffffffffffff; q1[2] = (f >> 24) & 0xffffffff; shr128(f, c, 56); mul64x64_128(c, x[4], y[3]) add128_64(c, f) mul64x64_128(mul, x[3], y[4]) add128(c, mul) f = lo128(c); q1[2] |= (f << 32) & 0xffffffffffffff; q1[3] = (f >> 24) & 0xffffffff; shr128(f, c, 56); mul64x64_128(c, x[4], y[4]) add128_64(c, f) f = lo128(c); q1[3] |= (f << 32) & 0xffffffffffffff; q1[4] = (f >> 24) & 0xffffffff; shr128(f, c, 56); q1[4] |= (f << 32); barrett_reduce256_modm(r, q1, r1); } static void expand256_modm(bignum256modm out, const unsigned char *in, size_t len) { unsigned char work[64] = {0}; bignum256modm_element_t x[16]; bignum256modm q1; memcpy(work, in, len); x[0] = U8TO64_LE(work + 0); x[1] = U8TO64_LE(work + 8); x[2] = U8TO64_LE(work + 16); x[3] = U8TO64_LE(work + 24); x[4] = U8TO64_LE(work + 32); x[5] = U8TO64_LE(work + 40); x[6] = U8TO64_LE(work + 48); x[7] = U8TO64_LE(work + 56); /* r1 = (x mod 256^(32+1)) = x mod (2^8)(31+1) = x & ((1 << 264) - 1) */ out[0] = ( x[0]) & 0xffffffffffffff; out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff; out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff; out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff; out[4] = ((x[ 3] >> 32) | (x[ 4] << 32)) & 0x0000ffffffffff; /* under 252 bits, no need to reduce */ if (len < 32) return; /* q1 = x >> 248 = 264 bits */ q1[0] = ((x[ 3] >> 56) | (x[ 4] << 8)) & 0xffffffffffffff; q1[1] = ((x[ 4] >> 48) | (x[ 5] << 16)) & 0xffffffffffffff; q1[2] = ((x[ 5] >> 40) | (x[ 6] << 24)) & 0xffffffffffffff; q1[3] = ((x[ 6] >> 32) | (x[ 7] << 32)) & 0xffffffffffffff; q1[4] = ((x[ 7] >> 24) ); barrett_reduce256_modm(out, q1, out); } static void expand_raw256_modm(bignum256modm out, const unsigned char in[32]) { bignum256modm_element_t x[4]; x[0] = U8TO64_LE(in + 0); x[1] = U8TO64_LE(in + 8); x[2] = U8TO64_LE(in + 16); x[3] = U8TO64_LE(in + 24); out[0] = ( x[0]) & 0xffffffffffffff; out[1] = ((x[ 0] >> 56) | (x[ 1] << 8)) & 0xffffffffffffff; out[2] = ((x[ 1] >> 48) | (x[ 2] << 16)) & 0xffffffffffffff; out[3] = ((x[ 2] >> 40) | (x[ 3] << 24)) & 0xffffffffffffff; out[4] = ((x[ 3] >> 32) ) & 0x000000ffffffff; } static void contract256_modm(unsigned char out[32], const bignum256modm in) { U64TO8_LE(out + 0, (in[0] ) | (in[1] << 56)); U64TO8_LE(out + 8, (in[1] >> 8) | (in[2] << 48)); U64TO8_LE(out + 16, (in[2] >> 16) | (in[3] << 40)); U64TO8_LE(out + 24, (in[3] >> 24) | (in[4] << 32)); } static void contract256_window4_modm(signed char r[64], const bignum256modm in) { char carry; signed char *quads = r; bignum256modm_element_t i, j, v, m; for (i = 0; i < 5; i++) { v = in[i]; m = (i == 4) ? 8 : 14; for (j = 0; j < m; j++) { *quads++ = (v & 15); v >>= 4; } } /* making it signed */ carry = 0; for(i = 0; i < 63; i++) { r[i] += carry; r[i+1] += (r[i] >> 4); r[i] &= 15; carry = (r[i] >> 3); r[i] -= (carry << 4); } r[63] += carry; } static void contract256_slidingwindow_modm(signed char r[256], const bignum256modm s, int windowsize) { int i,j,k,b; int m = (1 << (windowsize - 1)) - 1, soplen = 256; signed char *bits = r; bignum256modm_element_t v; /* first put the binary expansion into r */ for (i = 0; i < 4; i++) { v = s[i]; for (j = 0; j < 56; j++, v >>= 1) *bits++ = (v & 1); } v = s[4]; for (j = 0; j < 32; j++, v >>= 1) *bits++ = (v & 1); /* Making it sliding window */ for (j = 0; j < soplen; j++) { if (!r[j]) continue; for (b = 1; (b < (soplen - j)) && (b <= 6); b++) { if ((r[j] + (r[j + b] << b)) <= m) { r[j] += r[j + b] << b; r[j + b] = 0; } else if ((r[j] - (r[j + b] << b)) >= -m) { r[j] -= r[j + b] << b; for (k = j + b; k < soplen; k++) { if (!r[k]) { r[k] = 1; break; } r[k] = 0; } } else if (r[j + b]) { break; } } } } /* helpers for batch verifcation, are allowed to be vartime */ /* out = a - b, a must be larger than b */ static void sub256_modm_batch(bignum256modm out, const bignum256modm a, const bignum256modm b, size_t limbsize) { size_t i = 0; bignum256modm_element_t carry = 0; switch (limbsize) { case 4: out[i] = (a[i] - b[i]) ; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; case 0: default: out[i] = (a[i] - b[i]) - carry; } } /* is a < b */ static int lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { size_t i = 0; bignum256modm_element_t t, carry = 0; switch (limbsize) { case 4: t = (a[i] - b[i]) ; carry = (t >> 63); i++; case 3: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; case 2: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; case 1: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; case 0: t = (a[i] - b[i]) - carry; carry = (t >> 63); } return (int)carry; } /* is a <= b */ static int lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) { size_t i = 0; bignum256modm_element_t t, carry = 0; switch (limbsize) { case 4: t = (b[i] - a[i]) ; carry = (t >> 63); i++; case 3: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; case 2: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; case 1: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; case 0: t = (b[i] - a[i]) - carry; carry = (t >> 63); } return (int)!carry; } /* is a == 0 */ static int iszero256_modm_batch(const bignum256modm a) { size_t i; for (i = 0; i < 5; i++) if (a[i]) return 0; return 1; } /* is a == 1 */ static int isone256_modm_batch(const bignum256modm a) { size_t i; for (i = 0; i < 5; i++) if (a[i] != ((i) ? 0 : 1)) return 0; return 1; } /* can a fit in to (at most) 128 bits */ static int isatmost128bits256_modm_batch(const bignum256modm a) { uint64_t mask = ((a[4] ) | /* 32 */ (a[3] ) | /* 88 */ (a[2] & 0xffffffffff0000)); return (mask == 0); } cryptonite-0.23/cbits/ed448/x448.h0000644000000000000000000000116513054050744014645 0ustar0000000000000000 #define X448_BYTES (448/8) /* The base point (5) */ //extern const unsigned char X448_BASE_POINT[X448_BYTES]; /* Returns 0 on success, -1 on failure */ int __attribute__((visibility("default"))) cryptonite_x448 ( unsigned char out[X448_BYTES], const unsigned char scalar[X448_BYTES], const unsigned char base[X448_BYTES] ); /* Returns 0 on success, -1 on failure * * Same as x448(out,scalar,X448_BASE_POINT), except that * an implementation may optimize it. */ int __attribute__((visibility("default"))) cryptonite_x448_base ( unsigned char out[X448_BYTES], const unsigned char scalar[X448_BYTES] ); cryptonite-0.23/cbits/p256/p256.h0000644000000000000000000001366312521461531014502 0ustar0000000000000000/* * Copyright 2013 The Android Open Source Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Google Inc. nor the names of its contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_ #define SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_ // Collection of routines manipulating 256 bit unsigned integers. // Just enough to implement ecdsa-p256 and related algorithms. #include #ifdef __cplusplus extern "C" { #endif #define P256_BITSPERDIGIT 32 #define P256_NDIGITS 8 #define P256_NBYTES 32 typedef int cryptonite_p256_err; typedef uint32_t cryptonite_p256_digit; typedef int32_t cryptonite_p256_sdigit; typedef uint64_t cryptonite_p256_ddigit; typedef int64_t cryptonite_p256_sddigit; // Defining cryptonite_p256_int as struct to leverage struct assigment. typedef struct { cryptonite_p256_digit a[P256_NDIGITS]; } cryptonite_p256_int; extern const cryptonite_p256_int cryptonite_SECP256r1_n; // Curve order extern const cryptonite_p256_int cryptonite_SECP256r1_p; // Curve prime extern const cryptonite_p256_int cryptonite_SECP256r1_b; // Curve param // Initialize a cryptonite_p256_int to zero. void cryptonite_p256_init(cryptonite_p256_int* a); // Clear a cryptonite_p256_int to zero. void cryptonite_p256_clear(cryptonite_p256_int* a); // Return bit. Index 0 is least significant. int cryptonite_p256_get_bit(const cryptonite_p256_int* a, int index); // b := a % MOD void cryptonite_p256_mod( const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, cryptonite_p256_int* b); // c := a * (top_b | b) % MOD void cryptonite_p256_modmul( const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, const cryptonite_p256_digit top_b, const cryptonite_p256_int* b, cryptonite_p256_int* c); // b := 1 / a % MOD // MOD best be SECP256r1_n void cryptonite_p256_modinv( const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, cryptonite_p256_int* b); // b := 1 / a % MOD // MOD best be SECP256r1_n // Faster than cryptonite_p256_modinv() void cryptonite_p256_modinv_vartime( const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, cryptonite_p256_int* b); // b := a << (n % P256_BITSPERDIGIT) // Returns the bits shifted out of most significant digit. cryptonite_p256_digit cryptonite_p256_shl(const cryptonite_p256_int* a, int n, cryptonite_p256_int* b); // b := a >> (n % P256_BITSPERDIGIT) void cryptonite_p256_shr(const cryptonite_p256_int* a, int n, cryptonite_p256_int* b); int cryptonite_p256_is_zero(const cryptonite_p256_int* a); int cryptonite_p256_is_odd(const cryptonite_p256_int* a); int cryptonite_p256_is_even(const cryptonite_p256_int* a); // Returns -1, 0 or 1. int cryptonite_p256_cmp(const cryptonite_p256_int* a, const cryptonite_p256_int *b); // c: = a - b // Returns -1 on borrow. int cryptonite_p256_sub(const cryptonite_p256_int* a, const cryptonite_p256_int* b, cryptonite_p256_int* c); // c := a + b // Returns 1 on carry. int cryptonite_p256_add(const cryptonite_p256_int* a, const cryptonite_p256_int* b, cryptonite_p256_int* c); // c := a + (single digit)b // Returns carry 1 on carry. int cryptonite_p256_add_d(const cryptonite_p256_int* a, cryptonite_p256_digit b, cryptonite_p256_int* c); // ec routines. // {out_x,out_y} := nG void cryptonite_p256_base_point_mul(const cryptonite_p256_int *n, cryptonite_p256_int *out_x, cryptonite_p256_int *out_y); // {out_x,out_y} := n{in_x,in_y} void cryptonite_p256_point_mul(const cryptonite_p256_int *n, const cryptonite_p256_int *in_x, const cryptonite_p256_int *in_y, cryptonite_p256_int *out_x, cryptonite_p256_int *out_y); // {out_x,out_y} := n1G + n2{in_x,in_y} void cryptonite_p256_points_mul_vartime( const cryptonite_p256_int *n1, const cryptonite_p256_int *n2, const cryptonite_p256_int *in_x, const cryptonite_p256_int *in_y, cryptonite_p256_int *out_x, cryptonite_p256_int *out_y); // Return whether point {x,y} is on curve. int cryptonite_p256_is_valid_point(const cryptonite_p256_int* x, const cryptonite_p256_int* y); // Outputs big-endian binary form. No leading zero skips. void cryptonite_p256_to_bin(const cryptonite_p256_int* src, uint8_t dst[P256_NBYTES]); // Reads from big-endian binary form, // thus pre-pad with leading zeros if short. void cryptonite_p256_from_bin(const uint8_t src[P256_NBYTES], cryptonite_p256_int* dst); #define P256_DIGITS(x) ((x)->a) #define P256_DIGIT(x,y) ((x)->a[y]) #define P256_ZERO {{0}} #define P256_ONE {{1}} #ifdef __cplusplus } #endif #endif // SYSTEM_CORE_INCLUDE_MINCRYPT_LITE_P256_H_ cryptonite-0.23/cbits/blake2/ref/blake2-impl.h0000644000000000000000000001011713054050744017316 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2_IMPL_H #define BLAKE2_IMPL_H #include #include #if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) #if defined(_MSC_VER) #define BLAKE2_INLINE __inline #elif defined(__GNUC__) #define BLAKE2_INLINE __inline__ #else #define BLAKE2_INLINE #endif #else #define BLAKE2_INLINE inline #endif static BLAKE2_INLINE uint32_t load32( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint32_t w; memcpy(&w, src, sizeof w); return w; #else const uint8_t *p = ( const uint8_t * )src; return (( uint32_t )( p[0] ) << 0) | (( uint32_t )( p[1] ) << 8) | (( uint32_t )( p[2] ) << 16) | (( uint32_t )( p[3] ) << 24) ; #endif } static BLAKE2_INLINE uint64_t load64( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint64_t w; memcpy(&w, src, sizeof w); return w; #else const uint8_t *p = ( const uint8_t * )src; return (( uint64_t )( p[0] ) << 0) | (( uint64_t )( p[1] ) << 8) | (( uint64_t )( p[2] ) << 16) | (( uint64_t )( p[3] ) << 24) | (( uint64_t )( p[4] ) << 32) | (( uint64_t )( p[5] ) << 40) | (( uint64_t )( p[6] ) << 48) | (( uint64_t )( p[7] ) << 56) ; #endif } static BLAKE2_INLINE uint16_t load16( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint16_t w; memcpy(&w, src, sizeof w); return w; #else const uint8_t *p = ( const uint8_t * )src; return (( uint16_t )( p[0] ) << 0) | (( uint16_t )( p[1] ) << 8) ; #endif } static BLAKE2_INLINE void store16( void *dst, uint16_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8; *p++ = ( uint8_t )w; #endif } static BLAKE2_INLINE void store32( void *dst, uint32_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; p[0] = (uint8_t)(w >> 0); p[1] = (uint8_t)(w >> 8); p[2] = (uint8_t)(w >> 16); p[3] = (uint8_t)(w >> 24); #endif } static BLAKE2_INLINE void store64( void *dst, uint64_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; p[0] = (uint8_t)(w >> 0); p[1] = (uint8_t)(w >> 8); p[2] = (uint8_t)(w >> 16); p[3] = (uint8_t)(w >> 24); p[4] = (uint8_t)(w >> 32); p[5] = (uint8_t)(w >> 40); p[6] = (uint8_t)(w >> 48); p[7] = (uint8_t)(w >> 56); #endif } static BLAKE2_INLINE uint64_t load48( const void *src ) { const uint8_t *p = ( const uint8_t * )src; return (( uint64_t )( p[0] ) << 0) | (( uint64_t )( p[1] ) << 8) | (( uint64_t )( p[2] ) << 16) | (( uint64_t )( p[3] ) << 24) | (( uint64_t )( p[4] ) << 32) | (( uint64_t )( p[5] ) << 40) ; } static BLAKE2_INLINE void store48( void *dst, uint64_t w ) { uint8_t *p = ( uint8_t * )dst; p[0] = (uint8_t)(w >> 0); p[1] = (uint8_t)(w >> 8); p[2] = (uint8_t)(w >> 16); p[3] = (uint8_t)(w >> 24); p[4] = (uint8_t)(w >> 32); p[5] = (uint8_t)(w >> 40); } static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 32 - c ) ); } static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 64 - c ) ); } /* prevents compiler optimizing out memset() */ static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) { static void *(*const volatile memset_v)(void *, int, size_t) = &memset; memset_v(v, 0, n); } #endif cryptonite-0.23/cbits/blake2/ref/blake2.h0000644000000000000000000001446713054050744016373 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2_H #define BLAKE2_H #include #include #if defined(_MSC_VER) #define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) #else #define BLAKE2_PACKED(x) x __attribute__((packed)) #endif #if defined(__cplusplus) extern "C" { #endif enum blake2s_constant { BLAKE2S_BLOCKBYTES = 64, BLAKE2S_OUTBYTES = 32, BLAKE2S_KEYBYTES = 32, BLAKE2S_SALTBYTES = 8, BLAKE2S_PERSONALBYTES = 8 }; enum blake2b_constant { BLAKE2B_BLOCKBYTES = 128, BLAKE2B_OUTBYTES = 64, BLAKE2B_KEYBYTES = 64, BLAKE2B_SALTBYTES = 16, BLAKE2B_PERSONALBYTES = 16 }; typedef struct blake2s_state__ { uint32_t h[8]; uint32_t t[2]; uint32_t f[2]; uint8_t buf[BLAKE2S_BLOCKBYTES]; size_t buflen; size_t outlen; uint8_t last_node; } blake2s_state; typedef struct blake2b_state__ { uint64_t h[8]; uint64_t t[2]; uint64_t f[2]; uint8_t buf[BLAKE2B_BLOCKBYTES]; size_t buflen; size_t outlen; uint8_t last_node; } blake2b_state; typedef struct blake2sp_state__ { blake2s_state S[8][1]; blake2s_state R[1]; uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; size_t buflen; size_t outlen; } blake2sp_state; typedef struct blake2bp_state__ { blake2b_state S[4][1]; blake2b_state R[1]; uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; size_t buflen; size_t outlen; } blake2bp_state; BLAKE2_PACKED(struct blake2s_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */ uint32_t node_offset; /* 12 */ uint16_t xof_length; /* 14 */ uint8_t node_depth; /* 15 */ uint8_t inner_length; /* 16 */ /* uint8_t reserved[0]; */ uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ }); typedef struct blake2s_param__ blake2s_param; BLAKE2_PACKED(struct blake2b_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */ uint32_t node_offset; /* 12 */ uint32_t xof_length; /* 16 */ uint8_t node_depth; /* 17 */ uint8_t inner_length; /* 18 */ uint8_t reserved[14]; /* 32 */ uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ }); typedef struct blake2b_param__ blake2b_param; typedef struct blake2xs_state__ { blake2s_state S[1]; blake2s_param P[1]; } blake2xs_state; typedef struct blake2xb_state__ { blake2b_state S[1]; blake2b_param P[1]; } blake2xb_state; /* Padded structs result in a compile-time error */ enum { BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) }; /* Streaming API */ int blake2s_init( blake2s_state *S, size_t outlen ); int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); int blake2s_final( blake2s_state *S, void *out, size_t outlen ); int blake2b_init( blake2b_state *S, size_t outlen ); int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); int blake2b_final( blake2b_state *S, void *out, size_t outlen ); int blake2sp_init( blake2sp_state *S, size_t outlen ); int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); int blake2bp_init( blake2bp_state *S, size_t outlen ); int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); /* Variable output length API */ int blake2xs_init( blake2xs_state *S, const size_t outlen ); int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); int blake2xb_init( blake2xb_state *S, const size_t outlen ); int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); /* Simple API */ int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); /* This is simply an alias for blake2b */ int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); #if defined(__cplusplus) } #endif #endif cryptonite-0.23/cbits/blake2/sse/blake2-config.h0000644000000000000000000000253013054050744017640 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2_CONFIG_H #define BLAKE2_CONFIG_H /* These don't work everywhere */ #if defined(__SSE2__) || defined(__x86_64__) || defined(__amd64__) #define HAVE_SSE2 #endif #if defined(__SSSE3__) #define HAVE_SSSE3 #endif #if defined(__SSE4_1__) #define HAVE_SSE41 #endif #if defined(__AVX__) #define HAVE_AVX #endif #if defined(__XOP__) #define HAVE_XOP #endif #ifdef HAVE_AVX2 #ifndef HAVE_AVX #define HAVE_AVX #endif #endif #ifdef HAVE_XOP #ifndef HAVE_AVX #define HAVE_AVX #endif #endif #ifdef HAVE_AVX #ifndef HAVE_SSE41 #define HAVE_SSE41 #endif #endif #ifdef HAVE_SSE41 #ifndef HAVE_SSSE3 #define HAVE_SSSE3 #endif #endif #ifdef HAVE_SSSE3 #define HAVE_SSE2 #endif #if !defined(HAVE_SSE2) #error "This code requires at least SSE2." #endif #endif cryptonite-0.23/cbits/blake2/sse/blake2-impl.h0000644000000000000000000001011713054050744017334 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2_IMPL_H #define BLAKE2_IMPL_H #include #include #if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) #if defined(_MSC_VER) #define BLAKE2_INLINE __inline #elif defined(__GNUC__) #define BLAKE2_INLINE __inline__ #else #define BLAKE2_INLINE #endif #else #define BLAKE2_INLINE inline #endif static BLAKE2_INLINE uint32_t load32( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint32_t w; memcpy(&w, src, sizeof w); return w; #else const uint8_t *p = ( const uint8_t * )src; return (( uint32_t )( p[0] ) << 0) | (( uint32_t )( p[1] ) << 8) | (( uint32_t )( p[2] ) << 16) | (( uint32_t )( p[3] ) << 24) ; #endif } static BLAKE2_INLINE uint64_t load64( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint64_t w; memcpy(&w, src, sizeof w); return w; #else const uint8_t *p = ( const uint8_t * )src; return (( uint64_t )( p[0] ) << 0) | (( uint64_t )( p[1] ) << 8) | (( uint64_t )( p[2] ) << 16) | (( uint64_t )( p[3] ) << 24) | (( uint64_t )( p[4] ) << 32) | (( uint64_t )( p[5] ) << 40) | (( uint64_t )( p[6] ) << 48) | (( uint64_t )( p[7] ) << 56) ; #endif } static BLAKE2_INLINE uint16_t load16( const void *src ) { #if defined(NATIVE_LITTLE_ENDIAN) uint16_t w; memcpy(&w, src, sizeof w); return w; #else const uint8_t *p = ( const uint8_t * )src; return (( uint16_t )( p[0] ) << 0) | (( uint16_t )( p[1] ) << 8) ; #endif } static BLAKE2_INLINE void store16( void *dst, uint16_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; *p++ = ( uint8_t )w; w >>= 8; *p++ = ( uint8_t )w; #endif } static BLAKE2_INLINE void store32( void *dst, uint32_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; p[0] = (uint8_t)(w >> 0); p[1] = (uint8_t)(w >> 8); p[2] = (uint8_t)(w >> 16); p[3] = (uint8_t)(w >> 24); #endif } static BLAKE2_INLINE void store64( void *dst, uint64_t w ) { #if defined(NATIVE_LITTLE_ENDIAN) memcpy(dst, &w, sizeof w); #else uint8_t *p = ( uint8_t * )dst; p[0] = (uint8_t)(w >> 0); p[1] = (uint8_t)(w >> 8); p[2] = (uint8_t)(w >> 16); p[3] = (uint8_t)(w >> 24); p[4] = (uint8_t)(w >> 32); p[5] = (uint8_t)(w >> 40); p[6] = (uint8_t)(w >> 48); p[7] = (uint8_t)(w >> 56); #endif } static BLAKE2_INLINE uint64_t load48( const void *src ) { const uint8_t *p = ( const uint8_t * )src; return (( uint64_t )( p[0] ) << 0) | (( uint64_t )( p[1] ) << 8) | (( uint64_t )( p[2] ) << 16) | (( uint64_t )( p[3] ) << 24) | (( uint64_t )( p[4] ) << 32) | (( uint64_t )( p[5] ) << 40) ; } static BLAKE2_INLINE void store48( void *dst, uint64_t w ) { uint8_t *p = ( uint8_t * )dst; p[0] = (uint8_t)(w >> 0); p[1] = (uint8_t)(w >> 8); p[2] = (uint8_t)(w >> 16); p[3] = (uint8_t)(w >> 24); p[4] = (uint8_t)(w >> 32); p[5] = (uint8_t)(w >> 40); } static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 32 - c ) ); } static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c ) { return ( w >> c ) | ( w << ( 64 - c ) ); } /* prevents compiler optimizing out memset() */ static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n) { static void *(*const volatile memset_v)(void *, int, size_t) = &memset; memset_v(v, 0, n); } #endif cryptonite-0.23/cbits/blake2/sse/blake2.h0000644000000000000000000001446713054050744016411 0ustar0000000000000000/* BLAKE2 reference source code package - reference C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2_H #define BLAKE2_H #include #include #if defined(_MSC_VER) #define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop)) #else #define BLAKE2_PACKED(x) x __attribute__((packed)) #endif #if defined(__cplusplus) extern "C" { #endif enum blake2s_constant { BLAKE2S_BLOCKBYTES = 64, BLAKE2S_OUTBYTES = 32, BLAKE2S_KEYBYTES = 32, BLAKE2S_SALTBYTES = 8, BLAKE2S_PERSONALBYTES = 8 }; enum blake2b_constant { BLAKE2B_BLOCKBYTES = 128, BLAKE2B_OUTBYTES = 64, BLAKE2B_KEYBYTES = 64, BLAKE2B_SALTBYTES = 16, BLAKE2B_PERSONALBYTES = 16 }; typedef struct blake2s_state__ { uint32_t h[8]; uint32_t t[2]; uint32_t f[2]; uint8_t buf[BLAKE2S_BLOCKBYTES]; size_t buflen; size_t outlen; uint8_t last_node; } blake2s_state; typedef struct blake2b_state__ { uint64_t h[8]; uint64_t t[2]; uint64_t f[2]; uint8_t buf[BLAKE2B_BLOCKBYTES]; size_t buflen; size_t outlen; uint8_t last_node; } blake2b_state; typedef struct blake2sp_state__ { blake2s_state S[8][1]; blake2s_state R[1]; uint8_t buf[8 * BLAKE2S_BLOCKBYTES]; size_t buflen; size_t outlen; } blake2sp_state; typedef struct blake2bp_state__ { blake2b_state S[4][1]; blake2b_state R[1]; uint8_t buf[4 * BLAKE2B_BLOCKBYTES]; size_t buflen; size_t outlen; } blake2bp_state; BLAKE2_PACKED(struct blake2s_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */ uint32_t node_offset; /* 12 */ uint16_t xof_length; /* 14 */ uint8_t node_depth; /* 15 */ uint8_t inner_length; /* 16 */ /* uint8_t reserved[0]; */ uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */ uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */ }); typedef struct blake2s_param__ blake2s_param; BLAKE2_PACKED(struct blake2b_param__ { uint8_t digest_length; /* 1 */ uint8_t key_length; /* 2 */ uint8_t fanout; /* 3 */ uint8_t depth; /* 4 */ uint32_t leaf_length; /* 8 */ uint32_t node_offset; /* 12 */ uint32_t xof_length; /* 16 */ uint8_t node_depth; /* 17 */ uint8_t inner_length; /* 18 */ uint8_t reserved[14]; /* 32 */ uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ }); typedef struct blake2b_param__ blake2b_param; typedef struct blake2xs_state__ { blake2s_state S[1]; blake2s_param P[1]; } blake2xs_state; typedef struct blake2xb_state__ { blake2b_state S[1]; blake2b_param P[1]; } blake2xb_state; /* Padded structs result in a compile-time error */ enum { BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES), BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES) }; /* Streaming API */ int blake2s_init( blake2s_state *S, size_t outlen ); int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen ); int blake2s_init_param( blake2s_state *S, const blake2s_param *P ); int blake2s_update( blake2s_state *S, const void *in, size_t inlen ); int blake2s_final( blake2s_state *S, void *out, size_t outlen ); int blake2b_init( blake2b_state *S, size_t outlen ); int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen ); int blake2b_init_param( blake2b_state *S, const blake2b_param *P ); int blake2b_update( blake2b_state *S, const void *in, size_t inlen ); int blake2b_final( blake2b_state *S, void *out, size_t outlen ); int blake2sp_init( blake2sp_state *S, size_t outlen ); int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen ); int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen ); int blake2sp_final( blake2sp_state *S, void *out, size_t outlen ); int blake2bp_init( blake2bp_state *S, size_t outlen ); int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen ); int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen ); int blake2bp_final( blake2bp_state *S, void *out, size_t outlen ); /* Variable output length API */ int blake2xs_init( blake2xs_state *S, const size_t outlen ); int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen ); int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen ); int blake2xs_final(blake2xs_state *S, void *out, size_t outlen); int blake2xb_init( blake2xb_state *S, const size_t outlen ); int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen ); int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen ); int blake2xb_final(blake2xb_state *S, void *out, size_t outlen); /* Simple API */ int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); /* This is simply an alias for blake2b */ int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ); #if defined(__cplusplus) } #endif #endif cryptonite-0.23/cbits/blake2/sse/blake2b-load-sse2.h0000644000000000000000000001141313054050744020326 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2B_LOAD_SSE2_H #define BLAKE2B_LOAD_SSE2_H #define LOAD_MSG_0_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) #define LOAD_MSG_0_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) #define LOAD_MSG_0_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) #define LOAD_MSG_0_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) #define LOAD_MSG_1_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) #define LOAD_MSG_1_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) #define LOAD_MSG_1_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) #define LOAD_MSG_1_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) #define LOAD_MSG_2_1(b0, b1) b0 = _mm_set_epi64x(m12, m11); b1 = _mm_set_epi64x(m15, m5) #define LOAD_MSG_2_2(b0, b1) b0 = _mm_set_epi64x(m0, m8); b1 = _mm_set_epi64x(m13, m2) #define LOAD_MSG_2_3(b0, b1) b0 = _mm_set_epi64x(m3, m10); b1 = _mm_set_epi64x(m9, m7) #define LOAD_MSG_2_4(b0, b1) b0 = _mm_set_epi64x(m6, m14); b1 = _mm_set_epi64x(m4, m1) #define LOAD_MSG_3_1(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m13) #define LOAD_MSG_3_2(b0, b1) b0 = _mm_set_epi64x(m1, m9); b1 = _mm_set_epi64x(m14, m12) #define LOAD_MSG_3_3(b0, b1) b0 = _mm_set_epi64x(m5, m2); b1 = _mm_set_epi64x(m15, m4) #define LOAD_MSG_3_4(b0, b1) b0 = _mm_set_epi64x(m10, m6); b1 = _mm_set_epi64x(m8, m0) #define LOAD_MSG_4_1(b0, b1) b0 = _mm_set_epi64x(m5, m9); b1 = _mm_set_epi64x(m10, m2) #define LOAD_MSG_4_2(b0, b1) b0 = _mm_set_epi64x(m7, m0); b1 = _mm_set_epi64x(m15, m4) #define LOAD_MSG_4_3(b0, b1) b0 = _mm_set_epi64x(m11, m14); b1 = _mm_set_epi64x(m3, m6) #define LOAD_MSG_4_4(b0, b1) b0 = _mm_set_epi64x(m12, m1); b1 = _mm_set_epi64x(m13, m8) #define LOAD_MSG_5_1(b0, b1) b0 = _mm_set_epi64x(m6, m2); b1 = _mm_set_epi64x(m8, m0) #define LOAD_MSG_5_2(b0, b1) b0 = _mm_set_epi64x(m10, m12); b1 = _mm_set_epi64x(m3, m11) #define LOAD_MSG_5_3(b0, b1) b0 = _mm_set_epi64x(m7, m4); b1 = _mm_set_epi64x(m1, m15) #define LOAD_MSG_5_4(b0, b1) b0 = _mm_set_epi64x(m5, m13); b1 = _mm_set_epi64x(m9, m14) #define LOAD_MSG_6_1(b0, b1) b0 = _mm_set_epi64x(m1, m12); b1 = _mm_set_epi64x(m4, m14) #define LOAD_MSG_6_2(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m10, m13) #define LOAD_MSG_6_3(b0, b1) b0 = _mm_set_epi64x(m6, m0); b1 = _mm_set_epi64x(m8, m9) #define LOAD_MSG_6_4(b0, b1) b0 = _mm_set_epi64x(m3, m7); b1 = _mm_set_epi64x(m11, m2) #define LOAD_MSG_7_1(b0, b1) b0 = _mm_set_epi64x(m7, m13); b1 = _mm_set_epi64x(m3, m12) #define LOAD_MSG_7_2(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m9, m1) #define LOAD_MSG_7_3(b0, b1) b0 = _mm_set_epi64x(m15, m5); b1 = _mm_set_epi64x(m2, m8) #define LOAD_MSG_7_4(b0, b1) b0 = _mm_set_epi64x(m4, m0); b1 = _mm_set_epi64x(m10, m6) #define LOAD_MSG_8_1(b0, b1) b0 = _mm_set_epi64x(m14, m6); b1 = _mm_set_epi64x(m0, m11) #define LOAD_MSG_8_2(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m8, m3) #define LOAD_MSG_8_3(b0, b1) b0 = _mm_set_epi64x(m13, m12); b1 = _mm_set_epi64x(m10, m1) #define LOAD_MSG_8_4(b0, b1) b0 = _mm_set_epi64x(m7, m2); b1 = _mm_set_epi64x(m5, m4) #define LOAD_MSG_9_1(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m1, m7) #define LOAD_MSG_9_2(b0, b1) b0 = _mm_set_epi64x(m4, m2); b1 = _mm_set_epi64x(m5, m6) #define LOAD_MSG_9_3(b0, b1) b0 = _mm_set_epi64x(m9, m15); b1 = _mm_set_epi64x(m13, m3) #define LOAD_MSG_9_4(b0, b1) b0 = _mm_set_epi64x(m14, m11); b1 = _mm_set_epi64x(m0, m12) #define LOAD_MSG_10_1(b0, b1) b0 = _mm_set_epi64x(m2, m0); b1 = _mm_set_epi64x(m6, m4) #define LOAD_MSG_10_2(b0, b1) b0 = _mm_set_epi64x(m3, m1); b1 = _mm_set_epi64x(m7, m5) #define LOAD_MSG_10_3(b0, b1) b0 = _mm_set_epi64x(m10, m8); b1 = _mm_set_epi64x(m14, m12) #define LOAD_MSG_10_4(b0, b1) b0 = _mm_set_epi64x(m11, m9); b1 = _mm_set_epi64x(m15, m13) #define LOAD_MSG_11_1(b0, b1) b0 = _mm_set_epi64x(m4, m14); b1 = _mm_set_epi64x(m13, m9) #define LOAD_MSG_11_2(b0, b1) b0 = _mm_set_epi64x(m8, m10); b1 = _mm_set_epi64x(m6, m15) #define LOAD_MSG_11_3(b0, b1) b0 = _mm_set_epi64x(m0, m1); b1 = _mm_set_epi64x(m5, m11) #define LOAD_MSG_11_4(b0, b1) b0 = _mm_set_epi64x(m2, m12); b1 = _mm_set_epi64x(m3, m7) #endif cryptonite-0.23/cbits/blake2/sse/blake2b-load-sse41.h0000644000000000000000000001474613054050744020425 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2B_LOAD_SSE41_H #define BLAKE2B_LOAD_SSE41_H #define LOAD_MSG_0_1(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m0, m1); \ b1 = _mm_unpacklo_epi64(m2, m3); \ } while(0) #define LOAD_MSG_0_2(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m0, m1); \ b1 = _mm_unpackhi_epi64(m2, m3); \ } while(0) #define LOAD_MSG_0_3(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m4, m5); \ b1 = _mm_unpacklo_epi64(m6, m7); \ } while(0) #define LOAD_MSG_0_4(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m4, m5); \ b1 = _mm_unpackhi_epi64(m6, m7); \ } while(0) #define LOAD_MSG_1_1(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m7, m2); \ b1 = _mm_unpackhi_epi64(m4, m6); \ } while(0) #define LOAD_MSG_1_2(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m5, m4); \ b1 = _mm_alignr_epi8(m3, m7, 8); \ } while(0) #define LOAD_MSG_1_3(b0, b1) \ do \ { \ b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ b1 = _mm_unpackhi_epi64(m5, m2); \ } while(0) #define LOAD_MSG_1_4(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m6, m1); \ b1 = _mm_unpackhi_epi64(m3, m1); \ } while(0) #define LOAD_MSG_2_1(b0, b1) \ do \ { \ b0 = _mm_alignr_epi8(m6, m5, 8); \ b1 = _mm_unpackhi_epi64(m2, m7); \ } while(0) #define LOAD_MSG_2_2(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m4, m0); \ b1 = _mm_blend_epi16(m1, m6, 0xF0); \ } while(0) #define LOAD_MSG_2_3(b0, b1) \ do \ { \ b0 = _mm_blend_epi16(m5, m1, 0xF0); \ b1 = _mm_unpackhi_epi64(m3, m4); \ } while(0) #define LOAD_MSG_2_4(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m7, m3); \ b1 = _mm_alignr_epi8(m2, m0, 8); \ } while(0) #define LOAD_MSG_3_1(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m3, m1); \ b1 = _mm_unpackhi_epi64(m6, m5); \ } while(0) #define LOAD_MSG_3_2(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m4, m0); \ b1 = _mm_unpacklo_epi64(m6, m7); \ } while(0) #define LOAD_MSG_3_3(b0, b1) \ do \ { \ b0 = _mm_blend_epi16(m1, m2, 0xF0); \ b1 = _mm_blend_epi16(m2, m7, 0xF0); \ } while(0) #define LOAD_MSG_3_4(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m3, m5); \ b1 = _mm_unpacklo_epi64(m0, m4); \ } while(0) #define LOAD_MSG_4_1(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m4, m2); \ b1 = _mm_unpacklo_epi64(m1, m5); \ } while(0) #define LOAD_MSG_4_2(b0, b1) \ do \ { \ b0 = _mm_blend_epi16(m0, m3, 0xF0); \ b1 = _mm_blend_epi16(m2, m7, 0xF0); \ } while(0) #define LOAD_MSG_4_3(b0, b1) \ do \ { \ b0 = _mm_blend_epi16(m7, m5, 0xF0); \ b1 = _mm_blend_epi16(m3, m1, 0xF0); \ } while(0) #define LOAD_MSG_4_4(b0, b1) \ do \ { \ b0 = _mm_alignr_epi8(m6, m0, 8); \ b1 = _mm_blend_epi16(m4, m6, 0xF0); \ } while(0) #define LOAD_MSG_5_1(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m1, m3); \ b1 = _mm_unpacklo_epi64(m0, m4); \ } while(0) #define LOAD_MSG_5_2(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m6, m5); \ b1 = _mm_unpackhi_epi64(m5, m1); \ } while(0) #define LOAD_MSG_5_3(b0, b1) \ do \ { \ b0 = _mm_blend_epi16(m2, m3, 0xF0); \ b1 = _mm_unpackhi_epi64(m7, m0); \ } while(0) #define LOAD_MSG_5_4(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m6, m2); \ b1 = _mm_blend_epi16(m7, m4, 0xF0); \ } while(0) #define LOAD_MSG_6_1(b0, b1) \ do \ { \ b0 = _mm_blend_epi16(m6, m0, 0xF0); \ b1 = _mm_unpacklo_epi64(m7, m2); \ } while(0) #define LOAD_MSG_6_2(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m2, m7); \ b1 = _mm_alignr_epi8(m5, m6, 8); \ } while(0) #define LOAD_MSG_6_3(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m0, m3); \ b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1,0,3,2)); \ } while(0) #define LOAD_MSG_6_4(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m3, m1); \ b1 = _mm_blend_epi16(m1, m5, 0xF0); \ } while(0) #define LOAD_MSG_7_1(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m6, m3); \ b1 = _mm_blend_epi16(m6, m1, 0xF0); \ } while(0) #define LOAD_MSG_7_2(b0, b1) \ do \ { \ b0 = _mm_alignr_epi8(m7, m5, 8); \ b1 = _mm_unpackhi_epi64(m0, m4); \ } while(0) #define LOAD_MSG_7_3(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m2, m7); \ b1 = _mm_unpacklo_epi64(m4, m1); \ } while(0) #define LOAD_MSG_7_4(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m0, m2); \ b1 = _mm_unpacklo_epi64(m3, m5); \ } while(0) #define LOAD_MSG_8_1(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m3, m7); \ b1 = _mm_alignr_epi8(m0, m5, 8); \ } while(0) #define LOAD_MSG_8_2(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m7, m4); \ b1 = _mm_alignr_epi8(m4, m1, 8); \ } while(0) #define LOAD_MSG_8_3(b0, b1) \ do \ { \ b0 = m6; \ b1 = _mm_alignr_epi8(m5, m0, 8); \ } while(0) #define LOAD_MSG_8_4(b0, b1) \ do \ { \ b0 = _mm_blend_epi16(m1, m3, 0xF0); \ b1 = m2; \ } while(0) #define LOAD_MSG_9_1(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m5, m4); \ b1 = _mm_unpackhi_epi64(m3, m0); \ } while(0) #define LOAD_MSG_9_2(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m1, m2); \ b1 = _mm_blend_epi16(m3, m2, 0xF0); \ } while(0) #define LOAD_MSG_9_3(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m7, m4); \ b1 = _mm_unpackhi_epi64(m1, m6); \ } while(0) #define LOAD_MSG_9_4(b0, b1) \ do \ { \ b0 = _mm_alignr_epi8(m7, m5, 8); \ b1 = _mm_unpacklo_epi64(m6, m0); \ } while(0) #define LOAD_MSG_10_1(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m0, m1); \ b1 = _mm_unpacklo_epi64(m2, m3); \ } while(0) #define LOAD_MSG_10_2(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m0, m1); \ b1 = _mm_unpackhi_epi64(m2, m3); \ } while(0) #define LOAD_MSG_10_3(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m4, m5); \ b1 = _mm_unpacklo_epi64(m6, m7); \ } while(0) #define LOAD_MSG_10_4(b0, b1) \ do \ { \ b0 = _mm_unpackhi_epi64(m4, m5); \ b1 = _mm_unpackhi_epi64(m6, m7); \ } while(0) #define LOAD_MSG_11_1(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m7, m2); \ b1 = _mm_unpackhi_epi64(m4, m6); \ } while(0) #define LOAD_MSG_11_2(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m5, m4); \ b1 = _mm_alignr_epi8(m3, m7, 8); \ } while(0) #define LOAD_MSG_11_3(b0, b1) \ do \ { \ b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1,0,3,2)); \ b1 = _mm_unpackhi_epi64(m5, m2); \ } while(0) #define LOAD_MSG_11_4(b0, b1) \ do \ { \ b0 = _mm_unpacklo_epi64(m6, m1); \ b1 = _mm_unpackhi_epi64(m3, m1); \ } while(0) #endif cryptonite-0.23/cbits/blake2/sse/blake2b-round.h0000644000000000000000000001156713054050744017676 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2B_ROUND_H #define BLAKE2B_ROUND_H #define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) #define TOF(reg) _mm_castsi128_ps((reg)) #define TOI(reg) _mm_castps_si128((reg)) #define LIKELY(x) __builtin_expect((x),1) /* Microarchitecture-specific macros */ #ifndef HAVE_XOP #ifdef HAVE_SSSE3 #define _mm_roti_epi64(x, c) \ (-(c) == 32) ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2,3,0,1)) \ : (-(c) == 24) ? _mm_shuffle_epi8((x), r24) \ : (-(c) == 16) ? _mm_shuffle_epi8((x), r16) \ : (-(c) == 63) ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_add_epi64((x), (x))) \ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), _mm_slli_epi64((x), 64-(-(c)))) #else #define _mm_roti_epi64(r, c) _mm_xor_si128(_mm_srli_epi64( (r), -(c) ),_mm_slli_epi64( (r), 64-(-(c)) )) #endif #else /* ... */ #endif #define G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ \ row4l = _mm_xor_si128(row4l, row1l); \ row4h = _mm_xor_si128(row4h, row1h); \ \ row4l = _mm_roti_epi64(row4l, -32); \ row4h = _mm_roti_epi64(row4h, -32); \ \ row3l = _mm_add_epi64(row3l, row4l); \ row3h = _mm_add_epi64(row3h, row4h); \ \ row2l = _mm_xor_si128(row2l, row3l); \ row2h = _mm_xor_si128(row2h, row3h); \ \ row2l = _mm_roti_epi64(row2l, -24); \ row2h = _mm_roti_epi64(row2h, -24); \ #define G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1) \ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ \ row4l = _mm_xor_si128(row4l, row1l); \ row4h = _mm_xor_si128(row4h, row1h); \ \ row4l = _mm_roti_epi64(row4l, -16); \ row4h = _mm_roti_epi64(row4h, -16); \ \ row3l = _mm_add_epi64(row3l, row4l); \ row3h = _mm_add_epi64(row3h, row4h); \ \ row2l = _mm_xor_si128(row2l, row3l); \ row2h = _mm_xor_si128(row2h, row3h); \ \ row2l = _mm_roti_epi64(row2l, -63); \ row2h = _mm_roti_epi64(row2h, -63); \ #if defined(HAVE_SSSE3) #define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ t0 = _mm_alignr_epi8(row2h, row2l, 8); \ t1 = _mm_alignr_epi8(row2l, row2h, 8); \ row2l = t0; \ row2h = t1; \ \ t0 = row3l; \ row3l = row3h; \ row3h = t0; \ \ t0 = _mm_alignr_epi8(row4h, row4l, 8); \ t1 = _mm_alignr_epi8(row4l, row4h, 8); \ row4l = t1; \ row4h = t0; #define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ t0 = _mm_alignr_epi8(row2l, row2h, 8); \ t1 = _mm_alignr_epi8(row2h, row2l, 8); \ row2l = t0; \ row2h = t1; \ \ t0 = row3l; \ row3l = row3h; \ row3h = t0; \ \ t0 = _mm_alignr_epi8(row4l, row4h, 8); \ t1 = _mm_alignr_epi8(row4h, row4l, 8); \ row4l = t1; \ row4h = t0; #else #define DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ t0 = row4l;\ t1 = row2l;\ row4l = row3l;\ row3l = row3h;\ row3h = row4l;\ row4l = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t0, t0)); \ row4h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row4h, row4h)); \ row2l = _mm_unpackhi_epi64(row2l, _mm_unpacklo_epi64(row2h, row2h)); \ row2h = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(t1, t1)) #define UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h) \ t0 = row3l;\ row3l = row3h;\ row3h = t0;\ t0 = row2l;\ t1 = row4l;\ row2l = _mm_unpackhi_epi64(row2h, _mm_unpacklo_epi64(row2l, row2l)); \ row2h = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(row2h, row2h)); \ row4l = _mm_unpackhi_epi64(row4l, _mm_unpacklo_epi64(row4h, row4h)); \ row4h = _mm_unpackhi_epi64(row4h, _mm_unpacklo_epi64(t1, t1)) #endif #if defined(HAVE_SSE41) #include "blake2b-load-sse41.h" #else #include "blake2b-load-sse2.h" #endif #define ROUND(r) \ LOAD_MSG_ ##r ##_1(b0, b1); \ G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ LOAD_MSG_ ##r ##_2(b0, b1); \ G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ DIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); \ LOAD_MSG_ ##r ##_3(b0, b1); \ G1(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ LOAD_MSG_ ##r ##_4(b0, b1); \ G2(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h,b0,b1); \ UNDIAGONALIZE(row1l,row2l,row3l,row4l,row1h,row2h,row3h,row4h); #endif cryptonite-0.23/cbits/blake2/sse/blake2s-load-sse2.h0000644000000000000000000000601713054050744020353 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2S_LOAD_SSE2_H #define BLAKE2S_LOAD_SSE2_H #define LOAD_MSG_0_1(buf) buf = _mm_set_epi32(m6,m4,m2,m0) #define LOAD_MSG_0_2(buf) buf = _mm_set_epi32(m7,m5,m3,m1) #define LOAD_MSG_0_3(buf) buf = _mm_set_epi32(m14,m12,m10,m8) #define LOAD_MSG_0_4(buf) buf = _mm_set_epi32(m15,m13,m11,m9) #define LOAD_MSG_1_1(buf) buf = _mm_set_epi32(m13,m9,m4,m14) #define LOAD_MSG_1_2(buf) buf = _mm_set_epi32(m6,m15,m8,m10) #define LOAD_MSG_1_3(buf) buf = _mm_set_epi32(m5,m11,m0,m1) #define LOAD_MSG_1_4(buf) buf = _mm_set_epi32(m3,m7,m2,m12) #define LOAD_MSG_2_1(buf) buf = _mm_set_epi32(m15,m5,m12,m11) #define LOAD_MSG_2_2(buf) buf = _mm_set_epi32(m13,m2,m0,m8) #define LOAD_MSG_2_3(buf) buf = _mm_set_epi32(m9,m7,m3,m10) #define LOAD_MSG_2_4(buf) buf = _mm_set_epi32(m4,m1,m6,m14) #define LOAD_MSG_3_1(buf) buf = _mm_set_epi32(m11,m13,m3,m7) #define LOAD_MSG_3_2(buf) buf = _mm_set_epi32(m14,m12,m1,m9) #define LOAD_MSG_3_3(buf) buf = _mm_set_epi32(m15,m4,m5,m2) #define LOAD_MSG_3_4(buf) buf = _mm_set_epi32(m8,m0,m10,m6) #define LOAD_MSG_4_1(buf) buf = _mm_set_epi32(m10,m2,m5,m9) #define LOAD_MSG_4_2(buf) buf = _mm_set_epi32(m15,m4,m7,m0) #define LOAD_MSG_4_3(buf) buf = _mm_set_epi32(m3,m6,m11,m14) #define LOAD_MSG_4_4(buf) buf = _mm_set_epi32(m13,m8,m12,m1) #define LOAD_MSG_5_1(buf) buf = _mm_set_epi32(m8,m0,m6,m2) #define LOAD_MSG_5_2(buf) buf = _mm_set_epi32(m3,m11,m10,m12) #define LOAD_MSG_5_3(buf) buf = _mm_set_epi32(m1,m15,m7,m4) #define LOAD_MSG_5_4(buf) buf = _mm_set_epi32(m9,m14,m5,m13) #define LOAD_MSG_6_1(buf) buf = _mm_set_epi32(m4,m14,m1,m12) #define LOAD_MSG_6_2(buf) buf = _mm_set_epi32(m10,m13,m15,m5) #define LOAD_MSG_6_3(buf) buf = _mm_set_epi32(m8,m9,m6,m0) #define LOAD_MSG_6_4(buf) buf = _mm_set_epi32(m11,m2,m3,m7) #define LOAD_MSG_7_1(buf) buf = _mm_set_epi32(m3,m12,m7,m13) #define LOAD_MSG_7_2(buf) buf = _mm_set_epi32(m9,m1,m14,m11) #define LOAD_MSG_7_3(buf) buf = _mm_set_epi32(m2,m8,m15,m5) #define LOAD_MSG_7_4(buf) buf = _mm_set_epi32(m10,m6,m4,m0) #define LOAD_MSG_8_1(buf) buf = _mm_set_epi32(m0,m11,m14,m6) #define LOAD_MSG_8_2(buf) buf = _mm_set_epi32(m8,m3,m9,m15) #define LOAD_MSG_8_3(buf) buf = _mm_set_epi32(m10,m1,m13,m12) #define LOAD_MSG_8_4(buf) buf = _mm_set_epi32(m5,m4,m7,m2) #define LOAD_MSG_9_1(buf) buf = _mm_set_epi32(m1,m7,m8,m10) #define LOAD_MSG_9_2(buf) buf = _mm_set_epi32(m5,m6,m4,m2) #define LOAD_MSG_9_3(buf) buf = _mm_set_epi32(m13,m3,m9,m15) #define LOAD_MSG_9_4(buf) buf = _mm_set_epi32(m0,m12,m14,m11) #endif cryptonite-0.23/cbits/blake2/sse/blake2s-load-sse41.h0000644000000000000000000001546113054050744020441 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2S_LOAD_SSE41_H #define BLAKE2S_LOAD_SSE41_H #define LOAD_MSG_0_1(buf) \ buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(2,0,2,0))); #define LOAD_MSG_0_2(buf) \ buf = TOI(_mm_shuffle_ps(TOF(m0), TOF(m1), _MM_SHUFFLE(3,1,3,1))); #define LOAD_MSG_0_3(buf) \ buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(2,0,2,0))); #define LOAD_MSG_0_4(buf) \ buf = TOI(_mm_shuffle_ps(TOF(m2), TOF(m3), _MM_SHUFFLE(3,1,3,1))); #define LOAD_MSG_1_1(buf) \ t0 = _mm_blend_epi16(m1, m2, 0x0C); \ t1 = _mm_slli_si128(m3, 4); \ t2 = _mm_blend_epi16(t0, t1, 0xF0); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,0,3)); #define LOAD_MSG_1_2(buf) \ t0 = _mm_shuffle_epi32(m2,_MM_SHUFFLE(0,0,2,0)); \ t1 = _mm_blend_epi16(m1,m3,0xC0); \ t2 = _mm_blend_epi16(t0, t1, 0xF0); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); #define LOAD_MSG_1_3(buf) \ t0 = _mm_slli_si128(m1, 4); \ t1 = _mm_blend_epi16(m2, t0, 0x30); \ t2 = _mm_blend_epi16(m0, t1, 0xF0); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); #define LOAD_MSG_1_4(buf) \ t0 = _mm_unpackhi_epi32(m0,m1); \ t1 = _mm_slli_si128(m3, 4); \ t2 = _mm_blend_epi16(t0, t1, 0x0C); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,3,0,1)); #define LOAD_MSG_2_1(buf) \ t0 = _mm_unpackhi_epi32(m2,m3); \ t1 = _mm_blend_epi16(m3,m1,0x0C); \ t2 = _mm_blend_epi16(t0, t1, 0x0F); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); #define LOAD_MSG_2_2(buf) \ t0 = _mm_unpacklo_epi32(m2,m0); \ t1 = _mm_blend_epi16(t0, m0, 0xF0); \ t2 = _mm_slli_si128(m3, 8); \ buf = _mm_blend_epi16(t1, t2, 0xC0); #define LOAD_MSG_2_3(buf) \ t0 = _mm_blend_epi16(m0, m2, 0x3C); \ t1 = _mm_srli_si128(m1, 12); \ t2 = _mm_blend_epi16(t0,t1,0x03); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,3,2)); #define LOAD_MSG_2_4(buf) \ t0 = _mm_slli_si128(m3, 4); \ t1 = _mm_blend_epi16(m0, m1, 0x33); \ t2 = _mm_blend_epi16(t1, t0, 0xC0); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(0,1,2,3)); #define LOAD_MSG_3_1(buf) \ t0 = _mm_unpackhi_epi32(m0,m1); \ t1 = _mm_unpackhi_epi32(t0, m2); \ t2 = _mm_blend_epi16(t1, m3, 0x0C); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(3,1,0,2)); #define LOAD_MSG_3_2(buf) \ t0 = _mm_slli_si128(m2, 8); \ t1 = _mm_blend_epi16(m3,m0,0x0C); \ t2 = _mm_blend_epi16(t1, t0, 0xC0); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); #define LOAD_MSG_3_3(buf) \ t0 = _mm_blend_epi16(m0,m1,0x0F); \ t1 = _mm_blend_epi16(t0, m3, 0xC0); \ buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); #define LOAD_MSG_3_4(buf) \ t0 = _mm_unpacklo_epi32(m0,m2); \ t1 = _mm_unpackhi_epi32(m1,m2); \ buf = _mm_unpacklo_epi64(t1,t0); #define LOAD_MSG_4_1(buf) \ t0 = _mm_unpacklo_epi64(m1,m2); \ t1 = _mm_unpackhi_epi64(m0,m2); \ t2 = _mm_blend_epi16(t0,t1,0x33); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,0,1,3)); #define LOAD_MSG_4_2(buf) \ t0 = _mm_unpackhi_epi64(m1,m3); \ t1 = _mm_unpacklo_epi64(m0,m1); \ buf = _mm_blend_epi16(t0,t1,0x33); #define LOAD_MSG_4_3(buf) \ t0 = _mm_unpackhi_epi64(m3,m1); \ t1 = _mm_unpackhi_epi64(m2,m0); \ buf = _mm_blend_epi16(t1,t0,0x33); #define LOAD_MSG_4_4(buf) \ t0 = _mm_blend_epi16(m0,m2,0x03); \ t1 = _mm_slli_si128(t0, 8); \ t2 = _mm_blend_epi16(t1,m3,0x0F); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,0,3)); #define LOAD_MSG_5_1(buf) \ t0 = _mm_unpackhi_epi32(m0,m1); \ t1 = _mm_unpacklo_epi32(m0,m2); \ buf = _mm_unpacklo_epi64(t0,t1); #define LOAD_MSG_5_2(buf) \ t0 = _mm_srli_si128(m2, 4); \ t1 = _mm_blend_epi16(m0,m3,0x03); \ buf = _mm_blend_epi16(t1,t0,0x3C); #define LOAD_MSG_5_3(buf) \ t0 = _mm_blend_epi16(m1,m0,0x0C); \ t1 = _mm_srli_si128(m3, 4); \ t2 = _mm_blend_epi16(t0,t1,0x30); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,2,3,0)); #define LOAD_MSG_5_4(buf) \ t0 = _mm_unpacklo_epi64(m1,m2); \ t1= _mm_shuffle_epi32(m3, _MM_SHUFFLE(0,2,0,1)); \ buf = _mm_blend_epi16(t0,t1,0x33); #define LOAD_MSG_6_1(buf) \ t0 = _mm_slli_si128(m1, 12); \ t1 = _mm_blend_epi16(m0,m3,0x33); \ buf = _mm_blend_epi16(t1,t0,0xC0); #define LOAD_MSG_6_2(buf) \ t0 = _mm_blend_epi16(m3,m2,0x30); \ t1 = _mm_srli_si128(m1, 4); \ t2 = _mm_blend_epi16(t0,t1,0x03); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(2,1,3,0)); #define LOAD_MSG_6_3(buf) \ t0 = _mm_unpacklo_epi64(m0,m2); \ t1 = _mm_srli_si128(m1, 4); \ buf = _mm_shuffle_epi32(_mm_blend_epi16(t0,t1,0x0C), _MM_SHUFFLE(2,3,1,0)); #define LOAD_MSG_6_4(buf) \ t0 = _mm_unpackhi_epi32(m1,m2); \ t1 = _mm_unpackhi_epi64(m0,t0); \ buf = _mm_shuffle_epi32(t1, _MM_SHUFFLE(3,0,1,2)); #define LOAD_MSG_7_1(buf) \ t0 = _mm_unpackhi_epi32(m0,m1); \ t1 = _mm_blend_epi16(t0,m3,0x0F); \ buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(2,0,3,1)); #define LOAD_MSG_7_2(buf) \ t0 = _mm_blend_epi16(m2,m3,0x30); \ t1 = _mm_srli_si128(m0,4); \ t2 = _mm_blend_epi16(t0,t1,0x03); \ buf = _mm_shuffle_epi32(t2, _MM_SHUFFLE(1,0,2,3)); #define LOAD_MSG_7_3(buf) \ t0 = _mm_unpackhi_epi64(m0,m3); \ t1 = _mm_unpacklo_epi64(m1,m2); \ t2 = _mm_blend_epi16(t0,t1,0x3C); \ buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,2,3,1)); #define LOAD_MSG_7_4(buf) \ t0 = _mm_unpacklo_epi32(m0,m1); \ t1 = _mm_unpackhi_epi32(m1,m2); \ buf = _mm_unpacklo_epi64(t0,t1); #define LOAD_MSG_8_1(buf) \ t0 = _mm_unpackhi_epi32(m1,m3); \ t1 = _mm_unpacklo_epi64(t0,m0); \ t2 = _mm_blend_epi16(t1,m2,0xC0); \ buf = _mm_shufflehi_epi16(t2,_MM_SHUFFLE(1,0,3,2)); #define LOAD_MSG_8_2(buf) \ t0 = _mm_unpackhi_epi32(m0,m3); \ t1 = _mm_blend_epi16(m2,t0,0xF0); \ buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(0,2,1,3)); #define LOAD_MSG_8_3(buf) \ t0 = _mm_blend_epi16(m2,m0,0x0C); \ t1 = _mm_slli_si128(t0,4); \ buf = _mm_blend_epi16(t1,m3,0x0F); #define LOAD_MSG_8_4(buf) \ t0 = _mm_blend_epi16(m1,m0,0x30); \ buf = _mm_shuffle_epi32(t0,_MM_SHUFFLE(1,0,3,2)); #define LOAD_MSG_9_1(buf) \ t0 = _mm_blend_epi16(m0,m2,0x03); \ t1 = _mm_blend_epi16(m1,m2,0x30); \ t2 = _mm_blend_epi16(t1,t0,0x0F); \ buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(1,3,0,2)); #define LOAD_MSG_9_2(buf) \ t0 = _mm_slli_si128(m0,4); \ t1 = _mm_blend_epi16(m1,t0,0xC0); \ buf = _mm_shuffle_epi32(t1,_MM_SHUFFLE(1,2,0,3)); #define LOAD_MSG_9_3(buf) \ t0 = _mm_unpackhi_epi32(m0,m3); \ t1 = _mm_unpacklo_epi32(m2,m3); \ t2 = _mm_unpackhi_epi64(t0,t1); \ buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(3,0,2,1)); #define LOAD_MSG_9_4(buf) \ t0 = _mm_blend_epi16(m3,m2,0xC0); \ t1 = _mm_unpacklo_epi32(m0,m3); \ t2 = _mm_blend_epi16(t0,t1,0x0F); \ buf = _mm_shuffle_epi32(t2,_MM_SHUFFLE(0,1,2,3)); #endif cryptonite-0.23/cbits/blake2/sse/blake2s-load-xop.h0000644000000000000000000002004713054050744020304 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2S_LOAD_XOP_H #define BLAKE2S_LOAD_XOP_H #define TOB(x) ((x)*4*0x01010101 + 0x03020100) /* ..or not TOB */ #if 0 /* Basic VPPERM emulation, for testing purposes */ static __m128i _mm_perm_epi8(const __m128i src1, const __m128i src2, const __m128i sel) { const __m128i sixteen = _mm_set1_epi8(16); const __m128i t0 = _mm_shuffle_epi8(src1, sel); const __m128i s1 = _mm_shuffle_epi8(src2, _mm_sub_epi8(sel, sixteen)); const __m128i mask = _mm_or_si128(_mm_cmpeq_epi8(sel, sixteen), _mm_cmpgt_epi8(sel, sixteen)); /* (>=16) = 0xff : 00 */ return _mm_blendv_epi8(t0, s1, mask); } #endif #define LOAD_MSG_0_1(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); #define LOAD_MSG_0_2(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); #define LOAD_MSG_0_3(buf) \ buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(2),TOB(0)) ); #define LOAD_MSG_0_4(buf) \ buf = _mm_perm_epi8(m2, m3, _mm_set_epi32(TOB(7),TOB(5),TOB(3),TOB(1)) ); #define LOAD_MSG_1_1(buf) \ t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(5),TOB(0),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); #define LOAD_MSG_1_2(buf) \ t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(2),TOB(0),TOB(4),TOB(6)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); #define LOAD_MSG_1_3(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(0),TOB(0),TOB(1)) ); \ buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); #define LOAD_MSG_1_4(buf) \ t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(7),TOB(2),TOB(0)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); #define LOAD_MSG_2_1(buf) \ t0 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(0),TOB(1),TOB(0),TOB(7)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(4),TOB(0)) ); #define LOAD_MSG_2_2(buf) \ t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(2),TOB(0),TOB(4)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(0)) ); #define LOAD_MSG_2_3(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(7),TOB(3),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(6)) ); #define LOAD_MSG_2_4(buf) \ t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(1),TOB(6),TOB(0)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); #define LOAD_MSG_3_1(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(3),TOB(7)) ); \ t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(1),TOB(0)) ); #define LOAD_MSG_3_2(buf) \ t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(1),TOB(5)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(6),TOB(4),TOB(1),TOB(0)) ); #define LOAD_MSG_3_3(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(5),TOB(2)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); #define LOAD_MSG_3_4(buf) \ t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(6),TOB(0)) ); #define LOAD_MSG_4_1(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(5),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(5)) ); #define LOAD_MSG_4_2(buf) \ t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(4),TOB(7),TOB(0)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); #define LOAD_MSG_4_3(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(6),TOB(0),TOB(0)) ); \ t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(6)) ); #define LOAD_MSG_4_4(buf) \ t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(4),TOB(0),TOB(1)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(4),TOB(0)) ); #define LOAD_MSG_5_1(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(2)) ); \ buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(2),TOB(1),TOB(0)) ); #define LOAD_MSG_5_2(buf) \ t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(6),TOB(0)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(4)) ); #define LOAD_MSG_5_3(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(0),TOB(7),TOB(4)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); #define LOAD_MSG_5_4(buf) \ t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(5),TOB(0),TOB(1),TOB(0)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(5)) ); #define LOAD_MSG_6_1(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(4),TOB(0),TOB(1),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(6),TOB(1),TOB(4)) ); #define LOAD_MSG_6_2(buf) \ t1 = _mm_perm_epi8(m1, m2, _mm_set_epi32(TOB(6),TOB(0),TOB(0),TOB(1)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(5),TOB(7),TOB(0)) ); #define LOAD_MSG_6_3(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(6),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(4),TOB(5),TOB(1),TOB(0)) ); #define LOAD_MSG_6_4(buf) \ t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(2),TOB(3),TOB(7)) ); \ buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(7),TOB(2),TOB(1),TOB(0)) ); #define LOAD_MSG_7_1(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(3),TOB(0),TOB(7),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(5)) ); #define LOAD_MSG_7_2(buf) \ t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(5),TOB(1),TOB(0),TOB(7)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); #define LOAD_MSG_7_3(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(2),TOB(0),TOB(0),TOB(5)) ); \ t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(4),TOB(1),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(7),TOB(0)) ); #define LOAD_MSG_7_4(buf) \ t1 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(6),TOB(4),TOB(0)) ); \ buf = _mm_perm_epi8(t1, m2, _mm_set_epi32(TOB(6),TOB(2),TOB(1),TOB(0)) ); #define LOAD_MSG_8_1(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(6)) ); \ t0 = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(7),TOB(1),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(6),TOB(0)) ); #define LOAD_MSG_8_2(buf) \ t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(4),TOB(3),TOB(5),TOB(0)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(1),TOB(7)) ); #define LOAD_MSG_8_3(buf) \ t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(6),TOB(1),TOB(0),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(3),TOB(2),TOB(5),TOB(4)) ); \ #define LOAD_MSG_8_4(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(4),TOB(7),TOB(2)) ); #define LOAD_MSG_9_1(buf) \ t0 = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(1),TOB(7),TOB(0),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m2, _mm_set_epi32(TOB(3),TOB(2),TOB(4),TOB(6)) ); #define LOAD_MSG_9_2(buf) \ buf = _mm_perm_epi8(m0, m1, _mm_set_epi32(TOB(5),TOB(6),TOB(4),TOB(2)) ); #define LOAD_MSG_9_3(buf) \ t0 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(3),TOB(5),TOB(0)) ); \ buf = _mm_perm_epi8(t0, m3, _mm_set_epi32(TOB(5),TOB(2),TOB(1),TOB(7)) ); #define LOAD_MSG_9_4(buf) \ t1 = _mm_perm_epi8(m0, m2, _mm_set_epi32(TOB(0),TOB(0),TOB(0),TOB(7)) ); \ buf = _mm_perm_epi8(t1, m3, _mm_set_epi32(TOB(3),TOB(4),TOB(6),TOB(0)) ); #endif cryptonite-0.23/cbits/blake2/sse/blake2s-round.h0000644000000000000000000000552213054050744017711 0ustar0000000000000000/* BLAKE2 reference source code package - optimized C implementations Copyright 2012, Samuel Neves . You may use this under the terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at your option. The terms of these licenses can be found at: - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 - OpenSSL license : https://www.openssl.org/source/license.html - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 More information about the BLAKE2 hash function can be found at https://blake2.net. */ #ifndef BLAKE2S_ROUND_H #define BLAKE2S_ROUND_H #define LOADU(p) _mm_loadu_si128( (const __m128i *)(p) ) #define STOREU(p,r) _mm_storeu_si128((__m128i *)(p), r) #define TOF(reg) _mm_castsi128_ps((reg)) #define TOI(reg) _mm_castps_si128((reg)) #define LIKELY(x) __builtin_expect((x),1) /* Microarchitecture-specific macros */ #ifndef HAVE_XOP #ifdef HAVE_SSSE3 #define _mm_roti_epi32(r, c) ( \ (8==-(c)) ? _mm_shuffle_epi8(r,r8) \ : (16==-(c)) ? _mm_shuffle_epi8(r,r16) \ : _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) ) #else #define _mm_roti_epi32(r, c) _mm_xor_si128(_mm_srli_epi32( (r), -(c) ),_mm_slli_epi32( (r), 32-(-(c)) )) #endif #else /* ... */ #endif #define G1(row1,row2,row3,row4,buf) \ row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ row4 = _mm_xor_si128( row4, row1 ); \ row4 = _mm_roti_epi32(row4, -16); \ row3 = _mm_add_epi32( row3, row4 ); \ row2 = _mm_xor_si128( row2, row3 ); \ row2 = _mm_roti_epi32(row2, -12); #define G2(row1,row2,row3,row4,buf) \ row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ row4 = _mm_xor_si128( row4, row1 ); \ row4 = _mm_roti_epi32(row4, -8); \ row3 = _mm_add_epi32( row3, row4 ); \ row2 = _mm_xor_si128( row2, row3 ); \ row2 = _mm_roti_epi32(row2, -7); #define DIAGONALIZE(row1,row2,row3,row4) \ row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(2,1,0,3) ); \ row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(0,3,2,1) ); #define UNDIAGONALIZE(row1,row2,row3,row4) \ row4 = _mm_shuffle_epi32( row4, _MM_SHUFFLE(0,3,2,1) ); \ row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) ); #if defined(HAVE_XOP) #include "blake2s-load-xop.h" #elif defined(HAVE_SSE41) #include "blake2s-load-sse41.h" #else #include "blake2s-load-sse2.h" #endif #define ROUND(r) \ LOAD_MSG_ ##r ##_1(buf1); \ G1(row1,row2,row3,row4,buf1); \ LOAD_MSG_ ##r ##_2(buf2); \ G2(row1,row2,row3,row4,buf2); \ DIAGONALIZE(row1,row2,row3,row4); \ LOAD_MSG_ ##r ##_3(buf3); \ G1(row1,row2,row3,row4,buf3); \ LOAD_MSG_ ##r ##_4(buf4); \ G2(row1,row2,row3,row4,buf4); \ UNDIAGONALIZE(row1,row2,row3,row4); \ #endif cryptonite-0.23/cbits/argon2/argon2.h0000644000000000000000000002115713054050744015671 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #ifndef ARGON2_H #define ARGON2_H #include #include #include #if defined(__cplusplus) extern "C" { #endif /* Symbols visibility control */ #ifdef A2_VISCTL #define ARGON2_PUBLIC __attribute__((visibility("default"))) #elif _MSC_VER #define ARGON2_PUBLIC __declspec(dllexport) #else #define ARGON2_PUBLIC #endif /* * Argon2 input parameter restrictions */ /* Minimum and maximum number of lanes (degree of parallelism) */ #define ARGON2_MIN_LANES UINT32_C(1) #define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) /* Minimum and maximum number of threads */ #define ARGON2_MIN_THREADS UINT32_C(1) #define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) /* Number of synchronization points between lanes per pass */ #define ARGON2_SYNC_POINTS UINT32_C(4) /* Minimum and maximum digest size in bytes */ #define ARGON2_MIN_OUTLEN UINT32_C(4) #define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) /* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ #define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ #define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) /* Max memory size is addressing-space/2, topping at 2^32 blocks (4 TB) */ #define ARGON2_MAX_MEMORY_BITS \ ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) #define ARGON2_MAX_MEMORY \ ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) /* Minimum and maximum number of passes */ #define ARGON2_MIN_TIME UINT32_C(1) #define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) /* Minimum and maximum password length in bytes */ #define ARGON2_MIN_PWD_LENGTH UINT32_C(0) #define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) /* Minimum and maximum associated data length in bytes */ #define ARGON2_MIN_AD_LENGTH UINT32_C(0) #define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) /* Minimum and maximum salt length in bytes */ #define ARGON2_MIN_SALT_LENGTH UINT32_C(8) #define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) /* Minimum and maximum key length in bytes */ #define ARGON2_MIN_SECRET UINT32_C(0) #define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) /* Flags to determine which fields are securely wiped (default = no wipe). */ #define ARGON2_DEFAULT_FLAGS UINT32_C(0) #define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) #define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) /* Global flag to determine if we are wiping internal memory buffers. This flag * is defined in core.c and deafults to 1 (wipe internal memory). */ //extern int FLAG_clear_internal_memory; /* Error codes */ typedef enum Argon2_ErrorCodes { ARGON2_OK = 0, ARGON2_OUTPUT_PTR_NULL = -1, ARGON2_OUTPUT_TOO_SHORT = -2, ARGON2_OUTPUT_TOO_LONG = -3, ARGON2_PWD_TOO_SHORT = -4, ARGON2_PWD_TOO_LONG = -5, ARGON2_SALT_TOO_SHORT = -6, ARGON2_SALT_TOO_LONG = -7, ARGON2_AD_TOO_SHORT = -8, ARGON2_AD_TOO_LONG = -9, ARGON2_SECRET_TOO_SHORT = -10, ARGON2_SECRET_TOO_LONG = -11, ARGON2_TIME_TOO_SMALL = -12, ARGON2_TIME_TOO_LARGE = -13, ARGON2_MEMORY_TOO_LITTLE = -14, ARGON2_MEMORY_TOO_MUCH = -15, ARGON2_LANES_TOO_FEW = -16, ARGON2_LANES_TOO_MANY = -17, ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ ARGON2_MEMORY_ALLOCATION_ERROR = -22, ARGON2_FREE_MEMORY_CBK_NULL = -23, ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, ARGON2_INCORRECT_PARAMETER = -25, ARGON2_INCORRECT_TYPE = -26, ARGON2_OUT_PTR_MISMATCH = -27, ARGON2_THREADS_TOO_FEW = -28, ARGON2_THREADS_TOO_MANY = -29, ARGON2_MISSING_ARGS = -30, ARGON2_ENCODING_FAIL = -31, ARGON2_DECODING_FAIL = -32, ARGON2_THREAD_FAIL = -33, ARGON2_DECODING_LENGTH_FAIL = -34, ARGON2_VERIFY_MISMATCH = -35 } argon2_error_codes; /* Memory allocator types --- for external allocation */ typedef int (*allocate_fptr)(uint8_t **memory, size_t bytes_to_allocate); typedef void (*deallocate_fptr)(uint8_t *memory, size_t bytes_to_allocate); /* Argon2 external data structures */ /* ***** * Context: structure to hold Argon2 inputs: * output array and its length, * password and its length, * salt and its length, * secret and its length, * associated data and its length, * number of passes, amount of used memory (in KBytes, can be rounded up a bit) * number of parallel threads that will be run. * All the parameters above affect the output hash value. * Additionally, two function pointers can be provided to allocate and * deallocate the memory (if NULL, memory will be allocated internally). * Also, three flags indicate whether to erase password, secret as soon as they * are pre-hashed (and thus not needed anymore), and the entire memory ***** * Simplest situation: you have output array out[8], password is stored in * pwd[32], salt is stored in salt[16], you do not have keys nor associated * data. You need to spend 1 GB of RAM and you run 5 passes of Argon2d with * 4 parallel lanes. * You want to erase the password, but you're OK with last pass not being * erased. You want to use the default memory allocator. * Then you initialize: Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false) */ typedef struct Argon2_Context { uint8_t *out; /* output array */ uint32_t outlen; /* digest length */ uint8_t *pwd; /* password array */ uint32_t pwdlen; /* password length */ uint8_t *salt; /* salt array */ uint32_t saltlen; /* salt length */ uint8_t *secret; /* key array */ uint32_t secretlen; /* key length */ uint8_t *ad; /* associated data array */ uint32_t adlen; /* associated data length */ uint32_t t_cost; /* number of passes */ uint32_t m_cost; /* amount of memory requested (KB) */ uint32_t lanes; /* number of lanes */ uint32_t threads; /* maximum number of threads */ uint32_t version; /* version number */ allocate_fptr allocate_cbk; /* pointer to memory allocator */ deallocate_fptr free_cbk; /* pointer to memory deallocator */ uint32_t flags; /* array of bool options */ } argon2_context; /* Argon2 primitive type */ typedef enum Argon2_type { Argon2_d = 0, Argon2_i = 1, Argon2_id = 2 } argon2_type; /* Version of the algorithm */ typedef enum Argon2_version { ARGON2_VERSION_10 = 0x10, ARGON2_VERSION_13 = 0x13, ARGON2_VERSION_NUMBER = ARGON2_VERSION_13 } argon2_version; /* * Function that performs memory-hard hashing with certain degree of parallelism * @param context Pointer to the Argon2 internal structure * @return Error code if smth is wrong, ARGON2_OK otherwise */ ARGON2_PUBLIC int cryptonite_argon2_ctx(argon2_context *context, argon2_type type); /** * Hashes a password with Argon2i, producing a raw hash by allocating memory at * @hash * @param t_cost Number of iterations * @param m_cost Sets memory usage to m_cost kibibytes * @param parallelism Number of threads and compute lanes * @param pwd Pointer to password * @param pwdlen Password size in bytes * @param salt Pointer to salt * @param saltlen Salt size in bytes * @param hash Buffer where to write the raw hash - updated by the function * @param hashlen Desired length of the hash in bytes * @pre Different parallelism levels will give different results * @pre Returns ARGON2_OK if successful */ /* generic function underlying the above ones */ ARGON2_PUBLIC int cryptonite_argon2_hash(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, const size_t saltlen, void *hash, const size_t hashlen, argon2_type type, const uint32_t version); #if defined(__cplusplus) } #endif #endif cryptonite-0.23/cbits/argon2/blamka-round-opt.h0000644000000000000000000002563713054050744017664 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #ifndef BLAKE_ROUND_MKA_OPT_H #define BLAKE_ROUND_MKA_OPT_H #include "blake2-impl.h" #include #if defined(__SSSE3__) #include /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */ #endif #if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__)) #include #endif #if !defined(__XOP__) #if defined(__SSSE3__) #define r16 \ (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) #define r24 \ (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) #define _mm_roti_epi64(x, c) \ (-(c) == 32) \ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ : (-(c) == 24) \ ? _mm_shuffle_epi8((x), r24) \ : (-(c) == 16) \ ? _mm_shuffle_epi8((x), r16) \ : (-(c) == 63) \ ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ _mm_add_epi64((x), (x))) \ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ _mm_slli_epi64((x), 64 - (-(c)))) #else /* defined(__SSE2__) */ #define _mm_roti_epi64(r, c) \ _mm_xor_si128(_mm_srli_epi64((r), -(c)), _mm_slli_epi64((r), 64 - (-(c)))) #endif #else #endif static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) { const __m128i z = _mm_mul_epu32(x, y); return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z)); } #define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ do { \ A0 = fBlaMka(A0, B0); \ A1 = fBlaMka(A1, B1); \ \ D0 = _mm_xor_si128(D0, A0); \ D1 = _mm_xor_si128(D1, A1); \ \ D0 = _mm_roti_epi64(D0, -32); \ D1 = _mm_roti_epi64(D1, -32); \ \ C0 = fBlaMka(C0, D0); \ C1 = fBlaMka(C1, D1); \ \ B0 = _mm_xor_si128(B0, C0); \ B1 = _mm_xor_si128(B1, C1); \ \ B0 = _mm_roti_epi64(B0, -24); \ B1 = _mm_roti_epi64(B1, -24); \ } while ((void)0, 0) #define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ do { \ A0 = fBlaMka(A0, B0); \ A1 = fBlaMka(A1, B1); \ \ D0 = _mm_xor_si128(D0, A0); \ D1 = _mm_xor_si128(D1, A1); \ \ D0 = _mm_roti_epi64(D0, -16); \ D1 = _mm_roti_epi64(D1, -16); \ \ C0 = fBlaMka(C0, D0); \ C1 = fBlaMka(C1, D1); \ \ B0 = _mm_xor_si128(B0, C0); \ B1 = _mm_xor_si128(B1, C1); \ \ B0 = _mm_roti_epi64(B0, -63); \ B1 = _mm_roti_epi64(B1, -63); \ } while ((void)0, 0) #if defined(__SSSE3__) #define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ do { \ __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \ __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \ B0 = t0; \ B1 = t1; \ \ t0 = C0; \ C0 = C1; \ C1 = t0; \ \ t0 = _mm_alignr_epi8(D1, D0, 8); \ t1 = _mm_alignr_epi8(D0, D1, 8); \ D0 = t1; \ D1 = t0; \ } while ((void)0, 0) #define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ do { \ __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \ __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \ B0 = t0; \ B1 = t1; \ \ t0 = C0; \ C0 = C1; \ C1 = t0; \ \ t0 = _mm_alignr_epi8(D0, D1, 8); \ t1 = _mm_alignr_epi8(D1, D0, 8); \ D0 = t1; \ D1 = t0; \ } while ((void)0, 0) #else /* SSE2 */ #define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ do { \ __m128i t0 = D0; \ __m128i t1 = B0; \ D0 = C0; \ C0 = C1; \ C1 = D0; \ D0 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t0, t0)); \ D1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(D1, D1)); \ B0 = _mm_unpackhi_epi64(B0, _mm_unpacklo_epi64(B1, B1)); \ B1 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(t1, t1)); \ } while ((void)0, 0) #define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ do { \ __m128i t0, t1; \ t0 = C0; \ C0 = C1; \ C1 = t0; \ t0 = B0; \ t1 = D0; \ B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \ B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \ D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \ D1 = _mm_unpackhi_epi64(D1, _mm_unpacklo_epi64(t1, t1)); \ } while ((void)0, 0) #endif #define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \ do { \ G1(A0, B0, C0, D0, A1, B1, C1, D1); \ G2(A0, B0, C0, D0, A1, B1, C1, D1); \ \ DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ \ G1(A0, B0, C0, D0, A1, B1, C1, D1); \ G2(A0, B0, C0, D0, A1, B1, C1, D1); \ \ UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ } while ((void)0, 0) #endif cryptonite-0.23/cbits/argon2/blamka-round-ref.h0000644000000000000000000000525213054050744017625 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #ifndef BLAKE_ROUND_MKA_H #define BLAKE_ROUND_MKA_H #include "blake2.h" #include "blake2-impl.h" /*designed by the Lyra PHC team */ static BLAKE2_INLINE uint64_t fBlaMka(uint64_t x, uint64_t y) { const uint64_t m = UINT64_C(0xFFFFFFFF); const uint64_t xy = (x & m) * (y & m); return x + y + 2 * xy; } #define G(a, b, c, d) \ do { \ a = fBlaMka(a, b); \ d = rotr64(d ^ a, 32); \ c = fBlaMka(c, d); \ b = rotr64(b ^ c, 24); \ a = fBlaMka(a, b); \ d = rotr64(d ^ a, 16); \ c = fBlaMka(c, d); \ b = rotr64(b ^ c, 63); \ } while ((void)0, 0) #define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ v12, v13, v14, v15) \ do { \ G(v0, v4, v8, v12); \ G(v1, v5, v9, v13); \ G(v2, v6, v10, v14); \ G(v3, v7, v11, v15); \ G(v0, v5, v10, v15); \ G(v1, v6, v11, v12); \ G(v2, v7, v8, v13); \ G(v3, v4, v9, v14); \ } while ((void)0, 0) #endif cryptonite-0.23/cbits/argon2/core.h0000644000000000000000000002067013054050744015430 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #ifndef ARGON2_CORE_H #define ARGON2_CORE_H #include "argon2.h" #if defined(_MSC_VER) #define ALIGN(n) __declspec(align(16)) #elif defined(__GNUC__) || defined(__clang) #define ALIGN(x) __attribute__((__aligned__(x))) #else #define ALIGN(x) #endif #define CONST_CAST(x) (x)(uintptr_t) /**********************Argon2 internal constants*******************************/ enum argon2_core_constants { /* Memory block size in bytes */ ARGON2_BLOCK_SIZE = 1024, ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, /* Number of pseudo-random values generated by one call to Blake in Argon2i to generate reference block positions */ ARGON2_ADDRESSES_IN_BLOCK = 128, /* Pre-hashing digest length and its extension*/ ARGON2_PREHASH_DIGEST_LENGTH = 64, ARGON2_PREHASH_SEED_LENGTH = 72 }; /*************************Argon2 internal data types***********************/ /* * Structure for the (1KB) memory block implemented as 128 64-bit words. * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no * bounds checking). */ typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block; /*****************Functions that work with the block******************/ /* Initialize each byte of the block with @in */ static void init_block_value(block *b, uint8_t in); /* Copy block @src to block @dst */ static void copy_block(block *dst, const block *src); /* XOR @src onto @dst bytewise */ static void xor_block(block *dst, const block *src); /* * Argon2 instance: memory pointer, number of passes, amount of memory, type, * and derived values. * Used to evaluate the number and location of blocks to construct in each * thread */ typedef struct Argon2_instance_t { block *memory; /* Memory pointer */ uint32_t version; uint32_t passes; /* Number of passes */ uint32_t memory_blocks; /* Number of blocks in memory */ uint32_t segment_length; uint32_t lane_length; uint32_t lanes; uint32_t threads; argon2_type type; int print_internals; /* whether to print the memory blocks */ argon2_context *context_ptr; /* points back to original context */ } argon2_instance_t; /* * Argon2 position: where we construct the block right now. Used to distribute * work between threads. */ typedef struct Argon2_position_t { uint32_t pass; uint32_t lane; uint8_t slice; uint32_t index; } argon2_position_t; /*Struct that holds the inputs for thread handling FillSegment*/ typedef struct Argon2_thread_data { argon2_instance_t *instance_ptr; argon2_position_t pos; } argon2_thread_data; /*************************Argon2 core functions********************************/ /* Allocates memory to the given pointer, uses the appropriate allocator as * specified in the context. Total allocated memory is num*size. * @param context argon2_context which specifies the allocator * @param memory pointer to the pointer to the memory * @param size the size in bytes for each element to be allocated * @param num the number of elements to be allocated * @return ARGON2_OK if @memory is a valid pointer and memory is allocated */ static int allocate_memory(const argon2_context *context, uint8_t **memory, size_t num, size_t size); /* * Frees memory at the given pointer, uses the appropriate deallocator as * specified in the context. Also cleans the memory using clear_internal_memory. * @param context argon2_context which specifies the deallocator * @param memory pointer to buffer to be freed * @param size the size in bytes for each element to be deallocated * @param num the number of elements to be deallocated */ static void free_memory(const argon2_context *context, uint8_t *memory, size_t num, size_t size); /* Function that securely cleans the memory. This ignores any flags set * regarding clearing memory. Usually one just calls clear_internal_memory. * @param mem Pointer to the memory * @param s Memory size in bytes */ static void secure_wipe_memory(void *v, size_t n); /* Function that securely clears the memory if FLAG_clear_internal_memory is * set. If the flag isn't set, this function does nothing. * @param mem Pointer to the memory * @param s Memory size in bytes */ static void clear_internal_memory(void *v, size_t n); /* * Computes absolute position of reference block in the lane following a skewed * distribution and using a pseudo-random value as input * @param instance Pointer to the current instance * @param position Pointer to the current position * @param pseudo_rand 32-bit pseudo-random value used to determine the position * @param same_lane Indicates if the block will be taken from the current lane. * If so we can reference the current segment * @pre All pointers must be valid */ static uint32_t index_alpha(const argon2_instance_t *instance, const argon2_position_t *position, uint32_t pseudo_rand, int same_lane); /* * Function that validates all inputs against predefined restrictions and return * an error code * @param context Pointer to current Argon2 context * @return ARGON2_OK if everything is all right, otherwise one of error codes * (all defined in */ static int validate_inputs(const argon2_context *context); /* * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears * password and secret if needed * @param context Pointer to the Argon2 internal structure containing memory * pointer, and parameters for time and space requirements. * @param blockhash Buffer for pre-hashing digest * @param type Argon2 type * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes * allocated */ static void initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type); /* * Function creates first 2 blocks per lane * @param instance Pointer to the current instance * @param blockhash Pointer to the pre-hashing digest * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values */ static void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); /* * Function allocates memory, hashes the inputs with Blake, and creates first * two blocks. Returns the pointer to the main memory with 2 blocks per lane * initialized * @param context Pointer to the Argon2 internal structure containing memory * pointer, and parameters for time and space requirements. * @param instance Current Argon2 instance * @return Zero if successful, -1 if memory failed to allocate. @context->state * will be modified if successful. */ static int initialize(argon2_instance_t *instance, argon2_context *context); /* * XORing the last block of each lane, hashing it, making the tag. Deallocates * the memory. * @param context Pointer to current Argon2 context (use only the out parameters * from it) * @param instance Pointer to current instance of Argon2 * @pre instance->state must point to necessary amount of memory * @pre context->out must point to outlen bytes of memory * @pre if context->free_cbk is not NULL, it should point to a function that * deallocates memory */ static void finalize(const argon2_context *context, argon2_instance_t *instance); /* * Function that fills the segment using previous segments also from other * threads * @param context current context * @param instance Pointer to the current instance * @param position Current position * @pre all block pointers must be valid */ static void fill_segment(const argon2_instance_t *instance, argon2_position_t position); /* * Function that fills the entire memory t_cost times based on the first two * blocks in each lane * @param instance Pointer to the current instance * @return ARGON2_OK if successful, @context->state */ static int fill_memory_blocks(argon2_instance_t *instance); #endif cryptonite-0.23/cbits/argon2/opt.h0000644000000000000000000000245513054050744015303 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #ifndef ARGON2_OPT_H #define ARGON2_OPT_H #include "core.h" #include /* * Function fills a new memory block and optionally XORs the old block over the new one. * Memory must be initialized. * @param state Pointer to the just produced block. Content will be updated(!) * @param ref_block Pointer to the reference block * @param next_block Pointer to the block to be XORed over. May coincide with @ref_block * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) * @pre all block pointers must be valid */ static void fill_block(__m128i *s, const block *ref_block, block *next_block, int with_xor); #endif /* ARGON2_OPT_H */ cryptonite-0.23/cbits/argon2/ref.h0000644000000000000000000000237713054050744015260 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #ifndef ARGON2_REF_H #define ARGON2_REF_H #include "core.h" /* * Function fills a new memory block and optionally XORs the old block over the new one. * @next_block must be initialized. * @param prev_block Pointer to the previous block * @param ref_block Pointer to the reference block * @param next_block Pointer to the block to be constructed * @param with_xor Whether to XOR into the new block (1) or just overwrite (0) * @pre all block pointers must be valid */ static void fill_block(const block *prev_block, const block *ref_block, block *next_block, int with_xor); #endif /* ARGON2_REF_H */ cryptonite-0.23/cbits/argon2/thread.h0000644000000000000000000000453513054050744015751 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #ifndef ARGON2_THREAD_H #define ARGON2_THREAD_H #if !defined(ARGON2_NO_THREADS) /* Here we implement an abstraction layer for the simpĺe requirements of the Argon2 code. We only require 3 primitives---thread creation, joining, and termination---so full emulation of the pthreads API is unwarranted. Currently we wrap pthreads and Win32 threads. The API defines 2 types: the function pointer type, argon2_thread_func_t, and the type of the thread handle---argon2_thread_handle_t. */ #if defined(_WIN32) #include typedef unsigned(__stdcall *argon2_thread_func_t)(void *); typedef uintptr_t argon2_thread_handle_t; #else #include typedef void *(*argon2_thread_func_t)(void *); typedef pthread_t argon2_thread_handle_t; #endif /* Creates a thread * @param handle pointer to a thread handle, which is the output of this * function. Must not be NULL. * @param func A function pointer for the thread's entry point. Must not be * NULL. * @param args Pointer that is passed as an argument to @func. May be NULL. * @return 0 if @handle and @func are valid pointers and a thread is successfuly * created. */ static int argon2_thread_create(argon2_thread_handle_t *handle, argon2_thread_func_t func, void *args); /* Waits for a thread to terminate * @param handle Handle to a thread created with argon2_thread_create. * @return 0 if @handle is a valid handle, and joining completed successfully. */ static int argon2_thread_join(argon2_thread_handle_t handle); /* Terminate the current thread. Must be run inside a thread created by * argon2_thread_create. */ static void argon2_thread_exit(void); #endif /* ARGON2_NO_THREADS */ #endif cryptonite-0.23/cbits/argon2/argon2.c0000644000000000000000000000772313054050744015667 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #include #include #include #include "argon2.h" #include "core.c" int cryptonite_argon2_ctx(argon2_context *context, argon2_type type) { /* 1. Validate all inputs */ int result = validate_inputs(context); uint32_t memory_blocks, segment_length; argon2_instance_t instance; if (ARGON2_OK != result) { return result; } if (Argon2_d != type && Argon2_i != type && Argon2_id != type) { return ARGON2_INCORRECT_TYPE; } /* 2. Align memory size */ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ memory_blocks = context->m_cost; if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; } segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); /* Ensure that all segments have equal length */ memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); instance.version = context->version; instance.memory = NULL; instance.passes = context->t_cost; instance.memory_blocks = memory_blocks; instance.segment_length = segment_length; instance.lane_length = segment_length * ARGON2_SYNC_POINTS; instance.lanes = context->lanes; instance.threads = context->threads; instance.type = type; /* 3. Initialization: Hashing inputs, allocating memory, filling first * blocks */ result = initialize(&instance, context); if (ARGON2_OK != result) { return result; } /* 4. Filling memory */ result = fill_memory_blocks(&instance); if (ARGON2_OK != result) { return result; } /* 5. Finalization */ finalize(context, &instance); return ARGON2_OK; } int cryptonite_argon2_hash(const uint32_t t_cost, const uint32_t m_cost, const uint32_t parallelism, const void *pwd, const size_t pwdlen, const void *salt, const size_t saltlen, void *hash, const size_t hashlen, argon2_type type, const uint32_t version){ argon2_context context; int result; uint8_t *out; if (hashlen > ARGON2_MAX_OUTLEN) { return ARGON2_OUTPUT_TOO_LONG; } if (hashlen < ARGON2_MIN_OUTLEN) { return ARGON2_OUTPUT_TOO_SHORT; } out = malloc(hashlen); if (!out) { return ARGON2_MEMORY_ALLOCATION_ERROR; } context.out = (uint8_t *)out; context.outlen = (uint32_t)hashlen; context.pwd = CONST_CAST(uint8_t *)pwd; context.pwdlen = (uint32_t)pwdlen; context.salt = CONST_CAST(uint8_t *)salt; context.saltlen = (uint32_t)saltlen; context.secret = NULL; context.secretlen = 0; context.ad = NULL; context.adlen = 0; context.t_cost = t_cost; context.m_cost = m_cost; context.lanes = parallelism; context.threads = parallelism; context.allocate_cbk = NULL; context.free_cbk = NULL; context.flags = ARGON2_DEFAULT_FLAGS; context.version = version; result = cryptonite_argon2_ctx(&context, type); if (result != ARGON2_OK) { clear_internal_memory(out, hashlen); free(out); return result; } /* if raw hash requested, write it */ if (hash) { memcpy(hash, out, hashlen); } clear_internal_memory(out, hashlen); free(out); return ARGON2_OK; } cryptonite-0.23/cbits/argon2/core.c0000644000000000000000000005300013054050744015414 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ /*For memory wiping*/ #ifdef _MSC_VER #include #include /* For SecureZeroMemory */ #endif #if defined __STDC_LIB_EXT1__ #define __STDC_WANT_LIB_EXT1__ 1 #endif #define VC_GE_2005(version) (version >= 1400) #include #include #include #include #include "core.h" #include "thread.c" #include "blake2.h" #include "blake2-impl.h" #ifdef GENKAT #include "genkat.h" #endif #ifdef SUPPORT_SSE #include "opt.c" #else #include "ref.c" #endif #if defined(__clang__) #if __has_attribute(optnone) #define NOT_OPTIMIZED __attribute__((optnone)) #endif #elif defined(__GNUC__) #define GCC_VERSION \ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #if GCC_VERSION >= 40400 #define NOT_OPTIMIZED __attribute__((optimize("O0"))) #endif #endif #ifndef NOT_OPTIMIZED #define NOT_OPTIMIZED #endif /* Argon2 Team - Begin Code */ static int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) { uint8_t *out = (uint8_t *)pout; blake2b_state blake_state; uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; int ret = -1; if (outlen > UINT32_MAX) { goto fail; } /* Ensure little-endian byte order! */ store32(outlen_bytes, (uint32_t)outlen); #define TRY(statement) \ do { \ ret = statement; \ if (ret < 0) { \ goto fail; \ } \ } while ((void)0, 0) if (outlen <= BLAKE2B_OUTBYTES) { TRY(blake2b_init(&blake_state, outlen)); TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); TRY(blake2b_update(&blake_state, in, inlen)); TRY(blake2b_final(&blake_state, out, outlen)); } else { uint32_t toproduce; uint8_t out_buffer[BLAKE2B_OUTBYTES]; uint8_t in_buffer[BLAKE2B_OUTBYTES]; TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); TRY(blake2b_update(&blake_state, in, inlen)); TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES)); memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); out += BLAKE2B_OUTBYTES / 2; toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2; while (toproduce > BLAKE2B_OUTBYTES) { memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer, BLAKE2B_OUTBYTES, NULL, 0)); memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); out += BLAKE2B_OUTBYTES / 2; toproduce -= BLAKE2B_OUTBYTES / 2; } memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL, 0)); memcpy(out, out_buffer, toproduce); } fail: clear_internal_memory(&blake_state, sizeof(blake_state)); return ret; #undef TRY } /* Argon2 Team - End Code */ /***************Instance and Position constructors**********/ static void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); } static void copy_block(block *dst, const block *src) { memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); } static void xor_block(block *dst, const block *src) { int i; for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { dst->v[i] ^= src->v[i]; } } static void load_block(block *dst, const void *input) { unsigned i; for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i])); } } static void store_block(void *output, const block *src) { unsigned i; for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]); } } /***************Memory functions*****************/ static int allocate_memory(const argon2_context *context, uint8_t **memory, size_t num, size_t size) { size_t memory_size = num*size; if (memory == NULL) { return ARGON2_MEMORY_ALLOCATION_ERROR; } /* 1. Check for multiplication overflow */ if (size != 0 && memory_size / size != num) { return ARGON2_MEMORY_ALLOCATION_ERROR; } /* 2. Try to allocate with appropriate allocator */ if (context->allocate_cbk) { (context->allocate_cbk)(memory, memory_size); } else { *memory = malloc(memory_size); } if (*memory == NULL) { return ARGON2_MEMORY_ALLOCATION_ERROR; } return ARGON2_OK; } static void free_memory(const argon2_context *context, uint8_t *memory, size_t num, size_t size) { size_t memory_size = num*size; clear_internal_memory(memory, memory_size); if (context->free_cbk) { (context->free_cbk)(memory, memory_size); } else { free(memory); } } void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) { #if defined(_MSC_VER) && VC_GE_2005(_MSC_VER) SecureZeroMemory(v, n); #elif defined memset_s memset_s(v, n, 0, n); #elif defined(__OpenBSD__) explicit_bzero(v, n); #else static void *(*const volatile memset_sec)(void *, int, size_t) = &memset; memset_sec(v, 0, n); #endif } /* Memory clear flag defaults to true. */ static int FLAG_clear_internal_memory = 1; static void clear_internal_memory(void *v, size_t n) { if (FLAG_clear_internal_memory && v) { secure_wipe_memory(v, n); } } static void finalize(const argon2_context *context, argon2_instance_t *instance) { if (context != NULL && instance != NULL) { block blockhash; uint32_t l; copy_block(&blockhash, instance->memory + instance->lane_length - 1); /* XOR the last blocks */ for (l = 1; l < instance->lanes; ++l) { uint32_t last_block_in_lane = l * instance->lane_length + (instance->lane_length - 1); xor_block(&blockhash, instance->memory + last_block_in_lane); } /* Hash the result */ { uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; store_block(blockhash_bytes, &blockhash); blake2b_long(context->out, context->outlen, blockhash_bytes, ARGON2_BLOCK_SIZE); /* clear blockhash and blockhash_bytes */ clear_internal_memory(blockhash.v, ARGON2_BLOCK_SIZE); clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); } #ifdef GENKAT print_tag(context->out, context->outlen); #endif free_memory(context, (uint8_t *)instance->memory, instance->memory_blocks, sizeof(block)); } } static uint32_t index_alpha(const argon2_instance_t *instance, const argon2_position_t *position, uint32_t pseudo_rand, int same_lane) { /* * Pass 0: * This lane : all already finished segments plus already constructed * blocks in this segment * Other lanes : all already finished segments * Pass 1+: * This lane : (SYNC_POINTS - 1) last segments plus already constructed * blocks in this segment * Other lanes : (SYNC_POINTS - 1) last segments */ uint32_t reference_area_size; uint64_t relative_position; uint32_t start_position, absolute_position; if (0 == position->pass) { /* First pass */ if (0 == position->slice) { /* First slice */ reference_area_size = position->index - 1; /* all but the previous */ } else { if (same_lane) { /* The same lane => add current segment */ reference_area_size = position->slice * instance->segment_length + position->index - 1; } else { reference_area_size = position->slice * instance->segment_length + ((position->index == 0) ? (-1) : 0); } } } else { /* Second pass */ if (same_lane) { reference_area_size = instance->lane_length - instance->segment_length + position->index - 1; } else { reference_area_size = instance->lane_length - instance->segment_length + ((position->index == 0) ? (-1) : 0); } } /* 1.2.4. Mapping pseudo_rand to 0.. and produce * relative position */ relative_position = pseudo_rand; relative_position = relative_position * relative_position >> 32; relative_position = reference_area_size - 1 - (reference_area_size * relative_position >> 32); /* 1.2.5 Computing starting position */ start_position = 0; if (0 != position->pass) { start_position = (position->slice == ARGON2_SYNC_POINTS - 1) ? 0 : (position->slice + 1) * instance->segment_length; } /* 1.2.6. Computing absolute position */ absolute_position = (start_position + relative_position) % instance->lane_length; /* absolute position */ return absolute_position; } /* Single-threaded version for p=1 case */ static int fill_memory_blocks_st(argon2_instance_t *instance) { uint32_t r, s, l; for (r = 0; r < instance->passes; ++r) { for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { for (l = 0; l < instance->lanes; ++l) { argon2_position_t position = {r, l, (uint8_t)s, 0}; fill_segment(instance, position); } } #ifdef GENKAT internal_kat(instance, r); /* Print all memory blocks */ #endif } return ARGON2_OK; } #if !defined(ARGON2_NO_THREADS) #ifdef _WIN32 static unsigned __stdcall fill_segment_thr(void *thread_data) #else static void *fill_segment_thr(void *thread_data) #endif { argon2_thread_data *my_data = thread_data; fill_segment(my_data->instance_ptr, my_data->pos); argon2_thread_exit(); return 0; } /* Multi-threaded version for p > 1 case */ static int fill_memory_blocks_mt(argon2_instance_t *instance) { uint32_t r, s; argon2_thread_handle_t *thread = NULL; argon2_thread_data *thr_data = NULL; int rc = ARGON2_OK; /* 1. Allocating space for threads */ thread = calloc(instance->lanes, sizeof(argon2_thread_handle_t)); if (thread == NULL) { rc = ARGON2_MEMORY_ALLOCATION_ERROR; goto fail; } thr_data = calloc(instance->lanes, sizeof(argon2_thread_data)); if (thr_data == NULL) { rc = ARGON2_MEMORY_ALLOCATION_ERROR; goto fail; } for (r = 0; r < instance->passes; ++r) { for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { uint32_t l; /* 2. Calling threads */ for (l = 0; l < instance->lanes; ++l) { argon2_position_t position; /* 2.1 Join a thread if limit is exceeded */ if (l >= instance->threads) { if (argon2_thread_join(thread[l - instance->threads])) { rc = ARGON2_THREAD_FAIL; goto fail; } } /* 2.2 Create thread */ position.pass = r; position.lane = l; position.slice = (uint8_t)s; position.index = 0; thr_data[l].instance_ptr = instance; /* preparing the thread input */ memcpy(&(thr_data[l].pos), &position, sizeof(argon2_position_t)); if (argon2_thread_create(&thread[l], &fill_segment_thr, (void *)&thr_data[l])) { rc = ARGON2_THREAD_FAIL; goto fail; } /* fill_segment(instance, position); */ /*Non-thread equivalent of the lines above */ } /* 3. Joining remaining threads */ for (l = instance->lanes - instance->threads; l < instance->lanes; ++l) { if (argon2_thread_join(thread[l])) { rc = ARGON2_THREAD_FAIL; goto fail; } } } #ifdef GENKAT internal_kat(instance, r); /* Print all memory blocks */ #endif } fail: if (thread != NULL) { free(thread); } if (thr_data != NULL) { free(thr_data); } return rc; } #endif /* ARGON2_NO_THREADS */ static int fill_memory_blocks(argon2_instance_t *instance) { if (instance == NULL || instance->lanes == 0) { return ARGON2_INCORRECT_PARAMETER; } #if defined(ARGON2_NO_THREADS) return fill_memory_blocks_st(instance); #else return instance->threads == 1 ? fill_memory_blocks_st(instance) : fill_memory_blocks_mt(instance); #endif } static int validate_inputs(const argon2_context *context) { if (NULL == context) { return ARGON2_INCORRECT_PARAMETER; } if (NULL == context->out) { return ARGON2_OUTPUT_PTR_NULL; } /* Validate output length */ if (ARGON2_MIN_OUTLEN > context->outlen) { return ARGON2_OUTPUT_TOO_SHORT; } if (ARGON2_MAX_OUTLEN < context->outlen) { return ARGON2_OUTPUT_TOO_LONG; } /* Validate password (required param) */ if (NULL == context->pwd) { if (0 != context->pwdlen) { return ARGON2_PWD_PTR_MISMATCH; } } if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) { return ARGON2_PWD_TOO_SHORT; } if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) { return ARGON2_PWD_TOO_LONG; } /* Validate salt (required param) */ if (NULL == context->salt) { if (0 != context->saltlen) { return ARGON2_SALT_PTR_MISMATCH; } } if (ARGON2_MIN_SALT_LENGTH > context->saltlen) { return ARGON2_SALT_TOO_SHORT; } if (ARGON2_MAX_SALT_LENGTH < context->saltlen) { return ARGON2_SALT_TOO_LONG; } /* Validate secret (optional param) */ if (NULL == context->secret) { if (0 != context->secretlen) { return ARGON2_SECRET_PTR_MISMATCH; } } else { if (ARGON2_MIN_SECRET > context->secretlen) { return ARGON2_SECRET_TOO_SHORT; } if (ARGON2_MAX_SECRET < context->secretlen) { return ARGON2_SECRET_TOO_LONG; } } /* Validate associated data (optional param) */ if (NULL == context->ad) { if (0 != context->adlen) { return ARGON2_AD_PTR_MISMATCH; } } else { if (ARGON2_MIN_AD_LENGTH > context->adlen) { return ARGON2_AD_TOO_SHORT; } if (ARGON2_MAX_AD_LENGTH < context->adlen) { return ARGON2_AD_TOO_LONG; } } /* Validate memory cost */ if (ARGON2_MIN_MEMORY > context->m_cost) { return ARGON2_MEMORY_TOO_LITTLE; } if (ARGON2_MAX_MEMORY < context->m_cost) { return ARGON2_MEMORY_TOO_MUCH; } if (context->m_cost < 8 * context->lanes) { return ARGON2_MEMORY_TOO_LITTLE; } /* Validate time cost */ if (ARGON2_MIN_TIME > context->t_cost) { return ARGON2_TIME_TOO_SMALL; } if (ARGON2_MAX_TIME < context->t_cost) { return ARGON2_TIME_TOO_LARGE; } /* Validate lanes */ if (ARGON2_MIN_LANES > context->lanes) { return ARGON2_LANES_TOO_FEW; } if (ARGON2_MAX_LANES < context->lanes) { return ARGON2_LANES_TOO_MANY; } /* Validate threads */ if (ARGON2_MIN_THREADS > context->threads) { return ARGON2_THREADS_TOO_FEW; } if (ARGON2_MAX_THREADS < context->threads) { return ARGON2_THREADS_TOO_MANY; } if (NULL != context->allocate_cbk && NULL == context->free_cbk) { return ARGON2_FREE_MEMORY_CBK_NULL; } if (NULL == context->allocate_cbk && NULL != context->free_cbk) { return ARGON2_ALLOCATE_MEMORY_CBK_NULL; } return ARGON2_OK; } static void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { uint32_t l; /* Make the first and second block in each lane as G(H0||i||0) or G(H0||i||1) */ uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; for (l = 0; l < instance->lanes; ++l) { store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, ARGON2_PREHASH_SEED_LENGTH); load_block(&instance->memory[l * instance->lane_length + 0], blockhash_bytes); store32(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, ARGON2_PREHASH_SEED_LENGTH); load_block(&instance->memory[l * instance->lane_length + 1], blockhash_bytes); } clear_internal_memory(blockhash_bytes, ARGON2_BLOCK_SIZE); } static void initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type) { blake2b_state BlakeHash; uint8_t value[sizeof(uint32_t)]; if (NULL == context || NULL == blockhash) { return; } blake2b_init(&BlakeHash, ARGON2_PREHASH_DIGEST_LENGTH); store32(&value, context->lanes); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); store32(&value, context->outlen); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); store32(&value, context->m_cost); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); store32(&value, context->t_cost); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); store32(&value, context->version); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); store32(&value, (uint32_t)type); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); store32(&value, context->pwdlen); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); if (context->pwd != NULL) { blake2b_update(&BlakeHash, (const uint8_t *)context->pwd, context->pwdlen); if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { secure_wipe_memory(context->pwd, context->pwdlen); context->pwdlen = 0; } } store32(&value, context->saltlen); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); if (context->salt != NULL) { blake2b_update(&BlakeHash, (const uint8_t *)context->salt, context->saltlen); } store32(&value, context->secretlen); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); if (context->secret != NULL) { blake2b_update(&BlakeHash, (const uint8_t *)context->secret, context->secretlen); if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { secure_wipe_memory(context->secret, context->secretlen); context->secretlen = 0; } } store32(&value, context->adlen); blake2b_update(&BlakeHash, (const uint8_t *)&value, sizeof(value)); if (context->ad != NULL) { blake2b_update(&BlakeHash, (const uint8_t *)context->ad, context->adlen); } blake2b_final(&BlakeHash, blockhash, ARGON2_PREHASH_DIGEST_LENGTH); } static int initialize(argon2_instance_t *instance, argon2_context *context) { uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; int result = ARGON2_OK; if (instance == NULL || context == NULL) return ARGON2_INCORRECT_PARAMETER; instance->context_ptr = context; /* 1. Memory allocation */ result = allocate_memory(context, (uint8_t **)&(instance->memory), instance->memory_blocks, sizeof(block)); if (result != ARGON2_OK) { return result; } /* 2. Initial hashing */ /* H_0 + 8 extra bytes to produce the first blocks */ /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ /* Hashing all inputs */ initial_hash(blockhash, context, instance->type); /* Zeroing 8 extra bytes */ clear_internal_memory(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH); #ifdef GENKAT initial_kat(blockhash, context, instance->type); #endif /* 3. Creating first blocks, we always have at least two blocks in a slice */ fill_first_blocks(blockhash, instance); /* Clearing the hash */ clear_internal_memory(blockhash, ARGON2_PREHASH_SEED_LENGTH); return ARGON2_OK; } cryptonite-0.23/cbits/argon2/opt.c0000644000000000000000000001443313054050744015275 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #include #include #include #include "argon2.h" #include "opt.h" #include "blake2/blake2.h" #include "blake2/blamka-round-opt.h" static void fill_block(__m128i *state, const block *ref_block, block *next_block, int with_xor) { __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; unsigned int i; if (with_xor) { for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { state[i] = _mm_xor_si128( state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); block_XY[i] = _mm_xor_si128( state[i], _mm_loadu_si128((const __m128i *)next_block->v + i)); } } else { for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { block_XY[i] = state[i] = _mm_xor_si128( state[i], _mm_loadu_si128((const __m128i *)ref_block->v + i)); } } for (i = 0; i < 8; ++i) { BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); } for (i = 0; i < 8; ++i) { BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], state[8 * 6 + i], state[8 * 7 + i]); } for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { state[i] = _mm_xor_si128(state[i], block_XY[i]); _mm_storeu_si128((__m128i *)next_block->v + i, state[i]); } } static void next_addresses(block *address_block, block *input_block) { /*Temporary zero-initialized blocks*/ __m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; memset(zero_block, 0, sizeof(zero_block)); memset(zero2_block, 0, sizeof(zero2_block)); /*Increasing index counter*/ input_block->v[6]++; /*First iteration of G*/ fill_block(zero_block, input_block, address_block, 0); /*Second iteration of G*/ fill_block(zero2_block, address_block, address_block, 0); } static void fill_segment(const argon2_instance_t *instance, argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; block address_block, input_block; uint64_t pseudo_rand, ref_index, ref_lane; uint32_t prev_offset, curr_offset; uint32_t starting_index, i; __m128i state[64]; int data_independent_addressing; if (instance == NULL) { return; } data_independent_addressing = (instance->type == Argon2_i) || (instance->type == Argon2_id && (position.pass == 0) && (position.slice < ARGON2_SYNC_POINTS / 2)); if (data_independent_addressing) { init_block_value(&input_block, 0); input_block.v[0] = position.pass; input_block.v[1] = position.lane; input_block.v[2] = position.slice; input_block.v[3] = instance->memory_blocks; input_block.v[4] = instance->passes; input_block.v[5] = instance->type; } starting_index = 0; if ((0 == position.pass) && (0 == position.slice)) { starting_index = 2; /* we have already generated the first two blocks */ /* Don't forget to generate the first block of addresses: */ if (data_independent_addressing) { next_addresses(&address_block, &input_block); } } /* Offset of the current block */ curr_offset = position.lane * instance->lane_length + position.slice * instance->segment_length + starting_index; if (0 == curr_offset % instance->lane_length) { /* Last block in this lane */ prev_offset = curr_offset + instance->lane_length - 1; } else { /* Previous block */ prev_offset = curr_offset - 1; } memcpy(state, ((instance->memory + prev_offset)->v), ARGON2_BLOCK_SIZE); for (i = starting_index; i < instance->segment_length; ++i, ++curr_offset, ++prev_offset) { /*1.1 Rotating prev_offset if needed */ if (curr_offset % instance->lane_length == 1) { prev_offset = curr_offset - 1; } /* 1.2 Computing the index of the reference block */ /* 1.2.1 Taking pseudo-random value from the previous block */ if (data_independent_addressing) { if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { next_addresses(&address_block, &input_block); } pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; } else { pseudo_rand = instance->memory[prev_offset].v[0]; } /* 1.2.2 Computing the lane of the reference block */ ref_lane = ((pseudo_rand >> 32)) % instance->lanes; if ((position.pass == 0) && (position.slice == 0)) { /* Can not reference other lanes yet */ ref_lane = position.lane; } /* 1.2.3 Computing the number of possible reference block within the * lane. */ position.index = i; ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, ref_lane == position.lane); /* 2 Creating a new block */ ref_block = instance->memory + instance->lane_length * ref_lane + ref_index; curr_block = instance->memory + curr_offset; if (ARGON2_VERSION_10 == instance->version) { /* version 1.2.1 and earlier: overwrite, not XOR */ fill_block(state, ref_block, curr_block, 0); } else { if(0 == position.pass) { fill_block(state, ref_block, curr_block, 0); } else { fill_block(state, ref_block, curr_block, 1); } } } } cryptonite-0.23/cbits/argon2/ref.c0000644000000000000000000001530013054050744015241 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #include #include #include #include "argon2.h" #include "ref.h" #include "blamka-round-ref.h" #include "blake2-impl.h" #include "blake2.h" static void fill_block(const block *prev_block, const block *ref_block, block *next_block, int with_xor) { block blockR, block_tmp; unsigned i; copy_block(&blockR, ref_block); xor_block(&blockR, prev_block); copy_block(&block_tmp, &blockR); /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */ if (with_xor) { /* Saving the next block contents for XOR over: */ xor_block(&block_tmp, next_block); /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block + next_block */ } /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then (16,17,..31)... finally (112,113,...127) */ for (i = 0; i < 8; ++i) { BLAKE2_ROUND_NOMSG( blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], blockR.v[16 * i + 15]); } /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ for (i = 0; i < 8; i++) { BLAKE2_ROUND_NOMSG( blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], blockR.v[2 * i + 113]); } copy_block(next_block, &block_tmp); xor_block(next_block, &blockR); } static void next_addresses(block *address_block, block *input_block, const block *zero_block) { input_block->v[6]++; fill_block(zero_block, input_block, address_block, 0); fill_block(zero_block, address_block, address_block, 0); } static void fill_segment(const argon2_instance_t *instance, argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; block address_block, input_block, zero_block; uint64_t pseudo_rand, ref_index, ref_lane; uint32_t prev_offset, curr_offset; uint32_t starting_index; uint32_t i; int data_independent_addressing; if (instance == NULL) { return; } data_independent_addressing = (instance->type == Argon2_i) || (instance->type == Argon2_id && (position.pass == 0) && (position.slice < ARGON2_SYNC_POINTS / 2)); if (data_independent_addressing) { init_block_value(&zero_block, 0); init_block_value(&input_block, 0); input_block.v[0] = position.pass; input_block.v[1] = position.lane; input_block.v[2] = position.slice; input_block.v[3] = instance->memory_blocks; input_block.v[4] = instance->passes; input_block.v[5] = instance->type; } starting_index = 0; if ((0 == position.pass) && (0 == position.slice)) { starting_index = 2; /* we have already generated the first two blocks */ /* Don't forget to generate the first block of addresses: */ if (data_independent_addressing) { next_addresses(&address_block, &input_block, &zero_block); } } /* Offset of the current block */ curr_offset = position.lane * instance->lane_length + position.slice * instance->segment_length + starting_index; if (0 == curr_offset % instance->lane_length) { /* Last block in this lane */ prev_offset = curr_offset + instance->lane_length - 1; } else { /* Previous block */ prev_offset = curr_offset - 1; } for (i = starting_index; i < instance->segment_length; ++i, ++curr_offset, ++prev_offset) { /*1.1 Rotating prev_offset if needed */ if (curr_offset % instance->lane_length == 1) { prev_offset = curr_offset - 1; } /* 1.2 Computing the index of the reference block */ /* 1.2.1 Taking pseudo-random value from the previous block */ if (data_independent_addressing) { if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { next_addresses(&address_block, &input_block, &zero_block); } pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; } else { pseudo_rand = instance->memory[prev_offset].v[0]; } /* 1.2.2 Computing the lane of the reference block */ ref_lane = ((pseudo_rand >> 32)) % instance->lanes; if ((position.pass == 0) && (position.slice == 0)) { /* Can not reference other lanes yet */ ref_lane = position.lane; } /* 1.2.3 Computing the number of possible reference block within the * lane. */ position.index = i; ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, ref_lane == position.lane); /* 2 Creating a new block */ ref_block = instance->memory + instance->lane_length * ref_lane + ref_index; curr_block = instance->memory + curr_offset; if (ARGON2_VERSION_10 == instance->version) { /* version 1.2.1 and earlier: overwrite, not XOR */ fill_block(instance->memory + prev_offset, ref_block, curr_block, 0); } else { if(0 == position.pass) { fill_block(instance->memory + prev_offset, ref_block, curr_block, 0); } else { fill_block(instance->memory + prev_offset, ref_block, curr_block, 1); } } } } cryptonite-0.23/cbits/argon2/thread.c0000644000000000000000000000305213054050744015735 0ustar0000000000000000/* * Argon2 reference source code package - reference C implementations * * Copyright 2015 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves * * You may use this work under the terms of a Creative Commons CC0 1.0 * License/Waiver or the Apache Public License 2.0, at your option. The terms of * these licenses can be found at: * * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 * * You should have received a copy of both of these licenses along with this * software. If not, they may be obtained at the above URLs. */ #if !defined(ARGON2_NO_THREADS) #include "thread.h" #if defined(_WIN32) #include #endif static int argon2_thread_create(argon2_thread_handle_t *handle, argon2_thread_func_t func, void *args) { if (NULL == handle || func == NULL) { return -1; } #if defined(_WIN32) *handle = _beginthreadex(NULL, 0, func, args, 0, NULL); return *handle != 0 ? 0 : -1; #else return pthread_create(handle, NULL, func, args); #endif } static int argon2_thread_join(argon2_thread_handle_t handle) { #if defined(_WIN32) if (WaitForSingleObject((HANDLE)handle, INFINITE) == WAIT_OBJECT_0) { return CloseHandle((HANDLE)handle) != 0 ? 0 : -1; } return -1; #else return pthread_join(handle, NULL); #endif } static void argon2_thread_exit(void) { #if defined(_WIN32) _endthreadex(0); #else pthread_exit(NULL); #endif } #endif /* ARGON2_NO_THREADS */ cryptonite-0.23/cbits/aes/x86ni_impl.c0000644000000000000000000002147312643044626016057 0ustar0000000000000000/* * Copyright (c) 2012-2013 Vincent Hanquez * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of his contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ void SIZED(cryptonite_aesni_encrypt_block)(aes_block *out, aes_key *key, aes_block *in) { __m128i *k = (__m128i *) key->data; PRELOAD_ENC(k); __m128i m = _mm_loadu_si128((__m128i *) in); DO_ENC_BLOCK(m); _mm_storeu_si128((__m128i *) out, m); } void SIZED(cryptonite_aesni_decrypt_block)(aes_block *out, aes_key *key, aes_block *in) { __m128i *k = (__m128i *) key->data; PRELOAD_DEC(k); __m128i m = _mm_loadu_si128((__m128i *) in); DO_DEC_BLOCK(m); _mm_storeu_si128((__m128i *) out, m); } void SIZED(cryptonite_aesni_encrypt_ecb)(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks) { __m128i *k = (__m128i *) key->data; PRELOAD_ENC(k); for (; blocks-- > 0; in += 1, out += 1) { __m128i m = _mm_loadu_si128((__m128i *) in); DO_ENC_BLOCK(m); _mm_storeu_si128((__m128i *) out, m); } } void SIZED(cryptonite_aesni_decrypt_ecb)(aes_block *out, aes_key *key, aes_block *in, uint32_t blocks) { __m128i *k = (__m128i *) key->data; PRELOAD_DEC(k); for (; blocks-- > 0; in += 1, out += 1) { __m128i m = _mm_loadu_si128((__m128i *) in); DO_DEC_BLOCK(m); _mm_storeu_si128((__m128i *) out, m); } } void SIZED(cryptonite_aesni_encrypt_cbc)(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks) { __m128i *k = (__m128i *) key->data; __m128i iv = _mm_loadu_si128((__m128i *) _iv); PRELOAD_ENC(k); for (; blocks-- > 0; in += 1, out += 1) { __m128i m = _mm_loadu_si128((__m128i *) in); m = _mm_xor_si128(m, iv); DO_ENC_BLOCK(m); iv = m; _mm_storeu_si128((__m128i *) out, m); } } void SIZED(cryptonite_aesni_decrypt_cbc)(aes_block *out, aes_key *key, aes_block *_iv, aes_block *in, uint32_t blocks) { __m128i *k = (__m128i *) key->data; __m128i iv = _mm_loadu_si128((__m128i *) _iv); PRELOAD_DEC(k); for (; blocks-- > 0; in += 1, out += 1) { __m128i m = _mm_loadu_si128((__m128i *) in); __m128i ivnext = m; DO_DEC_BLOCK(m); m = _mm_xor_si128(m, iv); _mm_storeu_si128((__m128i *) out, m); iv = ivnext; } } void SIZED(cryptonite_aesni_encrypt_ctr)(uint8_t *output, aes_key *key, aes_block *_iv, uint8_t *input, uint32_t len) { __m128i *k = (__m128i *) key->data; __m128i bswap_mask = _mm_setr_epi8(7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8); __m128i one = _mm_set_epi32(0,1,0,0); uint32_t nb_blocks = len / 16; uint32_t part_block_len = len % 16; /* get the IV in little endian format */ __m128i iv = _mm_loadu_si128((__m128i *) _iv); iv = _mm_shuffle_epi8(iv, bswap_mask); PRELOAD_ENC(k); for (; nb_blocks-- > 0; output += 16, input += 16) { /* put back the iv in big endian mode, * encrypt it and and xor it the input block */ __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask); DO_ENC_BLOCK(tmp); __m128i m = _mm_loadu_si128((__m128i *) input); m = _mm_xor_si128(m, tmp); _mm_storeu_si128((__m128i *) output, m); /* iv += 1 */ iv = _mm_add_epi64(iv, one); } if (part_block_len != 0) { aes_block block; memset(&block.b, 0, 16); memcpy(&block.b, input, part_block_len); __m128i m = _mm_loadu_si128((__m128i *) &block); __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask); DO_ENC_BLOCK(tmp); m = _mm_xor_si128(m, tmp); _mm_storeu_si128((__m128i *) &block.b, m); memcpy(output, &block.b, part_block_len); } return ; } void SIZED(cryptonite_aesni_encrypt_xts)(aes_block *out, aes_key *key1, aes_key *key2, aes_block *_tweak, uint32_t spoint, aes_block *in, uint32_t blocks) { __m128i tweak = _mm_loadu_si128((__m128i *) _tweak); do { __m128i *k2 = (__m128i *) key2->data; PRELOAD_ENC(k2); DO_ENC_BLOCK(tweak); while (spoint-- > 0) tweak = gfmulx(tweak); } while (0) ; do { __m128i *k1 = (__m128i *) key1->data; PRELOAD_ENC(k1); for ( ; blocks-- > 0; in += 1, out += 1, tweak = gfmulx(tweak)) { __m128i m = _mm_loadu_si128((__m128i *) in); m = _mm_xor_si128(m, tweak); DO_ENC_BLOCK(m); m = _mm_xor_si128(m, tweak); _mm_storeu_si128((__m128i *) out, m); } } while (0); } void SIZED(cryptonite_aesni_gcm_encrypt)(uint8_t *output, aes_gcm *gcm, aes_key *key, uint8_t *input, uint32_t length) { __m128i *k = (__m128i *) key->data; __m128i bswap_mask = _mm_setr_epi8(7,6,5,4,3,2,1,0,15,14,13,12,11,10,9,8); __m128i one = _mm_set_epi32(0,1,0,0); uint32_t nb_blocks = length / 16; uint32_t part_block_len = length % 16; gcm->length_input += length; __m128i h = _mm_loadu_si128((__m128i *) &gcm->h); __m128i tag = _mm_loadu_si128((__m128i *) &gcm->tag); __m128i iv = _mm_loadu_si128((__m128i *) &gcm->civ); iv = _mm_shuffle_epi8(iv, bswap_mask); PRELOAD_ENC(k); for (; nb_blocks-- > 0; output += 16, input += 16) { /* iv += 1 */ iv = _mm_add_epi64(iv, one); /* put back iv in big endian, encrypt it, * and xor it to input */ __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask); DO_ENC_BLOCK(tmp); __m128i m = _mm_loadu_si128((__m128i *) input); m = _mm_xor_si128(m, tmp); tag = ghash_add(tag, h, m); /* store it out */ _mm_storeu_si128((__m128i *) output, m); } if (part_block_len > 0) { __m128i mask; aes_block block; /* FIXME could do something a bit more clever (slli & sub & and maybe) ... */ switch (part_block_len) { case 1: mask = _mm_setr_epi8(0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 2: mask = _mm_setr_epi8(0,1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 3: mask = _mm_setr_epi8(0,1,2,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 4: mask = _mm_setr_epi8(0,1,2,3,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 5: mask = _mm_setr_epi8(0,1,2,3,4,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 6: mask = _mm_setr_epi8(0,1,2,3,4,5,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 7: mask = _mm_setr_epi8(0,1,2,3,4,5,6,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 8: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 9: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,0x80,0x80,0x80,0x80,0x80,0x80,0x80); break; case 10: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,0x80,0x80,0x80,0x80,0x80,0x80); break; case 11: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,0x80,0x80,0x80,0x80,0x80); break; case 12: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,0x80,0x80,0x80,0x80); break; case 13: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,0x80,0x80,0x80); break; case 14: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,0x80,0x80); break; case 15: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,0x80); break; default: mask = _mm_setr_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); break; } block128_zero(&block); block128_copy_bytes(&block, input, part_block_len); /* iv += 1 */ iv = _mm_add_epi64(iv, one); /* put back iv in big endian mode, encrypt it and xor it with input */ __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask); DO_ENC_BLOCK(tmp); __m128i m = _mm_loadu_si128((__m128i *) &block); m = _mm_xor_si128(m, tmp); m = _mm_shuffle_epi8(m, mask); tag = ghash_add(tag, h, m); /* make output */ _mm_storeu_si128((__m128i *) &block.b, m); memcpy(output, &block.b, part_block_len); } /* store back IV & tag */ __m128i tmp = _mm_shuffle_epi8(iv, bswap_mask); _mm_storeu_si128((__m128i *) &gcm->civ, tmp); _mm_storeu_si128((__m128i *) &gcm->tag, tag); } cryptonite-0.23/tests/BCrypt.hs0000644000000000000000000000770312746570656014756 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module BCrypt ( tests ) where import Crypto.KDF.BCrypt import qualified Data.ByteString as B import Imports -- Openwall bcrypt tests, with 2x versions and 0xFF special cases removed. expected :: [(ByteString, ByteString)] expected = [ ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW", "U*U") , ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK", "U*U*") , ("$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a", "U*U*U") , ("$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui", "0123456789abcdefghijklmnopqrstuvwxyz\ \ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\ \chars after 72 are ignored") , ("$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", "\xff\xff\xa3") , ("$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e", "\xff\xff\xa3") , ("$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") , ("$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq", "\xa3") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\ \chars after 72 are ignored as usual") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy", "\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\ \\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55") , ("$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe", "\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\ \\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff") , ("$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy", "") , ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s.", "") , ("$2a$08$HqWuK6/Ng6sg9gQzbLrgb.Tl.ZHfXLhvt/SgVyWhQqgqcZ7ZuUtye", "") , ("$2a$10$k1wbIrmNyFAPwPVPSVa/zecw2BCEnBwVS2GbrmgzxFUOqW9dk4TCW", "") , ("$2a$12$k42ZFHFWqBp3vWli.nIn8uYyIkbvYRvodzbfbK18SSsY.CsIQPlxO", "") , ("$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe", "a") , ("$2a$08$cfcvVd2aQ8CMvoMpP2EBfeodLEkkFJ9umNEfPD18.hUF62qqlC/V.", "a") , ("$2a$12$8NJH3LsPrANStV6XtBakCez0cKHXVxmvxIlcz785vxAIZrihHZpeS", "a") , ("$2a$06$If6bvum7DFjUnE9p2uDeDu0YHzrHM6tf.iqN8.yx.jNN1ILEf7h0i", "abc") , ("$2a$08$Ro0CUfOqk6cXEKf3dyaM7OhSCvnwM9s4wIX9JeLapehKK5YdLxKcm", "abc") , ("$2a$10$WvvTPHKwdBJ3uk0Z37EMR.hLA2W6N9AEBhEgrAOljy2Ae5MtaSIUi", "abc") , ("$2a$06$.rCVZVOThsIa97pEDOxvGuRRgzG64bvtJ0938xuqzv18d3ZpQhstC", "abcdefghijklmnopqrstuvwxyz") ] makeKATs = concatMap maketest (zip3 is passwords hashes) where is :: [Int] is = [1..] passwords = map snd expected hashes = map fst expected maketest (i, password, hash) = [ testCase (show i) (assertBool "" (validatePassword password hash)) ] tests = testGroup "bcrypt" [ testGroup "KATs" makeKATs , testCase "Invalid hash length" (assertEqual "" (Left "Invalid hash format") (validatePasswordEither B.empty ("$2a$06$DCq7YPn5Rq63x1Lad4cll.TV4S6ytwfsfvkgY8jIucDrjc8deX1s" :: B.ByteString))) ] cryptonite-0.23/tests/BlockCipher.hs0000644000000000000000000004502012535566225015723 0ustar0000000000000000{-# LANGUAGE ViewPatterns #-} module BlockCipher ( KAT_ECB(..) , KAT_CBC(..) , KAT_CFB(..) , KAT_CTR(..) , KAT_XTS(..) , KAT_AEAD(..) , KATs(..) , defaultKATs , testBlockCipher , CipherInfo ) where import Imports import Data.Maybe import Crypto.Error import Crypto.Cipher.Types import Data.ByteArray as B hiding (pack, null) import qualified Data.ByteString as B ------------------------------------------------------------------------ -- KAT ------------------------------------------------------------------------ type BlockSize = Int type KeySize = Int type CipherInfo a = (BlockSize, KeySize, ByteString -> a) instance Show (IV c) where show _ = "IV" -- | ECB KAT data KAT_ECB = KAT_ECB { ecbKey :: ByteString -- ^ Key , ecbPlaintext :: ByteString -- ^ Plaintext , ecbCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | CBC KAT data KAT_CBC = KAT_CBC { cbcKey :: ByteString -- ^ Key , cbcIV :: ByteString -- ^ IV , cbcPlaintext :: ByteString -- ^ Plaintext , cbcCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | CFB KAT data KAT_CFB = KAT_CFB { cfbKey :: ByteString -- ^ Key , cfbIV :: ByteString -- ^ IV , cfbPlaintext :: ByteString -- ^ Plaintext , cfbCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | CTR KAT data KAT_CTR = KAT_CTR { ctrKey :: ByteString -- ^ Key , ctrIV :: ByteString -- ^ IV (usually represented as a 128 bits integer) , ctrPlaintext :: ByteString -- ^ Plaintext , ctrCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | XTS KAT data KAT_XTS = KAT_XTS { xtsKey1 :: ByteString -- ^ 1st XTS key , xtsKey2 :: ByteString -- ^ 2nd XTS key , xtsIV :: ByteString -- ^ XTS IV , xtsPlaintext :: ByteString -- ^ plaintext , xtsCiphertext :: ByteString -- ^ Ciphertext } deriving (Show,Eq) -- | AEAD KAT data KAT_AEAD = KAT_AEAD { aeadMode :: AEADMode , aeadKey :: ByteString -- ^ Key , aeadIV :: ByteString -- ^ IV for initialization , aeadHeader :: ByteString -- ^ Authenticated Header , aeadPlaintext :: ByteString -- ^ Plaintext , aeadCiphertext :: ByteString -- ^ Ciphertext , aeadTaglen :: Int -- ^ aead tag len , aeadTag :: ByteString -- ^ expected tag } deriving (Show,Eq) -- | all the KATs. use defaultKATs to prevent compilation error -- from future expansion of this data structure data KATs = KATs { kat_ECB :: [KAT_ECB] , kat_CBC :: [KAT_CBC] , kat_CFB :: [KAT_CFB] , kat_CTR :: [KAT_CTR] , kat_XTS :: [KAT_XTS] , kat_AEAD :: [KAT_AEAD] } deriving (Show,Eq) defaultKATs = KATs [] [] [] [] [] [] {- testECB (_, _, cipherInit) ecbEncrypt ecbDecrypt kats = testGroup "ECB" (concatMap katTest (zip is kats) {- ++ propTests-}) where katTest (i,d) = [ testCase ("E" ++ show i) (ecbEncrypt ctx (ecbPlaintext d) @?= ecbCiphertext d) , testCase ("D" ++ show i) (ecbDecrypt ctx (ecbCiphertext d) @?= ecbPlaintext d) ] where ctx = cipherInit (ecbKey d) --propTest = testProperty "decrypt.encrypt" (ECBUnit key plaintext) = --testProperty_ECB (ECBUnit (cipherInit -> ctx) (toBytes -> plaintext)) = -- plaintext `assertEq` ecbDecrypt ctx (ecbEncrypt ctx plaintext) testKatCBC cbcInit cbcEncrypt cbcDecrypt (i,d) = [ testCase ("E" ++ show i) (cbcEncrypt ctx iv (cbcPlaintext d) @?= cbcCiphertext d) , testCase ("D" ++ show i) (cbcDecrypt ctx iv (cbcCiphertext d) @?= cbcPlaintext d) ] where ctx = cbcInit $ cbcKey d iv = cbcIV d testKatCFB cfbInit cfbEncrypt cfbDecrypt (i,d) = [ testCase ("E" ++ show i) (cfbEncrypt ctx iv (cfbPlaintext d) @?= cfbCiphertext d) , testCase ("D" ++ show i) (cfbDecrypt ctx iv (cfbCiphertext d) @?= cfbPlaintext d) ] where ctx = cfbInit $ cfbKey d iv = cfbIV d testKatCTR ctrInit ctrCombine (i,d) = [ testCase ("E" ++ i) (ctrCombine ctx iv (ctrPlaintext d) @?= ctrCiphertext d) , testCase ("D" ++ i) (ctrCombine ctx iv (ctrCiphertext d) @?= ctrPlaintext d) ] where ctx = ctrInit $ ctrKey d iv = ctrIV d testKatXTS xtsInit xtsEncrypt xtsDecrypt (i,d) = [ testCase ("E" ++ i) (xtsEncrypt ctx iv 0 (xtsPlaintext d) @?= xtsCiphertext d) , testCase ("D" ++ i) (xtsDecrypt ctx iv 0 (xtsCiphertext d) @?= xtsPlaintext d) ] where ctx = xtsInit (xtsKey1 d, xtsKey2 d) iv = xtsIV d testKatAEAD cipherInit aeadInit aeadAppendHeader aeadEncrypt aeadDecrypt aeadFinalize (i,d) = [ testCase ("AE" ++ i) (etag @?= aeadTag d) , testCase ("AD" ++ i) (dtag @?= aeadTag d) , testCase ("E" ++ i) (ebs @?= aeadCiphertext d) , testCase ("D" ++ i) (dbs @?= aeadPlaintext d) ] where ctx = cipherInit $ aeadKey d (Just aead) = aeadInit ctx (aeadIV d) aeadHeaded = aeadAppendHeader aead (aeadHeader d) (ebs,aeadEFinal) = aeadEncrypt aeadHeaded (aeadPlaintext d) (dbs,aeadDFinal) = aeadDecrypt aeadHeaded (aeadCiphertext d) etag = aeadFinalize aeadEFinal (aeadTaglen d) dtag = aeadFinalize aeadDFinal (aeadTaglen d) -} testKATs :: BlockCipher cipher => KATs -> cipher -> TestTree testKATs kats cipher = testGroup "KAT" ( maybeGroup makeECBTest "ECB" (kat_ECB kats) ++ maybeGroup makeCBCTest "CBC" (kat_CBC kats) ++ maybeGroup makeCFBTest "CFB" (kat_CFB kats) ++ maybeGroup makeCTRTest "CTR" (kat_CTR kats) -- ++ maybeGroup makeXTSTest "XTS" (kat_XTS kats) -- ++ maybeGroup makeAEADTest "AEAD" (kat_AEAD kats) ) where makeECBTest i d = [ testCase ("E" ++ i) (ecbEncrypt ctx (ecbPlaintext d) @?= ecbCiphertext d) , testCase ("D" ++ i) (ecbDecrypt ctx (ecbCiphertext d) @?= ecbPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ ecbKey d) makeCBCTest i d = [ testCase ("E" ++ i) (cbcEncrypt ctx iv (cbcPlaintext d) @?= cbcCiphertext d) , testCase ("D" ++ i) (cbcDecrypt ctx iv (cbcCiphertext d) @?= cbcPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ cbcKey d) iv = cipherMakeIV cipher $ cbcIV d makeCFBTest i d = [ testCase ("E" ++ i) (cfbEncrypt ctx iv (cfbPlaintext d) @?= cfbCiphertext d) , testCase ("D" ++ i) (cfbDecrypt ctx iv (cfbCiphertext d) @?= cfbPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ cfbKey d) iv = cipherMakeIV cipher $ cfbIV d makeCTRTest i d = [ testCase ("E" ++ i) (ctrCombine ctx iv (ctrPlaintext d) @?= ctrCiphertext d) , testCase ("D" ++ i) (ctrCombine ctx iv (ctrCiphertext d) @?= ctrPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ ctrKey d) iv = cipherMakeIV cipher $ ctrIV d {- makeXTSTest i d = [ testCase ("E" ++ i) (xtsEncrypt ctx iv 0 (xtsPlaintext d) @?= xtsCiphertext d) , testCase ("D" ++ i) (xtsDecrypt ctx iv 0 (xtsCiphertext d) @?= xtsPlaintext d) ] where ctx1 = cipherInit (cipherMakeKey cipher $ xtsKey1 d) ctx2 = cipherInit (cipherMakeKey cipher $ xtsKey2 d) ctx = (ctx1, ctx2) iv = cipherMakeIV cipher $ xtsIV d makeAEADTest i d = [ testCase ("AE" ++ i) (etag @?= aeadTag d) , testCase ("AD" ++ i) (dtag @?= aeadTag d) , testCase ("E" ++ i) (ebs @?= aeadCiphertext d) , testCase ("D" ++ i) (dbs @?= aeadPlaintext d) ] where ctx = cipherInit (cipherMakeKey cipher $ aeadKey d) aead = maybe (error $ "cipher doesn't support aead mode: " ++ show (aeadMode d)) id $ aeadInit (aeadMode d) ctx (aeadIV d) aeadHeaded = aeadAppendHeader aead (aeadHeader d) (ebs,aeadEFinal) = aeadEncrypt aeadHeaded (aeadPlaintext d) (dbs,aeadDFinal) = aeadDecrypt aeadHeaded (aeadCiphertext d) etag = aeadFinalize aeadEFinal (aeadTaglen d) dtag = aeadFinalize aeadDFinal (aeadTaglen d) -} cipherInitNoErr :: BlockCipher c => Key c -> c cipherInitNoErr (Key k) = case cipherInit k of CryptoPassed a -> a CryptoFailed e -> error (show e) ------------------------------------------------------------------------ -- Properties ------------------------------------------------------------------------ -- | any sized bytestring newtype Plaintext a = Plaintext { unPlaintext :: B.ByteString } deriving (Show,Eq) -- | A multiple of blocksize bytestring newtype PlaintextBS a = PlaintextBS { unPlaintextBS :: B.ByteString } deriving (Show,Eq) newtype Key a = Key ByteString deriving (Show,Eq) -- | a ECB unit test data ECBUnit a = ECBUnit (Key a) (PlaintextBS a) deriving (Eq) -- | a CBC unit test data CBCUnit a = CBCUnit (Key a) (IV a) (PlaintextBS a) deriving (Eq) -- | a CBC unit test data CFBUnit a = CFBUnit (Key a) (IV a) (PlaintextBS a) deriving (Eq) -- | a CFB unit test data CFB8Unit a = CFB8Unit (Key a) (IV a) (Plaintext a) deriving (Eq) -- | a CTR unit test data CTRUnit a = CTRUnit (Key a) (IV a) (Plaintext a) deriving (Eq) -- | a XTS unit test data XTSUnit a = XTSUnit (Key a) (Key a) (IV a) (PlaintextBS a) deriving (Eq) -- | a AEAD unit test data AEADUnit a = AEADUnit (Key a) B.ByteString (Plaintext a) (Plaintext a) deriving (Eq) -- | Stream cipher unit test data StreamUnit a = StreamUnit (Key a) (Plaintext a) deriving (Eq) instance Show (ECBUnit a) where show (ECBUnit key b) = "ECB(key=" ++ show key ++ ",input=" ++ show b ++ ")" instance Show (CBCUnit a) where show (CBCUnit key iv b) = "CBC(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (CFBUnit a) where show (CFBUnit key iv b) = "CFB(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (CFB8Unit a) where show (CFB8Unit key iv b) = "CFB8(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (CTRUnit a) where show (CTRUnit key iv b) = "CTR(key=" ++ show key ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (XTSUnit a) where show (XTSUnit key1 key2 iv b) = "XTS(key1=" ++ show key1 ++ ",key2=" ++ show key2 ++ ",iv=" ++ show iv ++ ",input=" ++ show b ++ ")" instance Show (AEADUnit a) where show (AEADUnit key iv aad b) = "AEAD(key=" ++ show key ++ ",iv=" ++ show iv ++ ",aad=" ++ show (unPlaintext aad) ++ ",input=" ++ show b ++ ")" instance Show (StreamUnit a) where show (StreamUnit key b) = "Stream(key=" ++ show key ++ ",input=" ++ show b ++ ")" -- | Generate an arbitrary valid key for a specific block cipher generateKey :: Cipher a => Gen (Key a) generateKey = keyFromCipher undefined where keyFromCipher :: Cipher a => a -> Gen (Key a) keyFromCipher cipher = do sz <- case cipherKeySize cipher of KeySizeRange low high -> choose (low, high) KeySizeFixed v -> return v KeySizeEnum l -> elements l Key . B.pack <$> replicateM sz arbitrary -- | Generate an arbitrary valid IV for a specific block cipher generateIv :: BlockCipher a => Gen (IV a) generateIv = ivFromCipher undefined where ivFromCipher :: BlockCipher a => a -> Gen (IV a) ivFromCipher cipher = fromJust . makeIV . B.pack <$> replicateM (blockSize cipher) arbitrary -- | Generate an arbitrary valid IV for AEAD for a specific block cipher generateIvAEAD :: Gen B.ByteString generateIvAEAD = choose (12,90) >>= \sz -> (B.pack <$> replicateM sz arbitrary) -- | Generate a plaintext multiple of blocksize bytes generatePlaintextMultipleBS :: BlockCipher a => Gen (PlaintextBS a) generatePlaintextMultipleBS = choose (1,128) >>= \size -> replicateM (size * 16) arbitrary >>= return . PlaintextBS . B.pack -- | Generate any sized plaintext generatePlaintext :: Gen (Plaintext a) generatePlaintext = choose (0,324) >>= \size -> replicateM size arbitrary >>= return . Plaintext . B.pack instance BlockCipher a => Arbitrary (ECBUnit a) where arbitrary = ECBUnit <$> generateKey <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (CBCUnit a) where arbitrary = CBCUnit <$> generateKey <*> generateIv <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (CFBUnit a) where arbitrary = CFBUnit <$> generateKey <*> generateIv <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (CFB8Unit a) where arbitrary = CFB8Unit <$> generateKey <*> generateIv <*> generatePlaintext instance BlockCipher a => Arbitrary (CTRUnit a) where arbitrary = CTRUnit <$> generateKey <*> generateIv <*> generatePlaintext instance BlockCipher a => Arbitrary (XTSUnit a) where arbitrary = XTSUnit <$> generateKey <*> generateKey <*> generateIv <*> generatePlaintextMultipleBS instance BlockCipher a => Arbitrary (AEADUnit a) where arbitrary = AEADUnit <$> generateKey <*> generateIvAEAD <*> generatePlaintext <*> generatePlaintext instance StreamCipher a => Arbitrary (StreamUnit a) where arbitrary = StreamUnit <$> generateKey <*> generatePlaintext testBlockCipherBasic :: BlockCipher a => a -> [TestTree] testBlockCipherBasic cipher = [ testProperty "ECB" ecbProp ] where ecbProp = toTests cipher toTests :: BlockCipher a => a -> (ECBUnit a -> Bool) toTests _ = testProperty_ECB testProperty_ECB (ECBUnit key (unPlaintextBS -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` ecbDecrypt ctx (ecbEncrypt ctx plaintext) testBlockCipherModes :: BlockCipher a => a -> [TestTree] testBlockCipherModes cipher = [ testProperty "CBC" cbcProp , testProperty "CFB" cfbProp --, testProperty "CFB8" cfb8Prop , testProperty "CTR" ctrProp ] where (cbcProp,cfbProp,ctrProp) = toTests cipher toTests :: BlockCipher a => a -> ((CBCUnit a -> Bool), (CFBUnit a -> Bool), {-(CFB8Unit a -> Bool),-} (CTRUnit a -> Bool)) toTests _ = (testProperty_CBC ,testProperty_CFB --,testProperty_CFB8 ,testProperty_CTR ) testProperty_CBC (CBCUnit key testIV (unPlaintextBS -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` cbcDecrypt ctx testIV (cbcEncrypt ctx testIV plaintext) testProperty_CFB (CFBUnit key testIV (unPlaintextBS -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` cfbDecrypt ctx testIV (cfbEncrypt ctx testIV plaintext) {- testProperty_CFB8 (CFB8Unit (cipherInit -> ctx) testIV (unPlaintext -> plaintext)) = plaintext `assertEq` cfb8Decrypt ctx testIV (cfb8Encrypt ctx testIV plaintext) -} testProperty_CTR (CTRUnit key testIV (unPlaintext -> plaintext)) = withCtx key $ \ctx -> plaintext `assertEq` ctrCombine ctx testIV (ctrCombine ctx testIV plaintext) testBlockCipherAEAD :: BlockCipher a => a -> [TestTree] testBlockCipherAEAD cipher = [ testProperty "OCB" (aeadProp AEAD_OCB) , testProperty "CCM" (aeadProp AEAD_CCM) , testProperty "EAX" (aeadProp AEAD_EAX) , testProperty "CWC" (aeadProp AEAD_CWC) , testProperty "GCM" (aeadProp AEAD_GCM) ] where aeadProp = toTests cipher toTests :: BlockCipher a => a -> (AEADMode -> AEADUnit a -> Bool) toTests _ = testProperty_AEAD testProperty_AEAD mode (AEADUnit key testIV (unPlaintext -> aad) (unPlaintext -> plaintext)) = withCtx key $ \ctx -> case aeadInit mode ctx testIV of CryptoPassed iniAead -> let aead = aeadAppendHeader iniAead aad (eText, aeadE) = aeadEncrypt aead plaintext (dText, aeadD) = aeadDecrypt aead eText eTag = aeadFinalize aeadE (blockSize ctx) dTag = aeadFinalize aeadD (blockSize ctx) in (plaintext `assertEq` dText) && (eTag `B.eq` dTag) CryptoFailed err | err == CryptoError_AEADModeNotSupported -> True | otherwise -> error ("testProperty_AEAD: " ++ show err) withCtx :: Cipher c => Key c -> (c -> a) -> a withCtx (Key key) f = case cipherInit key of CryptoFailed e -> error ("init failed: " ++ show e) CryptoPassed ctx -> f ctx {- testBlockCipherXTS :: BlockCipher a => a -> [TestTree] testBlockCipherXTS cipher = [testProperty "XTS" xtsProp] where xtsProp = toTests cipher toTests :: BlockCipher a => a -> (XTSUnit a -> Bool) toTests _ = testProperty_XTS testProperty_XTS (XTSUnit (cipherInit -> ctx1) (cipherInit -> ctx2) testIV (toBytes -> plaintext)) | blockSize ctx1 == 16 = plaintext `assertEq` xtsDecrypt (ctx1, ctx2) testIV 0 (xtsEncrypt (ctx1, ctx2) testIV 0 plaintext) | otherwise = True -} -- | Test a generic block cipher for properties -- related to block cipher modes. testModes :: BlockCipher a => a -> [TestTree] testModes cipher = [ testGroup "decrypt.encrypt==id" -- (testBlockCipherBasic cipher ++ testBlockCipherModes cipher ++ testBlockCipherAEAD cipher ++ testBlockCipherXTS cipher) (testBlockCipherBasic cipher ++ testBlockCipherModes cipher ++ testBlockCipherAEAD cipher) ] -- | Return tests for a specific blockcipher and a list of KATs testBlockCipher :: BlockCipher a => KATs -> a -> TestTree testBlockCipher kats cipher = testGroup (cipherName cipher) ( (if kats == defaultKATs then [] else [testKATs kats cipher]) ++ testModes cipher ) cipherMakeKey :: Cipher cipher => cipher -> ByteString -> Key cipher cipherMakeKey _ bs = Key bs cipherMakeIV :: BlockCipher cipher => cipher -> ByteString -> IV cipher cipherMakeIV _ bs = fromJust $ makeIV bs maybeGroup :: (String -> t -> [TestTree]) -> TestName -> [t] -> [TestTree] maybeGroup mkTest groupName l | null l = [] | otherwise = [testGroup groupName (concatMap (\(i, d) -> mkTest (show i) d) $ zip nbs l)] where nbs :: [Int] nbs = [0..] cryptonite-0.23/tests/ChaCha.hs0000644000000000000000000001504212527624436014646 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module ChaCha (tests) where import qualified Crypto.Cipher.ChaCha as ChaCha import Imports import qualified Data.ByteString as B b8_128_k0_i0 = "\xe2\x8a\x5f\xa4\xa6\x7f\x8c\x5d\xef\xed\x3e\x6f\xb7\x30\x34\x86\xaa\x84\x27\xd3\x14\x19\xa7\x29\x57\x2d\x77\x79\x53\x49\x11\x20\xb6\x4a\xb8\xe7\x2b\x8d\xeb\x85\xcd\x6a\xea\x7c\xb6\x08\x9a\x10\x18\x24\xbe\xeb\x08\x81\x4a\x42\x8a\xab\x1f\xa2\xc8\x16\x08\x1b\x8a\x26\xaf\x44\x8a\x1b\xa9\x06\x36\x8f\xd8\xc8\x38\x31\xc1\x8c\xec\x8c\xed\x81\x1a\x02\x8e\x67\x5b\x8d\x2b\xe8\xfc\xe0\x81\x16\x5c\xea\xe9\xf1\xd1\xb7\xa9\x75\x49\x77\x49\x48\x05\x69\xce\xb8\x3d\xe6\xa0\xa5\x87\xd4\x98\x4f\x19\x92\x5f\x5d\x33\x8e\x43\x0d" b12_128_k0_i0 = "\xe1\x04\x7b\xa9\x47\x6b\xf8\xff\x31\x2c\x01\xb4\x34\x5a\x7d\x8c\xa5\x79\x2b\x0a\xd4\x67\x31\x3f\x1d\xc4\x12\xb5\xfd\xce\x32\x41\x0d\xea\x8b\x68\xbd\x77\x4c\x36\xa9\x20\xf0\x92\xa0\x4d\x3f\x95\x27\x4f\xbe\xff\x97\xbc\x84\x91\xfc\xef\x37\xf8\x59\x70\xb4\x50\x1d\x43\xb6\x1a\x8f\x7e\x19\xfc\xed\xde\xf3\x68\xae\x6b\xfb\x11\x10\x1b\xd9\xfd\x3e\x4d\x12\x7d\xe3\x0d\xb2\xdb\x1b\x47\x2e\x76\x42\x68\x03\xa4\x5e\x15\xb9\x62\x75\x19\x86\xef\x1d\x9d\x50\xf5\x98\xa5\xdc\xdc\x9f\xa5\x29\xa2\x83\x57\x99\x1e\x78\x4e\xa2\x0f" b20_128_k0_i0 = "\x89\x67\x09\x52\x60\x83\x64\xfd\x00\xb2\xf9\x09\x36\xf0\x31\xc8\xe7\x56\xe1\x5d\xba\x04\xb8\x49\x3d\x00\x42\x92\x59\xb2\x0f\x46\xcc\x04\xf1\x11\x24\x6b\x6c\x2c\xe0\x66\xbe\x3b\xfb\x32\xd9\xaa\x0f\xdd\xfb\xc1\x21\x23\xd4\xb9\xe4\x4f\x34\xdc\xa0\x5a\x10\x3f\x6c\xd1\x35\xc2\x87\x8c\x83\x2b\x58\x96\xb1\x34\xf6\x14\x2a\x9d\x4d\x8d\x0d\x8f\x10\x26\xd2\x0a\x0a\x81\x51\x2c\xbc\xe6\xe9\x75\x8a\x71\x43\xd0\x21\x97\x80\x22\xa3\x84\x14\x1a\x80\xce\xa3\x06\x2f\x41\xf6\x7a\x75\x2e\x66\xad\x34\x11\x98\x4c\x78\x7e\x30\xad" b8_256_k0_i0 = "\x3e\x00\xef\x2f\x89\x5f\x40\xd6\x7f\x5b\xb8\xe8\x1f\x09\xa5\xa1\x2c\x84\x0e\xc3\xce\x9a\x7f\x3b\x18\x1b\xe1\x88\xef\x71\x1a\x1e\x98\x4c\xe1\x72\xb9\x21\x6f\x41\x9f\x44\x53\x67\x45\x6d\x56\x19\x31\x4a\x42\xa3\xda\x86\xb0\x01\x38\x7b\xfd\xb8\x0e\x0c\xfe\x42\xd2\xae\xfa\x0d\xea\xa5\xc1\x51\xbf\x0a\xdb\x6c\x01\xf2\xa5\xad\xc0\xfd\x58\x12\x59\xf9\xa2\xaa\xdc\xf2\x0f\x8f\xd5\x66\xa2\x6b\x50\x32\xec\x38\xbb\xc5\xda\x98\xee\x0c\x6f\x56\x8b\x87\x2a\x65\xa0\x8a\xbf\x25\x1d\xeb\x21\xbb\x4b\x56\xe5\xd8\x82\x1e\x68\xaa" b12_256_k0_i0 = "\x9b\xf4\x9a\x6a\x07\x55\xf9\x53\x81\x1f\xce\x12\x5f\x26\x83\xd5\x04\x29\xc3\xbb\x49\xe0\x74\x14\x7e\x00\x89\xa5\x2e\xae\x15\x5f\x05\x64\xf8\x79\xd2\x7a\xe3\xc0\x2c\xe8\x28\x34\xac\xfa\x8c\x79\x3a\x62\x9f\x2c\xa0\xde\x69\x19\x61\x0b\xe8\x2f\x41\x13\x26\xbe\x0b\xd5\x88\x41\x20\x3e\x74\xfe\x86\xfc\x71\x33\x8c\xe0\x17\x3d\xc6\x28\xeb\xb7\x19\xbd\xcb\xcc\x15\x15\x85\x21\x4c\xc0\x89\xb4\x42\x25\x8d\xcd\xa1\x4c\xf1\x11\xc6\x02\xb8\x97\x1b\x8c\xc8\x43\xe9\x1e\x46\xca\x90\x51\x51\xc0\x27\x44\xa6\xb0\x17\xe6\x93\x16" b20_256_k0_i0 = "\x76\xb8\xe0\xad\xa0\xf1\x3d\x90\x40\x5d\x6a\xe5\x53\x86\xbd\x28\xbd\xd2\x19\xb8\xa0\x8d\xed\x1a\xa8\x36\xef\xcc\x8b\x77\x0d\xc7\xda\x41\x59\x7c\x51\x57\x48\x8d\x77\x24\xe0\x3f\xb8\xd8\x4a\x37\x6a\x43\xb8\xf4\x15\x18\xa1\x1c\xc3\x87\xb6\x69\xb2\xee\x65\x86\x9f\x07\xe7\xbe\x55\x51\x38\x7a\x98\xba\x97\x7c\x73\x2d\x08\x0d\xcb\x0f\x29\xa0\x48\xe3\x65\x69\x12\xc6\x53\x3e\x32\xee\x7a\xed\x29\xb7\x21\x76\x9c\xe6\x4e\x43\xd5\x71\x33\xb0\x74\xd8\x39\xd5\x31\xed\x1f\x28\x51\x0a\xfb\x45\xac\xe1\x0a\x1f\x4b\x79\x4d\x6f" data Vector = Vector Int -- rounds ByteString -- key ByteString -- nonce deriving (Show,Eq) instance Arbitrary Vector where arbitrary = Vector 20 <$> arbitraryBS 16 <*> arbitraryBS 12 tests = testGroup "ChaCha" [ testCase "8-128-K0-I0" (chachaRunSimple b8_128_k0_i0 8 16 8) , testCase "12-128-K0-I0" (chachaRunSimple b12_128_k0_i0 12 16 8) , testCase "20-128-K0-I0" (chachaRunSimple b20_128_k0_i0 20 16 8) , testCase "8-256-K0-I0" (chachaRunSimple b8_256_k0_i0 8 32 8) , testCase "12-256-K0-I0" (chachaRunSimple b12_256_k0_i0 12 32 8) , testCase "20-256-K0-I0" (chachaRunSimple b20_256_k0_i0 20 32 8) , testProperty "generate-combine" chachaGenerateCombine , testProperty "chunking-generate" chachaGenerateChunks , testProperty "chunking-combine" chachaCombineChunks ] where chachaRunSimple expected rounds klen nonceLen = let chacha = ChaCha.initialize rounds (B.replicate klen 0) (B.replicate nonceLen 0) in expected @=? fst (ChaCha.generate chacha (B.length expected)) chachaGenerateChunks :: ChunkingLen -> Vector -> Bool chachaGenerateChunks (ChunkingLen ckLen) (Vector rounds key iv) = let initChaCha = ChaCha.initialize rounds key iv nbBytes = 1048 (expected,_) = ChaCha.generate initChaCha nbBytes chunks = loop nbBytes ckLen initChaCha in expected `propertyEq` B.concat chunks where loop n [] chacha = loop n ckLen chacha loop 0 _ _ = [] loop n (x:xs) chacha = let len = min x n (c, next) = ChaCha.generate chacha len in c : loop (n - len) xs next chachaGenerateCombine :: ChunkingLen0_127 -> Vector -> Int0_2901 -> Bool chachaGenerateCombine (ChunkingLen0_127 ckLen) (Vector rounds key iv) (Int0_2901 nbBytes) = let initChaCha = ChaCha.initialize rounds key iv in loop nbBytes ckLen initChaCha where loop n [] chacha = loop n ckLen chacha loop 0 _ _ = True loop n (x:xs) chacha = let len = min x n (c1, next) = ChaCha.generate chacha len (c2, _) = ChaCha.combine chacha (B.replicate len 0) in if c1 == c2 then loop (n - len) xs next else False chachaCombineChunks :: ChunkingLen0_127 -> Vector -> ArbitraryBS0_2901 -> Bool chachaCombineChunks (ChunkingLen0_127 ckLen) (Vector rounds key iv) (ArbitraryBS0_2901 wholebs) = let initChaCha = ChaCha.initialize rounds key iv (expected,_) = ChaCha.combine initChaCha wholebs chunks = loop wholebs ckLen initChaCha in expected `propertyEq` B.concat chunks where loop bs [] chacha = loop bs ckLen chacha loop bs (x:xs) chacha | B.null bs = [] | otherwise = let (bs1, bs2) = B.splitAt (min x (B.length bs)) bs (c, next) = ChaCha.combine chacha bs1 in c : loop bs2 xs next cryptonite-0.23/tests/ChaChaPoly1305.hs0000644000000000000000000001015512673727640016026 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module ChaChaPoly1305 where import qualified Crypto.Cipher.ChaChaPoly1305 as AEAD import Imports import Crypto.Error import Poly1305 () import qualified Data.ByteString as B import qualified Data.ByteArray as B (convert) plaintext, aad, key, iv, ciphertext, tag, nonce1, nonce2, nonce3, nonce4, nonce5, nonce6, nonce7, nonce8, nonce9, nonce10 :: B.ByteString plaintext = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it." aad = "\x50\x51\x52\x53\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" key = "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f" iv = "\x40\x41\x42\x43\x44\x45\x46\x47" constant = "\x07\x00\x00\x00" ciphertext = "\xd3\x1a\x8d\x34\x64\x8e\x60\xdb\x7b\x86\xaf\xbc\x53\xef\x7e\xc2\xa4\xad\xed\x51\x29\x6e\x08\xfe\xa9\xe2\xb5\xa7\x36\xee\x62\xd6\x3d\xbe\xa4\x5e\x8c\xa9\x67\x12\x82\xfa\xfb\x69\xda\x92\x72\x8b\x1a\x71\xde\x0a\x9e\x06\x0b\x29\x05\xd6\xa5\xb6\x7e\xcd\x3b\x36\x92\xdd\xbd\x7f\x2d\x77\x8b\x8c\x98\x03\xae\xe3\x28\x09\x1b\x58\xfa\xb3\x24\xe4\xfa\xd6\x75\x94\x55\x85\x80\x8b\x48\x31\xd7\xbc\x3f\xf4\xde\xf0\x8e\x4b\x7a\x9d\xe5\x76\xd2\x65\x86\xce\xc6\x4b\x61\x16" tag = "\x1a\xe1\x0b\x59\x4f\x09\xe2\x6a\x7e\x90\x2e\xcb\xd0\x60\x06\x91" nonce1 = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce2 = "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce3 = "\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce4 = "\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" nonce5 = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" nonce6 = "\x00\x00\x00\x00\x00\x00\x00\x00" nonce7 = "\x01\x00\x00\x00\x00\x00\x00\x00" nonce8 = "\xff\x00\x00\x00\x00\x00\x00\x00" nonce9 = "\x00\x01\x00\x00\x00\x00\x00\x00" nonce10 = "\xff\xff\xff\xff\xff\xff\xff\xff" tests = testGroup "ChaChaPoly1305" [ testCase "V1" runEncrypt , testCase "V1-decrypt" runDecrypt , testCase "nonce increment" runNonceInc ] where runEncrypt = let ini = throwCryptoError $ AEAD.initialize key (throwCryptoError $ AEAD.nonce8 constant iv) afterAAD = AEAD.finalizeAAD (AEAD.appendAAD aad ini) (out, afterEncrypt) = AEAD.encrypt plaintext afterAAD outtag = AEAD.finalize afterEncrypt in propertyHoldCase [ eqTest "ciphertext" ciphertext out , eqTest "tag" tag (B.convert outtag) ] runDecrypt = let ini = throwCryptoError $ AEAD.initialize key (throwCryptoError $ AEAD.nonce8 constant iv) afterAAD = AEAD.finalizeAAD (AEAD.appendAAD aad ini) (out, afterDecrypt) = AEAD.decrypt ciphertext afterAAD outtag = AEAD.finalize afterDecrypt in propertyHoldCase [ eqTest "plaintext" plaintext out , eqTest "tag" tag (B.convert outtag) ] runNonceInc = let n1 = throwCryptoError . AEAD.nonce12 $ nonce1 n3 = throwCryptoError . AEAD.nonce12 $ nonce3 n5 = throwCryptoError . AEAD.nonce12 $ nonce5 n6 = throwCryptoError . AEAD.nonce8 constant $ nonce6 n8 = throwCryptoError . AEAD.nonce8 constant $ nonce8 n10 = throwCryptoError . AEAD.nonce8 constant $ nonce10 in propertyHoldCase [ eqTest "nonce12a" nonce2 $ B.convert . AEAD.incrementNonce $ n1 , eqTest "nonce12b" nonce4 $ B.convert . AEAD.incrementNonce $ n3 , eqTest "nonce12c" nonce1 $ B.convert . AEAD.incrementNonce $ n5 , eqTest "nonce8a" (B.concat [constant, nonce7]) $ B.convert . AEAD.incrementNonce $ n6 , eqTest "nonce8b" (B.concat [constant, nonce9]) $ B.convert . AEAD.incrementNonce $ n8 , eqTest "nonce8c" (B.concat [constant, nonce6]) $ B.convert . AEAD.incrementNonce $ n10 ] cryptonite-0.23/tests/Hash.hs0000644000000000000000000005117413063753164014425 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE ExistentialQuantification #-} #if MIN_VERSION_base(4,7,0) {-# LANGUAGE DataKinds #-} #endif module Hash ( tests ) where import Crypto.Hash import qualified Data.ByteString as B import qualified Data.ByteArray.Encoding as B (convertToBase, Base(..)) import Imports v0,v1,v2 :: ByteString v0 = "" v1 = "The quick brown fox jumps over the lazy dog" v2 = "The quick brown fox jumps over the lazy cog" vectors = [ v0, v1, v2 ] instance Arbitrary ByteString where arbitrary = B.pack `fmap` arbitrary data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg expected :: [ (String, HashAlg, [ByteString]) ] expected = [ ("MD2", HashAlg MD2, [ "8350e5a3e24c153df2275c9f80692773", "03d85a0d629d2c442e987525319fc471", "6b890c9292668cdbbfda00a4ebf31f05" ]), ("MD4", HashAlg MD4, [ "31d6cfe0d16ae931b73c59d7e0c089c0", "1bee69a46ba811185c194762abaeae90", "b86e130ce7028da59e672d56ad0113df" ]), ("MD5", HashAlg MD5, [ "d41d8cd98f00b204e9800998ecf8427e", "9e107d9d372bb6826bd81d3542a419d6", "1055d3e698d289f2af8663725127bd4b" ]), ("SHA1", HashAlg SHA1, [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", "de9f2c7fd25e1b3afad3e85a0bd17d9b100db4b3" ]), ("SHA224", HashAlg SHA224, [ "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525", "fee755f44a55f20fb3362cdc3c493615b3cb574ed95ce610ee5b1e9b" ]), ("SHA256", HashAlg SHA256, [ "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", "e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be" ]), ("SHA384", HashAlg SHA384, [ "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", "098cea620b0978caa5f0befba6ddcf22764bea977e1c70b3483edfdf1de25f4b40d6cea3cadf00f809d422feb1f0161b" ]), ("SHA512", HashAlg SHA512, [ "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", "3eeee1d0e11733ef152a6c29503b3ae20c4f1f3cda4cb26f1bc1a41f91c7fe4ab3bd86494049e201c4bd5155f31ecb7a3c8606843c4cc8dfcab7da11c8ae5045" ]), ("SHA512/224", HashAlg SHA512t_224, [ "6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4", "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37", "2b9d6565a7e40f780ba8ab7c8dcf41e3ed3b77997f4c55aa987eede5" ]), ("SHA512/256", HashAlg SHA512t_256, [ "c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a", "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d", "cc8d255a7f2f38fd50388fd1f65ea7910835c5c1e73da46fba01ea50d5dd76fb" ]), ("RIPEMD160", HashAlg RIPEMD160, [ "9c1185a5c5e9fc54612808977ee8f548b2258d31", "37f332f68db77bd9d7edd4969571ad671cf9dd3b", "132072df690933835eb8b6ad0b77e7b6f14acad7" ]), ("Tiger", HashAlg Tiger, [ "3293ac630c13f0245f92bbb1766e16167a4e58492dde73f3", "6d12a41e72e644f017b6f0e2f7b44c6285f06dd5d2c5b075", "a8f04b0f7201a0d728101c9d26525b31764a3493fcd8458f" ]) {- , ("Skein256-160", HashAlg Skein256_160, [ "ff800bed6d2044ee9d604a674e3fda50d9b24a72", "3265703c166aa3e0d7da070b9cf1b1a5953f0a77", "17b29aa1424b3ec022505bd215ff73fd2e6d1e5a" ]) -} , ("Skein256-256", HashAlg Skein256_256, [ "c8877087da56e072870daa843f176e9453115929094c3a40c463a196c29bf7ba", "c0fbd7d779b20f0a4614a66697f9e41859eaf382f14bf857e8cdb210adb9b3fe", "fb2f2f2deed0e1dd7ee2b91cee34e2d1c22072e1f5eaee288c35a0723eb653cd" ]) {- , ("Skein512-160", HashAlg Skein512_160, [ "49daf1ccebb3544bc93cb5019ba91b0eea8876ee", "826325ee55a6dd18c3b2dbbc9c10420f5475975e", "7544ec7a35712ec953f02b0d0c86641cae4eb6e5" ]) -} , ("Skein512-384", HashAlg Skein512_384, [ "dd5aaf4589dc227bd1eb7bc68771f5baeaa3586ef6c7680167a023ec8ce26980f06c4082c488b4ac9ef313f8cbe70808", "f814c107f3465e7c54048a5503547deddc377264f05c706b0d19db4847b354855ee52ab6a785c238c9e710d848542041", "e06520eeadc1d0a44fee1d2492547499c1e58526387c8b9c53905e5edb79f9840575cbf844e21b1ad1ea126dd8a8ca6f" ]) , ("Skein512-512", HashAlg Skein512_512, [ "bc5b4c50925519c290cc634277ae3d6257212395cba733bbad37a4af0fa06af41fca7903d06564fea7a2d3730dbdb80c1f85562dfcc070334ea4d1d9e72cba7a", "94c2ae036dba8783d0b3f7d6cc111ff810702f5c77707999be7e1c9486ff238a7044de734293147359b4ac7e1d09cd247c351d69826b78dcddd951f0ef912713", "7f81113575e4b4d3441940e87aca331e6d63d103fe5107f29cd877af0d0f5e0ea34164258c60da5190189d0872e63a96596d2ef25e709099842da71d64111e0f" ]) {- , ("Skein512-896", HashAlg Skein512_896, [ "b95175236c83a459ce7ec6c12b761a838b22d750e765b3fdaa892201b2aa714bc3d1d887dd64028bbf177c1dd11baa09c6c4ddb598fd07d6a8c131a09fc5b958e2999a8006754b25abe3bf8492b7eabec70e52e04e5ac867df2393c573f16eee3244554f1d2b724f2c0437c62007f770", "3265708553e7d146e5c7bcbc97b3e9e9f5b53a5e4af53612bdd6454da4fa7b13d413184fe34ed57b6574be10e389d0ec4b1d2b1dd2c80e0257d5a76b2cd86a19a27b1bcb3cc24d911b5dc5ee74d19ad558fd85b5f024e99f56d1d3199f1f9f88ed85fab9f945f11cf9fc00e94e3ca4c7", "3d23d3db9be719bbd2119f8402a28f38d8225faa79d5b68b80738c64a82004aafc7a840cd6dd9bced6644fa894a3d8d7d2ee89525fd1956a2db052c4c2f8d2111c91ef46b0997540d42bcf384826af1a5ef6510077f52d0574cf2b46f1b6a5dad07ed40f3d21a13ca2d079fa602ff02d" ]) -} , ("Whirlpool", HashAlg Whirlpool, [ "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", "b97de512e91e3828b40d2b0fdce9ceb3c4a71f9bea8d88e75c4fa854df36725fd2b52eb6544edcacd6f8beddfea403cb55ae31f03ad62a5ef54e42ee82c3fb35", "dce81fc695cfea3d7e1446509238daf89f24cc61896f2d265927daa70f2108f8902f0dfd68be085d5abb9fcd2e482c1dc24f2fabf81f40b73495cad44d7360d3"]) , ("Keccak-224", HashAlg Keccak_224, [ "f71837502ba8e10837bdd8d365adb85591895602fc552b48b7390abd", "310aee6b30c47350576ac2873fa89fd190cdc488442f3ef654cf23fe", "0b27ff3b732133287f6831e2af47cf342b7ef1f3fcdee248811090cd" ]) , ("Keccak-256", HashAlg Keccak_256, [ "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "4d741b6f1eb29cb2a9b9911c82f56fa8d73b04959d3d9d222895df6c0b28aa15", "ed6c07f044d7573cc53bf1276f8cba3dac497919597a45b4599c8f73e22aa334" ]) , ("Keccak-384", HashAlg Keccak_384, [ "2c23146a63a29acf99e73b88f8c24eaa7dc60aa771780ccc006afbfa8fe2479b2dd2b21362337441ac12b515911957ff", "283990fa9d5fb731d786c5bbee94ea4db4910f18c62c03d173fc0a5e494422e8a0b3da7574dae7fa0baf005e504063b3", "1cc515e1812491058d8b8b226fd85045e746b4937a58b0111b6b7a39dd431b6295bd6b6d05e01e225586b4dab3cbb87a" ]) , ("Keccak-512", HashAlg Keccak_512, [ "0eab42de4c3ceb9235fc91acffe746b29c29a8c366b7c60e4e67c466f36a4304c00fa9caf9d87976ba469bcbe06713b435f091ef2769fb160cdab33d3670680e", "d135bb84d0439dbac432247ee573a23ea7d3c9deb2a968eb31d47c4fb45f1ef4422d6c531b5b9bd6f449ebcc449ea94d0a8f05f62130fda612da53c79659f609", "10f8caabb5b179861da5e447d34b84d604e3eb81830880e1c2135ffc94580a47cb21f6243ec0053d58b1124d13af2090033659075ee718e0f111bb3f69fb24cf" ]) , ("SHA3-224", HashAlg SHA3_224, [ "6b4e03423667dbb73b6e15454f0eb1abd4597f9a1b078e3f5b5a6bc7", "d15dadceaa4d5d7bb3b48f446421d542e08ad8887305e28d58335795", "b770eb6ac3ac52bd2f9e8dc186d6b604e7c3b7ffc8bd9220b0078ced" ]) , ("SHA3-256", HashAlg SHA3_256, [ "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a", "69070dda01975c8c120c3aada1b282394e7f032fa9cf32f4cb2259a0897dfc04", "cc80b0b13ba89613d93f02ee7ccbe72ee26c6edfe577f22e63a1380221caedbc" ]) , ("SHA3-384", HashAlg SHA3_384, [ "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004", "7063465e08a93bce31cd89d2e3ca8f602498696e253592ed26f07bf7e703cf328581e1471a7ba7ab119b1a9ebdf8be41", "e414797403c7d01ab64b41e90df4165d59b7f147e4292ba2da336acba242fd651949eb1cfff7e9012e134b40981842e1" ]) , ("SHA3-512", HashAlg SHA3_512, [ "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26", "01dedd5de4ef14642445ba5f5b97c15e47b9ad931326e4b0727cd94cefc44fff23f07bf543139939b49128caf436dc1bdee54fcb24023a08d9403f9b4bf0d450", "28e361fe8c56e617caa56c28c7c36e5c13be552b77081be82b642f08bb7ef085b9a81910fe98269386b9aacfd2349076c9506126e198f6f6ad44c12017ca77b1" ]) , ("Blake2b-160", HashAlg Blake2b_160, [ "3345524abf6bbe1809449224b5972c41790b6cf2", "3c523ed102ab45a37d54f5610d5a983162fde84f", "a3d365b5fba5d36fbb19c03b7fde496058969c5a" ]) , ("Blake2b-224", HashAlg Blake2b_224, [ "836cc68931c2e4e3e838602eca1902591d216837bafddfe6f0c8cb07", "477c3985751dd4d1b8c93827ea5310b33bb02a26463a050dffd3e857", "a4a1b6851be66891a3deff406c4d7556879ebf952407450755f90eb6" ]) , ("Blake2b-256", HashAlg Blake2b_256, [ "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", "01718cec35cd3d796dd00020e0bfecb473ad23457d063b75eff29c0ffa2e58a9", "036c13096926b3dfccfe3f233bd1b2f583b818b8b15c01be65af69238e900b2c" ]) , ("Blake2b-384", HashAlg Blake2b_384, [ "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", "b7c81b228b6bd912930e8f0b5387989691c1cee1e65aade4da3b86a3c9f678fc8018f6ed9e2906720c8d2a3aeda9c03d", "927a1f297873cbe887a93b2183c4e2eba53966ba92c6db8b87029a1d8c673471d09740676cced79c5016838973f630c3" ]) , ("Blake2b-512", HashAlg Blake2b_512, [ "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918", "af438eea5d8cdb209336a7e85bf58090dc21b49d823f89a7d064c119f127bd361af9c7d109edda0f0e91bdce078d1d86b8e6f25727c98f6d3bb6f50acb2dd376" ]) , ("Blake2s-160", HashAlg Blake2s_160, [ "354c9c33f735962418bdacb9479873429c34916f", "5a604fec9713c369e84b0ed68daed7d7504ef240", "759bef6d041bcbd861b8b51baaece6c8fffd0acf" ]) , ("Blake2s-224", HashAlg Blake2s_224, [ "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", "e4e5cb6c7cae41982b397bf7b7d2d9d1949823ae78435326e8db4912", "e220025fd46a9a635c3f7f60bb96a84c01019ac0817f5901e7eeaa2c" ]) , ("Blake2s-256", HashAlg Blake2s_256, [ "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", "606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812", "94662583a600a12dff357c0a6f1b514a710ef0f587a38e8d2e4d7f67e9c81667" ]) #if MIN_VERSION_base(4,7,0) , ("SHAKE128_4096", HashAlg (SHAKE128 :: SHAKE128 4096), [ "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef263cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e235b8cc873c23dc62b8d260169afa2f75ab916a58d974918835d25e6a435085b2badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea17cda7cfad765f5623474d368ccca8af0007cd9f5e4c849f167a580b14aabdefaee7eef47cb0fca9767be1fda69419dfb927e9df07348b196691abaeb580b32def58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c922a96188d032675c8ac850933c7aff1533b94c834adbb69c6115bad4692d8619f90b0cdf8a7b9c264029ac185b70b83f2801f2f4b3f70c593ea3aeeb613a7f1b1de33fd75081f592305f2e4526edc09631b10958f464d889f31ba010250fda7f1368ec2967fc84ef2ae9aff268e0b1700affc6820b523a3d917135f2dff2ee06bfe72b3124721d4a26c04e53a75e30e73a7a9c4a95d91c55d495e9f51dd0b5e9d83c6d5e8ce803aa62b8d654db53d09b8dcff273cdfeb573fad8bcd45578bec2e770d01efde86e721a3f7c6cce275dabe6e2143f1af18da7efddc4c7b70b5e345db93cc936bea323491ccb38a388f546a9ff00dd4e1300b9b2153d2041d205b443e41b45a653f2a5c4492c1add544512dda2529833462b71a41a45be97290b6f", "f4202e3c5852f9182a0430fd8144f0a74b95e7417ecae17db0f8cfeed0e3e66eb5585ec6f86021cacf272c798bcf97d368b886b18fec3a571f096086a523717a3732d50db2b0b7998b4117ae66a761ccf1847a1616f4c07d5178d0d965f9feba351420f8bfb6f5ab9a0cb102568eabf3dfa4e22279f8082dce8143eb78235a1a54914ab71abb07f2f3648468370b9fbb071e074f1c030a4030225f40c39480339f3dc71d0f04f71326de1381674cc89e259e219927fae8ea2799a03da862a55afafe670957a2af3318d919d0a3358f3b891236d6a8e8d19999d1076b529968faefbd880d77bb300829dca87e9c8e4c28e0800ff37490a5bd8c36c0b0bdb2701a5d58d03378b9dbd384389e3ef0fd4003b08998fd3f32fe1a0810fc0eccaad94bca8dd83b34559c333f0b16dfc2896ed87b30ba14c81f87cd8b4bb6317db89b0e7e94c0616f9a665fba5b0e6fb3549c9d7b68e66d08a86eb2faec05cc462a771806b93cc38b0a4feb9935c6c8945da6a589891ba5ee99753cfdd38e1abc7147fd74b7c7d1ce0609b6680a2e18888d84949b6e6cf6a2aa4113535aaee079459e3f257b569a9450523c41f5b5ba4b79b3ba5949140a74bb048de0657d04954bdd71dae76f61e2a1f88aecb91cfa5b36c1bf3350a798dc4dcf48628effe3a0c5340c756bd922f78d0e36ef7df12ce78c179cc721ad087e15ea496bf5f60b21b5822d", "22fd225fb8f2c8d0d2097e1f8d38b6a9e619d39664dad3795f0336fda544d305e1be56a9953ecd6e4bec14b622f53da492eccbe257b9af84775a6bdf81aab6b1ba3492149b7ce4ea402c56e343939f78b9a9727193269798420c9323a9eb1fa63006e1482fcf15e3696aa1ae5cb66eb8aad4ac6041ca0b576b78785ad95bc5fb6f8a420ba9e1726552c0f2b97050ae69fc018d3f63b3a812a2d39ef64b8ae368472dec4341511b02cf77363c74f216055d5905412bc2bf57b4010b1bdce2882cb28fc7e4d470ed05219fc4d1ce11d11e10db369c807cd71891653638956b2f9d176e116188aff2fbb8519d9ad8c3fb52fa8bb4a0413364e89d9f9d7db627f2a2288babedcc314a19e45c6b7fb93b16a15d9953ff619ab4d523c481552588f711b450f854c858ebcb8cf49492d6240a753bde2109c486cac666bdba767c6e9254cc723f67855534c34d08ed486c67c1b8dd288c6010ce8e6c1c9b7f927acf4d71ee99729cee55ecec544245d0b51b31dd78eb99c2723e8ba5cf92ac7720e8933d9fd3596b90073f6980c5ed3f1cbfada26bdb6946e72391198e3d1cedebdba092324500e32b8e04e32550f6dd6c4befafa95acc206c5708300d2a8df2765751102f9738a1449c4c0d588f0076d0c1a5ee445eb85c97ada5837d5dc1d34ea081c8411d64a4d9ce9279bfe9feb25696cf741c705ed46f171e2239216d6c45dc8d15" ]) , ("SHAKE256_4096", HashAlg (SHAKE256 :: SHAKE256 4096), [ "46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762fd75dc4ddd8c0f200cb05019d67b592f6fc821c49479ab48640292eacb3b7c4be141e96616fb13957692cc7edd0b45ae3dc07223c8e92937bef84bc0eab862853349ec75546f58fb7c2775c38462c5010d846c185c15111e595522a6bcd16cf86f3d122109e3b1fdd943b6aec468a2d621a7c06c6a957c62b54dafc3be87567d677231395f6147293b68ceab7a9e0c58d864e8efde4e1b9a46cbe854713672f5caaae314ed9083dab4b099f8e300f01b8650f1f4b1d8fcf3f3cb53fb8e9eb2ea203bdc970f50ae55428a91f7f53ac266b28419c3778a15fd248d339ede785fb7f5a1aaa96d313eacc890936c173cdcd0fab882c45755feb3aed96d477ff96390bf9a66d1368b208e21f7c10d04a3dbd4e360633e5db4b602601c14cea737db3dcf722632cc77851cbdde2aaf0a33a07b373445df490cc8fc1e4160ff118378f11f0477de055a81a9eda57a4a2cfb0c83929d310912f729ec6cfa36c6ac6a75837143045d791cc85eff5b21932f23861bcf23a52b5da67eaf7baae0f5fb1369db78f3ac45f8c4ac5671d85735cdddb09d2b1e34a1fc066ff4a162cb263d6541274ae2fcc865f618abe27c124cd8b074ccd516301b91875824d09958f341ef274bdab0bae316339894304e35877b0c28a9b1fd166c796b9cc258a064a8f57e27f2a", "2f671343d9b2e1604dc9dcf0753e5fe15c7c64a0d283cbbf722d411a0e36f6ca1d01d1369a23539cd80f7c054b6e5daf9c962cad5b8ed5bd11998b40d5734442bed798f6e5c915bd8bb07e0188d0a55c1290074f1c287af06352299184492cbdec9acba737ee292e5adaa445547355e72a03a3bac3aac770fe5d6b66600ff15d37d5b4789994ea2aeb097f550aa5e88e4d8ff0ba07b88c1c88573063f5d96df820abc2abd177ab037f351c375e553af917132cf2f563c79a619e1bb76e8e2266b0c5617d695f2c496a25f4073b6840c1833757ebb386f16757a8e16a21e9355e9b248f3b33be672da700266be99b8f8725e8ab06075f0219e655ebc188976364b7db139390d34a6ea67b4b223229183a94cf455ece91fdaf5b9c707fa4b40ec39816c1120c7aaaf47920977be900e6b9ca4b8940e192b927c475bd58e836f512ae3e52924e36ff8e9b1d0251047770a5e465905622b1f159be121ab93819c5e5c6dae299ac73bf1c4ed4a1e2c7fa3caa1039b05e94c9f993d04feb272b6e00bb0276939cf746c42936831fc8f2b4cb0cf94808ae0af405ce4bc67d1e7acfc6fd6590d3de91f795df5aaf57e2cee1845a303d0ea564be3f1299acdce67efe0d62cfc6d6829ff4ecc0a05153c24696c4d34c076453827e796f3062f94f62f4528b7cfc870f0dcd615b7c97b95da4b9be5830e8b3f66cce71e0f622c771994443e2", "fffcaac0606c0edb7bc0d15f033accb68538159016e5ae8470bf9ebea89fa6c9fcc3e027d94f7f967b7246346bd9f6b8084e45a057b976847c4db03bf383c834054866f6a8282a497368c46e1852fc09e20f22c45607a27c8b2a4798ebefada54f8d3795b9f07606b1cd6e41f90d765480ef5c0d5790659cf1d210adfd412378b92e1dd9bd7fd95a1a66677fc6baa0e3a53c9031c1fb59cbad9f5dc5881a3c8e25c80ecb1abf0971488ada1f533dcbf8d37031335378574b8d3fad61159c9fae28caa543b3072ce308d369be340e78c6edc664cc6dde9b2f0a4ad2e60ce9c8b1e5722b8d5b73d0962b74fb9ed86307a180f53933339f9d56d3b345c2a0e98fcf5de7754f3845f6be30089f0e142ad4602f18abdc750bda7c91c3f32872e66640db46045ab4c276b379f1b834c2cbb1bd8601305649ec6b3bf20618695136dee6541492d1d985ea1fb765fd7a559e810eba30f2f710233ae5a411b94ddcaa01a08f1c31320d111c0714422cd5e987c9a76fc865de34003ab12664081be8017d23d977f2bf4ed9e3ce09ea3d64bb4ae8ebfa9d0721f57841008c297e2f455a0441a2bd618ca379dbd239a21e410defb4001b1e11f87e36bf894c222f76f12ddcc3771bbb17d5c0dfd86d89a3e13e084f6dc1c4762bcd393c1757db7afb1434221569e7ddaaffd6318253ec3df8cf5f826b81896d6474ee06a2e30ccc8c6a96bdd5" ]) , ("Blake2b 160", HashAlg (Blake2b :: Blake2b 160), [ "3345524abf6bbe1809449224b5972c41790b6cf2", "3c523ed102ab45a37d54f5610d5a983162fde84f", "a3d365b5fba5d36fbb19c03b7fde496058969c5a" ]) , ("Blake2b 224", HashAlg (Blake2b :: Blake2b 224), [ "836cc68931c2e4e3e838602eca1902591d216837bafddfe6f0c8cb07", "477c3985751dd4d1b8c93827ea5310b33bb02a26463a050dffd3e857", "a4a1b6851be66891a3deff406c4d7556879ebf952407450755f90eb6" ]) , ("Blake2b 256", HashAlg (Blake2b :: Blake2b 256), [ "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8", "01718cec35cd3d796dd00020e0bfecb473ad23457d063b75eff29c0ffa2e58a9", "036c13096926b3dfccfe3f233bd1b2f583b818b8b15c01be65af69238e900b2c" ]) , ("Blake2b 384", HashAlg (Blake2b :: Blake2b 384), [ "b32811423377f52d7862286ee1a72ee540524380fda1724a6f25d7978c6fd3244a6caf0498812673c5e05ef583825100", "b7c81b228b6bd912930e8f0b5387989691c1cee1e65aade4da3b86a3c9f678fc8018f6ed9e2906720c8d2a3aeda9c03d", "927a1f297873cbe887a93b2183c4e2eba53966ba92c6db8b87029a1d8c673471d09740676cced79c5016838973f630c3" ]) , ("Blake2b 512", HashAlg (Blake2b :: Blake2b 512), [ "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce", "a8add4bdddfd93e4877d2746e62817b116364a1fa7bc148d95090bc7333b3673f82401cf7aa2e4cb1ecd90296e3f14cb5413f8ed77be73045b13914cdcd6a918", "af438eea5d8cdb209336a7e85bf58090dc21b49d823f89a7d064c119f127bd361af9c7d109edda0f0e91bdce078d1d86b8e6f25727c98f6d3bb6f50acb2dd376" ]) , ("Blake2s 160", HashAlg (Blake2s :: Blake2s 160), [ "354c9c33f735962418bdacb9479873429c34916f", "5a604fec9713c369e84b0ed68daed7d7504ef240", "759bef6d041bcbd861b8b51baaece6c8fffd0acf" ]) , ("Blake2s 224", HashAlg (Blake2s :: Blake2s 224), [ "1fa1291e65248b37b3433475b2a0dd63d54a11ecc4e3e034e7bc1ef4", "e4e5cb6c7cae41982b397bf7b7d2d9d1949823ae78435326e8db4912", "e220025fd46a9a635c3f7f60bb96a84c01019ac0817f5901e7eeaa2c" ]) , ("Blake2s 256", HashAlg (Blake2s ::Blake2s 256), [ "69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9", "606beeec743ccbeff6cbcdf5d5302aa855c256c29b88c8ed331ea1a6bf3c8812", "94662583a600a12dff357c0a6f1b514a710ef0f587a38e8d2e4d7f67e9c81667" ]) #endif ] runhash :: HashAlg -> ByteString -> ByteString runhash (HashAlg hashAlg) v = B.convertToBase B.Base16 $ hashWith hashAlg $ v runhashinc :: HashAlg -> [ByteString] -> ByteString runhashinc (HashAlg hashAlg) v = B.convertToBase B.Base16 $ hashinc $ v where hashinc = hashFinalize . foldl hashUpdate (hashInitWith hashAlg) makeTestAlg (name, hashAlg, results) = testGroup name $ concatMap maketest (zip3 is vectors results) where is :: [Int] is = [1..] maketest (i, v, r) = [ testCase (show i) (r @=? runhash hashAlg v) ] makeTestChunk (hashName, hashAlg, _) = [ testProperty hashName $ \ckLen (ArbitraryBS0_2901 inp) -> runhash hashAlg inp `propertyEq` runhashinc hashAlg (chunkS ckLen inp) ] tests = testGroup "hash" [ testGroup "KATs" (map makeTestAlg expected) , testGroup "Chunking" (concatMap makeTestChunk expected) ] cryptonite-0.23/tests/Imports.hs0000644000000000000000000000075412510212375015163 0ustar0000000000000000module Imports ( -- * Individual Types Word16, Word32, Word64 , ByteString -- * Modules , module X ) where import Data.Word (Word16, Word32, Word64) import Data.ByteString (ByteString) import Control.Applicative as X import Control.Monad as X import Data.Foldable as X (foldl') import Data.Monoid as X import Data.ByteString.Char8 as X () import Test.Tasty as X import Test.Tasty.HUnit as X import Test.Tasty.QuickCheck as X hiding (vector) import Utils as X cryptonite-0.23/tests/KAT_AES.hs0000644000000000000000000000566112522370606014644 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES (tests) where import Imports import BlockCipher import Crypto.Cipher.Types import qualified Crypto.Cipher.AES as AES import qualified KAT_AES.KATECB as KATECB import qualified KAT_AES.KATCBC as KATCBC import qualified KAT_AES.KATXTS as KATXTS import qualified KAT_AES.KATGCM as KATGCM import qualified KAT_AES.KATOCB3 as KATOCB3 {- instance Show AES.AES where show _ = "AES" instance Arbitrary AES.AESIV where arbitrary = AES.aesIV_ . B.pack <$> replicateM 16 arbitrary instance Arbitrary AES.AES where arbitrary = AES.initAES . B.pack <$> replicateM 16 arbitrary -} toKatECB (k,p,c) = KAT_ECB { ecbKey = k, ecbPlaintext = p, ecbCiphertext = c } toKatCBC (k,iv,p,c) = KAT_CBC { cbcKey = k, cbcIV = iv, cbcPlaintext = p, cbcCiphertext = c } toKatXTS (k1,k2,iv,p,_,c) = KAT_XTS { xtsKey1 = k1, xtsKey2 = k2, xtsIV = iv, xtsPlaintext = p, xtsCiphertext = c } toKatAEAD mode (k,iv,h,p,c,taglen,tag) = KAT_AEAD { aeadMode = mode , aeadKey = k , aeadIV = iv , aeadHeader = h , aeadPlaintext = p , aeadCiphertext = c , aeadTaglen = taglen , aeadTag = tag } toKatGCM = toKatAEAD AEAD_GCM toKatOCB = toKatAEAD AEAD_OCB kats128 = defaultKATs { kat_ECB = map toKatECB KATECB.vectors_aes128_enc , kat_CBC = map toKatCBC KATCBC.vectors_aes128_enc , kat_CFB = [ KAT_CFB { cfbKey = "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c" , cfbIV = "\xC8\xA6\x45\x37\xA0\xB3\xA9\x3F\xCD\xE3\xCD\xAD\x9F\x1C\xE5\x8B" , cfbPlaintext = "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" , cfbCiphertext = "\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" } ] , kat_XTS = map toKatXTS KATXTS.vectors_aes128_enc , kat_AEAD = map toKatGCM KATGCM.vectors_aes128_enc ++ map toKatOCB KATOCB3.vectors_aes128_enc } kats192 = defaultKATs { kat_ECB = map toKatECB KATECB.vectors_aes192_enc , kat_CBC = map toKatCBC KATCBC.vectors_aes192_enc } kats256 = defaultKATs { kat_ECB = map toKatECB KATECB.vectors_aes256_enc , kat_CBC = map toKatCBC KATCBC.vectors_aes256_enc , kat_XTS = map toKatXTS KATXTS.vectors_aes256_enc , kat_AEAD = map toKatGCM KATGCM.vectors_aes256_enc } tests = testGroup "AES" [ testBlockCipher kats128 (undefined :: AES.AES128) , testBlockCipher kats192 (undefined :: AES.AES192) , testBlockCipher kats256 (undefined :: AES.AES256) {- , testProperty "genCtr" $ \(key, iv1) -> let (bs1, iv2) = AES.genCounter key iv1 32 (bs2, iv3) = AES.genCounter key iv2 32 (bsAll, iv3') = AES.genCounter key iv1 64 in (B.concat [bs1,bs2] == bsAll && iv3 == iv3') -} ] cryptonite-0.23/tests/KAT_AFIS.hs0000644000000000000000000000360512524377653014765 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ExistentialQuantification #-} module KAT_AFIS (tests) where import Imports import Crypto.Hash import Crypto.Random import qualified Crypto.Data.AFIS as AFIS import qualified Data.ByteString as B mergeVec :: [ (Int, SHA1, B.ByteString, B.ByteString) ] mergeVec = [ (3 , SHA1 , "\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02" , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\xd4\x76\xc8\x58\xbd\xf0\x15\xbe\x9f\x40\xe3\x65\x20\x1c\x9c\xb8\xd8\x1c\x16\x64" ) , (3 , SHA1 , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17" , "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\xd6\x75\xc8\x59\xbb\xf7\x11\xbb\x95\x4b\xeb\x6c\x2e\x13\x90\xb5\xca\x0f\x06\x75\x17\x70\x39\x28" ) ] mergeKATs = map toProp $ zip mergeVec [(0 :: Int)..] where toProp ((nbExpands, hashAlg, expected, dat), i) = testCase ("merge " ++ show i) (expected @=? AFIS.merge hashAlg nbExpands dat) data AFISParams = AFISParams B.ByteString Int SHA1 ChaChaDRG instance Show AFISParams where show (AFISParams dat expand _ _) = "data: " ++ show dat ++ " expanded: " ++ show expand instance Arbitrary AFISParams where arbitrary = AFISParams <$> arbitraryBSof 3 46 <*> choose (2,2) <*> elements [SHA1] <*> arbitrary instance Arbitrary ChaChaDRG where arbitrary = drgNewTest <$> arbitrary tests = testGroup "AFIS" [ testGroup "KAT merge" mergeKATs , testProperty "merge.split == id" $ \(AFISParams bs e hf rng) -> bs == (AFIS.merge hf e $ fst (AFIS.split hf rng e bs)) ] cryptonite-0.23/tests/KAT_Argon2.hs0000644000000000000000000000232013054050744015350 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Argon2 (tests) where import Crypto.Error import qualified Crypto.KDF.Argon2 as Argon2 import qualified Data.ByteString as B import Imports data KDFVector = KDFVector { kdfPass :: ByteString , kdfSalt :: ByteString , kdfOptions :: Argon2.Options , kdfResult :: ByteString } argon2i_13 :: Argon2.TimeCost -> Argon2.MemoryCost -> Argon2.Options argon2i_13 iters memory = Argon2.Options { Argon2.iterations = iters , Argon2.memory = memory , Argon2.parallelism = 1 , Argon2.variant = Argon2.Argon2i , Argon2.version = Argon2.Version13 } vectors = [ KDFVector "password" "somesalt" (argon2i_13 2 65536) "\xc1\x62\x88\x32\x14\x7d\x97\x20\xc5\xbd\x1c\xfd\x61\x36\x70\x78\x72\x9f\x6d\xfb\x6f\x8f\xea\x9f\xf9\x81\x58\xe0\xd7\x81\x6e\xd0" ] kdfTests :: [TestTree] kdfTests = map toKDFTest $ zip is vectors where toKDFTest (i, v) = testCase (show i) (CryptoPassed (kdfResult v) @=? Argon2.hash (kdfOptions v) (kdfPass v) (kdfSalt v) (B.length $ kdfResult v)) is :: [Int] is = [1..] tests = testGroup "Argon2" [ testGroup "KATs" kdfTests ] cryptonite-0.23/tests/KAT_Blowfish.hs0000644000000000000000000001034212512146401015772 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Blowfish where import Crypto.Cipher.Blowfish import Imports () import BlockCipher vectors_ecb = -- key plaintext cipher [ KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x4E\xF9\x97\x45\x61\x98\xDD\x78" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x51\x86\x6F\xD5\xB8\x5E\xCB\x8A" , KAT_ECB "\x30\x00\x00\x00\x00\x00\x00\x00" "\x10\x00\x00\x00\x00\x00\x00\x01" "\x7D\x85\x6F\x9A\x61\x30\x63\xF2" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x24\x66\xDD\x87\x8B\x96\x3C\x9D" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x61\xF9\xC3\x80\x22\x81\xB0\x96" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x7D\x0C\xC6\x30\xAF\xDA\x1E\xC7" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x4E\xF9\x97\x45\x61\x98\xDD\x78" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x0A\xCE\xAB\x0F\xC6\xA0\xA2\x8D" , KAT_ECB "\x7C\xA1\x10\x45\x4A\x1A\x6E\x57" "\x01\xA1\xD6\xD0\x39\x77\x67\x42" "\x59\xC6\x82\x45\xEB\x05\x28\x2B" , KAT_ECB "\x01\x31\xD9\x61\x9D\xC1\x37\x6E" "\x5C\xD5\x4C\xA8\x3D\xEF\x57\xDA" "\xB1\xB8\xCC\x0B\x25\x0F\x09\xA0" , KAT_ECB "\x07\xA1\x13\x3E\x4A\x0B\x26\x86" "\x02\x48\xD4\x38\x06\xF6\x71\x72" "\x17\x30\xE5\x77\x8B\xEA\x1D\xA4" , KAT_ECB "\x38\x49\x67\x4C\x26\x02\x31\x9E" "\x51\x45\x4B\x58\x2D\xDF\x44\x0A" "\xA2\x5E\x78\x56\xCF\x26\x51\xEB" , KAT_ECB "\x04\xB9\x15\xBA\x43\xFE\xB5\xB6" "\x42\xFD\x44\x30\x59\x57\x7F\xA2" "\x35\x38\x82\xB1\x09\xCE\x8F\x1A" , KAT_ECB "\x01\x13\xB9\x70\xFD\x34\xF2\xCE" "\x05\x9B\x5E\x08\x51\xCF\x14\x3A" "\x48\xF4\xD0\x88\x4C\x37\x99\x18" , KAT_ECB "\x01\x70\xF1\x75\x46\x8F\xB5\xE6" "\x07\x56\xD8\xE0\x77\x47\x61\xD2" "\x43\x21\x93\xB7\x89\x51\xFC\x98" , KAT_ECB "\x43\x29\x7F\xAD\x38\xE3\x73\xFE" "\x76\x25\x14\xB8\x29\xBF\x48\x6A" "\x13\xF0\x41\x54\xD6\x9D\x1A\xE5" , KAT_ECB "\x07\xA7\x13\x70\x45\xDA\x2A\x16" "\x3B\xDD\x11\x90\x49\x37\x28\x02" "\x2E\xED\xDA\x93\xFF\xD3\x9C\x79" , KAT_ECB "\x04\x68\x91\x04\xC2\xFD\x3B\x2F" "\x26\x95\x5F\x68\x35\xAF\x60\x9A" "\xD8\x87\xE0\x39\x3C\x2D\xA6\xE3" , KAT_ECB "\x37\xD0\x6B\xB5\x16\xCB\x75\x46" "\x16\x4D\x5E\x40\x4F\x27\x52\x32" "\x5F\x99\xD0\x4F\x5B\x16\x39\x69" , KAT_ECB "\x1F\x08\x26\x0D\x1A\xC2\x46\x5E" "\x6B\x05\x6E\x18\x75\x9F\x5C\xCA" "\x4A\x05\x7A\x3B\x24\xD3\x97\x7B" , KAT_ECB "\x58\x40\x23\x64\x1A\xBA\x61\x76" "\x00\x4B\xD6\xEF\x09\x17\x60\x62" "\x45\x20\x31\xC1\xE4\xFA\xDA\x8E" , KAT_ECB "\x02\x58\x16\x16\x46\x29\xB0\x07" "\x48\x0D\x39\x00\x6E\xE7\x62\xF2" "\x75\x55\xAE\x39\xF5\x9B\x87\xBD" , KAT_ECB "\x49\x79\x3E\xBC\x79\xB3\x25\x8F" "\x43\x75\x40\xC8\x69\x8F\x3C\xFA" "\x53\xC5\x5F\x9C\xB4\x9F\xC0\x19" , KAT_ECB "\x4F\xB0\x5E\x15\x15\xAB\x73\xA7" "\x07\x2D\x43\xA0\x77\x07\x52\x92" "\x7A\x8E\x7B\xFA\x93\x7E\x89\xA3" , KAT_ECB "\x49\xE9\x5D\x6D\x4C\xA2\x29\xBF" "\x02\xFE\x55\x77\x81\x17\xF1\x2A" "\xCF\x9C\x5D\x7A\x49\x86\xAD\xB5" , KAT_ECB "\x01\x83\x10\xDC\x40\x9B\x26\xD6" "\x1D\x9D\x5C\x50\x18\xF7\x28\xC2" "\xD1\xAB\xB2\x90\x65\x8B\xC7\x78" , KAT_ECB "\x1C\x58\x7F\x1C\x13\x92\x4F\xEF" "\x30\x55\x32\x28\x6D\x6F\x29\x5A" "\x55\xCB\x37\x74\xD1\x3E\xF2\x01" , KAT_ECB "\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xFA\x34\xEC\x48\x47\xB2\x68\xB2" , KAT_ECB "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xA7\x90\x79\x51\x08\xEA\x3C\xAE" , KAT_ECB "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xC3\x9E\x07\x2D\x9F\xAC\x63\x1D" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x01\x49\x33\xE0\xCD\xAF\xF6\xE4" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\xF2\x1E\x9A\x77\xB7\x1C\x49\xBC" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x24\x59\x46\x88\x57\x54\x36\x9A" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x6B\x5C\x5A\x9C\x5D\x9E\x0A\x5A" ] kats = defaultKATs { kat_ECB = vectors_ecb } tests = testBlockCipher kats (undefined :: Blowfish64) cryptonite-0.23/tests/KAT_Camellia.hs0000644000000000000000000000337712512146401015736 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} {-# OPTIONS_GHC -fno-warn-unused-binds #-} {-# OPTIONS_GHC -fno-warn-unused-matches #-} module KAT_Camellia (tests) where import Imports () import BlockCipher import qualified Data.ByteString as B import Crypto.Cipher.Camellia vectors_camellia128 = [ KAT_ECB (B.replicate 16 0) (B.replicate 16 0) (B.pack [0x3d,0x02,0x80,0x25,0xb1,0x56,0x32,0x7c,0x17,0xf7,0x62,0xc1,0xf2,0xcb,0xca,0x71]) , KAT_ECB (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43]) ] vectors_camellia192 = [ KAT_ECB (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77]) (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9]) ] vectors_camellia256 = [ KAT_ECB (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 ,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff]) (B.pack [0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10]) (B.pack [0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09]) ] kats128 = defaultKATs { kat_ECB = vectors_camellia128 } kats192 = defaultKATs { kat_ECB = vectors_camellia192 } kats256 = defaultKATs { kat_ECB = vectors_camellia256 } tests = testBlockCipher kats128 (undefined :: Camellia128) cryptonite-0.23/tests/KAT_CMAC.hs0000644000000000000000000001426712702145361014737 0ustar0000000000000000 module KAT_CMAC (tests) where import qualified Crypto.MAC.CMAC as CMAC import Crypto.Cipher.Types (Cipher, cipherInit, BlockCipher, ecbEncrypt, blockSize) import Crypto.Error (eitherCryptoError) import Crypto.Cipher.AES (AES128, AES192, AES256) import Crypto.Cipher.TripleDES (DES_EDE3, DES_EDE2) import Imports import Data.Char (digitToInt) import qualified Data.ByteString as BS import qualified Data.ByteArray as B hxs :: String -> ByteString hxs = BS.pack . rec' where dtoW8 = fromIntegral . digitToInt rec' (' ':xs) = rec' xs rec' (x:y:xs) = dtoW8 x * 16 + dtoW8 y : rec' xs rec' [_] = error "hxs: invalid hex pattern." rec' [] = [] unsafeCipher :: Cipher k => ByteString -> k unsafeCipher = either (error . show) id . eitherCryptoError . cipherInit ecb0 :: BlockCipher k => k -> ByteString ecb0 k = ecbEncrypt k $ BS.replicate (blockSize k) 0 {- Test vectors from NIST data-sheet (AES128-CMAC, AES192-CMAC, AES256-CMAC, Three Key TDEA, Two Key TDEA) http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf The data of AES128-CMAC is same as them in RFC4493. -} msg512 :: ByteString msg512 = hxs $ "6bc1bee2 2e409f96 e93d7e11 7393172a" ++ "ae2d8a57 1e03ac9c 9eb76fac 45af8e51" ++ "30c81c46 a35ce411 e5fbc119 1a0a52ef" ++ "f69f2445 df4f9b17 ad2b417b e66c3710" msg320 :: ByteString msg320 = BS.take 40 msg512 msg256 :: ByteString msg256 = BS.take 32 msg512 msg160 :: ByteString msg160 = BS.take 20 msg512 msg128 :: ByteString msg128 = BS.take 16 msg512 msg64 :: ByteString msg64 = BS.take 8 msg512 msg0 :: ByteString msg0 = BS.empty bsCMAC :: BlockCipher k => k -> ByteString -> ByteString bsCMAC k = B.convert . CMAC.cmac k gAES128 :: TestTree gAES128 = igroup "aes128" [ ecb0 aes128key @?= hxs "7df76b0c 1ab899b3 3e42f047 b91b546f" , aes128k1 @?= hxs "fbeed618 35713366 7c85e08f 7236a8de" , aes128k2 @?= hxs "f7ddac30 6ae266cc f90bc11e e46d513b" , bsCMAC aes128key msg0 @?= hxs "bb1d6929 e9593728 7fa37d12 9b756746" , bsCMAC aes128key msg128 @?= hxs "070a16b4 6b4d4144 f79bdd9d d04a287c" , bsCMAC aes128key msg320 @?= hxs "dfa66747 de9ae630 30ca3261 1497c827" , bsCMAC aes128key msg512 @?= hxs "51f0bebf 7e3b9d92 fc497417 79363cfe" ] where aes128key :: AES128 aes128key = unsafeCipher $ hxs "2b7e1516 28aed2a6 abf71588 09cf4f3c" aes128k1, aes128k2 :: ByteString (aes128k1, aes128k2) = CMAC.subKeys aes128key gAES192 :: TestTree gAES192 = igroup "aes192" [ ecb0 aes192key @?= hxs "22452d8e 49a8a593 9f7321ce ea6d514b" , aes192k1 @?= hxs "448a5b1c 93514b27 3ee6439d d4daa296" , aes192k2 @?= hxs "8914b639 26a2964e 7dcc873b a9b5452c" , bsCMAC aes192key msg0 @?= hxs "d17ddf46 adaacde5 31cac483 de7a9367" , bsCMAC aes192key msg128 @?= hxs "9e99a7bf 31e71090 0662f65e 617c5184" , bsCMAC aes192key msg320 @?= hxs "8a1de5be 2eb31aad 089a82e6 ee908b0e" , bsCMAC aes192key msg512 @?= hxs "a1d5df0e ed790f79 4d775896 59f39a11" ] where aes192key :: AES192 aes192key = unsafeCipher . hxs $ "8e73b0f7 da0e6452 c810f32b 809079e5" ++ "62f8ead2 522c6b7b" aes192k1, aes192k2 :: ByteString (aes192k1, aes192k2) = CMAC.subKeys aes192key gAES256 :: TestTree gAES256 = igroup "aes256" [ ecb0 aes256key @?= hxs "e568f681 94cf76d6 174d4cc0 4310a854" , aes256k1 @?= hxs "cad1ed03 299eedac 2e9a9980 8621502f" , aes256k2 @?= hxs "95a3da06 533ddb58 5d353301 0c42a0d9" , bsCMAC aes256key msg0 @?= hxs "028962f6 1b7bf89e fc6b551f 4667d983" , bsCMAC aes256key msg128 @?= hxs "28a7023f 452e8f82 bd4bf28d 8c37c35c" , bsCMAC aes256key msg320 @?= hxs "aaf3d8f1 de5640c2 32f5b169 b9c911e6" , bsCMAC aes256key msg512 @?= hxs "e1992190 549f6ed5 696a2c05 6c315410" ] where aes256key :: AES256 aes256key = unsafeCipher . hxs $ "603deb10 15ca71be 2b73aef0 857d7781" ++ "1f352c07 3b6108d7 2d9810a3 0914dff4" aes256k1, aes256k2 :: ByteString (aes256k1, aes256k2) = CMAC.subKeys aes256key gTDEA3 :: TestTree gTDEA3 = igroup "Three Key TDEA" [ ecb0 tdea3key @?= hxs "c8cc74e9 8a7329a2" , tdea3k1 @?= hxs "9198e9d3 14e6535f" , tdea3k2 @?= hxs "2331d3a6 29cca6a5" , bsCMAC tdea3key msg0 @?= hxs "b7a688e1 22ffaf95" , bsCMAC tdea3key msg64 @?= hxs "8e8f2931 36283797" , bsCMAC tdea3key msg160 @?= hxs "743ddbe0 ce2dc2ed" , bsCMAC tdea3key msg256 @?= hxs "33e6b109 2400eae5" ] where tdea3key :: DES_EDE3 tdea3key = unsafeCipher . hxs $ "8aa83bf8 cbda1062" ++ "0bc1bf19 fbb6cd58" ++ "bc313d4a 371ca8b5" tdea3k1, tdea3k2 :: ByteString (tdea3k1, tdea3k2) = CMAC.subKeys tdea3key gTDEA2 :: TestTree gTDEA2 = igroup "Two Key TDEA" [ ecb0 tdea2key @?= hxs "c7679b9f 6b8d7d7a" , tdea2k1 @?= hxs "8ecf373e d71afaef" , tdea2k2 @?= hxs "1d9e6e7d ae35f5c5" , bsCMAC tdea2key msg0 @?= hxs "bd2ebf9a 3ba00361" , bsCMAC tdea2key msg64 @?= hxs "4ff2ab81 3c53ce83" , bsCMAC tdea2key msg160 @?= hxs "62dd1b47 1902bd4e" , bsCMAC tdea2key msg256 @?= hxs "31b1e431 dabc4eb8" ] where tdea2key :: DES_EDE2 tdea2key = unsafeCipher . hxs $ "4cf15134 a2850dd5" ++ "8a3d10ba 80570d38" tdea2k1, tdea2k2 :: ByteString (tdea2k1, tdea2k2) = CMAC.subKeys tdea2key igroup :: TestName -> [Assertion] -> TestTree igroup nm = testGroup nm . zipWith (flip ($)) [1..] . map icase where icase c i = testCase (show (i :: Int)) c nistVectors :: TestTree nistVectors = testGroup "KAT - NIST test vectors" [ gAES128, gAES192, gAES256, gTDEA3, gTDEA2 ] tests :: TestTree tests = testGroup "CMAC" [ nistVectors ] cryptonite-0.23/tests/KAT_Curve25519.hs0000644000000000000000000000270412673727640015734 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Curve25519 ( tests ) where import Crypto.Error import qualified Crypto.PubKey.Curve25519 as Curve25519 import Data.ByteArray as B import Imports alicePrivate = throwCryptoError $ Curve25519.secretKey ("\x77\x07\x6d\x0a\x73\x18\xa5\x7d\x3c\x16\xc1\x72\x51\xb2\x66\x45\xdf\x4c\x2f\x87\xeb\xc0\x99\x2a\xb1\x77\xfb\xa5\x1d\xb9\x2c\x2a" :: ByteString) alicePublic = throwCryptoError $ Curve25519.publicKey ("\x85\x20\xf0\x09\x89\x30\xa7\x54\x74\x8b\x7d\xdc\xb4\x3e\xf7\x5a\x0d\xbf\x3a\x0d\x26\x38\x1a\xf4\xeb\xa4\xa9\x8e\xaa\x9b\x4e\x6a" :: ByteString) bobPrivate = throwCryptoError $ Curve25519.secretKey ("\x5d\xab\x08\x7e\x62\x4a\x8a\x4b\x79\xe1\x7f\x8b\x83\x80\x0e\xe6\x6f\x3b\xb1\x29\x26\x18\xb6\xfd\x1c\x2f\x8b\x27\xff\x88\xe0\xeb" :: ByteString) bobPublic = throwCryptoError $ Curve25519.publicKey ("\xde\x9e\xdb\x7d\x7b\x7d\xc1\xb4\xd3\x5b\x61\xc2\xec\xe4\x35\x37\x3f\x83\x43\xc8\x5b\x78\x67\x4d\xad\xfc\x7e\x14\x6f\x88\x2b\x4f" :: ByteString) aliceMultBob = "\x4a\x5d\x9d\x5b\xa4\xce\x2d\xe1\x72\x8e\x3b\xf4\x80\x35\x0f\x25\xe0\x7e\x21\xc9\x47\xd1\x9e\x33\x76\xf0\x9b\x3c\x1e\x16\x17\x42" :: ByteString katTests :: [TestTree] katTests = [ testCase "0" (aliceMultBob @=? B.convert (Curve25519.dh alicePublic bobPrivate)) , testCase "1" (aliceMultBob @=? B.convert (Curve25519.dh bobPublic alicePrivate)) ] tests = testGroup "Curve25519" [ testGroup "KATs" katTests ] cryptonite-0.23/tests/KAT_Curve448.hs0000644000000000000000000000403013050556742015551 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Curve448 ( tests ) where import Crypto.Error import qualified Crypto.PubKey.Curve448 as Curve448 import Data.ByteArray as B import Imports alicePrivate = throwCryptoError $ Curve448.secretKey ("\x9a\x8f\x49\x25\xd1\x51\x9f\x57\x75\xcf\x46\xb0\x4b\x58\x00\xd4\xee\x9e\xe8\xba\xe8\xbc\x55\x65\xd4\x98\xc2\x8d\xd9\xc9\xba\xf5\x74\xa9\x41\x97\x44\x89\x73\x91\x00\x63\x82\xa6\xf1\x27\xab\x1d\x9a\xc2\xd8\xc0\xa5\x98\x72\x6b" :: ByteString) alicePublic = throwCryptoError $ Curve448.publicKey ("\x9b\x08\xf7\xcc\x31\xb7\xe3\xe6\x7d\x22\xd5\xae\xa1\x21\x07\x4a\x27\x3b\xd2\xb8\x3d\xe0\x9c\x63\xfa\xa7\x3d\x2c\x22\xc5\xd9\xbb\xc8\x36\x64\x72\x41\xd9\x53\xd4\x0c\x5b\x12\xda\x88\x12\x0d\x53\x17\x7f\x80\xe5\x32\xc4\x1f\xa0" :: ByteString) bobPrivate = throwCryptoError $ Curve448.secretKey ("\x1c\x30\x6a\x7a\xc2\xa0\xe2\xe0\x99\x0b\x29\x44\x70\xcb\xa3\x39\xe6\x45\x37\x72\xb0\x75\x81\x1d\x8f\xad\x0d\x1d\x69\x27\xc1\x20\xbb\x5e\xe8\x97\x2b\x0d\x3e\x21\x37\x4c\x9c\x92\x1b\x09\xd1\xb0\x36\x6f\x10\xb6\x51\x73\x99\x2d" :: ByteString) bobPublic = throwCryptoError $ Curve448.publicKey ("\x3e\xb7\xa8\x29\xb0\xcd\x20\xf5\xbc\xfc\x0b\x59\x9b\x6f\xec\xcf\x6d\xa4\x62\x71\x07\xbd\xb0\xd4\xf3\x45\xb4\x30\x27\xd8\xb9\x72\xfc\x3e\x34\xfb\x42\x32\xa1\x3c\xa7\x06\xdc\xb5\x7a\xec\x3d\xae\x07\xbd\xc1\xc6\x7b\xf3\x36\x09" :: ByteString) aliceMultBob = "\x07\xff\xf4\x18\x1a\xc6\xcc\x95\xec\x1c\x16\xa9\x4a\x0f\x74\xd1\x2d\xa2\x32\xce\x40\xa7\x75\x52\x28\x1d\x28\x2b\xb6\x0c\x0b\x56\xfd\x24\x64\xc3\x35\x54\x39\x36\x52\x1c\x24\x40\x30\x85\xd5\x9a\x44\x9a\x50\x37\x51\x4a\x87\x9d" :: ByteString katTests :: [TestTree] katTests = [ testCase "0" (aliceMultBob @=? B.convert (Curve448.dh alicePublic bobPrivate)) , testCase "1" (aliceMultBob @=? B.convert (Curve448.dh bobPublic alicePrivate)) , testCase "2" (alicePublic @=? Curve448.toPublic alicePrivate) , testCase "3" (bobPublic @=? Curve448.toPublic bobPrivate) ] tests = testGroup "Curve448" [ testGroup "KATs" katTests ] cryptonite-0.23/tests/KAT_DES.hs0000644000000000000000000001046512512146401014636 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} module KAT_DES (tests) where import Imports import BlockCipher import qualified Crypto.Cipher.DES as DES vectors_ecb = -- key plaintext ciphertext [ KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x8C\xA6\x4D\xE9\xC1\xB1\x23\xA7" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x73\x59\xB2\x16\x3E\x4E\xDC\x58" , KAT_ECB "\x30\x00\x00\x00\x00\x00\x00\x00" "\x10\x00\x00\x00\x00\x00\x00\x01" "\x95\x8E\x6E\x62\x7A\x05\x55\x7B" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x11\x11\x11\x11\x11\x11\x11\x11" "\xF4\x03\x79\xAB\x9E\x0E\xC5\x33" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x11\x11\x11\x11\x11\x11\x11\x11" "\x17\x66\x8D\xFC\x72\x92\x53\x2D" , KAT_ECB "\x11\x11\x11\x11\x11\x11\x11\x11" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x8A\x5A\xE1\xF8\x1A\xB8\xF2\xDD" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00" "\x8C\xA6\x4D\xE9\xC1\xB1\x23\xA7" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xED\x39\xD9\x50\xFA\x74\xBC\xC4" , KAT_ECB "\x7C\xA1\x10\x45\x4A\x1A\x6E\x57" "\x01\xA1\xD6\xD0\x39\x77\x67\x42" "\x69\x0F\x5B\x0D\x9A\x26\x93\x9B" , KAT_ECB "\x01\x31\xD9\x61\x9D\xC1\x37\x6E" "\x5C\xD5\x4C\xA8\x3D\xEF\x57\xDA" "\x7A\x38\x9D\x10\x35\x4B\xD2\x71" , KAT_ECB "\x07\xA1\x13\x3E\x4A\x0B\x26\x86" "\x02\x48\xD4\x38\x06\xF6\x71\x72" "\x86\x8E\xBB\x51\xCA\xB4\x59\x9A" , KAT_ECB "\x38\x49\x67\x4C\x26\x02\x31\x9E" "\x51\x45\x4B\x58\x2D\xDF\x44\x0A" "\x71\x78\x87\x6E\x01\xF1\x9B\x2A" , KAT_ECB "\x04\xB9\x15\xBA\x43\xFE\xB5\xB6" "\x42\xFD\x44\x30\x59\x57\x7F\xA2" "\xAF\x37\xFB\x42\x1F\x8C\x40\x95" , KAT_ECB "\x01\x13\xB9\x70\xFD\x34\xF2\xCE" "\x05\x9B\x5E\x08\x51\xCF\x14\x3A" "\x86\xA5\x60\xF1\x0E\xC6\xD8\x5B" , KAT_ECB "\x01\x70\xF1\x75\x46\x8F\xB5\xE6" "\x07\x56\xD8\xE0\x77\x47\x61\xD2" "\x0C\xD3\xDA\x02\x00\x21\xDC\x09" , KAT_ECB "\x43\x29\x7F\xAD\x38\xE3\x73\xFE" "\x76\x25\x14\xB8\x29\xBF\x48\x6A" "\xEA\x67\x6B\x2C\xB7\xDB\x2B\x7A" , KAT_ECB "\x07\xA7\x13\x70\x45\xDA\x2A\x16" "\x3B\xDD\x11\x90\x49\x37\x28\x02" "\xDF\xD6\x4A\x81\x5C\xAF\x1A\x0F" , KAT_ECB "\x04\x68\x91\x04\xC2\xFD\x3B\x2F" "\x26\x95\x5F\x68\x35\xAF\x60\x9A" "\x5C\x51\x3C\x9C\x48\x86\xC0\x88" , KAT_ECB "\x37\xD0\x6B\xB5\x16\xCB\x75\x46" "\x16\x4D\x5E\x40\x4F\x27\x52\x32" "\x0A\x2A\xEE\xAE\x3F\xF4\xAB\x77" , KAT_ECB "\x1F\x08\x26\x0D\x1A\xC2\x46\x5E" "\x6B\x05\x6E\x18\x75\x9F\x5C\xCA" "\xEF\x1B\xF0\x3E\x5D\xFA\x57\x5A" , KAT_ECB "\x58\x40\x23\x64\x1A\xBA\x61\x76" "\x00\x4B\xD6\xEF\x09\x17\x60\x62" "\x88\xBF\x0D\xB6\xD7\x0D\xEE\x56" , KAT_ECB "\x02\x58\x16\x16\x46\x29\xB0\x07" "\x48\x0D\x39\x00\x6E\xE7\x62\xF2" "\xA1\xF9\x91\x55\x41\x02\x0B\x56" , KAT_ECB "\x49\x79\x3E\xBC\x79\xB3\x25\x8F" "\x43\x75\x40\xC8\x69\x8F\x3C\xFA" "\x6F\xBF\x1C\xAF\xCF\xFD\x05\x56" , KAT_ECB "\x4F\xB0\x5E\x15\x15\xAB\x73\xA7" "\x07\x2D\x43\xA0\x77\x07\x52\x92" "\x2F\x22\xE4\x9B\xAB\x7C\xA1\xAC" , KAT_ECB "\x49\xE9\x5D\x6D\x4C\xA2\x29\xBF" "\x02\xFE\x55\x77\x81\x17\xF1\x2A" "\x5A\x6B\x61\x2C\xC2\x6C\xCE\x4A" , KAT_ECB "\x01\x83\x10\xDC\x40\x9B\x26\xD6" "\x1D\x9D\x5C\x50\x18\xF7\x28\xC2" "\x5F\x4C\x03\x8E\xD1\x2B\x2E\x41" , KAT_ECB "\x1C\x58\x7F\x1C\x13\x92\x4F\xEF" "\x30\x55\x32\x28\x6D\x6F\x29\x5A" "\x63\xFA\xC0\xD0\x34\xD9\xF7\x93" , KAT_ECB "\x01\x01\x01\x01\x01\x01\x01\x01" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x61\x7B\x3A\x0C\xE8\xF0\x71\x00" , KAT_ECB "\x1F\x1F\x1F\x1F\x0E\x0E\x0E\x0E" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xDB\x95\x86\x05\xF8\xC8\xC6\x06" , KAT_ECB "\xE0\xFE\xE0\xFE\xF1\xFE\xF1\xFE" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xED\xBF\xD1\xC6\x6C\x29\xCC\xC7" , KAT_ECB "\x00\x00\x00\x00\x00\x00\x00\x00" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x35\x55\x50\xB2\x15\x0E\x24\x51" , KAT_ECB "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\xCA\xAA\xAF\x4D\xEA\xF1\xDB\xAE" , KAT_ECB "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x00\x00\x00\x00\x00\x00\x00\x00" "\xD5\xD4\x4F\xF7\x20\x68\x3D\x0D" , KAT_ECB "\xFE\xDC\xBA\x98\x76\x54\x32\x10" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x2A\x2B\xB0\x08\xDF\x97\xC2\xF2" ] kats = defaultKATs { kat_ECB = vectors_ecb } tests = localOption (QuickCheckTests 5) $ testBlockCipher kats (undefined :: DES.DES) cryptonite-0.23/tests/KAT_Ed25519.hs0000644000000000000000000000273612514663134015174 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE BangPatterns #-} module KAT_Ed25519 ( tests ) where import Crypto.Error import qualified Crypto.PubKey.Ed25519 as Ed25519 import Imports data Vec = Vec { vecSec :: ByteString , vecPub :: ByteString , vecMsg :: ByteString , vecSig :: ByteString } deriving (Show,Eq) vec1 = Vec { vecSec = "\x4c\xcd\x08\x9b\x28\xff\x96\xda\x9d\xb6\xc3\x46\xec\x11\x4e\x0f\x5b\x8a\x31\x9f\x35\xab\xa6\x24\xda\x8c\xf6\xed\x4f\xb8\xa6\xfb" , vecPub = "\x3d\x40\x17\xc3\xe8\x43\x89\x5a\x92\xb7\x0a\xa7\x4d\x1b\x7e\xbc\x9c\x98\x2c\xcf\x2e\xc4\x96\x8c\xc0\xcd\x55\xf1\x2a\xf4\x66\x0c" , vecMsg = "\x72" , vecSig = "\x92\xa0\x09\xa9\xf0\xd4\xca\xb8\x72\x0e\x82\x0b\x5f\x64\x25\x40\xa2\xb2\x7b\x54\x16\x50\x3f\x8f\xb3\x76\x22\x23\xeb\xdb\x69\xda\x08\x5a\xc1\xe4\x3e\x15\x99\x6e\x45\x8f\x36\x13\xd0\xf1\x1d\x8c\x38\x7b\x2e\xae\xb4\x30\x2a\xee\xb0\x0d\x29\x16\x12\xbb\x0c\x00" } testVec :: String -> Vec -> [TestTree] testVec s vec = [ testCase (s ++ " gen publickey") (pub @=? Ed25519.toPublic sec) , testCase (s ++ " gen signature") (sig @=? Ed25519.sign sec pub (vecMsg vec)) ] where !sig = throwCryptoError $ Ed25519.signature (vecSig vec) !pub = throwCryptoError $ Ed25519.publicKey (vecPub vec) !sec = throwCryptoError $ Ed25519.secretKey (vecSec vec) katTests :: [TestTree] katTests = testVec "vec 1" vec1 tests = testGroup "Ed25519" [ testGroup "KATs" katTests ] cryptonite-0.23/tests/KAT_HKDF.hs0000644000000000000000000000644612673727640014765 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_HKDF (tests) where import qualified Crypto.KDF.HKDF as HKDF import Crypto.Hash (MD5(..), SHA1(..), SHA256(..) , Keccak_224(..), Keccak_256(..), Keccak_384(..), Keccak_512(..) , SHA3_224(..), SHA3_256(..), SHA3_384(..), SHA3_512(..) , HashAlgorithm, digestFromByteString) import qualified Data.ByteString as B import Imports data KDFVector hash = KDFVector { kdfIKM :: ByteString , kdfSalt :: ByteString , kdfInfo :: ByteString , kdfResult :: ByteString } sha256KDFVectors :: [KDFVector SHA256] sha256KDFVectors = [ KDFVector "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" (B.pack [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c]) "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9" "\x3c\xb2\x5f\x25\xfa\xac\xd5\x7a\x90\x43\x4f\x64\xd0\x36\x2f\x2a\x2d\x2d\x0a\x90\xcf\x1a\x5a\x4c\x5d\xb0\x2d\x56\xec\xc4\xc5\xbf\x34\x00\x72\x08\xd5\xb8\x87\x18\x58\x65" , KDFVector (B.pack [0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f]) (B.pack [0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf]) (B.pack [0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff]) (B.pack [0xb1,0x1e,0x39,0x8d,0xc8,0x03,0x27,0xa1,0xc8,0xe7,0xf7,0x8c,0x59,0x6a,0x49,0x34,0x4f,0x01,0x2e,0xda,0x2d,0x4e,0xfa,0xd8,0xa0,0x50,0xcc,0x4c,0x19,0xaf,0xa9,0x7c,0x59,0x04,0x5a,0x99,0xca,0xc7,0x82,0x72,0x71,0xcb,0x41,0xc6,0x5e,0x59,0x0e,0x09,0xda,0x32,0x75,0x60,0x0c,0x2f,0x09,0xb8,0x36,0x77,0x93,0xa9,0xac,0xa3,0xdb,0x71,0xcc,0x30,0xc5,0x81,0x79,0xec,0x3e,0x87,0xc1,0x4c,0x01,0xd5,0xc1,0xf3,0x43,0x4f,0x1d,0x87]) ] kdfTests :: [TestTree] kdfTests = [ testGroup "sha256" $ concatMap toKDFTest $ zip is sha256KDFVectors ] where toKDFTest (i, kdfVector) = [ testCase (show i) (t HKDF.extract kdfVector) ] t :: HashAlgorithm a => (ByteString -> ByteString -> HKDF.PRK a) -> KDFVector a -> Assertion t ext v = let prk = ext (kdfSalt v) (kdfIKM v) in kdfResult v @=? HKDF.expand prk (kdfInfo v) (B.length $ kdfResult v) is :: [Int] is = [1..] tests = testGroup "HKDF" [ testGroup "KATs" kdfTests ] cryptonite-0.23/tests/KAT_HMAC.hs0000644000000000000000000001664412673727640014762 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_HMAC (tests) where import qualified Crypto.MAC.HMAC as HMAC import Crypto.Hash (MD5(..), SHA1(..), SHA256(..) , Keccak_224(..), Keccak_256(..), Keccak_384(..), Keccak_512(..) , SHA3_224(..), SHA3_256(..), SHA3_384(..), SHA3_512(..) , HashAlgorithm, digestFromByteString) import qualified Data.ByteString as B import Imports data MACVector hash = MACVector { macKey :: ByteString , macSecret :: ByteString , macResult :: HMAC.HMAC hash } instance Show (HMAC.HMAC a) where show (HMAC.HMAC d) = show d digest :: HashAlgorithm hash => ByteString -> HMAC.HMAC hash digest = maybe (error "cannot get digest") HMAC.HMAC . digestFromByteString v1 :: ByteString v1 = "The quick brown fox jumps over the lazy dog" md5MACVectors :: [MACVector MD5] md5MACVectors = [ MACVector B.empty B.empty $ digest "\x74\xe6\xf7\x29\x8a\x9c\x2d\x16\x89\x35\xf5\x8c\x00\x1b\xad\x88" , MACVector "key" v1 $ digest "\x80\x07\x07\x13\x46\x3e\x77\x49\xb9\x0c\x2d\xc2\x49\x11\xe2\x75" ] sha1MACVectors :: [MACVector SHA1] sha1MACVectors = [ MACVector B.empty B.empty $ digest "\xfb\xdb\x1d\x1b\x18\xaa\x6c\x08\x32\x4b\x7d\x64\xb7\x1f\xb7\x63\x70\x69\x0e\x1d" , MACVector "key" v1 $ digest "\xde\x7c\x9b\x85\xb8\xb7\x8a\xa6\xbc\x8a\x7a\x36\xf7\x0a\x90\x70\x1c\x9d\xb4\xd9" ] sha256MACVectors :: [MACVector SHA256] sha256MACVectors = [ MACVector B.empty B.empty $ digest "\xb6\x13\x67\x9a\x08\x14\xd9\xec\x77\x2f\x95\xd7\x78\xc3\x5f\xc5\xff\x16\x97\xc4\x93\x71\x56\x53\xc6\xc7\x12\x14\x42\x92\xc5\xad" , MACVector "key" v1 $ digest "\xf7\xbc\x83\xf4\x30\x53\x84\x24\xb1\x32\x98\xe6\xaa\x6f\xb1\x43\xef\x4d\x59\xa1\x49\x46\x17\x59\x97\x47\x9d\xbc\x2d\x1a\x3c\xd8" ] keccak_key1 = "\x4a\x65\x66\x65" keccak_data1 = "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f" keccak_224_MAC_Vectors :: [MACVector Keccak_224] keccak_224_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\xe8\x24\xfe\xc9\x6c\x07\x4f\x22\xf9\x92\x35\xbb\x94\x2d\xa1\x98\x26\x64\xab\x69\x2c\xa8\x50\x10\x53\xcb\xd4\x14" ] keccak_256_MAC_Vectors :: [MACVector Keccak_256] keccak_256_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\xaa\x9a\xed\x44\x8c\x7a\xbc\x8b\x5e\x32\x6f\xfa\x6a\x01\xcd\xed\xf7\xb4\xb8\x31\x88\x14\x68\xc0\x44\xba\x8d\xd4\x56\x63\x69\xa1" ] keccak_384_MAC_Vectors :: [MACVector Keccak_384] keccak_384_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\x5a\xf5\xc9\xa7\x7a\x23\xa6\xa9\x3d\x80\x64\x9e\x56\x2a\xb7\x7f\x4f\x35\x52\xe3\xc5\xca\xff\xd9\x3b\xdf\x8b\x3c\xfc\x69\x20\xe3\x02\x3f\xc2\x67\x75\xd9\xdf\x1f\x3c\x94\x61\x31\x46\xad\x2c\x9d" ] keccak_512_MAC_Vectors :: [MACVector Keccak_512] keccak_512_MAC_Vectors = [ MACVector keccak_key1 keccak_data1 $ digest "\xc2\x96\x2e\x5b\xbe\x12\x38\x00\x78\x52\xf7\x9d\x81\x4d\xbb\xec\xd4\x68\x2e\x6f\x09\x7d\x37\xa3\x63\x58\x7c\x03\xbf\xa2\xeb\x08\x59\xd8\xd9\xc7\x01\xe0\x4c\xec\xec\xfd\x3d\xd7\xbf\xd4\x38\xf2\x0b\x8b\x64\x8e\x01\xbf\x8c\x11\xd2\x68\x24\xb9\x6c\xeb\xbd\xcb" ] sha3_key1 = "\x4a\x65\x66\x65" sha3_data1 = "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f" sha3_224_MAC_Vectors :: [MACVector SHA3_224] sha3_224_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\x7f\xdb\x8d\xd8\x8b\xd2\xf6\x0d\x1b\x79\x86\x34\xad\x38\x68\x11\xc2\xcf\xc8\x5b\xfa\xf5\xd5\x2b\xba\xce\x5e\x66" ] sha3_256_MAC_Vectors :: [MACVector SHA3_256] sha3_256_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\xc7\xd4\x07\x2e\x78\x88\x77\xae\x35\x96\xbb\xb0\xda\x73\xb8\x87\xc9\x17\x1f\x93\x09\x5b\x29\x4a\xe8\x57\xfb\xe2\x64\x5e\x1b\xa5" ] sha3_384_MAC_Vectors :: [MACVector SHA3_384] sha3_384_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\xf1\x10\x1f\x8c\xbf\x97\x66\xfd\x67\x64\xd2\xed\x61\x90\x3f\x21\xca\x9b\x18\xf5\x7c\xf3\xe1\xa2\x3c\xa1\x35\x08\xa9\x32\x43\xce\x48\xc0\x45\xdc\x00\x7f\x26\xa2\x1b\x3f\x5e\x0e\x9d\xf4\xc2\x0a" ] sha3_512_MAC_Vectors :: [MACVector SHA3_512] sha3_512_MAC_Vectors = [ MACVector sha3_key1 sha3_data1 $ digest "\x5a\x4b\xfe\xab\x61\x66\x42\x7c\x7a\x36\x47\xb7\x47\x29\x2b\x83\x84\x53\x7c\xdb\x89\xaf\xb3\xbf\x56\x65\xe4\xc5\xe7\x09\x35\x0b\x28\x7b\xae\xc9\x21\xfd\x7c\xa0\xee\x7a\x0c\x31\xd0\x22\xa9\x5e\x1f\xc9\x2b\xa9\xd7\x7d\xf8\x83\x96\x02\x75\xbe\xb4\xe6\x20\x24" ] macTests :: [TestTree] macTests = [ testGroup "md5" $ concatMap toMACTest $ zip is md5MACVectors , testGroup "sha1" $ concatMap toMACTest $ zip is sha1MACVectors , testGroup "sha256" $ concatMap toMACTest $ zip is sha256MACVectors , testGroup "keccak-224" $ concatMap toMACTest $ zip is keccak_224_MAC_Vectors , testGroup "keccak-256" $ concatMap toMACTest $ zip is keccak_256_MAC_Vectors , testGroup "keccak-384" $ concatMap toMACTest $ zip is keccak_384_MAC_Vectors , testGroup "keccak-512" $ concatMap toMACTest $ zip is keccak_512_MAC_Vectors , testGroup "sha3-224" $ concatMap toMACTest $ zip is sha3_224_MAC_Vectors , testGroup "sha3-256" $ concatMap toMACTest $ zip is sha3_256_MAC_Vectors , testGroup "sha3-384" $ concatMap toMACTest $ zip is sha3_384_MAC_Vectors , testGroup "sha3-512" $ concatMap toMACTest $ zip is sha3_512_MAC_Vectors ] where toMACTest (i, macVector) = [ testCase (show i) (macResult macVector @=? HMAC.hmac (macKey macVector) (macSecret macVector)) , testCase ("incr-" ++ show i) (macResult macVector @=? HMAC.finalize (HMAC.update (HMAC.initialize (macKey macVector)) (macSecret macVector))) ] is :: [Int] is = [1..] data MacIncremental a = MacIncremental ByteString ByteString (HMAC.HMAC a) deriving (Show,Eq) instance HashAlgorithm a => Arbitrary (MacIncremental a) where arbitrary = do key <- arbitraryBSof 1 89 msg <- arbitraryBSof 1 99 return $ MacIncremental key msg (HMAC.hmac key msg) data MacIncrementalList a = MacIncrementalList ByteString [ByteString] (HMAC.HMAC a) deriving (Show,Eq) instance HashAlgorithm a => Arbitrary (MacIncrementalList a) where arbitrary = do key <- arbitraryBSof 1 89 msgs <- choose (1,20) >>= \n -> replicateM n (arbitraryBSof 1 99) return $ MacIncrementalList key msgs (HMAC.hmac key (B.concat msgs)) macIncrementalTests :: [TestTree] macIncrementalTests = [ testProperties MD5 , testProperties SHA1 , testProperties SHA256 , testProperties SHA3_224 , testProperties SHA3_256 , testProperties SHA3_384 , testProperties SHA3_512 ] where --testProperties :: HashAlgorithm a => a -> [Property] testProperties a = testGroup (show a) [ testProperty "list-one" (prop_inc0 a) , testProperty "list-multi" (prop_inc1 a) ] prop_inc0 :: HashAlgorithm a => a -> MacIncremental a -> Bool prop_inc0 _ (MacIncremental secret msg result) = result `assertEq` HMAC.finalize (HMAC.update (HMAC.initialize secret) msg) prop_inc1 :: HashAlgorithm a => a -> MacIncrementalList a -> Bool prop_inc1 _ (MacIncrementalList secret msgs result) = result `assertEq` HMAC.finalize (foldl' HMAC.update (HMAC.initialize secret) msgs) tests = testGroup "HMAC" [ testGroup "KATs" macTests , testGroup "properties" macIncrementalTests ] cryptonite-0.23/tests/KAT_MiyaguchiPreneel.hs0000644000000000000000000000264512727442704017473 0ustar0000000000000000 module KAT_MiyaguchiPreneel (tests) where import Crypto.Cipher.AES (AES128) import Crypto.ConstructHash.MiyaguchiPreneel as MiyaguchiPreneel import Imports import Data.Char (digitToInt) import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteArray as B import Data.ByteArray.Encoding (Base (Base16), convertFromBase) runMP128 :: ByteString -> ByteString runMP128 s = B.convert (MiyaguchiPreneel.compute s :: MiyaguchiPreneel AES128) hxs :: String -> ByteString hxs = either (error . ("hxs:" ++)) id . convertFromBase Base16 . B8.pack . filter (/= ' ') gAES128 :: TestTree gAES128 = igroup "aes128" [ runMP128 B8.empty @?= hxs "66e94bd4 ef8a2c3b 884cfa59 ca342b2e" , runMP128 (hxs "01000000 00000000 00000000 00000000") @?= hxs "46711816 e91d6ff0 59bbbf2b f58e0fd3" , runMP128 (hxs "00000000 00000000 00000000 00000001") @?= hxs "58e2fcce fa7e3061 367f1d57 a4e7455b" , runMP128 (hxs $ "00000000 00000000 00000000 00000000" ++ "01") @?= hxs "a5ff35ae 097adf5d 646abf5e bf4c16f4" ] igroup :: TestName -> [Assertion] -> TestTree igroup nm = testGroup nm . zipWith (flip ($)) [1..] . map icase where icase c i = testCase (show (i :: Int)) c vectors :: TestTree vectors = testGroup "KATs" [ gAES128 ] tests :: TestTree tests = testGroup "MiyaguchiPreneel" [ vectors ] cryptonite-0.23/tests/KAT_OTP.hs0000644000000000000000000000570313050556742014677 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_OTP ( tests ) where import Crypto.Hash.Algorithms (SHA1(..), SHA256(..), SHA512(..)) import Crypto.OTP import Data.ByteString (ByteString) import Imports -- | Test values from Appendix D of http://tools.ietf.org/html/rfc4226 hotpExpected :: [(Word64, Word32)] hotpExpected = [ (0, 755224) , (1, 287082) , (3, 969429) , (4, 338314) , (5, 254676) , (6, 287922) , (7, 162583) , (8, 399871) , (9, 520489) ] -- | Test data from Appendix B of http://tools.ietf.org/html/rfc6238 -- Note that the shared keys for the non SHA-1 values are actually -- different (see the errata, or the Java example code). totpSHA1Expected :: [(Word64, Word32)] totpSHA1Expected = [ (59 , 94287082) , (1111111109, 07081804) , (1111111111, 14050471) , (1234567890, 89005924) , (2000000000, 69279037) , (20000000000, 65353130) ] totpSHA256Expected :: [(Word64, Word32)] totpSHA256Expected = [ (59 , 46119246) , (1111111109, 68084774) , (1111111111, 67062674) , (1234567890, 91819424) , (2000000000, 90698825) , (20000000000, 77737706) ] totpSHA512Expected :: [(Word64, Word32)] totpSHA512Expected = [ (59 , 90693936) , (1111111109, 25091201) , (1111111111, 99943326) , (1234567890, 93441116) , (2000000000, 38618901) , (20000000000, 47863826) ] otpKey = "12345678901234567890" :: ByteString totpSHA256Key = "12345678901234567890123456789012" :: ByteString totpSHA512Key = "1234567890123456789012345678901234567890123456789012345678901234" :: ByteString makeKATs otp expected = concatMap (makeTest otp) (zip3 is counts otps) where is :: [Int] is = [1..] counts = map fst expected otps = map snd expected makeTest otp (i, count, password) = [ testCase (show i) (assertEqual "" password (otp count)) ] Right totpSHA1Params = mkTOTPParams SHA1 0 30 OTP8 TwoSteps Right totpSHA256Params = mkTOTPParams SHA256 0 30 OTP8 TwoSteps Right totpSHA512Params = mkTOTPParams SHA512 0 30 OTP8 TwoSteps -- resynching with the expected value should just return the current counter + 1 prop_resyncExpected ctr window = resynchronize SHA1 OTP6 window key ctr (otp, []) == Just (ctr + 1) where key = "1234" :: ByteString otp = hotp SHA1 OTP6 key ctr tests = testGroup "OTP" [ testGroup "HOTP" [ testGroup "KATs" (makeKATs (hotp SHA1 OTP6 otpKey) hotpExpected) , testGroup "properties" [ testProperty "resync-expected" prop_resyncExpected ] ] , testGroup "TOTP" [ testGroup "KATs" [ testGroup "SHA1" (makeKATs (totp totpSHA1Params otpKey . fromIntegral) totpSHA1Expected) , testGroup "SHA256" (makeKATs (totp totpSHA256Params totpSHA256Key . fromIntegral) totpSHA256Expected) , testGroup "SHA512" (makeKATs (totp totpSHA512Params totpSHA512Key . fromIntegral) totpSHA512Expected) ] ] ] cryptonite-0.23/tests/KAT_PBKDF2.hs0000644000000000000000000001030413050556742015136 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} -- from module KAT_PBKDF2 (tests) where import Crypto.Hash (SHA1(..), SHA256(..), SHA512(..)) import qualified Crypto.KDF.PBKDF2 as PBKDF2 import Data.ByteString (ByteString) import Data.ByteString.Char8 () import Test.Tasty import Test.Tasty.HUnit type VectParams = (ByteString, ByteString, Int, Int) vectors_hmac_sha1 :: [ (VectParams, ByteString) ] vectors_hmac_sha1 = [ ( ("password","salt",2,20) , "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57" ) , ( ("password","salt",4096,20) , "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1" ) , ( ("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25) , "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96\x4c\xf2\xf0\x70\x38" ) , ( ("pass\0word", "sa\0lt", 4096, 16) , "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37\xd7\xf0\x34\x25\xe0\xc3" ) ] vectors_hmac_sha256 :: [ (VectParams, ByteString) ] vectors_hmac_sha256 = [ ( ("password", "salt", 2, 32) , "\xae\x4d\x0c\x95\xaf\x6b\x46\xd3\x2d\x0a\xdf\xf9\x28\xf0\x6d\xd0\x2a\x30\x3f\x8e\xf3\xc2\x51\xdf\xd6\xe2\xd8\x5a\x95\x47\x4c\x43" ) , ( ("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 40) , "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1\xc6\x35\x51\x8c\x7d\xac\x47\xe9" ) ] vectors_hmac_sha512 :: [ (VectParams, ByteString) ] vectors_hmac_sha512 = [ ( ("password", "salt", 1, 32) , "\x86\x7f\x70\xcf\x1a\xde\x02\xcf\xf3\x75\x25\x99\xa3\xa5\x3d\xc4\xaf\x34\xc7\xa6\x69\x81\x5a\xe5\xd5\x13\x55\x4e\x1c\x8c\xf2\x52" ) , ( ("password", "salt", 2, 32) , "\xe1\xd9\xc1\x6a\xa6\x81\x70\x8a\x45\xf5\xc7\xc4\xe2\x15\xce\xb6\x6e\x01\x1a\x2e\x9f\x00\x40\x71\x3f\x18\xae\xfd\xb8\x66\xd5\x3c" ) , ( ("password", "salt", 4096, 32) , "\xd1\x97\xb1\xb3\x3d\xb0\x14\x3e\x01\x8b\x12\xf3\xd1\xd1\x47\x9e\x6c\xde\xbd\xcc\x97\xc5\xc0\xf8\x7f\x69\x02\xe0\x72\xf4\x57\xb5" ) , ( ("passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", 1, 72) , "n\x23\xf2\x76\x38\x08\x4b\x0f\x7e\xa1\x73\x4e\x0d\x98\x41\xf5\x5d\xd2\x9e\xa6\x0a\x83\x44\x66\xf3\x39\x6b\xac\x80\x1f\xac\x1e\xeb\x63\x80\x2f\x03\xa0\xb4\xac\xd7\x60\x3e\x36\x99\xc8\xb7\x44\x37\xbe\x83\xff\x01\xad\x7f\x55\xda\xc1\xef\x60\xf4\xd5\x64\x80\xc3\x5e\xe6\x8f\xd5\x2c\x69\x36" ) ] tests = testGroup "PBKDF2" [ testGroup "KATs-HMAC-SHA1" (katTests (PBKDF2.prfHMAC SHA1) vectors_hmac_sha1) , testGroup "KATs-HMAC-SHA1 (fast)" (katTestFastPBKDF2_SHA1 vectors_hmac_sha1) , testGroup "KATs-HMAC-SHA256" (katTests (PBKDF2.prfHMAC SHA256) vectors_hmac_sha256) , testGroup "KATs-HMAC-SHA256 (fast)" (katTestFastPBKDF2_SHA256 vectors_hmac_sha256) , testGroup "KATs-HMAC-SHA512" (katTests (PBKDF2.prfHMAC SHA512) vectors_hmac_sha512) , testGroup "KATs-HMAC-SHA512 (fast)" (katTestFastPBKDF2_SHA512 vectors_hmac_sha512) ] where katTests prf vects = map (toKatTest prf) $ zip is vects toKatTest prf (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.generate prf (PBKDF2.Parameters iter dkLen) pass salt) katTestFastPBKDF2_SHA1 = map toKatTestFastPBKDF2_SHA1 . zip is toKatTestFastPBKDF2_SHA1 (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.fastPBKDF2_SHA1 (PBKDF2.Parameters iter dkLen) pass salt) katTestFastPBKDF2_SHA256 = map toKatTestFastPBKDF2_SHA256 . zip is toKatTestFastPBKDF2_SHA256 (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.fastPBKDF2_SHA256 (PBKDF2.Parameters iter dkLen) pass salt) katTestFastPBKDF2_SHA512 = map toKatTestFastPBKDF2_SHA512 . zip is toKatTestFastPBKDF2_SHA512 (i, ((pass, salt, iter, dkLen), output)) = testCase (show i) (output @=? PBKDF2.fastPBKDF2_SHA512 (PBKDF2.Parameters iter dkLen) pass salt) is :: [Int] is = [1..] cryptonite-0.23/tests/KAT_PubKey.hs0000644000000000000000000000276412533034410015424 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey (tests) where import Test.Tasty import Test.Tasty.HUnit import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.ByteString.Char8 () import Crypto.PubKey.MaskGenFunction import Crypto.Hash import KAT_PubKey.OAEP import KAT_PubKey.PSS import KAT_PubKey.DSA import KAT_PubKey.ECC import KAT_PubKey.ECDSA import Utils import qualified KAT_PubKey.P256 as P256 data VectorMgf = VectorMgf { seed :: ByteString , dbMask :: ByteString } doMGFTest (i, vmgf) = testCase (show i) (dbMask vmgf @=? actual) where actual = mgf1 SHA1 (seed vmgf) (B.length $ dbMask vmgf) vectorsMGF = [ VectorMgf { seed = "\xdf\x1a\x89\x6f\x9d\x8b\xc8\x16\xd9\x7c\xd7\xa2\xc4\x3b\xad\x54\x6f\xbe\x8c\xfe" , dbMask = "\x66\xe4\x67\x2e\x83\x6a\xd1\x21\xba\x24\x4b\xed\x65\x76\xb8\x67\xd9\xa4\x47\xc2\x8a\x6e\x66\xa5\xb8\x7d\xee\x7f\xbc\x7e\x65\xaf\x50\x57\xf8\x6f\xae\x89\x84\xd9\xba\x7f\x96\x9a\xd6\xfe\x02\xa4\xd7\x5f\x74\x45\xfe\xfd\xd8\x5b\x6d\x3a\x47\x7c\x28\xd2\x4b\xa1\xe3\x75\x6f\x79\x2d\xd1\xdc\xe8\xca\x94\x44\x0e\xcb\x52\x79\xec\xd3\x18\x3a\x31\x1f\xc8\x97\x39\xa9\x66\x43\x13\x6e\x8b\x0f\x46\x5e\x87\xa4\x53\x5c\xd4\xc5\x9b\x10\x02\x8d" } ] tests = testGroup "PubKey" [ testGroup "MGF1" $ map doMGFTest (zip [katZero..] vectorsMGF) , pssTests , oaepTests , dsaTests , eccTests , ecdsaTests , P256.tests ] --newKats = [ eccKatTests ] cryptonite-0.23/tests/KAT_RC4.hs0000644000000000000000000000155712400310060014603 0ustar0000000000000000{-# LANGUAGE ViewPatterns #-} {-# LANGUAGE OverloadedStrings #-} module KAT_RC4 where import Test.Tasty import Test.Tasty.HUnit import Data.ByteString (ByteString) import Data.ByteString.Char8 () import qualified Crypto.Cipher.RC4 as RC4 -- taken from wikipedia pages vectors :: [(ByteString, ByteString, ByteString)] vectors = [ ("Key" ,"Plaintext" ,"\xBB\xF3\x16\xE8\xD9\x40\xAF\x0A\xD3" ) , ("Wiki" ,"pedia" ,"\x10\x21\xBF\x04\x20" ) , ("Secret" ,"Attack at dawn" ,"\x45\xA0\x1F\x64\x5F\xC3\x5B\x38\x35\x52\x54\x4B\x9B\xF5" ) ] tests = testGroup "RC4" $ map toKatTest $ zip is vectors where toKatTest (i, (key, plainText, cipherText)) = testCase (show i) (cipherText @=? snd (RC4.combine (RC4.initialize key) plainText)) is :: [Int] is = [1..] cryptonite-0.23/tests/KAT_Scrypt.hs0000644000000000000000000000355012527635130015514 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_Scrypt (tests) where import Data.ByteString (ByteString) import Data.ByteString.Char8 () import Test.Tasty import Test.Tasty.HUnit import Data.Word import qualified Crypto.KDF.Scrypt as Scrypt vectors :: [ ((ByteString, ByteString, Word64, Int, Int, Int), ByteString) ] vectors = [ ( ("", "", 16, 1, 1, 64) , "\x77\xd6\x57\x62\x38\x65\x7b\x20\x3b\x19\xca\x42\xc1\x8a\x04\x97\xf1\x6b\x48\x44\xe3\x07\x4a\xe8\xdf\xdf\xfa\x3f\xed\xe2\x14\x42\xfc\xd0\x06\x9d\xed\x09\x48\xf8\x32\x6a\x75\x3a\x0f\xc8\x1f\x17\xe8\xd3\xe0\xfb\x2e\x0d\x36\x28\xcf\x35\xe2\x0c\x38\xd1\x89\x06" ) , ( ("password", "NaCl", 1024, 8, 16, 64) , "\xfd\xba\xbe\x1c\x9d\x34\x72\x00\x78\x56\xe7\x19\x0d\x01\xe9\xfe\x7c\x6a\xd7\xcb\xc8\x23\x78\x30\xe7\x73\x76\x63\x4b\x37\x31\x62\x2e\xaf\x30\xd9\x2e\x22\xa3\x88\x6f\xf1\x09\x27\x9d\x98\x30\xda\xc7\x27\xaf\xb9\x4a\x83\xee\x6d\x83\x60\xcb\xdf\xa2\xcc\x06\x40" ) , ( ("pleaseletmein", "SodiumChloride", 16384, 8, 1, 64) , "\x70\x23\xbd\xcb\x3a\xfd\x73\x48\x46\x1c\x06\xcd\x81\xfd\x38\xeb\xfd\xa8\xfb\xba\x90\x4f\x8e\x3e\xa9\xb5\x43\xf6\x54\x5d\xa1\xf2\xd5\x43\x29\x55\x61\x3f\x0f\xcf\x62\xd4\x97\x05\x24\x2a\x9a\xf9\xe6\x1e\x85\xdc\x0d\x65\x1e\x40\xdf\xcf\x01\x7b\x45\x57\x58\x87" ) , ( ("pleaseletmein", "SodiumChloride", 1048576, 8, 1, 64) , "\x21\x01\xcb\x9b\x6a\x51\x1a\xae\xad\xdb\xbe\x09\xcf\x70\xf8\x81\xec\x56\x8d\x57\x4a\x2f\xfd\x4d\xab\xe5\xee\x98\x20\xad\xaa\x47\x8e\x56\xfd\x8f\x4b\xa5\xd0\x9f\xfa\x1c\x6d\x92\x7c\x40\xf4\xc3\x37\x30\x40\x49\xe8\xa9\x52\xfb\xcb\xf4\x5c\x6f\xa7\x7a\x41\xa4" ) ] tests = testGroup "Scrypt" $ map toCase $ zip [(1::Int)..] vectors where toCase (i, ((pass,salt,n,r,p,dklen), output)) = testCase (show i) (output @=? Scrypt.generate (Scrypt.Parameters n r p dklen) pass salt) cryptonite-0.23/tests/KAT_TripleDES.hs0000644000000000000000000000047112512146401016012 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ViewPatterns #-} module KAT_TripleDES (tests) where import Imports import BlockCipher import qualified Crypto.Cipher.TripleDES as TripleDES kats = defaultKATs tests = localOption (QuickCheckTests 5) $ testBlockCipher kats (undefined :: TripleDES.DES_EEE3) cryptonite-0.23/tests/KAT_Twofish.hs0000644000000000000000000000554313075454604015663 0ustar0000000000000000module KAT_Twofish (tests) where import Imports import BlockCipher import qualified Data.ByteString as B import Crypto.Cipher.Twofish vectors_twofish128 = [ KAT_ECB (B.replicate 16 0x00) (B.replicate 16 0x00) (B.pack [0x9F,0x58,0x9F,0x5C,0xF6,0x12,0x2C,0x32,0xB6,0xBF,0xEC,0x2F,0x2A,0xE8,0xC3,0x5A]) , KAT_ECB (B.pack [0x9F,0x58,0x9F,0x5C,0xF6,0x12,0x2C,0x32,0xB6,0xBF,0xEC,0x2F,0x2A,0xE8,0xC3,0x5A]) (B.pack [0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19]) (B.pack [0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3]) ] vectors_twofish192 = [ KAT_ECB (B.pack [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77]) (B.pack [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) (B.pack [0xCF, 0xD1, 0xD2, 0xE5, 0xA9, 0xBE, 0x9C, 0xDF, 0x50, 0x1F, 0x13, 0xB8, 0x92, 0xBD, 0x22, 0x48]) , KAT_ECB (B.pack [0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44]) (B.pack [0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2]) (B.pack [0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65])] vectors_twofish256 = [ KAT_ECB (B.pack [0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF]) (B.pack [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) (B.pack [0x37, 0x52, 0x7B, 0xE0, 0x05, 0x23, 0x34, 0xB8, 0x9F, 0x0C, 0xFC, 0xCA, 0xE8, 0x7C, 0xFA, 0x20]) , KAT_ECB (B.pack [0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F]) (B.pack [0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6]) (B.pack [0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA])] kats128 = defaultKATs { kat_ECB = vectors_twofish128 } kats192 = defaultKATs { kat_ECB = vectors_twofish192 } kats256 = defaultKATs { kat_ECB = vectors_twofish256 } tests = testGroup "Twofish" [ testBlockCipher kats128 (undefined :: Twofish128) , testBlockCipher kats192 (undefined :: Twofish192) , testBlockCipher kats256 (undefined :: Twofish256) ] cryptonite-0.23/tests/Number.hs0000644000000000000000000001512213050556742014762 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Number (tests) where import Imports import Data.ByteArray (Bytes) import Crypto.Number.Basic import Crypto.Number.Generate import Crypto.Number.Serialize import Crypto.Number.Prime import Data.Bits serializationVectors :: [(Int, Integer, ByteString)] serializationVectors = [ (128, 468189858948067662094510918729062682059955669513914188715630930503497261316361784677177564296207557978182700664806717692596876084916561811001371208806217360635705059859428069669992937334724312890015700331031248133952795914192719979937664050389500162437642525331653766885896869239678885404647468665996400635, "\x00\xaa\xae\x74\xc8\xec\x3c\x36\x06\x5e\x46\xca\x8e\x57\xab\x09\x87\xfd\xcd\x1f\xa4\xe7\xf9\xd2\x60\xd5\x4a\x1b\x74\xdc\xa8\x75\xd8\xdd\xff\x2b\x74\x28\x14\x59\x67\x6c\x82\xae\xa3\xa5\x1d\x3f\xb4\xb7\xfe\x5c\xd2\xf0\x7f\xd8\xd9\xa9\xb0\xce\x26\xc1\x26\x74\x96\xf5\xf6\x4c\x8f\x66\x7f\x5d\xf1\x68\x38\xd4\x03\x62\xe9\x30\xc8\xa1\xc1\x84\x97\x62\x20\xfd\xd7\x03\x35\xc1\x25\x45\x1b\x86\x81\x3d\xa4\x92\xc0\xd3\xdd\xfa\x86\x1d\xdf\x0a\xbb\xf4\xc0\x56\xf7\xa2\xb0\x3b\x52\xf7\xa5\x89\x4c\x69\x34\x91\x46\xd9\x57\xfb") , (128, 40031303476923779996794876613623495515025748694978019540894726181695410095832601107261950025830235596060960914255795497479135806963313279476038687192202016132891881954743054164975707083302554941058329647014950354509055121290280892911153779672733723699997592027662953953692834215577119173225643193201177329, "\x00\x0e\x97\xf9\xd5\x79\xb9\x90\x7c\x85\x48\x49\x01\x19\x64\xfb\x76\x31\xcd\x51\xfb\x8a\x9d\x55\xe5\xd3\x7b\x87\x2d\xad\x63\x2d\x6b\x1c\x84\x3f\x65\x95\xb6\xf3\x1a\xa9\x43\x3f\x06\x46\x7b\xf8\xf3\x35\x45\x84\x11\x56\x91\x53\x43\xd7\xe1\x6d\x80\x64\x14\x45\x35\x4e\x93\x7d\x5e\x48\xec\xe0\x79\x7b\x44\x8e\xab\x0f\xc4\x5f\xc6\xa1\x71\xee\x37\xb1\x55\x51\x98\x44\x57\xe3\xc3\x56\x3a\x50\x27\xaf\xa5\x1d\x1a\x0a\x90\x19\x0d\x14\xed\x3d\x93\x40\x62\x76\xa3\xaa\x00\x23\x86\xca\x98\xb2\x6e\x02\x43\xa7\xbc\xb1\xb2\xf1") , (128, 75152325976543603337003024341071663845101857195436434620947904288957274825323005869230041326941600298094896018190395352332646796347130114769768242670539699217743549573961461985255265474392937773768121046339453584830072421569334022498680626938734088755136253492360177084153487115846920446085149631919580041, "\x00\x1b\x65\xb1\x73\x74\xed\xd2\xcb\xb8\xf3\x6b\x3f\xc2\x05\xaa\x91\xab\x48\x5b\x03\x30\xae\x24\xa3\xec\x7a\x6a\xf0\x34\x73\x18\x04\xea\xe4\xd6\x19\x97\xc4\xc1\x13\x7d\x12\x0d\xd5\xcb\xbd\x18\x05\xc2\xce\x87\x66\x84\x12\xe8\x24\xa3\x31\x69\xfa\xf4\x2c\x21\x53\xa6\x04\x74\x78\xc4\x93\x0d\x38\x7f\x28\xfe\x80\x8e\xd2\x7b\x20\xc8\xf5\x1f\x0f\x73\x68\xb2\xe5\x08\xf1\x94\xa1\xe6\xcf\x3a\x2c\x12\x63\xda\x08\x3a\x78\x12\xb8\x11\x23\x3c\x38\x38\x10\x94\x2b\xac\x64\x5d\x67\x0c\xb6\x0d\xc3\x9a\x45\x39\x50\x8a\x63\x89") , (128, 132094272981815297755209818914225029878347650582749561568514551350741192910991391836297682842650690115955454061006435646226436379226218676796260483719213285072886626400953065229934239690821114513313427305727000011361769875430428291375851099221794646192854831002408178061474948738788927399080262963320752452, "\x00\x30\x27\xe0\xbf\x46\xec\x77\x2d\xc6\x06\x77\xbc\x68\x87\x3c\x1b\x2e\xc7\xb7\x6c\x88\x25\xec\x8c\x95\xbf\x74\xe5\x37\x01\x25\x96\xe1\x70\x33\x5c\x7d\xab\x1f\xc2\x9c\xad\xf7\xca\x26\x85\x2d\xfc\x8f\xc7\xab\x49\x28\xa4\x47\xe6\xd5\x6e\xfa\x0a\xbb\x57\xe4\xa2\x51\xc7\xc6\x12\x0f\xa9\x98\x69\xb8\x05\x84\xc5\xe3\x28\x86\x0f\x54\x1d\xf9\x92\x42\x9f\xb1\x77\x2b\x58\x89\xe2\xfc\x22\xb0\x1e\x71\x78\xea\x39\xc1\x87\x4f\xd4\x83\x2c\x96\x1d\xea\xd5\xf9\xf9\xb9\x7b\x86\xfa\xf6\xad\x5b\xb1\x3c\xe7\x11\xd7\x96\x89\x44") , (128, 577245873336454863811643140721674509319073059708446946821011267146688442860798353087462545395033001525475835015592425207995480357299993009193426638306801669333644226765032464458284920004140299209138389393494751627076239104390434285377314678827349631962212281858308570255468721491493027423799738158196939966, "\x00\xd2\x70\x41\xdb\x3d\xb5\xfe\x8c\xef\x79\xcf\x5b\x7b\x37\xb0\x05\xb8\x5a\x9b\x7d\x01\x28\xc7\xf5\x5a\x02\xba\xce\xbc\xf5\x8e\x91\x59\xd0\x42\x6f\x04\x82\x4b\x78\xb0\xdd\x91\x2e\x15\x9d\xea\x4f\x0c\x21\xc0\x67\x54\xa2\x39\xa8\xe1\x13\x8f\xa9\xff\x46\x2d\x11\x56\x04\xa0\xde\x64\xc8\x0f\xf4\x2c\xd2\x31\xdf\x2a\xfd\xac\xc7\x25\x58\xc8\xea\xfd\x47\x6e\xdd\x2a\x53\x02\x77\x49\xa7\x0d\x18\xfb\x05\x18\x4b\x28\xd3\xa2\x39\x8c\x83\x80\x90\xd1\xa8\x81\x56\x6f\xd1\x94\x9d\x65\x34\x95\x79\xc1\x27\xbc\x76\xc3\x5c\xbe") ] tests = testGroup "number" [ testProperty "num-bits" $ \(Int1_2901 i) -> and [ (numBits (2^i-1) == i) , (numBits (2^i) == i+1) , (numBits (2^i + (2^i-1)) == i+1) ] , testProperty "num-bits2" $ \(Positive i) -> not (i `testBit` numBits i) && (i `testBit` (numBits i - 1)) , testProperty "generate-param" $ \testDRG (Int1_2901 bits) -> let r = withTestDRG testDRG $ generateParams bits (Just SetHighest) False in r >= 0 && numBits r == bits && testBit r (bits-1) , testProperty "generate-param2" $ \testDRG (Int1_2901 m1bits) -> let bits = m1bits + 1 -- make sure minimum is 2 r = withTestDRG testDRG $ generateParams bits (Just SetTwoHighest) False in r >= 0 && numBits r == bits && testBit r (bits-1) && testBit r (bits-2) , testProperty "generate-param-odd" $ \testDRG (Int1_2901 bits) -> let r = withTestDRG testDRG $ generateParams bits Nothing True in r >= 0 && odd r , testProperty "generate-range" $ \testDRG (Positive range) -> let r = withTestDRG testDRG $ generateMax range in 0 <= r && r < range , testProperty "generate-prime" $ \testDRG (Int0_2901 baseBits') -> let baseBits = baseBits' `mod` 800 bits = 5 + baseBits -- generating lower than 5 bits causes an error .. prime = withTestDRG testDRG $ generatePrime bits in bits == numBits prime , testProperty "generate-safe-prime" $ \testDRG (Int0_2901 baseBits') -> let baseBits = baseBits' `mod` 200 bits = 6 + baseBits prime = withTestDRG testDRG $ generateSafePrime bits in bits == numBits prime , testProperty "marshalling" $ \qaInt -> getQAInteger qaInt == os2ip (i2osp (getQAInteger qaInt) :: Bytes) , testGroup "marshalling-kat-to-bytearray" $ map toSerializationKat $ zip [katZero..] serializationVectors , testGroup "marshalling-kat-to-integer" $ map toSerializationKatInteger $ zip [katZero..] serializationVectors ] where toSerializationKat (i, (sz, n, ba)) = testCase (show i) (ba @=? i2ospOf_ sz n) toSerializationKatInteger (i, (_, n, ba)) = testCase (show i) (n @=? os2ip ba) cryptonite-0.23/tests/Padding.hs0000644000000000000000000000252312727442704015103 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Padding (tests) where import qualified Data.ByteString as B import Imports import Crypto.Error import Crypto.Data.Padding cases = [ ("abcdef", 8, "abcdef\x02\x02") , ("abcd", 4, "abcd\x04\x04\x04\x04") , ("xyze", 5, "xyze\x01") ] zeroCases = [ ("", 4, "\NUL\NUL\NUL\NUL", Nothing) , ("abcdef", 8, "abcdef\NUL\NUL", Nothing) , ("0123456789abcdef", 16, "0123456789abcdef", Just "0123456789abcdef") ] --instance Arbitrary where testPad :: Int -> (B.ByteString, Int, B.ByteString) -> TestTree testPad n (inp, sz, padded) = testCase (show n) $ propertyHoldCase [ eqTest "padded" padded (pad (PKCS7 sz) inp) , eqTest "unpadded" (Just inp) (unpad (PKCS7 sz) padded) ] testZeroPad :: Int -> (B.ByteString, Int, B.ByteString, Maybe B.ByteString) -> TestTree testZeroPad n (inp, sz, padded, unpadded) = testCase (show n) $ propertyHoldCase [ eqTest "padded" padded (pad (ZERO sz) inp) , eqTest "unpadded" unpadded (unpad (ZERO sz) padded) ] tests = testGroup "Padding" [ testGroup "Cases" $ map (uncurry testPad) (zip [1..] cases) , testGroup "ZeroCases" $ map (uncurry testZeroPad) (zip [1..] zeroCases) ] cryptonite-0.23/tests/Poly1305.hs0000644000000000000000000000260212567303757014775 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Poly1305 (tests) where import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as B () import Imports import Crypto.Error import qualified Crypto.MAC.Poly1305 as Poly1305 import qualified Data.ByteArray as B (convert) instance Show Poly1305.Auth where show _ = "Auth" data Chunking = Chunking Int Int deriving (Show,Eq) instance Arbitrary Chunking where arbitrary = Chunking <$> choose (1,34) <*> choose (1,2048) tests = testGroup "Poly1305" [ testCase "V0" $ let key = "\x85\xd6\xbe\x78\x57\x55\x6d\x33\x7f\x44\x52\xfe\x42\xd5\x06\xa8\x01\x03\x80\x8a\xfb\x0d\xb2\xfd\x4a\xbf\xf6\xaf\x41\x49\xf5\x1b" :: ByteString msg = "Cryptographic Forum Research Group" :: ByteString tag = "\xa8\x06\x1d\xc1\x30\x51\x36\xc6\xc2\x2b\x8b\xaf\x0c\x01\x27\xa9" :: ByteString in tag @=? B.convert (Poly1305.auth key msg) , testProperty "Chunking" $ \(Chunking chunkLen totalLen) -> let key = B.replicate 32 0 msg = B.pack $ take totalLen $ concat (replicate 10 [1..255]) in Poly1305.auth key msg == Poly1305.finalize (foldr (flip Poly1305.update) (throwCryptoError $ Poly1305.initialize key) (chunks chunkLen msg)) ] where chunks i bs | B.length bs < i = [bs] | otherwise = let (b1,b2) = B.splitAt i bs in b1 : chunks i b2 cryptonite-0.23/tests/Salsa.hs0000644000000000000000000001431512527624334014601 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Salsa (tests) where import qualified Data.ByteString as B import qualified Crypto.Cipher.Salsa as Salsa import Imports type Vector = (Int, B.ByteString, B.ByteString, [(Int, B.ByteString)]) vectors :: [Vector] vectors = [ (20, key, iv , [ (0, "\x99\xA8\xCC\xEC\x6C\x5B\x2A\x0B\x6E\x33\x6C\xB2\x06\x52\x24\x1C\x32\xB2\x4D\x34\xAC\xC0\x45\x7E\xF6\x79\x17\x8E\xDE\x7C\xF8\x05\x80\x5A\x93\x05\xC7\xC4\x99\x09\x68\x3B\xD1\xA8\x03\x32\x78\x17\x62\x7C\xA4\x6F\xE8\xB9\x29\xB6\xDF\x00\x12\xBD\x86\x41\x83\xBE") , (192, "\x2D\x22\x6C\x11\xF4\x7B\x3C\x0C\xCD\x09\x59\xB6\x1F\x59\xD5\xCC\x30\xFC\xEF\x6D\xBB\x8C\xBB\x3D\xCC\x1C\xC2\x52\x04\xFC\xD4\x49\x8C\x37\x42\x6A\x63\xBE\xA3\x28\x2B\x1A\x8A\x0D\x60\xE1\x3E\xB2\xFE\x59\x24\x1A\x9F\x6A\xF4\x26\x68\x98\x66\xED\xC7\x69\xE1\xE6\x48\x2F\xE1\xC1\x28\xA1\x5C\x11\x23\xB5\x65\x5E\xD5\x46\xDF\x01\x4C\xE0\xC4\x55\xDB\xF5\xD3\xA1\x3D\x9C\xD4\xF0\xE2\xD1\xDA\xB9\xF1\x2F\xB6\x8C\x54\x42\x61\xD7\xF8\x8E\xAC\x1C\x6C\xBF\x99\x3F\xBB\xB8\xE0\xAA\x85\x10\xBF\xF8\xE7\x38\x35\xA1\xE8\x6E\xAD\xBB") , (448, "\x05\x97\x18\x8A\x1C\x19\x25\x57\x69\xBE\x1C\x21\x03\x99\xAD\x17\x2E\xB4\x6C\x52\xF9\x2F\xD5\x41\xDF\x2E\xAD\x71\xB1\xFF\x8E\xA7\xAD\xD3\x80\xEC\x71\xA5\xFD\x7A\xDB\x51\x81\xEA\xDD\x18\x25\xEC\x02\x77\x9A\x45\x09\xBE\x58\x32\x70\x8C\xA2\x83\x6C\x16\x93\xA5") ]) , (20 , "\x00\x53\xA6\xF9\x4C\x9F\xF2\x45\x98\xEB\x3E\x91\xE4\x37\x8A\xDD\x30\x83\xD6\x29\x7C\xCF\x22\x75\xC8\x1B\x6E\xC1\x14\x67\xBA\x0D" , "\x0D\x74\xDB\x42\xA9\x10\x77\xDE" , [ (0, "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58\xC4\xAE\xA0\xD0\xED\x9A\x96\x01\xF2\x78\x11\x2C\xA7\x18\x0D\x56\x5B\x42\x0A\x48\x01\x96\x70\xEA\xF2\x4C\xE4\x93\xA8\x62\x63\xF6\x77\xB4\x6A\xCE\x19\x24\x77\x3D\x2B\xB2\x55\x71\xE1\xAA\x85\x93\x75\x8F\xC3\x82\xB1\x28\x0B\x71") , (65472, "\xB7\x0C\x50\x13\x9C\x63\x33\x2E\xF6\xE7\x7A\xC5\x43\x38\xA4\x07\x9B\x82\xBE\xC9\xF9\xA4\x03\xDF\xEA\x82\x1B\x83\xF7\x86\x07\x91\x65\x0E\xF1\xB2\x48\x9D\x05\x90\xB1\xDE\x77\x2E\xED\xA4\xE3\xBC\xD6\x0F\xA7\xCE\x9C\xD6\x23\xD9\xD2\xFD\x57\x58\xB8\x65\x3E\x70\x81\x58\x2C\x65\xD7\x56\x2B\x80\xAE\xC2\xF1\xA6\x73\xA9\xD0\x1C\x9F\x89\x2A\x23\xD4\x91\x9F\x6A\xB4\x7B\x91\x54\xE0\x8E\x69\x9B\x41\x17\xD7\xC6\x66\x47\x7B\x60\xF8\x39\x14\x81\x68\x2F\x5D\x95\xD9\x66\x23\xDB\xC4\x89\xD8\x8D\xAA\x69\x56\xB9\xF0\x64\x6B\x6E") , (131008, "\xA1\x3F\xFA\x12\x08\xF8\xBF\x50\x90\x08\x86\xFA\xAB\x40\xFD\x10\xE8\xCA\xA3\x06\xE6\x3D\xF3\x95\x36\xA1\x56\x4F\xB7\x60\xB2\x42\xA9\xD6\xA4\x62\x8C\xDC\x87\x87\x62\x83\x4E\x27\xA5\x41\xDA\x2A\x5E\x3B\x34\x45\x98\x9C\x76\xF6\x11\xE0\xFE\xC6\xD9\x1A\xCA\xCC") ]) ] where key :: B.ByteString key = "\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09" iv = B.replicate 8 0 newtype RandomVector = RandomVector Vector deriving (Show,Eq) instance Arbitrary RandomVector where arbitrary = RandomVector <$> elements vectors tests = testGroup "Salsa" [ testGroup "KAT" $ map (\(i,f) -> testCase (show (i :: Int)) f) $ zip [1..] $ map (\(r, k,i,e) -> salsaRunSimple e r k i) vectors , testProperty "generate-combine" salsaGenerateCombine , testProperty "chunking-generate" salsaGenerateChunks , testProperty "chunking-combine" salsaCombineChunks ] where salsaRunSimple expected rounds key nonce = let salsa = Salsa.initialize rounds key nonce in map snd expected @=? salsaLoop 0 salsa expected salsaLoop _ _ [] = [] salsaLoop current salsa (r@(ofs,expectBs):rs) | current < ofs = let (_, salsaNext) = Salsa.generate salsa (ofs - current) :: (ByteString, Salsa.State) in salsaLoop ofs salsaNext (r:rs) | current == ofs = let (e, salsaNext) = Salsa.generate salsa (B.length expectBs) in e : salsaLoop (current + B.length expectBs) salsaNext rs | otherwise = error "internal error in salsaLoop" salsaGenerateCombine :: ChunkingLen0_127 -> RandomVector -> Int0_2901 -> Bool salsaGenerateCombine (ChunkingLen0_127 ckLen) (RandomVector (rounds, key, iv, _)) (Int0_2901 nbBytes) = let initSalsa = Salsa.initialize rounds key iv in loop nbBytes ckLen initSalsa where loop n [] salsa = loop n ckLen salsa loop 0 _ _ = True loop n (x:xs) salsa = let len = min x n (c1, next) = Salsa.generate salsa len (c2, _) = Salsa.combine salsa (B.replicate len 0) in if c1 == c2 then loop (n - len) xs next else False salsaGenerateChunks :: ChunkingLen -> RandomVector -> Bool salsaGenerateChunks (ChunkingLen ckLen) (RandomVector (rounds, key, iv, _)) = let initSalsa = Salsa.initialize rounds key iv nbBytes = 1048 (expected,_) = Salsa.generate initSalsa nbBytes chunks = loop nbBytes ckLen (Salsa.initialize rounds key iv) in expected == B.concat chunks where loop n [] salsa = loop n ckLen salsa loop 0 _ _ = [] loop n (x:xs) salsa = let len = min x n (c, next) = Salsa.generate salsa len in c : loop (n - len) xs next salsaCombineChunks :: ChunkingLen -> RandomVector -> ArbitraryBS0_2901 -> Bool salsaCombineChunks (ChunkingLen ckLen) (RandomVector (rounds, key, iv, _)) (ArbitraryBS0_2901 wholebs) = let initSalsa = Salsa.initialize rounds key iv (expected,_) = Salsa.combine initSalsa wholebs chunks = loop wholebs ckLen initSalsa in expected `propertyEq` B.concat chunks where loop bs [] salsa = loop bs ckLen salsa loop bs (x:xs) salsa | B.null bs = [] | otherwise = let (bs1, bs2) = B.splitAt (min x (B.length bs)) bs (c, next) = Salsa.combine salsa bs1 in c : loop bs2 xs next cryptonite-0.23/tests/Tests.hs0000644000000000000000000000366113075454604014642 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Main where import Imports import qualified Number import qualified Number.F2m import qualified BCrypt import qualified Hash import qualified Poly1305 import qualified Salsa import qualified XSalsa import qualified ChaCha import qualified ChaChaPoly1305 import qualified KAT_MiyaguchiPreneel import qualified KAT_CMAC import qualified KAT_HMAC import qualified KAT_HKDF import qualified KAT_Argon2 import qualified KAT_PBKDF2 import qualified KAT_Curve25519 import qualified KAT_Curve448 import qualified KAT_Ed25519 import qualified KAT_OTP import qualified KAT_PubKey import qualified KAT_Scrypt -- symmetric cipher -------------------- import qualified KAT_AES import qualified KAT_Blowfish import qualified KAT_Camellia import qualified KAT_DES import qualified KAT_RC4 import qualified KAT_TripleDES import qualified KAT_Twofish -- misc -------------------------------- import qualified KAT_AFIS import qualified Padding tests = testGroup "cryptonite" [ Number.tests , Number.F2m.tests , Hash.tests , Padding.tests , testGroup "ConstructHash" [ KAT_MiyaguchiPreneel.tests ] , testGroup "MAC" [ Poly1305.tests , KAT_CMAC.tests , KAT_HMAC.tests ] , KAT_Curve25519.tests , KAT_Curve448.tests , KAT_Ed25519.tests , KAT_PubKey.tests , KAT_OTP.tests , testGroup "KDF" [ KAT_PBKDF2.tests , KAT_Scrypt.tests , BCrypt.tests , KAT_HKDF.tests , KAT_Argon2.tests ] , testGroup "block-cipher" [ KAT_AES.tests , KAT_Blowfish.tests , KAT_Camellia.tests , KAT_DES.tests , KAT_TripleDES.tests , KAT_Twofish.tests ] , testGroup "stream-cipher" [ KAT_RC4.tests , ChaCha.tests , ChaChaPoly1305.tests , Salsa.tests , XSalsa.tests ] , KAT_AFIS.tests ] main = defaultMain tests cryptonite-0.23/tests/Utils.hs0000644000000000000000000001130612567614233014634 0ustar0000000000000000{-# LANGUAGE ExistentialQuantification #-} module Utils where import Control.Applicative import Control.Monad (replicateM) import Data.Char import Data.Word import Data.List import Data.ByteString (ByteString) import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L import Crypto.Random import Crypto.Number.Serialize (os2ip) import Prelude import Test.Tasty.QuickCheck import Test.Tasty.HUnit ((@=?)) newtype TestDRG = TestDRG (Word64, Word64, Word64, Word64, Word64) deriving (Show,Eq) instance Arbitrary TestDRG where arbitrary = TestDRG `fmap` arbitrary withTestDRG (TestDRG l) f = fst $ withDRG (drgNewTest l) f newtype ChunkingLen = ChunkingLen [Int] deriving (Show,Eq) instance Arbitrary ChunkingLen where arbitrary = ChunkingLen `fmap` replicateM 16 (choose (0,14)) newtype ChunkingLen0_127 = ChunkingLen0_127 [Int] deriving (Show,Eq) instance Arbitrary ChunkingLen0_127 where arbitrary = ChunkingLen0_127 `fmap` replicateM 16 (choose (0,127)) newtype ArbitraryBS0_2901 = ArbitraryBS0_2901 ByteString deriving (Show,Eq,Ord) instance Arbitrary ArbitraryBS0_2901 where arbitrary = ArbitraryBS0_2901 `fmap` arbitraryBSof 0 2901 newtype Int0_2901 = Int0_2901 Int deriving (Show,Eq,Ord) newtype Int1_2901 = Int1_2901 Int deriving (Show,Eq,Ord) instance Arbitrary Int0_2901 where arbitrary = Int0_2901 `fmap` choose (0,2901) instance Arbitrary Int1_2901 where arbitrary = Int1_2901 `fmap` choose (1,2901) -- | a integer wrapper with a better range property newtype QAInteger = QAInteger { getQAInteger :: Integer } deriving (Show,Eq) instance Arbitrary QAInteger where arbitrary = oneof [ QAInteger . fromIntegral <$> (choose (0, 65536) :: Gen Int) -- small integer , larger <$> choose (0,4096) <*> choose (0, 65536) -- medium integer , QAInteger . os2ip . B.pack <$> (choose (0,32) >>= \n -> replicateM n arbitrary) -- [ 0 .. 2^32 ] sized integer ] where larger :: Int -> Int -> QAInteger larger p b = QAInteger (fromIntegral p * somePrime + fromIntegral b) somePrime :: Integer somePrime = 18446744073709551557 arbitraryBS :: Int -> Gen ByteString arbitraryBS n = B.pack `fmap` replicateM n arbitrary arbitraryBSof :: Int -> Int -> Gen ByteString arbitraryBSof minSize maxSize = choose (minSize, maxSize) >>= \n -> (B.pack `fmap` replicateM n arbitrary) chunkS :: ChunkingLen -> ByteString -> [ByteString] chunkS (ChunkingLen originalChunks) = loop originalChunks where loop l bs | B.null bs = [] | otherwise = case l of (x:xs) -> let (b1, b2) = B.splitAt x bs in b1 : loop xs b2 [] -> loop originalChunks bs chunksL :: ChunkingLen -> L.ByteString -> L.ByteString chunksL (ChunkingLen originalChunks) = L.fromChunks . loop originalChunks . L.toChunks where loop _ [] = [] loop l (b:bs) | B.null b = loop l bs | otherwise = case l of (x:xs) -> let (b1, b2) = B.splitAt x b in b1 : loop xs (b2:bs) [] -> loop originalChunks (b:bs) katZero :: Int katZero = 0 --hexalise :: String -> [Word8] hexalise s = concatMap (\c -> [ hex $ c `div` 16, hex $ c `mod` 16 ]) s where hex i | i >= 0 && i <= 9 = fromIntegral (ord '0') + i | i >= 10 && i <= 15 = fromIntegral (ord 'a') + i - 10 | otherwise = 0 splitB :: Int -> ByteString -> [ByteString] splitB l b = if B.length b > l then let (b1, b2) = B.splitAt l b in b1 : splitB l b2 else [ b ] assertBytesEq :: ByteString -> ByteString -> Bool assertBytesEq b1 b2 | b1 /= b2 = error ("expected: " ++ show b1 ++ " got: " ++ show b2) | otherwise = True assertEq :: (Show a, Eq a) => a -> a -> Bool assertEq b1 b2 | b1 /= b2 = error ("expected: " ++ show b1 ++ " got: " ++ show b2) | otherwise = True propertyEq :: (Show a, Eq a) => a -> a -> Bool propertyEq = assertEq data PropertyTest = forall a . (Show a, Eq a) => EqTest String a a type PropertyName = String eqTest :: (Show a, Eq a) => PropertyName -> a -- ^ expected value -> a -- ^ got -> PropertyTest eqTest name a b = EqTest name a b propertyHold :: [PropertyTest] -> Bool propertyHold l = case foldl runProperty [] l of [] -> True failed -> error (intercalate "\n" failed) where runProperty acc (EqTest name a b) | a == b = acc | otherwise = (name ++ ": expected " ++ show a ++ " but got: " ++ show b) : acc propertyHoldCase :: [PropertyTest] -> IO () propertyHoldCase l = True @=? propertyHold l cryptonite-0.23/tests/XSalsa.hs0000644000000000000000000005467512777073622014753 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module XSalsa (tests) where import qualified Data.ByteString as B import qualified Crypto.Cipher.XSalsa as XSalsa import Imports type Vector = (Int, B.ByteString, B.ByteString, B.ByteString, B.ByteString) -- Test vectors generated by naclcrypto library (https://nacl.cr.yp.to) vectors :: [Vector] vectors = [ ( 20 , "\xA6\xA7\x25\x1C\x1E\x72\x91\x6D\x11\xC2\xCB\x21\x4D\x3C\x25\x25\x39\x12\x1D\x8E\x23\x4E\x65\x2D\x65\x1F\xA4\xC8\xCF\xF8\x80\x30" , "\x9E\x64\x5A\x74\xE9\xE0\xA6\x0D\x82\x43\xAC\xD9\x17\x7A\xB5\x1A\x1B\xEB\x8D\x5A\x2F\x5D\x70\x0C" , "\x09\x3C\x5E\x55\x85\x57\x96\x25\x33\x7B\xD3\xAB\x61\x9D\x61\x57\x60\xD8\xC5\xB2\x24\xA8\x5B\x1D\x0E\xFE\x0E\xB8\xA7\xEE\x16\x3A\xBB\x03\x76\x52\x9F\xCC\x09\xBA\xB5\x06\xC6\x18\xE1\x3C\xE7\x77\xD8\x2C\x3A\xE9\xD1\xA6\xF9\x72\xD4\x16\x02\x87\xCB\xFE\x60\xBF\x21\x30\xFC\x0A\x6F\xF6\x04\x9D\x0A\x5C\x8A\x82\xF4\x29\x23\x1F\x00\x80\x82\xE8\x45\xD7\xE1\x89\xD3\x7F\x9E\xD2\xB4\x64\xE6\xB9\x19\xE6\x52\x3A\x8C\x12\x10\xBD\x52\xA0\x2A\x4C\x3F\xE4\x06\xD3\x08\x5F\x50\x68\xD1\x90\x9E\xEE\xCA\x63\x69\xAB\xC9\x81\xA4\x2E\x87\xFE\x66\x55\x83\xF0\xAB\x85\xAE\x71\xF6\xF8\x4F\x52\x8E\x6B\x39\x7A\xF8\x6F\x69\x17\xD9\x75\x4B\x73\x20\xDB\xDC\x2F\xEA\x81\x49\x6F\x27\x32\xF5\x32\xAC\x78\xC4\xE9\xC6\xCF\xB1\x8F\x8E\x9B\xDF\x74\x62\x2E\xB1\x26\x14\x14\x16\x77\x69\x71\xA8\x4F\x94\xD1\x56\xBE\xAF\x67\xAE\xCB\xF2\xAD\x41\x2E\x76\xE6\x6E\x8F\xAD\x76\x33\xF5\xB6\xD7\xF3\xD6\x4B\x5C\x6C\x69\xCE\x29\x00\x3C\x60\x24\x46\x5A\xE3\xB8\x9B\xE7\x8E\x91\x5D\x88\xB4\xB5\x62\x1D" , "\xB2\xAF\x68\x8E\x7D\x8F\xC4\xB5\x08\xC0\x5C\xC3\x9D\xD5\x83\xD6\x71\x43\x22\xC6\x4D\x7F\x3E\x63\x14\x7A\xED\xE2\xD9\x53\x49\x34\xB0\x4F\xF6\xF3\x37\xB0\x31\x81\x5C\xD0\x94\xBD\xBC\x6D\x7A\x92\x07\x7D\xCE\x70\x94\x12\x28\x68\x22\xEF\x07\x37\xEE\x47\xF6\xB7\xFF\xA2\x2F\x9D\x53\xF1\x1D\xD2\xB0\xA3\xBB\x9F\xC0\x1D\x9A\x88\xF9\xD5\x3C\x26\xE9\x36\x5C\x2C\x3C\x06\x3B\xC4\x84\x0B\xFC\x81\x2E\x4B\x80\x46\x3E\x69\xD1\x79\x53\x0B\x25\xC1\x58\xF5\x43\x19\x1C\xFF\x99\x31\x06\x51\x1A\xA0\x36\x04\x3B\xBC\x75\x86\x6A\xB7\xE3\x4A\xFC\x57\xE2\xCC\xE4\x93\x4A\x5F\xAA\xE6\xEA\xBE\x4F\x22\x17\x70\x18\x3D\xD0\x60\x46\x78\x27\xC2\x7A\x35\x41\x59\xA0\x81\x27\x5A\x29\x1F\x69\xD9\x46\xD6\xFE\x28\xED\x0B\x9C\xE0\x82\x06\xCF\x48\x49\x25\xA5\x1B\x94\x98\xDB\xDE\x17\x8D\xDD\x3A\xE9\x1A\x85\x81\xB9\x16\x82\xD8\x60\xF8\x40\x78\x2F\x6E\xEA\x49\xDB\xB9\xBD\x72\x15\x01\xD2\xC6\x71\x22\xDE\xA3\xB7\x28\x38\x48\xC5\xF1\x3E\x0C\x0D\xE8\x76\xBD\x22\x7A\x85\x6E\x4D\xE5\x93\xA3") , ( 20 , "\x9E\x1D\xA2\x39\xD1\x55\xF5\x2A\xD3\x7F\x75\xC7\x36\x8A\x53\x66\x68\xB0\x51\x95\x29\x23\xAD\x44\xF5\x7E\x75\xAB\x58\x8E\x47\x5A" , "\xAF\x06\xF1\x78\x59\xDF\xFA\x79\x98\x91\xC4\x28\x8F\x66\x35\xB5\xC5\xA4\x5E\xEE\x90\x17\xFD\x72" , "\xFE\xAC\x9D\x54\xFC\x8C\x11\x5A\xE2\x47\xD9\xA7\xE9\x19\xDD\x76\xCF\xCB\xC7\x2D\x32\xCA\xE4\x94\x48\x60\x81\x7C\xBD\xFB\x8C\x04\xE6\xB1\xDF\x76\xA1\x65\x17\xCD\x33\xCC\xF1\xAC\xDA\x92\x06\x38\x9E\x9E\x31\x8F\x59\x66\xC0\x93\xCF\xB3\xEC\x2D\x9E\xE2\xDE\x85\x64\x37\xED\x58\x1F\x55\x2F\x26\xAC\x29\x07\x60\x9D\xF8\xC6\x13\xB9\xE3\x3D\x44\xBF\xC2\x1F\xF7\x91\x53\xE9\xEF\x81\xA9\xD6\x6C\xC3\x17\x85\x7F\x75\x2C\xC1\x75\xFD\x88\x91\xFE\xFE\xBB\x7D\x04\x1E\x65\x17\xC3\x16\x2D\x19\x7E\x21\x12\x83\x7D\x3B\xC4\x10\x43\x12\xAD\x35\xB7\x5E\xA6\x86\xE7\xC7\x0D\x4E\xC0\x47\x46\xB5\x2F\xF0\x9C\x42\x14\x51\x45\x9F\xB5\x9F" , "\x2C\x26\x1A\x2F\x4E\x61\xA6\x2E\x1B\x27\x68\x99\x16\xBF\x03\x45\x3F\xCB\xC9\x7B\xB2\xAF\x6F\x32\x93\x91\xEF\x06\x3B\x5A\x21\x9B\xF9\x84\xD0\x7D\x70\xF6\x02\xD8\x5F\x6D\xB6\x14\x74\xE9\xD9\xF5\xA2\xDE\xEC\xB4\xFC\xD9\x01\x84\xD1\x6F\x3B\x5B\x5E\x16\x8E\xE0\x3E\xA8\xC9\x3F\x39\x33\xA2\x2B\xC3\xD1\xA5\xAE\x8C\x2D\x8B\x02\x75\x7C\x87\xC0\x73\x40\x90\x52\xA2\xA8\xA4\x1E\x7F\x48\x7E\x04\x1F\x9A\x49\xA0\x99\x7B\x54\x0E\x18\x62\x1C\xAD\x3A\x24\xF0\xA5\x6D\x9B\x19\x22\x79\x29\x05\x7A\xB3\xBA\x95\x0F\x62\x74\xB1\x21\xF1\x93\xE3\x2E\x06\xE5\x38\x87\x81\xA1\xCB\x57\x31\x7C\x0B\xA6\x30\x5E\x91\x09\x61\xD0\x10\x02\xF0") , ( 20 , "\xD5\xC7\xF6\x79\x7B\x7E\x7E\x9C\x1D\x7F\xD2\x61\x0B\x2A\xBF\x2B\xC5\xA7\x88\x5F\xB3\xFF\x78\x09\x2F\xB3\xAB\xE8\x98\x6D\x35\xE2" , "\x74\x4E\x17\x31\x2B\x27\x96\x9D\x82\x64\x44\x64\x0E\x9C\x4A\x37\x8A\xE3\x34\xF1\x85\x36\x9C\x95" , "\x77\x58\x29\x8C\x62\x8E\xB3\xA4\xB6\x96\x3C\x54\x45\xEF\x66\x97\x12\x22\xBE\x5D\x1A\x4A\xD8\x39\x71\x5D\x11\x88\x07\x17\x39\xB7\x7C\xC6\xE0\x5D\x54\x10\xF9\x63\xA6\x41\x67\x62\x97\x57" , "\x27\xB8\xCF\xE8\x14\x16\xA7\x63\x01\xFD\x1E\xEC\x6A\x4D\x99\x67\x50\x69\xB2\xDA\x27\x76\xC3\x60\xDB\x1B\xDF\xEA\x7C\x0A\xA6\x13\x91\x3E\x10\xF7\xA6\x0F\xEC\x04\xD1\x1E\x65\xF2\xD6\x4E") , ( 20 , "\x73\x7D\x78\x11\xCE\x96\x47\x2E\xFE\xD1\x22\x58\xB7\x81\x22\xF1\x1D\xEA\xEC\x87\x59\xCC\xBD\x71\xEA\xC6\xBB\xEF\xA6\x27\x78\x5C" , "\x6F\xB2\xEE\x3D\xDA\x6D\xBD\x12\xF1\x27\x4F\x12\x67\x01\xEC\x75\xC3\x5C\x86\x60\x7A\xDB\x3E\xDD" , "\x50\x13\x25\xFB\x26\x45\x26\x48\x64\xDF\x11\xFA\xA1\x7B\xBD\x58\x31\x2B\x77\xCA\xD3\xD9\x4A\xC8\xFB\x85\x42\xF0\xEB\x65\x3A\xD7\x3D\x7F\xCE\x93\x2B\xB8\x74\xCB\x89\xAC\x39\xFC\x47\xF8\x26\x7C\xF0\xF0\xC2\x09\xF2\x04\xB2\xD8\x57\x8A\x3B\xDF\x46\x1C\xB6\xA2\x71\xA4\x68\xBE\xBA\xCC\xD9\x68\x50\x14\xCC\xBC\x9A\x73\x61\x8C\x6A\x5E\x77\x8A\x21\xCC\x84\x16\xC6\x0A\xD2\x4D\xDC\x41\x7A\x13\x0D\x53\xED\xA6\xDF\xBF\xE4\x7D\x09\x17\x0A\x7B\xE1\xA7\x08\xB7\xB5\xF3\xAD\x46\x43\x10\xBE\x36\xD9\xA2\xA9\x5D\xC3\x9E\x83\xD3\x86\x67\xE8\x42\xEB\x64\x11\xE8\xA2\x37\x12\x29\x7B\x16\x5F\x69\x0C\x2D\x7C\xA1\xB1\x34\x6E\x3C\x1F\xCC\xF5\xCA\xFD\x4F\x8B\xE0" , "\x67\x24\xC3\x72\xD2\xE9\x07\x4D\xA5\xE2\x7A\x6C\x54\xB2\xD7\x03\xDC\x1D\x4C\x9B\x1F\x8D\x90\xF0\x0C\x12\x2E\x69\x2A\xCE\x77\x00\xEA\xDC\xA9\x42\x54\x45\x07\xF1\x37\x5B\x65\x81\xD5\xA8\xFB\x39\x98\x1C\x1C\x0E\x6E\x1F\xF2\x14\x0B\x08\x2E\x9E\xC0\x16\xFC\xE1\x41\xD5\x19\x96\x47\xD4\x3B\x0B\x68\xBF\xD0\xFE\xA5\xE0\x0F\x46\x89\x62\xC7\x38\x4D\xD6\x12\x9A\xEA\x6A\x3F\xDF\xE7\x5A\xBB\x21\x0E\xD5\x60\x7C\xEF\x8F\xA0\xE1\x52\x83\x3D\x5A\xC3\x7D\x52\xE5\x57\xB9\x10\x98\xA3\x22\xE7\x6A\x45\xBB\xBC\xF4\x89\x9E\x79\x06\x18\xAA\x3F\x4C\x2E\x5E\x0F\xC3\xDE\x93\x26\x9A\x57\x7D\x77\xA5\x50\x2E\x8E\xA0\x2F\x71\x7B\x1D\xD2\xDF\x1E\xC6\x9D\x8B\x61\xCA") , ( 20 , "\x76\x01\x58\xDA\x09\xF8\x9B\xBA\xB2\xC9\x9E\x69\x97\xF9\x52\x3A\x95\xFC\xEF\x10\x23\x9B\xCC\xA2\x57\x3B\x71\x05\xF6\x89\x8D\x34" , "\x43\x63\x6B\x2C\xC3\x46\xFC\x8B\x7C\x85\xA1\x9B\xF5\x07\xBD\xC3\xDA\xFE\x95\x3B\x88\xC6\x9D\xBA" , "\xD3\x0A\x6D\x42\xDF\xF4\x9F\x0E\xD0\x39\xA3\x06\xBA\xE9\xDE\xC8\xD9\xE8\x83\x66\xCC\x19\xE8\xC3\x64\x2F\xD5\x8F\xA0\x79\x4E\xBF\x80\x29\xD9\x49\x73\x03\x39\xB0\x82\x3A\x51\xF0\xF4\x9F\x0D\x2C\x71\xF1\x05\x1C\x1E\x0E\x2C\x86\x94\x1F\x17\x27\x89\xCD\xB1\xB0\x10\x74\x13\xE7\x0F\x98\x2F\xF9\x76\x18\x77\xBB\x52\x6E\xF1\xC3\xEB\x11\x06\xA9\x48\xD6\x0E\xF2\x1B\xD3\x5D\x32\xCF\xD6\x4F\x89\xB7\x9E\xD6\x3E\xCC\x5C\xCA\x56\x24\x6A\xF7\x36\x76\x6F\x28\x5D\x8E\x6B\x0D\xA9\xCB\x1C\xD2\x10\x20\x22\x3F\xFA\xCC\x5A\x32" , "\xC8\x15\xB6\xB7\x9B\x64\xF9\x36\x9A\xEC\x8D\xCE\x8C\x75\x3D\xF8\xA5\x0F\x2B\xC9\x7C\x70\xCE\x2F\x01\x4D\xB3\x3A\x65\xAC\x58\x16\xBA\xC9\xE3\x0A\xC0\x8B\xDD\xED\x30\x8C\x65\xCB\x87\xE2\x8E\x2E\x71\xB6\x77\xDC\x25\xC5\xA6\x49\x9C\x15\x53\x55\x5D\xAF\x1F\x55\x27\x0A\x56\x95\x9D\xFF\xA0\xC6\x6F\x24\xE0\xAF\x00\x95\x1E\xC4\xBB\x59\xCC\xC3\xA6\xC5\xF5\x2E\x09\x81\x64\x7E\x53\xE4\x39\x31\x3A\x52\xC4\x0F\xA7\x00\x4C\x85\x5B\x6E\x6E\xB2\x5B\x21\x2A\x13\x8E\x84\x3A\x9B\xA4\x6E\xDB\x2A\x03\x9E\xE8\x2A\x26\x3A\xBE") , ( 20 , "\x27\xBA\x7E\x81\xE7\xED\xD4\xE7\x1B\xE5\x3C\x07\xCE\x8E\x63\x31\x38\xF2\x87\xE1\x55\xC7\xFA\x9E\x84\xC4\xAD\x80\x4B\x7F\xA1\xB9" , "\xEA\x05\xF4\xEB\xCD\x2F\xB6\xB0\x00\xDA\x06\x12\x86\x1B\xA5\x4F\xF5\xC1\x76\xFB\x60\x13\x91\xAA" , "\xE0\x9F\xF5\xD2\xCB\x05\x0D\x69\xB2\xD4\x24\x94\xBD\xE5\x82\x52\x38\xC7\x56\xD6\x99\x1D\x99\xD7\xA2\x0D\x1E\xF0\xB8\x3C\x37\x1C\x89\x87\x26\x90\xB2\xFC\x11\xD5\x36\x9F\x4F\xC4\x97\x1B\x6D\x3D\x6C\x07\x8A\xEF\x9B\x0F\x05\xC0\xE6\x1A\xB8\x9C\x02\x51\x68\x05\x4D\xEF\xEB\x03\xFE\xF6\x33\x85\x87\x00\xC5\x8B\x12\x62\xCE\x01\x13\x00\x01\x26\x73\xE8\x93\xE4\x49\x01\xDC\x18\xEE\xE3\x10\x56\x99\xC4\x4C\x80\x58\x97\xBD\xAF\x77\x6A\xF1\x83\x31\x62\xA2\x1A" , "\xA2\x3E\x7E\xF9\x3C\x5D\x06\x67\xC9\x6D\x9E\x40\x4D\xCB\xE6\xBE\x62\x02\x6F\xA9\x8F\x7A\x3F\xF9\xBA\x5D\x45\x86\x43\xA1\x6A\x1C\xEF\x72\x72\xDC\x60\x97\xA9\xB5\x2F\x35\x98\x35\x57\xC7\x7A\x11\xB3\x14\xB4\xF7\xD5\xDC\x2C\xCA\x15\xEE\x47\x61\x6F\x86\x18\x73\xCB\xFE\xD1\xD3\x23\x72\x17\x1A\x61\xE3\x8E\x44\x7F\x3C\xF3\x62\xB3\xAB\xBB\x2E\xD4\x17\x0D\x89\xDC\xB2\x81\x87\xB7\xBF\xD2\x06\xA3\xE0\x26\xF0\x84\xA7\xE0\xED\x63\xD3\x19\xDE\x6B\xC9\xAF\xC0") , ( 20 , "\x67\x99\xD7\x6E\x5F\xFB\x5B\x49\x20\xBC\x27\x68\xBA\xFD\x3F\x8C\x16\x55\x4E\x65\xEF\xCF\x9A\x16\xF4\x68\x3A\x7A\x06\x92\x7C\x11" , "\x61\xAB\x95\x19\x21\xE5\x4F\xF0\x6D\x9B\x77\xF3\x13\xA4\xE4\x9D\xF7\xA0\x57\xD5\xFD\x62\x79\x89" , "\x47\x27\x66" , "\x8F\xD7\xDF") , ( 20 , "\xF6\x82\x38\xC0\x83\x65\xBB\x29\x3D\x26\x98\x0A\x60\x64\x88\xD0\x9C\x2F\x10\x9E\xDA\xFA\x0B\xBA\xE9\x93\x7B\x5C\xC2\x19\xA4\x9C" , "\x51\x90\xB5\x1E\x9B\x70\x86\x24\x82\x0B\x5A\xBD\xF4\xE4\x0F\xAD\x1F\xB9\x50\xAD\x1A\xDC\x2D\x26" , "\x47\xEC\x6B\x1F\x73\xC4\xB7\xFF\x52\x74\xA0\xBF\xD7\xF4\x5F\x86\x48\x12\xC8\x5A\x12\xFB\xCB\x3C\x2C\xF8\xA3\xE9\x0C\xF6\x6C\xCF\x2E\xAC\xB5\x21\xE7\x48\x36\x3C\x77\xF5\x2E\xB4\x26\xAE\x57\xA0\xC6\xC7\x8F\x75\xAF\x71\x28\x45\x69\xE7\x9D\x1A\x92\xF9\x49\xA9\xD6\x9C\x4E\xFC\x0B\x69\x90\x2F\x1E\x36\xD7\x56\x27\x65\x54\x3E\x2D\x39\x42\xD9\xF6\xFF\x59\x48\xD8\xA3\x12\xCF\xF7\x2C\x1A\xFD\x9E\xA3\x08\x8A\xFF\x76\x40\xBF\xD2\x65\xF7\xA9\x94\x6E\x60\x6A\xBC\x77\xBC\xED\xAE\x6B\xDD\xC7\x5A\x0D\xBA\x0B\xD9\x17\xD7\x3E\x3B\xD1\x26\x8F\x72\x7E\x00\x96\x34\x5D\xA1\xED\x25\xCF\x55\x3E\xA7\xA9\x8F\xEA\x6B\x6F\x28\x57\x32\xDE\x37\x43\x15\x61\xEE\x1B\x30\x64\x88\x7F\xBC\xBD\x71\x93\x5E\x02" , "\x36\x16\x0E\x88\xD3\x50\x05\x29\xBA\x4E\xDB\xA1\x7B\xC2\x4D\x8C\xFA\xCA\x9A\x06\x80\xB3\xB1\xFC\x97\xCF\x03\xF3\x67\x5B\x7A\xC3\x01\xC8\x83\xA6\x8C\x07\x1B\xC5\x4A\xCD\xD3\xB6\x3A\xF4\xA2\xD7\x2F\x98\x5E\x51\xF9\xD6\x0A\x4C\x7F\xD4\x81\xAF\x10\xB2\xFC\x75\xE2\x52\xFD\xEE\x7E\xA6\xB6\x45\x31\x90\x61\x7D\xCC\x6E\x2F\xE1\xCD\x56\x58\x5F\xC2\xF0\xB0\xE9\x7C\x5C\x3F\x8A\xD7\xEB\x4F\x31\xBC\x48\x90\xC0\x38\x82\xAA\xC2\x4C\xC5\x3A\xCC\x19\x82\x29\x65\x26\x69\x0A\x22\x02\x71\xC2\xF6\xE3\x26\x75\x0D\x3F\xBD\xA5\xD5\xB6\x35\x12\xC8\x31\xF6\x78\x30\xF5\x9A\xC4\x9A\xAE\x33\x0B\x3E\x0E\x02\xC9\xEA\x00\x91\xD1\x98\x41\xF1\xB0\xE1\x3D\x69\xC9\xFB\xFE\x8A\x12\xD6\xF3\x0B\xB7\x34\xD9\xD2") , ( 20 , "\x45\xB2\xBD\x0D\xE4\xED\x92\x93\xEC\x3E\x26\xC4\x84\x0F\xAA\xF6\x4B\x7D\x61\x9D\x51\xE9\xD7\xA2\xC7\xE3\x6C\x83\xD5\x84\xC3\xDF" , "\x54\x6C\x8C\x5D\x6B\xE8\xF9\x09\x52\xCA\xB3\xF3\x6D\x7C\x19\x57\xBA\xAA\x7A\x59\xAB\xE3\xD7\xE5" , "\x50\x07\xC8\xCD\x5B\x3C\x40\xE1\x7D\x7F\xE4\x23\xA8\x7A\xE0\xCE\xD8\x6B\xEC\x1C\x39\xDC\x07\xA2\x57\x72\xF3\xE9\x6D\xAB\xD5\x6C\xD3\xFD\x73\x19\xF6\xC9\x65\x49\x25\xF2\xD8\x70\x87\xA7\x00\xE1\xB1\x30\xDA\x79\x68\x95\xD1\xC9\xB9\xAC\xD6\x2B\x26\x61\x44\x06\x7D\x37\x3E\xD5\x1E\x78\x74\x98\xB0\x3C\x52\xFA\xAD\x16\xBB\x38\x26\xFA\x51\x1B\x0E\xD2\xA1\x9A\x86\x63\xF5\xBA\x2D\x6E\xA7\xC3\x8E\x72\x12\xE9\x69\x7D\x91\x48\x6C\x49\xD8\xA0\x00\xB9\xA1\x93\x5D\x6A\x7F\xF7\xEF\x23\xE7\x20\xA4\x58\x55\x48\x14\x40\x46\x3B\x4A\xC8\xC4\xF6\xE7\x06\x2A\xDC\x1F\x1E\x1E\x25\xD3\xD6\x5A\x31\x81\x2F\x58\xA7\x11\x60" , "\x8E\xAC\xFB\xA5\x68\x89\x8B\x10\xC0\x95\x7A\x7D\x44\x10\x06\x85\xE8\x76\x3A\x71\xA6\x9A\x8D\x16\xBC\x7B\x3F\x88\x08\x5B\xB9\xA2\xF0\x96\x42\xE4\xD0\x9A\x9F\x0A\xD0\x9D\x0A\xAD\x66\xB2\x26\x10\xC8\xBD\x02\xFF\x66\x79\xBB\x92\xC2\xC0\x26\xA2\x16\xBF\x42\x5C\x6B\xE3\x5F\xB8\xDA\xE7\xFF\x0C\x72\xB0\xEF\xD6\xA1\x80\x37\xC7\x0E\xED\x0C\xA9\x00\x62\xA4\x9A\x3C\x97\xFD\xC9\x0A\x8F\x9C\x2E\xA5\x36\xBF\xDC\x41\x91\x8A\x75\x82\xC9\x92\x7F\xAE\x47\xEF\xAA\x3D\xC8\x79\x67\xB7\x88\x7D\xEE\x1B\xF0\x71\x73\x4C\x76\x65\x90\x1D\x91\x05\xDA\xE2\xFD\xF6\x6B\x49\x18\xE5\x1D\x8F\x4A\x48\xC6\x0D\x19\xFB\xFB\xBC\xBA") , ( 20 , "\xFE\x55\x9C\x9A\x28\x2B\xEB\x40\x81\x4D\x01\x6D\x6B\xFC\xB2\xC0\xC0\xD8\xBF\x07\x7B\x11\x10\xB8\x70\x3A\x3C\xE3\x9D\x70\xE0\xE1" , "\xB0\x76\x20\x0C\xC7\x01\x12\x59\x80\x5E\x18\xB3\x04\x09\x27\x54\x00\x27\x23\xEB\xEC\x5D\x62\x00" , "\x6D\xB6\x5B\x9E\xC8\xB1\x14\xA9\x44\x13\x7C\x82\x1F\xD6\x06\xBE\x75\x47\x8D\x92\x83\x66\xD5\x28\x40\x96\xCD\xEF\x78\x2F\xCF\xF7\xE8\xF5\x9C\xB8\xFF\xCD\xA9\x79\x75\x79\x02\xC5\xFF\xA6\xBC\x47\x7C\xEA\xA4\xCB\x5D\x5E\xA7\x6F\x94\xD9\x1E\x83\x3F\x82\x3A\x6B\xC7\x8F\x10\x55\xDF\xA6\xA9\x7B\xEA\x89\x65\xC1\xCD\xE6\x7A\x66\x8E\x00\x12\x57\x33\x4A\x58\x57\x27\xD9\xE0\xF7\xC1\xA0\x6E\x88\xD3\xD2\x5A\x4E\x6D\x90\x96\xC9\x68\xBF\x13\x8E\x11\x6A\x3E\xBE\xFF\xD4\xBB\x48\x08\xAD\xB1\xFD\x69\x81\x64\xBA\x0A\x35\xC7\x09\xA4\x7F\x16\xF1\xF4\x43\x5A\x23\x45\xA9\x19\x4A\x00\xB9\x5A\xBD\x51\x85\x1D\x50\x58\x09\xA6\x07\x7D\xA9\xBA\xCA\x58\x31\xAF\xFF\x31\x57\x8C\x48\x7E\xE6\x8F\x27\x67\x97\x4A\x98\xA7\xE8\x03\xAA\xC7\x88\xDA\x98\x31\x9C\x4E\xA8\xEA\xA3\xD3\x94\x85\x56\x51\xF4\x84\xCE\xF5\x43\xF5\x37\xE3\x51\x58\xEE\x29" , "\x4D\xCE\x9C\x8F\x97\xA0\x28\x05\x1B\x07\x27\xF3\x4E\x1B\x9E\xF2\x1F\x06\xF0\x76\x0F\x36\xE7\x17\x13\x20\x40\x27\x90\x20\x90\xBA\x2B\xB6\xB1\x34\x36\xEE\x77\x8D\x9F\x50\x53\x0E\xFB\xD7\xA3\x2B\x0D\x41\x44\x3F\x58\xCC\xAE\xE7\x81\xC7\xB7\x16\xD3\xA9\x6F\xDE\xC0\xE3\x76\x4E\xD7\x95\x9F\x34\xC3\x94\x12\x78\x59\x1E\xA0\x33\xB5\xCB\xAD\xC0\xF1\x91\x60\x32\xE9\xBE\xBB\xD1\xA8\x39\x5B\x83\xFB\x63\xB1\x45\x4B\xD7\x75\xBD\x20\xB3\xA2\xA9\x6F\x95\x12\x46\xAC\x14\xDA\xF6\x81\x66\xBA\x62\xF6\xCB\xFF\x8B\xD1\x21\xAC\x94\x98\xFF\x88\x52\xFD\x2B\xE9\x75\xDF\x52\xB5\xDA\xEF\x38\x29\xD1\x8E\xDA\x42\xE7\x15\x02\x2D\xCB\xF9\x30\xD0\xA7\x89\xEE\x6A\x14\x6C\x2C\x70\x88\xC3\x57\x73\xC6\x3C\x06\xB4\xAF\x45\x59\x85\x6A\xC1\x99\xCE\xD8\x68\x63\xE4\x29\x47\x07\x82\x53\x37\xC5\x85\x79\x70\xEB\x7F\xDD\xEB\x26\x37\x81\x30\x90\x11") , ( 20 , "\x0A\xE1\x00\x12\xD7\xE5\x66\x14\xB0\x3D\xCC\x89\xB1\x4B\xAE\x92\x42\xFF\xE6\x30\xF3\xD7\xE3\x5C\xE8\xBB\xB9\x7B\xBC\x2C\x92\xC3" , "\xF9\x6B\x02\x5D\x6C\xF4\x6A\x8A\x12\xAC\x2A\xF1\xE2\xAE\xF1\xFB\x83\x59\x0A\xDA\xDA\xA5\xC5\xEA" , "\xEA\x0F\x35\x4E\x96\xF1\x2B\xC7\x2B\xBA\xA3\xD1\x2B\x4A\x8E\xD8\x79\xB0\x42\xF0\x68\x98\x78\xF4\x6B\x65\x1C\xC4\x11\x6D\x6F\x78\x40\x9B\x11\x43\x0B\x3A\xAA\x30\xB2\x07\x68\x91\xE8\xE1\xFA\x52\x8F\x2F\xD1\x69\xED\x93\xDC\x9F\x84\xE2\x44\x09\xEE\xC2\x10\x1D\xAF\x4D\x05\x7B\xE2\x49\x2D\x11\xDE\x64\x0C\xBD\x7B\x35\x5A\xD2\x9F\xB7\x04\x00\xFF\xFD\x7C\xD6\xD4\x25\xAB\xEE\xB7\x32\xA0\xEA\xA4\x33\x0A\xF4\xC6\x56\x25\x2C\x41\x73\xDE\xAB\x65\x3E\xB8\x5C\x58\x46\x2D\x7A\xB0\xF3\x5F\xD1\x2B\x61\x3D\x29\xD4\x73\xD3\x30\x31\x0D\xC3\x23\xD3\xC6\x63\x48\xBB\xDB\xB6\x8A\x32\x63\x24\x65\x7C\xAE\x7B\x77\xA9\xE3\x43\x58\xF2\xCE\xC5\x0C\x85\x60\x9E\x73\x05\x68\x56\x79\x6E\x3B\xE8\xD6\x2B\x6E\x2F\xE9\xF9\x53" , "\xE8\xAB\xD4\x89\x24\xB5\x4E\x5B\x80\x86\x6B\xE7\xD4\xEB\xE5\xCF\x42\x74\xCA\xFF\xF0\x8B\x39\xCB\x2D\x40\xA8\xF0\xB4\x72\x39\x8A\xED\xC7\x76\xE0\x79\x38\x12\xFB\xF1\xF6\x00\x78\x63\x5D\x2E\xD8\x6B\x15\xEF\xCD\xBA\x60\x41\x1E\xE2\x3B\x07\x23\x35\x92\xA4\x4E\xC3\x1B\x10\x13\xCE\x89\x64\x23\x66\x75\xF8\xF1\x83\xAE\xF8\x85\xE8\x64\xF2\xA7\x2E\xDF\x42\x15\xB5\x33\x8F\xA2\xB5\x46\x53\xDF\xA1\xA8\xC5\x5C\xE5\xD9\x5C\xC6\x05\xB9\xB3\x11\x52\x7F\x2E\x34\x63\xFF\xBE\xC7\x8A\x9D\x1D\x65\xDA\xBA\xD2\xF3\x38\x76\x9C\x9F\x43\xF1\x33\xA7\x91\xA1\x1C\x7E\xCA\x9A\xF0\xB7\x71\xA4\xAC\x32\x96\x3D\xC8\xF6\x31\xA2\xC1\x12\x17\xAC\x6E\x1B\x94\x30\xC1\xAA\xE1\xCE\xEB\xE2\x27\x03\xF4\x29\x99\x8A\x8F\xB8\xC6\x41") , ( 20 , "\x08\x2C\x53\x9B\xC5\xB2\x0F\x97\xD7\x67\xCD\x3F\x22\x9E\xDA\x80\xB2\xAD\xC4\xFE\x49\xC8\x63\x29\xB5\xCD\x62\x50\xA9\x87\x74\x50" , "\x84\x55\x43\x50\x2E\x8B\x64\x91\x2D\x8F\x2C\x8D\x9F\xFF\xB3\xC6\x93\x65\x68\x65\x87\xC0\x8D\x0C" , "\xA9\x6B\xB7\xE9\x10\x28\x1A\x6D\xFA\xD7\xC8\xA9\xC3\x70\x67\x4F\x0C\xEE\xC1\xAD\x8D\x4F\x0D\xE3\x2F\x9A\xE4\xA2\x3E\xD3\x29\xE3\xD6\xBC\x70\x8F\x87\x66\x40\xA2\x29\x15\x3A\xC0\xE7\x28\x1A\x81\x88\xDD\x77\x69\x51\x38\xF0\x1C\xDA\x5F\x41\xD5\x21\x5F\xD5\xC6\xBD\xD4\x6D\x98\x2C\xB7\x3B\x1E\xFE\x29\x97\x97\x0A\x9F\xDB\xDB\x1E\x76\x8D\x7E\x5D\xB7\x12\x06\x8D\x8B\xA1\xAF\x60\x67\xB5\x75\x34\x95\xE2\x3E\x6E\x19\x63\xAF\x01\x2F\x9C\x7C\xE4\x50\xBF\x2D\xE6\x19\xD3\xD5\x95\x42\xFB\x55\xF3" , "\x83\x5D\xA7\x4F\xC6\xDE\x08\xCB\xDA\x27\x7A\x79\x66\xA0\x7C\x8D\xCD\x62\x7E\x7B\x17\xAD\xDE\x6D\x93\x0B\x65\x81\xE3\x12\x4B\x8B\xAA\xD0\x96\xF6\x93\x99\x1F\xED\xB1\x57\x29\x30\x60\x1F\xC7\x70\x95\x41\x83\x9B\x8E\x3F\xFD\x5F\x03\x3D\x20\x60\xD9\x99\xC6\xC6\xE3\x04\x82\x76\x61\x3E\x64\x80\x00\xAC\xB5\x21\x2C\xC6\x32\xA9\x16\xAF\xCE\x29\x0E\x20\xEB\xDF\x61\x2D\x08\xA6\xAA\x4C\x79\xA7\x4B\x07\x0D\x3F\x87\x2A\x86\x1F\x8D\xC6\xBB\x07\x61\x4D\xB5\x15\xD3\x63\x34\x9D\x3A\x8E\x33\x36\xA3") , ( 20 , "\x3D\x02\xBF\xF3\x37\x5D\x40\x30\x27\x35\x6B\x94\xF5\x14\x20\x37\x37\xEE\x9A\x85\xD2\x05\x2D\xB3\xE4\xE5\xA2\x17\xC2\x59\xD1\x8A" , "\x74\x21\x6C\x95\x03\x18\x95\xF4\x8C\x1D\xBA\x65\x15\x55\xEB\xFA\x3C\xA3\x26\xA7\x55\x23\x70\x25" , "\x0D\x4B\x0F\x54\xFD\x09\xAE\x39\xBA\xA5\xFA\x4B\xAC\xCF\x2E\x66\x82\xE6\x1B\x25\x7E\x01\xF4\x2B\x8F" , "\x16\xC4\x00\x6C\x28\x36\x51\x90\x41\x1E\xB1\x59\x38\x14\xCF\x15\xE7\x4C\x22\x23\x8F\x21\x0A\xFC\x3D") , ( 20 , "\xAD\x1A\x5C\x47\x68\x88\x74\xE6\x66\x3A\x0F\x3F\xA1\x6F\xA7\xEF\xB7\xEC\xAD\xC1\x75\xC4\x68\xE5\x43\x29\x14\xBD\xB4\x80\xFF\xC6" , "\xE4\x89\xEE\xD4\x40\xF1\xAA\xE1\xFA\xC8\xFB\x7A\x98\x25\x63\x54\x54\xF8\xF8\xF1\xF5\x2E\x2F\xCC" , "\xAA\x6C\x1E\x53\x58\x0F\x03\xA9\xAB\xB7\x3B\xFD\xAD\xED\xFE\xCA\xDA\x4C\x6B\x0E\xBE\x02\x0E\xF1\x0D\xB7\x45\xE5\x4B\xA8\x61\xCA\xF6\x5F\x0E\x40\xDF\xC5\x20\x20\x3B\xB5\x4D\x29\xE0\xA8\xF7\x8F\x16\xB3\xF1\xAA\x52\x5D\x6B\xFA\x33\xC5\x47\x26\xE5\x99\x88\xCF\xBE\xC7\x80\x56" , "\x02\xFE\x84\xCE\x81\xE1\x78\xE7\xAA\xBD\xD3\xBA\x92\x5A\x76\x6C\x3C\x24\x75\x6E\xEF\xAE\x33\x94\x2A\xF7\x5E\x8B\x46\x45\x56\xB5\x99\x7E\x61\x6F\x3F\x2D\xFC\x7F\xCE\x91\x84\x8A\xFD\x79\x91\x2D\x9F\xB5\x52\x01\xB5\x81\x3A\x5A\x07\x4D\x2C\x0D\x42\x92\xC1\xFD\x44\x18\x07\xC5") , ( 20 , "\x05\x3A\x02\xBE\xDD\x63\x68\xC1\xFB\x8A\xFC\x7A\x1B\x19\x9F\x7F\x7E\xA2\x22\x0C\x9A\x4B\x64\x2A\x68\x50\x09\x1C\x9D\x20\xAB\x9C" , "\xC7\x13\xEE\xA5\xC2\x6D\xAD\x75\xAD\x3F\x52\x45\x1E\x00\x3A\x9C\xB0\xD6\x49\xF9\x17\xC8\x9D\xDE" , "\x8F\x0A\x8A\x16\x47\x60\x42\x65\x67\xE3\x88\x84\x02\x76\xDE\x3F\x95\xCB\x5E\x3F\xAD\xC6\xED\x3F\x3E\x4F\xE8\xBC\x16\x9D\x93\x88\x80\x4D\xCB\x94\xB6\x58\x7D\xBB\x66\xCB\x0B\xD5\xF8\x7B\x8E\x98\xB5\x2A\xF3\x7B\xA2\x90\x62\x9B\x85\x8E\x0E\x2A\xA7\x37\x80\x47\xA2\x66\x02" , "\x51\x67\x10\xE5\x98\x43\xE6\xFB\xD4\xF2\x5D\x0D\x8C\xA0\xEC\x0D\x47\xD3\x9D\x12\x5E\x9D\xAD\x98\x7E\x05\x18\xD4\x91\x07\x01\x4C\xB0\xAE\x40\x5E\x30\xC2\xEB\x37\x94\x75\x0B\xCA\x14\x2C\xE9\x5E\x29\x0C\xF9\x5A\xBE\x15\xE8\x22\x82\x3E\x2E\x7D\x3A\xB2\x1B\xC8\xFB\xD4\x45") , ( 20 ,"\x5B\x14\xAB\x0F\xBE\xD4\xC5\x89\x52\x54\x8A\x6C\xB1\xE0\x00\x0C\xF4\x48\x14\x21\xF4\x12\x88\xEA\x0A\xA8\x4A\xDD\x9F\x7D\xEB\x96" , "\x54\xBF\x52\xB9\x11\x23\x1B\x95\x2B\xA1\xA6\xAF\x8E\x45\xB1\xC5\xA2\x9D\x97\xE2\xAB\xAD\x7C\x83" , "\x37\xFB\x44\xA6\x75\x97\x8B\x56\x0F\xF9\xA4\xA8\x70\x11\xD6\xF3\xAD\x2D\x37\xA2\xC3\x81\x5B\x45\xA3\xC0\xE6\xD1\xB1\xD8\xB1\x78\x4C\xD4\x68\x92\x7C\x2E\xE3\x9E\x1D\xCC\xD4\x76\x5E\x1C\x3D\x67\x6A\x33\x5B\xE1\xCC\xD6\x90\x0A\x45\xF5\xD4\x1A\x31\x76\x48\x31\x5D\x8A\x8C\x24\xAD\xC6\x4E\xB2\x85\xF6\xAE\xBA\x05\xB9\x02\x95\x86\x35\x3D\x30\x3F\x17\xA8\x07\x65\x8B\x9F\xF7\x90\x47\x4E\x17\x37\xBD\x5F\xDC\x60\x4A\xEF\xF8\xDF\xCA\xF1\x42\x7D\xCC\x3A\xAC\xBB\x02\x56\xBA\xDC\xD1\x83\xED\x75\xA2\xDC\x52\x45\x2F\x87\xD3\xC1\xED\x2A\xA5\x83\x47\x2B\x0A\xB9\x1C\xDA\x20\x61\x4E\x9B\x6F\xDB\xDA\x3B\x49\xB0\x98\xC9\x58\x23\xCC\x72\xD8\xE5\xB7\x17\xF2\x31\x4B\x03\x24\xE9\xCE" , "\xAE\x6D\xEB\x5D\x6C\xE4\x3D\x4B\x09\xD0\xE6\xB1\xC0\xE9\xF4\x61\x57\xBC\xD8\xAB\x50\xEA\xA3\x19\x7F\xF9\xFA\x2B\xF7\xAF\x64\x9E\xB5\x2C\x68\x54\x4F\xD3\xAD\xFE\x6B\x1E\xB3\x16\xF1\xF2\x35\x38\xD4\x70\xC3\x0D\xBF\xEC\x7E\x57\xB6\x0C\xBC\xD0\x96\xC7\x82\xE7\x73\x6B\x66\x91\x99\xC8\x25\x3E\x70\x21\x4C\xF2\xA0\x98\xFD\xA8\xEA\xC5\xDA\x79\xA9\x49\x6A\x3A\xAE\x75\x4D\x03\xB1\x7C\x6D\x70\xD1\x02\x7F\x42\xBF\x7F\x95\xCE\x3D\x1D\x9C\x33\x88\x54\xE1\x58\xFC\xC8\x03\xE4\xD6\x26\x2F\xB6\x39\x52\x1E\x47\x11\x6E\xF7\x8A\x7A\x43\x7C\xA9\x42\x7B\xA6\x45\xCD\x64\x68\x32\xFE\xAB\x82\x2A\x20\x82\x78\xE4\x5E\x93\xE1\x18\xD7\x80\xB9\x88\xD6\x53\x97\xED\xDF\xD7\xA8\x19\x52\x6E") , ( 20 , "\xD7\x46\x36\xE3\x41\x3A\x88\xD8\x5F\x32\x2C\xA8\x0F\xB0\xBD\x65\x0B\xD0\xBF\x01\x34\xE2\x32\x91\x60\xB6\x96\x09\xCD\x58\xA4\xB0" , "\xEF\xB6\x06\xAA\x1D\x9D\x9F\x0F\x46\x5E\xAA\x7F\x81\x65\xF1\xAC\x09\xF5\xCB\x46\xFE\xCF\x2A\x57" , "\xF8\x54\x71\xB7\x5F\x6E\xC8\x1A\xBA\xC2\x79\x9E\xC0\x9E\x98\xE2\x80\xB2\xFF\xD6\x4C\xA2\x85\xE5\xA0\x10\x9C\xFB\x31\xFF\xAB\x2D\x61\x7B\x2C\x29\x52\xA2\xA8\xA7\x88\xFC\x0D\xA2\xAF\x7F\x53\x07\x58\xF7\x4F\x1A\xB5\x63\x91\xAB\x5F\xF2\xAD\xBC\xC5\xBE\x2D\x6C\x7F\x49\xFB\xE8\x11\x81\x04\xC6\xFF\x9A\x23\xC6\xDF\xE5\x2F\x57\x95\x4E\x6A\x69\xDC\xEE\x5D\xB0\x6F\x51\x4F\x4A\x0A\x57\x2A\x9A\x85\x25\xD9\x61\xDA\xE7\x22\x69\xB9\x87\x18\x9D\x46\x5D\xF6\x10\x71\x19\xC7\xFA\x79\x08\x53\xE0\x63\xCB\xA0\xFA\xB7\x80\x0C\xA9\x32\xE2\x58\x88\x0F\xD7\x4C\x33\xC7\x84\x67\x5B\xED\xAD\x0E\x7C\x09\xE9\xCC\x4D\x63\xDD\x5E\x97\x13\xD5\xD4\xA0\x19\x6E\x6B\x56\x22\x26\xAC\x31\xB4\xF5\x7C\x04\xF9\x0A\x18\x19\x73\x73\x7D\xDC\x7E\x80\xF3\x64\x11\x2A\x9F\xBB\x43\x5E\xBD\xBC\xAB\xF7\xD4\x90\xCE\x52" , "\xB2\xB7\x95\xFE\x6C\x1D\x4C\x83\xC1\x32\x7E\x01\x5A\x67\xD4\x46\x5F\xD8\xE3\x28\x13\x57\x5C\xBA\xB2\x63\xE2\x0E\xF0\x58\x64\xD2\xDC\x17\xE0\xE4\xEB\x81\x43\x6A\xDF\xE9\xF6\x38\xDC\xC1\xC8\xD7\x8F\x6B\x03\x06\xBA\xF9\x38\xE5\xD2\xAB\x0B\x3E\x05\xE7\x35\xCC\x6F\xFF\x2D\x6E\x02\xE3\xD6\x04\x84\xBE\xA7\xC7\xA8\xE1\x3E\x23\x19\x7F\xEA\x7B\x04\xD4\x7D\x48\xF4\xA4\xE5\x94\x41\x74\x53\x94\x92\x80\x0D\x3E\xF5\x1E\x2E\xE5\xE4\xC8\xA0\xBD\xF0\x50\xC2\xDD\x3D\xD7\x4F\xCE\x5E\x7E\x5C\x37\x36\x4F\x75\x47\xA1\x14\x80\xA3\x06\x3B\x9A\x0A\x15\x7B\x15\xB1\x0A\x5A\x95\x4D\xE2\x73\x1C\xED\x05\x5A\xA2\xE2\x76\x7F\x08\x91\xD4\x32\x9C\x42\x6F\x38\x08\xEE\x86\x7B\xED\x0D\xC7\x5B\x59\x22\xB7\xCF\xB8\x95\x70\x0F\xDA\x01\x61\x05\xA4\xC7\xB7\xF0\xBB\x90\xF0\x29\xF6\xBB\xCB\x04\xAC\x36\xAC\x16") ] tests = testGroup "XSalsa" [ testGroup "KAT" $ map (\(i,f) -> testCase (show (i :: Int)) f) $ zip [1..] $ map (\(r, k, i, p, e) -> salsaRunSimple r k i p e) vectors ] where salsaRunSimple rounds key nonce plain expected = let salsa = XSalsa.initialize rounds key nonce in fst (XSalsa.combine salsa plain) @?= expected