cryptonite-0.26/Crypto/0000755000000000000000000000000013470442731013314 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/0000755000000000000000000000000013470442731014526 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/AES/0000755000000000000000000000000013414232447015135 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/Blowfish/0000755000000000000000000000000013470442731016303 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/CAST5/0000755000000000000000000000000013414232447015344 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/Camellia/0000755000000000000000000000000013414232447016234 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/DES/0000755000000000000000000000000013414232447015140 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/Twofish/0000755000000000000000000000000013470442731016151 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/Types/0000755000000000000000000000000013470442731015632 5ustar0000000000000000cryptonite-0.26/Crypto/ConstructHash/0000755000000000000000000000000013414232447016103 5ustar0000000000000000cryptonite-0.26/Crypto/Data/0000755000000000000000000000000013470442731014165 5ustar0000000000000000cryptonite-0.26/Crypto/ECC/0000755000000000000000000000000013470442731013706 5ustar0000000000000000cryptonite-0.26/Crypto/ECC/Simple/0000755000000000000000000000000013470442731015137 5ustar0000000000000000cryptonite-0.26/Crypto/Error/0000755000000000000000000000000013470442731014405 5ustar0000000000000000cryptonite-0.26/Crypto/Hash/0000755000000000000000000000000013470442731014177 5ustar0000000000000000cryptonite-0.26/Crypto/Internal/0000755000000000000000000000000013470442731015070 5ustar0000000000000000cryptonite-0.26/Crypto/KDF/0000755000000000000000000000000013470442731013720 5ustar0000000000000000cryptonite-0.26/Crypto/MAC/0000755000000000000000000000000013470442731013714 5ustar0000000000000000cryptonite-0.26/Crypto/Number/0000755000000000000000000000000013470442731014544 5ustar0000000000000000cryptonite-0.26/Crypto/Number/Serialize/0000755000000000000000000000000013470442731016473 5ustar0000000000000000cryptonite-0.26/Crypto/Number/Serialize/Internal/0000755000000000000000000000000013470442731020247 5ustar0000000000000000cryptonite-0.26/Crypto/PubKey/0000755000000000000000000000000013470442731014513 5ustar0000000000000000cryptonite-0.26/Crypto/PubKey/ECC/0000755000000000000000000000000013470442731015105 5ustar0000000000000000cryptonite-0.26/Crypto/PubKey/RSA/0000755000000000000000000000000013470442731015140 5ustar0000000000000000cryptonite-0.26/Crypto/PubKey/Rabin/0000755000000000000000000000000013470442731015546 5ustar0000000000000000cryptonite-0.26/Crypto/Random/0000755000000000000000000000000013470442731014534 5ustar0000000000000000cryptonite-0.26/Crypto/Random/Entropy/0000755000000000000000000000000013470442731016174 5ustar0000000000000000cryptonite-0.26/benchs/0000755000000000000000000000000013470442731013276 5ustar0000000000000000cryptonite-0.26/benchs/Number/0000755000000000000000000000000013414232447014525 5ustar0000000000000000cryptonite-0.26/cbits/0000755000000000000000000000000013470447012013135 5ustar0000000000000000cryptonite-0.26/cbits/aes/0000755000000000000000000000000013470442731013710 5ustar0000000000000000cryptonite-0.26/cbits/argon2/0000755000000000000000000000000013414232447014327 5ustar0000000000000000cryptonite-0.26/cbits/blake2/0000755000000000000000000000000013414232447014277 5ustar0000000000000000cryptonite-0.26/cbits/blake2/ref/0000755000000000000000000000000013470442731015054 5ustar0000000000000000cryptonite-0.26/cbits/blake2/sse/0000755000000000000000000000000013470442731015072 5ustar0000000000000000cryptonite-0.26/cbits/curve25519/0000755000000000000000000000000013414232447014671 5ustar0000000000000000cryptonite-0.26/cbits/decaf/0000755000000000000000000000000013414232447014201 5ustar0000000000000000cryptonite-0.26/cbits/decaf/ed448goldilocks/0000755000000000000000000000000013414232447017104 5ustar0000000000000000cryptonite-0.26/cbits/decaf/include/0000755000000000000000000000000013414232447015624 5ustar0000000000000000cryptonite-0.26/cbits/decaf/include/arch_32/0000755000000000000000000000000013414232447017045 5ustar0000000000000000cryptonite-0.26/cbits/decaf/include/arch_ref64/0000755000000000000000000000000013414232447017547 5ustar0000000000000000cryptonite-0.26/cbits/decaf/include/decaf/0000755000000000000000000000000013414232447016666 5ustar0000000000000000cryptonite-0.26/cbits/decaf/p448/0000755000000000000000000000000013414232447014700 5ustar0000000000000000cryptonite-0.26/cbits/decaf/p448/arch_32/0000755000000000000000000000000013414232447016121 5ustar0000000000000000cryptonite-0.26/cbits/decaf/p448/arch_ref64/0000755000000000000000000000000013414232447016623 5ustar0000000000000000cryptonite-0.26/cbits/ed25519/0000755000000000000000000000000013414232447014135 5ustar0000000000000000cryptonite-0.26/cbits/p256/0000755000000000000000000000000013470442731013634 5ustar0000000000000000cryptonite-0.26/tests/0000755000000000000000000000000013470442731013176 5ustar0000000000000000cryptonite-0.26/tests/ECC/0000755000000000000000000000000013414232447013567 5ustar0000000000000000cryptonite-0.26/tests/KAT_AES/0000755000000000000000000000000013414232447014304 5ustar0000000000000000cryptonite-0.26/tests/KAT_PubKey/0000755000000000000000000000000013470442731015074 5ustar0000000000000000cryptonite-0.26/tests/Number/0000755000000000000000000000000013414232447014425 5ustar0000000000000000cryptonite-0.26/Crypto/Cipher/AES.hs0000644000000000000000000000442613470442731015500 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 -- | 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 (AEAD_CCM n m l) (CSTR aes) iv = AEAD (ccmMode aes) <$> ccmInit aes iv n m l \ ; 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.26/Crypto/Cipher/Blowfish.hs0000644000000000000000000000341213414232447016636 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.26/Crypto/Cipher/CAST5.hs0000644000000000000000000000244013414232447015700 0ustar0000000000000000-- | -- Module : Crypto.Cipher.CAST5 -- License : BSD-style -- Maintainer : Olivier Chéron -- Stability : stable -- Portability : good -- module Crypto.Cipher.CAST5 ( CAST5 ) where import Crypto.Error import Crypto.Cipher.Types import Crypto.Cipher.CAST5.Primitive import Crypto.Internal.ByteArray (ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B -- | CAST5 block cipher (also known as CAST-128). Key is between -- 40 and 128 bits. newtype CAST5 = CAST5 Key instance Cipher CAST5 where cipherName _ = "CAST5" cipherKeySize _ = KeySizeRange 5 16 cipherInit = initCAST5 instance BlockCipher CAST5 where blockSize _ = 8 ecbEncrypt (CAST5 k) = B.mapAsWord64 (encrypt k) ecbDecrypt (CAST5 k) = B.mapAsWord64 (decrypt k) initCAST5 :: ByteArrayAccess key => key -> CryptoFailable CAST5 initCAST5 bs | len < 5 = CryptoFailed CryptoError_KeySizeInvalid | len < 16 = CryptoPassed (CAST5 $ buildKey short padded) | len == 16 = CryptoPassed (CAST5 $ buildKey False bs) | otherwise = CryptoFailed CryptoError_KeySizeInvalid where len = B.length bs short = len <= 10 padded :: B.Bytes padded = B.convert bs `B.append` B.replicate (16 - len) 0 cryptonite-0.26/Crypto/Cipher/Camellia.hs0000644000000000000000000000141213414232447016566 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.26/Crypto/Cipher/ChaCha.hs0000644000000000000000000001156213470442731016176 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 nbRounds kLen keyPtr nonceLen noncePtr return $ State stPtr where kLen = B.length key nonceLen = B.length nonce -- | Initialize simple ChaCha State -- -- The seed need to be at least 40 bytes long initializeSimple :: ByteArrayAccess 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.26/Crypto/Cipher/ChaChaPoly1305.hs0000644000000000000000000001647713414232447017364 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.26/Crypto/Cipher/DES.hs0000644000000000000000000000213313414232447015473 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.26/Crypto/Cipher/RC4.hs0000644000000000000000000000543613414232447015461 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.26/Crypto/Cipher/Salsa.hs0000644000000000000000000000635713470442731016140 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 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.26/Crypto/Cipher/TripleDES.hs0000644000000000000000000000653613414232447016666 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.26/Crypto/Cipher/Twofish.hs0000644000000000000000000000263513470442731016513 0ustar0000000000000000module Crypto.Cipher.Twofish ( Twofish128 , Twofish192 , Twofish256 ) where import Crypto.Cipher.Twofish.Primitive import Crypto.Cipher.Types import Crypto.Cipher.Utils 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.26/Crypto/Cipher/Types.hs0000644000000000000000000000155613414232447016174 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(..) , CCM_M(..) , CCM_L(..) , 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.26/Crypto/Cipher/Utils.hs0000644000000000000000000000117513470442731016166 0ustar0000000000000000module Crypto.Cipher.Utils ( validateKeySize ) where import Crypto.Error import Crypto.Cipher.Types 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.26/Crypto/Cipher/XSalsa.hs0000644000000000000000000000356713470442731016270 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) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Foreign.Ptr 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 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.26/Crypto/ConstructHash/MiyaguchiPreneel.hs0000644000000000000000000000435513414232447021700 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.26/Crypto/Data/AFIS.hs0000644000000000000000000001346713470442731015256 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 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.26/Crypto/Data/Padding.hs0000644000000000000000000000421313414232447016066 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.26/Crypto/ECC.hs0000644000000000000000000002465713470442731014260 0ustar0000000000000000-- | -- Module : Crypto.ECC -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Elliptic Curve Cryptography -- {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ScopedTypeVariables #-} module Crypto.ECC ( Curve_P256R1(..) , Curve_P384R1(..) , Curve_P521R1(..) , Curve_X25519(..) , Curve_X448(..) , Curve_Edwards25519(..) , EllipticCurve(..) , EllipticCurveDH(..) , EllipticCurveArith(..) , KeyPair(..) , SharedSecret(..) ) where import qualified Crypto.PubKey.ECC.P256 as P256 import qualified Crypto.ECC.Edwards25519 as Edwards25519 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.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.ByteArray (convert) import Data.Data (Data()) import Data.Kind (Type) import Data.Proxy -- | 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, NFData) class EllipticCurve curve where -- | Point on an Elliptic Curve type Point curve :: Type -- | Scalar in the Elliptic Curve domain type Scalar curve :: Type -- | 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. -- -- /WARNING:/ Curve implementations may return a special value or an -- exception when the public point lies in a subgroup of small order. -- This function is adequate when the scalar is in expected range and -- contributory behaviour is not needed. Otherwise use 'ecdh'. ecdhRaw :: proxy curve -> Scalar curve -> Point curve -> SharedSecret ecdhRaw prx s = throwCryptoError . ecdh prx s -- | Generate a Diffie hellman secret value and verify that the result -- is not the point at infinity. -- -- This additional test avoids risks existing with function 'ecdhRaw'. -- Implementations always return a 'CryptoError' instead of a special -- value or an exception. ecdh :: proxy curve -> Scalar curve -> Point curve -> CryptoFailable SharedSecret class EllipticCurve curve => EllipticCurveArith curve where -- | Add points on a curve pointAdd :: proxy curve -> Point curve -> Point curve -> Point curve -- | Negate a curve point pointNegate :: proxy 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 deriving (Show,Data) 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 pointNegate _ p = P256.pointNegate p pointSmul _ s p = P256.pointMul s p instance EllipticCurveDH Curve_P256R1 where ecdhRaw _ s p = SharedSecret $ P256.pointDh s p ecdh prx s p = checkNonZeroDH (ecdhRaw prx s p) data Curve_P384R1 = Curve_P384R1 deriving (Show,Data) 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 pointNegate _ p = Simple.pointNegate p pointSmul _ s p = Simple.pointMul s p instance EllipticCurveDH Curve_P384R1 where ecdh _ s p = encodeECShared prx (Simple.pointMul s p) where prx = Proxy :: Proxy Simple.SEC_p384r1 data Curve_P521R1 = Curve_P521R1 deriving (Show,Data) 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 pointNegate _ p = Simple.pointNegate p pointSmul _ s p = Simple.pointMul s p instance EllipticCurveDH Curve_P521R1 where ecdh _ s p = encodeECShared prx (Simple.pointMul s p) where prx = Proxy :: Proxy Simple.SEC_p521r1 data Curve_X25519 = Curve_X25519 deriving (Show,Data) 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 ecdhRaw _ s p = SharedSecret $ convert secret where secret = X25519.dh p s ecdh prx s p = checkNonZeroDH (ecdhRaw prx s p) data Curve_X448 = Curve_X448 deriving (Show,Data) 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 ecdhRaw _ s p = SharedSecret $ convert secret where secret = X448.dh p s ecdh prx s p = checkNonZeroDH (ecdhRaw prx s p) data Curve_Edwards25519 = Curve_Edwards25519 deriving (Show,Data) instance EllipticCurve Curve_Edwards25519 where type Point Curve_Edwards25519 = Edwards25519.Point type Scalar Curve_Edwards25519 = Edwards25519.Scalar curveSizeBits _ = 255 curveGenerateScalar _ = Edwards25519.scalarGenerate curveGenerateKeyPair _ = toKeyPair <$> Edwards25519.scalarGenerate where toKeyPair scalar = KeyPair (Edwards25519.toPoint scalar) scalar encodePoint _ point = Edwards25519.pointEncode point decodePoint _ bs = Edwards25519.pointDecode bs instance EllipticCurveArith Curve_Edwards25519 where pointAdd _ a b = Edwards25519.pointAdd a b pointNegate _ p = Edwards25519.pointNegate p pointSmul _ s p = Edwards25519.pointMul s p checkNonZeroDH :: SharedSecret -> CryptoFailable SharedSecret checkNonZeroDH s@(SharedSecret b) | B.constAllZero b = CryptoFailed CryptoError_ScalarMultiplicationInvalid | otherwise = CryptoPassed s encodeECShared :: Simple.Curve curve => Proxy curve -> Simple.Point curve -> CryptoFailable SharedSecret encodeECShared _ Simple.PointO = CryptoFailed CryptoError_ScalarMultiplicationInvalid encodeECShared prx (Simple.Point x _) = CryptoPassed . SharedSecret $ i2ospOf_ (Simple.curveSizeBytes prx) x 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 cryptonite-0.26/Crypto/ECC/Edwards25519.hs0000644000000000000000000003141213470442731016242 0ustar0000000000000000-- | -- Module : Crypto.ECC.Edwards25519 -- License : BSD-style -- Maintainer : Olivier Chéron -- Stability : experimental -- Portability : unknown -- -- Arithmetic primitives over curve edwards25519. -- -- Twisted Edwards curves are a familly of elliptic curves allowing -- complete addition formulas without any special case and no point at -- infinity. Curve edwards25519 is based on prime 2^255 - 19 for -- efficient implementation. Equation and parameters are given in -- . -- -- This module provides types and primitive operations that are useful -- to implement cryptographic schemes based on curve edwards25519: -- -- - arithmetic functions for point addition, doubling, negation, -- scalar multiplication with an arbitrary point, with the base point, -- etc. -- -- - arithmetic functions dealing with scalars modulo the prime order -- L of the base point -- -- All functions run in constant time unless noted otherwise. -- -- Warnings: -- -- 1. Curve edwards25519 has a cofactor h = 8 so the base point does -- not generate the entire curve and points with order 2, 4, 8 exist. -- When implementing cryptographic algorithms, special care must be -- taken using one of the following methods: -- -- - points must be checked for membership in the prime-order -- subgroup -- -- - or cofactor must be cleared by multiplying points by 8 -- -- Utility functions are provided to implement this. Testing -- subgroup membership with 'pointHasPrimeOrder' is 50-time slower -- than call 'pointMulByCofactor'. -- -- 2. Scalar arithmetic is always reduced modulo L, allowing fixed -- length and constant execution time, but this reduction is valid -- only when points are in the prime-order subgroup. -- -- 3. Because of modular reduction in this implementation it is not -- possible to multiply points directly by scalars like 8.s or L. -- This has to be decomposed into several steps. -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.ECC.Edwards25519 ( Scalar , Point -- * Scalars , scalarGenerate , scalarDecodeLong , scalarEncode -- * Points , pointDecode , pointEncode , pointHasPrimeOrder -- * Arithmetic functions , toPoint , scalarAdd , scalarMul , pointNegate , pointAdd , pointDouble , pointMul , pointMulByCofactor , pointsMulVarTime ) where import Data.Word import Foreign.C.Types import Foreign.Ptr import Crypto.Error import Crypto.Internal.ByteArray (Bytes, ScrubbedBytes, withByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Random scalarArraySize :: Int scalarArraySize = 40 -- maximum [9 * 4 {- 32 bits -}, 5 * 8 {- 64 bits -}] -- | A scalar modulo prime order of curve edwards25519. newtype Scalar = Scalar ScrubbedBytes deriving (Show,NFData) instance Eq Scalar where (Scalar s1) == (Scalar s2) = unsafeDoIO $ withByteArray s1 $ \ps1 -> withByteArray s2 $ \ps2 -> fmap (/= 0) (ed25519_scalar_eq ps1 ps2) {-# NOINLINE (==) #-} pointArraySize :: Int pointArraySize = 160 -- maximum [4 * 10 * 4 {- 32 bits -}, 4 * 5 * 8 {- 64 bits -}] -- | A point on curve edwards25519. newtype Point = Point Bytes deriving NFData instance Show Point where showsPrec d p = let bs = pointEncode p :: Bytes in showParen (d > 10) $ showString "Point " . shows (B.convertToBase B.Base16 bs :: Bytes) instance Eq Point where (Point p1) == (Point p2) = unsafeDoIO $ withByteArray p1 $ \pp1 -> withByteArray p2 $ \pp2 -> fmap (/= 0) (ed25519_point_eq pp1 pp2) {-# NOINLINE (==) #-} -- | Generate a random scalar. scalarGenerate :: MonadRandom randomly => randomly Scalar scalarGenerate = throwCryptoError . scalarDecodeLong <$> generate where -- Scalar generation is based on a fixed number of bytes so that -- there is no timing leak. But because of modular reduction -- distribution is not uniform. We use many more bytes than -- necessary so the probability bias is small. With 512 bits we -- get 22% of scalars with a higher frequency, but the relative -- probability difference is only 2^(-260). generate :: MonadRandom randomly => randomly ScrubbedBytes generate = getRandomBytes 64 -- | Serialize a scalar to binary, i.e. a 32-byte little-endian -- number. scalarEncode :: B.ByteArray bs => Scalar -> bs scalarEncode (Scalar s) = B.allocAndFreeze 32 $ \out -> withByteArray s $ \ps -> ed25519_scalar_encode out ps -- | Deserialize a little-endian number as a scalar. Input array can -- have any length from 0 to 64 bytes. -- -- Note: it is not advised to put secret information in the 3 lowest -- bits of a scalar if this scalar may be multiplied to untrusted -- points outside the prime-order subgroup. scalarDecodeLong :: B.ByteArrayAccess bs => bs -> CryptoFailable Scalar scalarDecodeLong bs | B.length bs > 64 = CryptoFailed CryptoError_EcScalarOutOfBounds | otherwise = unsafeDoIO $ withByteArray bs initialize where len = fromIntegral $ B.length bs initialize inp = do s <- B.alloc scalarArraySize $ \ps -> ed25519_scalar_decode_long ps inp len return $ CryptoPassed (Scalar s) {-# NOINLINE scalarDecodeLong #-} -- | Add two scalars. scalarAdd :: Scalar -> Scalar -> Scalar scalarAdd (Scalar a) (Scalar b) = Scalar $ B.allocAndFreeze scalarArraySize $ \out -> withByteArray a $ \pa -> withByteArray b $ \pb -> ed25519_scalar_add out pa pb -- | Multiply two scalars. scalarMul :: Scalar -> Scalar -> Scalar scalarMul (Scalar a) (Scalar b) = Scalar $ B.allocAndFreeze scalarArraySize $ \out -> withByteArray a $ \pa -> withByteArray b $ \pb -> ed25519_scalar_mul out pa pb -- | Multiplies a scalar with the curve base point. toPoint :: Scalar -> Point toPoint (Scalar scalar) = Point $ B.allocAndFreeze pointArraySize $ \out -> withByteArray scalar $ \pscalar -> ed25519_point_base_scalarmul out pscalar -- | Serialize a point to a 32-byte array. -- -- Format is binary compatible with 'Crypto.PubKey.Ed25519.PublicKey' -- from module "Crypto.PubKey.Ed25519". pointEncode :: B.ByteArray bs => Point -> bs pointEncode (Point p) = B.allocAndFreeze 32 $ \out -> withByteArray p $ \pp -> ed25519_point_encode out pp -- | Deserialize a 32-byte array as a point, ensuring the point is -- valid on edwards25519. -- -- /WARNING:/ variable time pointDecode :: B.ByteArrayAccess bs => bs -> CryptoFailable Point pointDecode bs | B.length bs == 32 = unsafeDoIO $ withByteArray bs initialize | otherwise = CryptoFailed CryptoError_PointSizeInvalid where initialize inp = do (res, p) <- B.allocRet pointArraySize $ \pp -> ed25519_point_decode_vartime pp inp if res == 0 then return $ CryptoFailed CryptoError_PointCoordinatesInvalid else return $ CryptoPassed (Point p) {-# NOINLINE pointDecode #-} -- | Test whether a point belongs to the prime-order subgroup -- generated by the base point. Result is 'True' for the identity -- point. -- -- @ -- pointHasPrimeOrder p = 'pointNegate' p == 'pointMul' l_minus_one p -- @ pointHasPrimeOrder :: Point -> Bool pointHasPrimeOrder (Point p) = unsafeDoIO $ withByteArray p $ \pp -> fmap (/= 0) (ed25519_point_has_prime_order pp) {-# NOINLINE pointHasPrimeOrder #-} -- | Negate a point. pointNegate :: Point -> Point pointNegate (Point a) = Point $ B.allocAndFreeze pointArraySize $ \out -> withByteArray a $ \pa -> ed25519_point_negate out pa -- | Add two points. pointAdd :: Point -> Point -> Point pointAdd (Point a) (Point b) = Point $ B.allocAndFreeze pointArraySize $ \out -> withByteArray a $ \pa -> withByteArray b $ \pb -> ed25519_point_add out pa pb -- | Add a point to itself. -- -- @ -- pointDouble p = 'pointAdd' p p -- @ pointDouble :: Point -> Point pointDouble (Point a) = Point $ B.allocAndFreeze pointArraySize $ \out -> withByteArray a $ \pa -> ed25519_point_double out pa -- | Multiply a point by h = 8. -- -- @ -- pointMulByCofactor p = 'pointMul' scalar_8 p -- @ pointMulByCofactor :: Point -> Point pointMulByCofactor (Point a) = Point $ B.allocAndFreeze pointArraySize $ \out -> withByteArray a $ \pa -> ed25519_point_mul_by_cofactor out pa -- | Scalar multiplication over curve edwards25519. -- -- Note: when the scalar had reduction modulo L and the input point -- has a torsion component, the output point may not be in the -- expected subgroup. pointMul :: Scalar -> Point -> Point pointMul (Scalar scalar) (Point base) = Point $ B.allocAndFreeze pointArraySize $ \out -> withByteArray scalar $ \pscalar -> withByteArray base $ \pbase -> ed25519_point_scalarmul out pbase pscalar -- | Multiply the point @p@ with @s2@ and add a lifted to curve value @s1@. -- -- @ -- pointsMulVarTime s1 s2 p = 'pointAdd' ('toPoint' s1) ('pointMul' s2 p) -- @ -- -- /WARNING:/ variable time pointsMulVarTime :: Scalar -> Scalar -> Point -> Point pointsMulVarTime (Scalar s1) (Scalar s2) (Point p) = Point $ B.allocAndFreeze pointArraySize $ \out -> withByteArray s1 $ \ps1 -> withByteArray s2 $ \ps2 -> withByteArray p $ \pp -> ed25519_base_double_scalarmul_vartime out ps1 pp ps2 foreign import ccall "cryptonite_ed25519_scalar_eq" ed25519_scalar_eq :: Ptr Scalar -> Ptr Scalar -> IO CInt foreign import ccall "cryptonite_ed25519_scalar_encode" ed25519_scalar_encode :: Ptr Word8 -> Ptr Scalar -> IO () foreign import ccall "cryptonite_ed25519_scalar_decode_long" ed25519_scalar_decode_long :: Ptr Scalar -> Ptr Word8 -> CSize -> IO () foreign import ccall "cryptonite_ed25519_scalar_add" ed25519_scalar_add :: Ptr Scalar -- sum -> Ptr Scalar -- a -> Ptr Scalar -- b -> IO () foreign import ccall "cryptonite_ed25519_scalar_mul" ed25519_scalar_mul :: Ptr Scalar -- out -> Ptr Scalar -- a -> Ptr Scalar -- b -> IO () foreign import ccall "cryptonite_ed25519_point_encode" ed25519_point_encode :: Ptr Word8 -> Ptr Point -> IO () foreign import ccall "cryptonite_ed25519_point_decode_vartime" ed25519_point_decode_vartime :: Ptr Point -> Ptr Word8 -> IO CInt foreign import ccall "cryptonite_ed25519_point_eq" ed25519_point_eq :: Ptr Point -> Ptr Point -> IO CInt foreign import ccall "cryptonite_ed25519_point_has_prime_order" ed25519_point_has_prime_order :: Ptr Point -> IO CInt foreign import ccall "cryptonite_ed25519_point_negate" ed25519_point_negate :: Ptr Point -- minus_a -> Ptr Point -- a -> IO () foreign import ccall "cryptonite_ed25519_point_add" ed25519_point_add :: Ptr Point -- sum -> Ptr Point -- a -> Ptr Point -- b -> IO () foreign import ccall "cryptonite_ed25519_point_double" ed25519_point_double :: Ptr Point -- two_a -> Ptr Point -- a -> IO () foreign import ccall "cryptonite_ed25519_point_mul_by_cofactor" ed25519_point_mul_by_cofactor :: Ptr Point -- eight_a -> Ptr Point -- a -> IO () foreign import ccall "cryptonite_ed25519_point_base_scalarmul" ed25519_point_base_scalarmul :: Ptr Point -- scaled -> Ptr Scalar -- scalar -> IO () foreign import ccall "cryptonite_ed25519_point_scalarmul" ed25519_point_scalarmul :: Ptr Point -- scaled -> Ptr Point -- base -> Ptr Scalar -- scalar -> IO () foreign import ccall "cryptonite_ed25519_base_double_scalarmul_vartime" ed25519_base_double_scalarmul_vartime :: Ptr Point -- combo -> Ptr Scalar -- scalar1 -> Ptr Point -- base2 -> Ptr Scalar -- scalar2 -> IO () cryptonite-0.26/Crypto/Error.hs0000644000000000000000000000040413414232447014736 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.26/Crypto/MAC/CMAC.hs0000644000000000000000000001017413414232447014755 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.26/Crypto/MAC/Poly1305.hs0000644000000000000000000000761113414232447015510 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.26/Crypto/MAC/HMAC.hs0000644000000000000000000001132213470442731014757 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, ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Data.Memory.PtrMethods import Crypto.Internal.Compat -- | Represent an HMAC that is a phantom type with the hash used to produce the mac. -- -- The Eq instance is constant time. No Show instance is provided, to avoid -- printing by mistake. 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.26/Crypto/MAC/KMAC.hs0000644000000000000000000001324113470442731014764 0ustar0000000000000000-- | -- Module : Crypto.MAC.KMAC -- License : BSD-style -- Maintainer : Olivier Chéron -- Stability : experimental -- Portability : unknown -- -- Provide the KMAC (Keccak Message Authentication Code) algorithm, derived from -- the SHA-3 base algorithm Keccak and defined in NIST SP800-185. -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} module Crypto.MAC.KMAC ( HashSHAKE , kmac , KMAC(..) -- * Incremental , Context , initialize , update , updates , finalize ) where import qualified Crypto.Hash as H import Crypto.Hash.SHAKE (HashSHAKE(..)) import Crypto.Hash.Types (HashAlgorithm(..), Digest(..)) import qualified Crypto.Hash.Types as H import Foreign.Ptr (Ptr, plusPtr) import Foreign.Storable (poke) import Data.Bits (shiftR) import Data.ByteArray (ByteArray, ByteArrayAccess) import qualified Data.ByteArray as B import Data.Word (Word8) import Data.Memory.PtrMethods (memSet) -- cSHAKE cshakeInit :: forall a name string prefix . (HashSHAKE a, ByteArrayAccess name, ByteArrayAccess string, ByteArrayAccess prefix) => name -> string -> prefix -> H.Context a cshakeInit n s p = H.Context $ B.allocAndFreeze c $ \(ptr :: Ptr (H.Context a)) -> do hashInternalInit ptr B.withByteArray b $ \d -> hashInternalUpdate ptr d (fromIntegral $ B.length b) B.withByteArray p $ \d -> hashInternalUpdate ptr d (fromIntegral $ B.length p) where c = hashInternalContextSize (undefined :: a) w = hashBlockSize (undefined :: a) x = encodeString n <+> encodeString s b = builderAllocAndFreeze (bytepad x w) :: B.Bytes cshakeUpdate :: (HashSHAKE a, ByteArrayAccess ba) => H.Context a -> ba -> H.Context a cshakeUpdate = H.hashUpdate cshakeUpdates :: (HashSHAKE a, ByteArrayAccess ba) => H.Context a -> [ba] -> H.Context a cshakeUpdates = H.hashUpdates cshakeFinalize :: forall a suffix . (HashSHAKE a, ByteArrayAccess suffix) => H.Context a -> suffix -> Digest a cshakeFinalize !c s = Digest $ B.allocAndFreeze (hashDigestSize (undefined :: a)) $ \dig -> do ((!_) :: B.Bytes) <- B.copy c $ \(ctx :: Ptr (H.Context a)) -> do B.withByteArray s $ \d -> hashInternalUpdate ctx d (fromIntegral $ B.length s) cshakeInternalFinalize ctx dig return () -- KMAC -- | Represent a KMAC that is a phantom type with the hash used to produce the -- mac. -- -- The Eq instance is constant time. No Show instance is provided, to avoid -- printing by mistake. newtype KMAC a = KMAC { kmacGetDigest :: Digest a } deriving ByteArrayAccess instance Eq (KMAC a) where (KMAC b1) == (KMAC b2) = B.constEq b1 b2 -- | Compute a KMAC using the supplied customization string and key. kmac :: (HashSHAKE a, ByteArrayAccess string, ByteArrayAccess key, ByteArrayAccess ba) => string -> key -> ba -> KMAC a kmac str key msg = finalize $ updates (initialize str key) [msg] -- | Represent an ongoing KMAC state, that can be appended with 'update' and -- finalized to a 'KMAC' with 'finalize'. newtype Context a = Context (H.Context a) -- | Initialize a new incremental KMAC context with the supplied customization -- string and key. initialize :: forall a string key . (HashSHAKE a, ByteArrayAccess string, ByteArrayAccess key) => string -> key -> Context a initialize str key = Context $ cshakeInit n str p where n = B.pack [75,77,65,67] :: B.Bytes -- "KMAC" w = hashBlockSize (undefined :: a) p = builderAllocAndFreeze (bytepad (encodeString key) w) :: B.ScrubbedBytes -- | Incrementally update a KMAC context. update :: (HashSHAKE a, ByteArrayAccess ba) => Context a -> ba -> Context a update (Context ctx) = Context . cshakeUpdate ctx -- | Incrementally update a KMAC context with multiple inputs. updates :: (HashSHAKE a, ByteArrayAccess ba) => Context a -> [ba] -> Context a updates (Context ctx) = Context . cshakeUpdates ctx -- | Finalize a KMAC context and return the KMAC. finalize :: forall a . HashSHAKE a => Context a -> KMAC a finalize (Context ctx) = KMAC $ cshakeFinalize ctx suffix where l = cshakeOutputLength (undefined :: a) suffix = builderAllocAndFreeze (rightEncode l) :: B.Bytes -- Utilities bytepad :: Builder -> Int -> Builder bytepad x w = prefix <+> x <+> zero padLen where prefix = leftEncode w padLen = (w - builderLength prefix - builderLength x) `mod` w encodeString :: ByteArrayAccess bin => bin -> Builder encodeString s = leftEncode (8 * B.length s) <+> bytes s leftEncode :: Int -> Builder leftEncode x = byte len <+> digits where digits = i2osp x len = fromIntegral (builderLength digits) rightEncode :: Int -> Builder rightEncode x = digits <+> byte len where digits = i2osp x len = fromIntegral (builderLength digits) i2osp :: Int -> Builder i2osp i | i >= 256 = i2osp (shiftR i 8) <+> byte (fromIntegral i) | otherwise = byte (fromIntegral i) -- Delaying and merging ByteArray allocations data Builder = Builder !Int (Ptr Word8 -> IO ()) -- size and initializer (<+>) :: Builder -> Builder -> Builder (Builder s1 f1) <+> (Builder s2 f2) = Builder (s1 + s2) f where f p = f1 p >> f2 (p `plusPtr` s1) builderLength :: Builder -> Int builderLength (Builder s _) = s builderAllocAndFreeze :: ByteArray ba => Builder -> ba builderAllocAndFreeze (Builder s f) = B.allocAndFreeze s f byte :: Word8 -> Builder byte !b = Builder 1 (`poke` b) bytes :: ByteArrayAccess ba => ba -> Builder bytes bs = Builder (B.length bs) (B.copyByteArrayToPtr bs) zero :: Int -> Builder zero s = Builder s (\p -> memSet p 0 s) cryptonite-0.26/Crypto/Number/Basic.hs0000644000000000000000000000776213414232447016134 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 , asPowerOf2AndOdd ) where import Data.Bits import Crypto.Number.Compat -- | @sqrti@ returns two integers @(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) -- | Express an integer as an odd number and a power of 2 asPowerOf2AndOdd :: Integer -> (Int, Integer) asPowerOf2AndOdd a | a == 0 = (0, 0) | odd a = (0, a) | a < 0 = let (e, a1) = asPowerOf2AndOdd $ abs a in (e, -a1) | isPowerOf2 a = (log2 a, 1) | otherwise = loop a 0 where isPowerOf2 n = (n /= 0) && ((n .&. (n - 1)) == 0) loop n pw = if n `mod` 2 == 0 then loop (n `div` 2) (pw + 1) else (pw, n)cryptonite-0.26/Crypto/Number/F2m.hs0000644000000000000000000001140613470442731015526 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.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.26/Crypto/Number/Generate.hs0000644000000000000000000001074213414232447016635 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.26/Crypto/Number/ModArithmetic.hs0000644000000000000000000001011613470442731017630 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 , jacobi ) where import Control.Exception (throw, Exception) 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) instance Exception CoprimesAssertionError -- | Compute the modular exponentiation of base^exponent 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. -- -- Before GHC 8.4.2, powModSecInteger is missing from integer-gmp, -- so expSafe has the same security as expFast. expSafe :: Integer -- ^ base -> Integer -- ^ exponent -> 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^exponent 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 -- ^ exponent -> 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 two 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 -- | Computes the Jacobi symbol (a/n). -- 0 ≤ a < n; n ≥ 3 and odd. -- -- The Legendre and Jacobi symbols are indistinguishable exactly when the -- lower argument is an odd prime, in which case they have the same value. -- -- See algorithm 2.149 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. jacobi :: Integer -> Integer -> Maybe Integer jacobi a n | n < 3 || even n = Nothing | a == 0 || a == 1 = Just a | n <= a = jacobi (a `mod` n) n | a < 0 = let b = if n `mod` 4 == 1 then 1 else -1 in fmap (*b) (jacobi (-a) n) | otherwise = let (e, a1) = asPowerOf2AndOdd a nMod8 = n `mod` 8 nMod4 = n `mod` 4 a1Mod4 = a1 `mod` 4 s' = if even e || nMod8 == 1 || nMod8 == 7 then 1 else -1 s = if nMod4 == 3 && a1Mod4 == 3 then -s' else s' n1 = n `mod` a1 in if a1 == 1 then Just s else fmap (*s) (jacobi n1 a1) cryptonite-0.26/Crypto/Number/Nat.hs0000644000000000000000000000435613470442731015632 0ustar0000000000000000-- | -- Module : Crypto.Number.Nat -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- Numbers at type level. -- -- This module provides extensions to "GHC.TypeLits" and "GHC.TypeNats" useful -- to work with cryptographic algorithms parameterized with a variable bit -- length. Constraints like @'IsDivisibleBy8' n@ ensure that the type-level -- parameter is applicable to the algorithm. -- -- Functions are also provided to test whether constraints are satisfied from -- values known at runtime. The following example shows how to discharge -- 'IsDivisibleBy8' in a computation @fn@ requiring this constraint: -- -- > withDivisibleBy8 :: Integer -- > -> (forall proxy n . (KnownNat n, IsDivisibleBy8 n) => proxy n -> a) -- > -> Maybe a -- > withDivisibleBy8 len fn = do -- > SomeNat p <- someNatVal len -- > Refl <- isDivisibleBy8 p -- > pure (fn p) -- -- Function @withDivisibleBy8@ above returns 'Nothing' when the argument @len@ -- is negative or not divisible by 8. {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeOperators #-} module Crypto.Number.Nat ( type IsDivisibleBy8 , type IsAtMost, type IsAtLeast , isDivisibleBy8 , isAtMost , isAtLeast ) where import Data.Type.Equality import GHC.TypeLits import Unsafe.Coerce (unsafeCoerce) import Crypto.Internal.Nat -- | get a runtime proof that the constraint @'IsDivisibleBy8' n@ is satified isDivisibleBy8 :: KnownNat n => proxy n -> Maybe (IsDiv8 n n :~: 'True) isDivisibleBy8 n | mod (natVal n) 8 == 0 = Just (unsafeCoerce Refl) | otherwise = Nothing -- | get a runtime proof that the constraint @'IsAtMost' value bound@ is -- satified isAtMost :: (KnownNat value, KnownNat bound) => proxy value -> proxy' bound -> Maybe ((value <=? bound) :~: 'True) isAtMost x y | natVal x <= natVal y = Just (unsafeCoerce Refl) | otherwise = Nothing -- | get a runtime proof that the constraint @'IsAtLeast' value bound@ is -- satified isAtLeast :: (KnownNat value, KnownNat bound) => proxy value -> proxy' bound -> Maybe ((bound <=? value) :~: 'True) isAtLeast = flip isAtMost cryptonite-0.26/Crypto/Number/Prime.hs0000644000000000000000000002337513470442731016166 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.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.26/Crypto/Number/Serialize.hs0000644000000000000000000000374413470442731017037 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. -- -- The first byte is MSB (most significant byte); the 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 takes 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. {-# INLINABLE i2ospOf #-} 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.26/Crypto/Number/Serialize/LE.hs0000644000000000000000000000377513470442731017343 0ustar0000000000000000-- | -- Module : Crypto.Number.Serialize.LE -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- Fast serialization primitives for integer (little endian) {-# LANGUAGE BangPatterns #-} module Crypto.Number.Serialize.LE ( 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.LE 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. -- -- The first byte is LSB (least significant byte); the last byte is the MSB (most 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 takes 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. {-# INLINABLE i2ospOf #-} 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.26/Crypto/Number/Serialize/Internal.hs0000644000000000000000000000463013470442731020606 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.26/Crypto/Number/Serialize/Internal/LE.hs0000644000000000000000000000455713470442731021116 0ustar0000000000000000-- | -- Module : Crypto.Number.Serialize.Internal.LE -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- Fast serialization primitives for integer using raw pointers (little endian) {-# LANGUAGE BangPatterns #-} module Crypto.Number.Serialize.Internal.LE ( 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 little 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 sz m return ptrSz where !sz = numBytes m fillPtr :: Ptr Word8 -> Int -> Integer -> IO () fillPtr p sz m = gmpExportIntegerLE m p `onGmpUnsupported` export 0 m where export ofs i | ofs >= sz = return () | otherwise = do let (i', b) = i `divMod` 256 pokeByteOff p ofs (fromIntegral b :: Word8) export (ofs+1) i' -- | Transform a little 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 = gmpImportIntegerLE ptrSz ptr `onGmpUnsupported` loop 0 (ptrSz-1) ptr where loop :: Integer -> Int -> Ptr Word8 -> IO Integer loop !acc i !p | i < 0 = return acc | otherwise = do w <- peekByteOff p i :: IO Word8 loop ((acc `shiftL` 8) .|. fromIntegral w) (i-1) p cryptonite-0.26/Crypto/KDF/Argon2.hs0000644000000000000000000001275213470442731015413 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 (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 -- ^ Argon2d is faster than Argon2i and uses data-depending memory access, -- which makes it suitable for cryptocurrencies and applications with no -- threats from side-channel timing attacks. | Argon2i -- ^ 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. | 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.26/Crypto/KDF/PBKDF2.hs0000644000000000000000000001514113470442731015166 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(..), 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.26/Crypto/KDF/Scrypt.hs0000644000000000000000000000511213414232447015536 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.26/Crypto/KDF/BCrypt.hs0000644000000000000000000002100413470442731015454 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 otherPassword :: 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 evolved to account for bugs in the standard -- C implementations. They don't represent different versions of the algorithm -- itself and in most cases should produce identical results. -- The most up to date version is @2b@ and this implementation uses 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) and less than 256 -- characters long. -- -- 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 (forM_, unless, when) import Crypto.Cipher.Blowfish.Primitive (Context, createKeySchedule, encrypt, expandKey, expandKeyWithSalt, freezeKeySchedule) import Crypto.Internal.Compat import Crypto.Random (MonadRandom, getRandomBytes) import Data.ByteArray (ByteArray, ByteArrayAccess, 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 'b'), 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 = expensiveBlowfishContext key salt cost -- 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 + 10*costTens :: Int decodeSaltHash saltHash = do let (s, h) = B.splitAt 22 saltHash salt <- convertFromBase Base64OpenBSD s hash <- convertFromBase Base64OpenBSD h return (salt, hash) -- | Create a key schedule for the BCrypt "EKS" version. -- -- Salt must be a 128-bit byte array. -- Cost must be between 4 and 31 inclusive -- See expensiveBlowfishContext :: (ByteArrayAccess key, ByteArrayAccess salt) => key-> salt -> Int -> Context expensiveBlowfishContext keyBytes saltBytes cost | B.length saltBytes /= 16 = error "bcrypt salt must be 16 bytes" | otherwise = unsafeDoIO $ do ks <- createKeySchedule expandKeyWithSalt ks keyBytes saltBytes forM_ [1..2^cost :: Int] $ \_ -> do expandKey ks keyBytes expandKey ks saltBytes freezeKeySchedule ks cryptonite-0.26/Crypto/KDF/BCryptPBKDF.hs0000644000000000000000000002270013470442731016227 0ustar0000000000000000-- | -- Module : Crypto.KDF.BCryptPBKDF -- License : BSD-style -- Stability : experimental -- Portability : Good -- -- Port of the bcrypt_pbkdf key derivation function from OpenBSD -- as described at . module Crypto.KDF.BCryptPBKDF ( Parameters (..) , generate , hashInternal ) where import Basement.Block (MutableBlock) import qualified Basement.Block as Block import qualified Basement.Block.Mutable as Block import Basement.Monad (PrimState) import Basement.Types.OffsetSize (CountOf (..), Offset (..)) import Control.Exception (finally) import Control.Monad (when) import qualified Crypto.Cipher.Blowfish.Box as Blowfish import qualified Crypto.Cipher.Blowfish.Primitive as Blowfish import Crypto.Hash.Algorithms (SHA512 (..)) import Crypto.Hash.Types (Context, hashDigestSize, hashInternalContextSize, hashInternalFinalize, hashInternalInit, hashInternalUpdate) import Crypto.Internal.Compat (unsafeDoIO) import Data.Bits import qualified Data.ByteArray as B import Data.Foldable (forM_) import Data.Memory.PtrMethods (memCopy, memSet, memXor) import Data.Word import Foreign.Ptr (Ptr, castPtr) import Foreign.Storable (peekByteOff, pokeByteOff) data Parameters = Parameters { iterCounts :: Int -- ^ The number of user-defined iterations for the algorithm -- (must be > 0) , outputLength :: Int -- ^ The number of bytes to generate out of BCryptPBKDF -- (must be in 1..1024) } deriving (Eq, Ord, Show) -- | Derive a key of specified length using the bcrypt_pbkdf algorithm. generate :: (B.ByteArray pass, B.ByteArray salt, B.ByteArray output) => Parameters -> pass -> salt -> output generate params pass salt | iterCounts params < 1 = error "BCryptPBKDF: iterCounts must be > 0" | keyLen < 1 || keyLen > 1024 = error "BCryptPBKDF: outputLength must be in 1..1024" | otherwise = B.unsafeCreate keyLen deriveKey where outLen, tmpLen, blkLen, keyLen, passLen, saltLen, ctxLen, hashLen, blocks :: Int outLen = 32 tmpLen = 32 blkLen = 4 passLen = B.length pass saltLen = B.length salt keyLen = outputLength params ctxLen = hashInternalContextSize SHA512 hashLen = hashDigestSize SHA512 -- 64 blocks = (keyLen + outLen - 1) `div` outLen deriveKey :: Ptr Word8 -> IO () deriveKey keyPtr = do -- Allocate all necessary memory. The algorihm shall not allocate -- any more dynamic memory after this point. Blocks need to be pinned -- as pointers to them are passed to the SHA512 implementation. ksClean <- Blowfish.createKeySchedule ksDirty <- Blowfish.createKeySchedule ctxMBlock <- Block.newPinned (CountOf ctxLen :: CountOf Word8) outMBlock <- Block.newPinned (CountOf outLen :: CountOf Word8) tmpMBlock <- Block.newPinned (CountOf tmpLen :: CountOf Word8) blkMBlock <- Block.newPinned (CountOf blkLen :: CountOf Word8) passHashMBlock <- Block.newPinned (CountOf hashLen :: CountOf Word8) saltHashMBlock <- Block.newPinned (CountOf hashLen :: CountOf Word8) -- Finally erase all memory areas that contain information from -- which the derived key could be reconstructed. -- As all MutableBlocks are pinned it shall be guaranteed that -- no temporary trampoline buffers are allocated. finallyErase outMBlock $ finallyErase passHashMBlock $ B.withByteArray pass $ \passPtr-> B.withByteArray salt $ \saltPtr-> Block.withMutablePtr ctxMBlock $ \ctxPtr-> Block.withMutablePtr outMBlock $ \outPtr-> Block.withMutablePtr tmpMBlock $ \tmpPtr-> Block.withMutablePtr blkMBlock $ \blkPtr-> Block.withMutablePtr passHashMBlock $ \passHashPtr-> Block.withMutablePtr saltHashMBlock $ \saltHashPtr-> do -- Hash the password. let shaPtr = castPtr ctxPtr :: Ptr (Context SHA512) hashInternalInit shaPtr hashInternalUpdate shaPtr passPtr (fromIntegral passLen) hashInternalFinalize shaPtr (castPtr passHashPtr) passHashBlock <- Block.unsafeFreeze passHashMBlock forM_ [1..blocks] $ \block-> do -- Poke the increased block counter. Block.unsafeWrite blkMBlock 0 (fromIntegral $ block `shiftR` 24) Block.unsafeWrite blkMBlock 1 (fromIntegral $ block `shiftR` 16) Block.unsafeWrite blkMBlock 2 (fromIntegral $ block `shiftR` 8) Block.unsafeWrite blkMBlock 3 (fromIntegral $ block `shiftR` 0) -- First round (slightly different). hashInternalInit shaPtr hashInternalUpdate shaPtr saltPtr (fromIntegral saltLen) hashInternalUpdate shaPtr blkPtr (fromIntegral blkLen) hashInternalFinalize shaPtr (castPtr saltHashPtr) Block.unsafeFreeze saltHashMBlock >>= \x-> do Blowfish.copyKeySchedule ksDirty ksClean hashInternalMutable ksDirty passHashBlock x tmpMBlock memCopy outPtr tmpPtr outLen -- Remaining rounds. forM_ [2..iterCounts params] $ const $ do hashInternalInit shaPtr hashInternalUpdate shaPtr tmpPtr (fromIntegral tmpLen) hashInternalFinalize shaPtr (castPtr saltHashPtr) Block.unsafeFreeze saltHashMBlock >>= \x-> do Blowfish.copyKeySchedule ksDirty ksClean hashInternalMutable ksDirty passHashBlock x tmpMBlock memXor outPtr outPtr tmpPtr outLen -- Spread the current out buffer evenly over the key buffer. -- After both loops have run every byte of the key buffer -- will have been written to exactly once and every byte -- of the output will have been used. forM_ [0..outLen - 1] $ \outIdx-> do let keyIdx = outIdx * blocks + block - 1 when (keyIdx < keyLen) $ do w8 <- peekByteOff outPtr outIdx :: IO Word8 pokeByteOff keyPtr keyIdx w8 -- | Internal hash function used by `generate`. -- -- Normal users should not need this. hashInternal :: (B.ByteArrayAccess pass, B.ByteArrayAccess salt, B.ByteArray output) => pass -> salt -> output hashInternal passHash saltHash | B.length passHash /= 64 = error "passHash must be 512 bits" | B.length saltHash /= 64 = error "saltHash must be 512 bits" | otherwise = unsafeDoIO $ do ks0 <- Blowfish.createKeySchedule outMBlock <- Block.newPinned 32 hashInternalMutable ks0 passHash saltHash outMBlock B.convert `fmap` Block.freeze outMBlock hashInternalMutable :: (B.ByteArrayAccess pass, B.ByteArrayAccess salt) => Blowfish.KeySchedule -> pass -> salt -> MutableBlock Word8 (PrimState IO) -> IO () hashInternalMutable bfks passHash saltHash outMBlock = do Blowfish.expandKeyWithSalt bfks passHash saltHash forM_ [0..63 :: Int] $ const $ do Blowfish.expandKey bfks saltHash Blowfish.expandKey bfks passHash -- "OxychromaticBlowfishSwatDynamite" represented as 4 Word64 in big-endian. store 0 =<< cipher 64 0x4f78796368726f6d store 8 =<< cipher 64 0x61746963426c6f77 store 16 =<< cipher 64 0x6669736853776174 store 24 =<< cipher 64 0x44796e616d697465 where store :: Offset Word8 -> Word64 -> IO () store o w64 = do Block.unsafeWrite outMBlock (o + 0) (fromIntegral $ w64 `shiftR` 32) Block.unsafeWrite outMBlock (o + 1) (fromIntegral $ w64 `shiftR` 40) Block.unsafeWrite outMBlock (o + 2) (fromIntegral $ w64 `shiftR` 48) Block.unsafeWrite outMBlock (o + 3) (fromIntegral $ w64 `shiftR` 56) Block.unsafeWrite outMBlock (o + 4) (fromIntegral $ w64 `shiftR` 0) Block.unsafeWrite outMBlock (o + 5) (fromIntegral $ w64 `shiftR` 8) Block.unsafeWrite outMBlock (o + 6) (fromIntegral $ w64 `shiftR` 16) Block.unsafeWrite outMBlock (o + 7) (fromIntegral $ w64 `shiftR` 24) cipher :: Int -> Word64 -> IO Word64 cipher 0 block = return block cipher i block = Blowfish.cipherBlockMutable bfks block >>= cipher (i - 1) finallyErase :: MutableBlock Word8 (PrimState IO) -> IO () -> IO () finallyErase mblock action = action `finally` Block.withMutablePtr mblock (\ptr-> memSet ptr 0 len) where CountOf len = Block.mutableLengthBytes mblock cryptonite-0.26/Crypto/KDF/HKDF.hs0000644000000000000000000000534613414232447014777 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.26/Crypto/Hash.hs0000644000000000000000000001036013470442731014533 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 Basement.Types.OffsetSize (CountOf (..)) import Basement.Block (Block, unsafeFreeze) import Basement.Block.Mutable (copyFromPtr, new) import Crypto.Internal.Compat (unsafeDoIO) 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 import Data.Word (Word8) -- | 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 :: forall a ba . (HashAlgorithm a, ByteArrayAccess ba) => ba -> Maybe (Digest a) digestFromByteString = from undefined where from :: a -> ba -> Maybe (Digest a) from alg bs | B.length bs == (hashDigestSize alg) = Just $ Digest $ unsafeDoIO $ copyBytes bs | otherwise = Nothing copyBytes :: ba -> IO (Block Word8) copyBytes ba = do muArray <- new count B.withByteArray ba $ \ptr -> copyFromPtr ptr muArray 0 count unsafeFreeze muArray where count = CountOf (B.length ba) cryptonite-0.26/Crypto/Hash/IO.hs0000644000000000000000000000502213414232447015040 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.26/Crypto/Hash/Algorithms.hs0000644000000000000000000000375513414232447016655 0ustar0000000000000000-- | -- 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(..) , SHAKE128(..) , SHAKE256(..) , Blake2b(..), Blake2bp(..) , Blake2s(..), Blake2sp(..) , 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 import Crypto.Hash.SHAKE import Crypto.Hash.Blake2 cryptonite-0.26/Crypto/OTP.hs0000644000000000000000000001460213470442731014315 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, (.&.), (.|.)) import Data.ByteArray.Mapping (fromW64BE) import Data.List (elemIndex) import Data.Word import Control.Monad (unless) import Crypto.Hash (HashAlgorithm, SHA1(..)) import Crypto.MAC.HMAC import Crypto.Internal.ByteArray (ByteArrayAccess, 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.26/Crypto/PubKey/Curve25519.hs0000644000000000000000000001111013470442731016533 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, ScrubbedBytes, Bytes, withByteArray) import qualified Crypto.Internal.ByteArray as B 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. -- -- This implementation may return an all-zero value as it does not check for -- the condition. 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.26/Crypto/PubKey/Curve448.hs0000644000000000000000000000763213470442731016403 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Curve448 -- License : BSD-style -- Maintainer : John Galt -- Stability : experimental -- Portability : unknown -- -- Curve448 support -- -- Internally uses Decaf point compression to omit the cofactor -- and implementation by Mike Hamburg. Externally API and -- data types are compatible with the encoding specified in RFC 7748. -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.PubKey.Curve448 ( SecretKey , PublicKey , DhSecret -- * Smart constructors , dhSecret , publicKey , secretKey -- * Methods , dh , toPublic , generateSecretKey ) where import Data.Word import Foreign.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. -- -- This implementation may return an all-zero value as it does not check for -- the condition. dh :: PublicKey -> SecretKey -> DhSecret dh (PublicKey pub) (SecretKey sec) = DhSecret <$> B.allocAndFreeze x448_bytes $ \result -> withByteArray sec $ \psec -> withByteArray pub $ \ppub -> decaf_x448 result ppub psec {-# 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 -> decaf_x448_derive_public_key result psec {-# 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_decaf_x448" decaf_x448 :: Ptr Word8 -- ^ public -> Ptr Word8 -- ^ basepoint -> Ptr Word8 -- ^ secret -> IO () foreign import ccall "cryptonite_decaf_x448_derive_public_key" decaf_x448_derive_public_key :: Ptr Word8 -- ^ public -> Ptr Word8 -- ^ secret -> IO () cryptonite-0.26/Crypto/PubKey/MaskGenFunction.hs0000644000000000000000000000245313414232447020105 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.26/Crypto/PubKey/DH.hs0000644000000000000000000000575113470442731015352 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) instance NFData Params where rnf (Params p g bits) = rnf p `seq` rnf g `seq` bits `seq` () -- | Represent Diffie Hellman public number Y. newtype PublicNumber = PublicNumber Integer deriving (Show,Read,Eq,Enum,Real,Num,Ord,NFData) -- | Represent Diffie Hellman private number X. newtype PrivateNumber = PrivateNumber Integer deriving (Show,Read,Eq,Enum,Real,Num,Ord,NFData) -- | Represent Diffie Hellman shared secret. newtype SharedKey = SharedKey ScrubbedBytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | 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.26/Crypto/PubKey/DSA.hs0000644000000000000000000001173113470442731015461 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 Data.Data import Data.Maybe import Crypto.Number.ModArithmetic (expFast, expSafe, inverse) import Crypto.Number.Generate import Crypto.Internal.ByteArray (ByteArrayAccess) import Crypto.Internal.Imports import Crypto.Hash import Crypto.PubKey.Internal (dsaTruncHash) import Crypto.Random.Types -- | 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) 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) 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) 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) 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) 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 = dsaTruncHash hashAlg msg q 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 = dsaTruncHash hashAlg m q 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 cryptonite-0.26/Crypto/PubKey/ECC/Generate.hs0000644000000000000000000000144713414232447017200 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.26/Crypto/PubKey/ECC/Prim.hs0000644000000000000000000001342413414232447016353 0ustar0000000000000000-- | Elliptic Curve Arithmetic. -- -- /WARNING:/ These functions are vulnerable to timing attacks. module Crypto.PubKey.ECC.Prim ( scalarGenerate , pointAdd , pointNegate , 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 c) (Point x y) = Point x (ecc_p c - 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.26/Crypto/PubKey/ECC/DH.hs0000644000000000000000000000261313414232447015735 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.26/Crypto/PubKey/ECC/ECDSA.hs0000644000000000000000000001044713470442731016266 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 , signDigestWith , sign , signDigest , verify , verifyDigest ) where import Control.Monad import Data.Data import Crypto.Hash import Crypto.Internal.ByteArray (ByteArrayAccess) import Crypto.Number.ModArithmetic (inverse) import Crypto.Number.Generate import Crypto.PubKey.ECC.Types import Crypto.PubKey.ECC.Prim import Crypto.PubKey.Internal (dsaTruncHashDigest) import Crypto.Random.Types -- | 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) -- | ECDSA Private Key. data PrivateKey = PrivateKey { private_curve :: Curve , private_d :: PrivateNumber } deriving (Show,Read,Eq,Data) -- | ECDSA Public Key. data PublicKey = PublicKey { public_curve :: Curve , public_q :: PublicPoint } deriving (Show,Read,Eq,Data) -- | ECDSA Key Pair. data KeyPair = KeyPair Curve PublicPoint PrivateNumber deriving (Show,Read,Eq,Data) -- | 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 digest using the private key and an explicit k number. -- -- /WARNING:/ Vulnerable to timing attacks. signDigestWith :: HashAlgorithm hash => Integer -- ^ k random number -> PrivateKey -- ^ private key -> Digest hash -- ^ digest to sign -> Maybe Signature signDigestWith k (PrivateKey curve d) digest = do let z = dsaTruncHashDigest digest 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 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 pk hashAlg msg = signDigestWith k pk (hashWith hashAlg msg) -- | Sign digest using the private key. -- -- /WARNING:/ Vulnerable to timing attacks. signDigest :: (HashAlgorithm hash, MonadRandom m) => PrivateKey -> Digest hash -> m Signature signDigest pk digest = do k <- generateBetween 1 (n - 1) case signDigestWith k pk digest of Nothing -> signDigest pk digest Just sig -> return sig where n = ecc_n . common_curve $ private_curve pk -- | 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 = signDigest pk (hashWith hashAlg msg) -- | Verify a digest using the public key. verifyDigest :: HashAlgorithm hash => PublicKey -> Signature -> Digest hash -> Bool verifyDigest (PublicKey _ PointO) _ _ = False verifyDigest pk@(PublicKey curve q) (Signature r s) digest | r < 1 || r >= n || s < 1 || s >= n = False | otherwise = maybe False (r ==) $ do w <- inverse s n let z = dsaTruncHashDigest digest 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 -- | Verify a bytestring using the public key. verify :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> PublicKey -> Signature -> msg -> Bool verify hashAlg pk sig msg = verifyDigest pk sig (hashWith hashAlg msg) cryptonite-0.26/Crypto/PubKey/ECC/P256.hs0000644000000000000000000003362613470442731016107 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 , pointNegate , pointMul , pointDh , pointsMulVarTime , pointIsValid , toPoint , pointToIntegers , pointFromIntegers , pointToBinary , pointFromBinary , unsafePointFromBinary -- * 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 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,NFData) -- | A P256 point newtype Point = Point Bytes deriving (Show,Eq,NFData) 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 -- | Negate a point pointNegate :: Point -> Point pointNegate a = withNewPoint $ \dx dy -> withPoint a $ \ax ay -> do ccryptonite_p256e_point_negate ax ay 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. -- When scalar is multiple of point order the result is all zero. 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 valid point pointFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Point pointFromBinary ba = unsafePointFromBinary ba >>= validatePoint where validatePoint :: Point -> CryptoFailable Point validatePoint p | pointIsValid p = CryptoPassed p | otherwise = CryptoFailed $ CryptoError_PointCoordinatesInvalid -- | Convert from binary to a point, possibly invalid unsafePointFromBinary :: ByteArrayAccess ba => ba -> CryptoFailable Point unsafePointFromBinary 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 -- | Perform addition between two scalars -- -- > a + b scalarAdd :: Scalar -> Scalar -> Scalar scalarAdd a b = withNewScalarFreeze $ \d -> withScalar a $ \pa -> withScalar b $ \pb -> ccryptonite_p256e_modadd ccryptonite_SECP256r1_n pa pb d -- | Perform subtraction between two scalars -- -- > a - b scalarSub :: Scalar -> Scalar -> Scalar scalarSub a b = withNewScalarFreeze $ \d -> withScalar a $ \pa -> withScalar b $ \pb -> ccryptonite_p256e_modsub ccryptonite_SECP256r1_n pa pb 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_p256e_modadd" ccryptonite_p256e_modadd :: Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> IO () foreign import ccall "cryptonite_p256_add_d" ccryptonite_p256_add_d :: Ptr P256Scalar -> P256Digit -> Ptr P256Scalar -> IO CInt foreign import ccall "cryptonite_p256e_modsub" ccryptonite_p256e_modsub :: Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> Ptr P256Scalar -> IO () 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 () foreign import ccall "cryptonite_p256e_point_negate" ccryptonite_p256e_point_negate :: 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.26/Crypto/PubKey/ECC/Types.hs0000644000000000000000000005676013470442731016563 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) -- | 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) 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) 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) -- | 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) -- | 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) {- 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.26/Crypto/PubKey/ECIES.hs0000644000000000000000000000412613470442731015702 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.Error import Crypto.Random -- | 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 (CryptoFailable (Point curve, SharedSecret)) deriveEncrypt proxy pub = do (KeyPair rPoint rScalar) <- curveGenerateKeyPair proxy return $ (\s -> (rPoint, s)) `fmap` 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 -> CryptoFailable SharedSecret deriveDecrypt proxy point secret = ecdh proxy secret point cryptonite-0.26/Crypto/PubKey/Ed25519.hs0000644000000000000000000001170513414232447016010 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Ed25519 -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Ed25519 support -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.PubKey.Ed25519 ( SecretKey , PublicKey , Signature -- * Size constants , publicKeySize , secretKeySize , signatureSize -- * Smart constructors , signature , publicKey , secretKey -- * Methods , toPublic , sign , verify , generateSecretKey ) where import Data.Word import Foreign.C.Types import Foreign.Ptr import Crypto.Error import Crypto.Internal.ByteArray (ByteArrayAccess, Bytes, ScrubbedBytes, withByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Random -- | An Ed25519 Secret key newtype SecretKey = SecretKey ScrubbedBytes deriving (Show,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 -- | Generate a secret key generateSecretKey :: MonadRandom m => m SecretKey generateSecretKey = SecretKey <$> getRandomBytes secretKeySize -- | A public key is 32 bytes publicKeySize :: Int publicKeySize = 32 -- | A secret key is 32 bytes secretKeySize :: Int secretKeySize = 32 -- | A signature is 64 bytes 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.26/Crypto/PubKey/Ed448.hs0000644000000000000000000001266613414232447015651 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Ed448 -- License : BSD-style -- Maintainer : Olivier Chéron -- Stability : experimental -- Portability : unknown -- -- Ed448 support -- -- Internally uses Decaf point compression to omit the cofactor -- and implementation by Mike Hamburg. Externally API and -- data types are compatible with the encoding specified in RFC 8032. -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Crypto.PubKey.Ed448 ( SecretKey , PublicKey , Signature -- * Size constants , publicKeySize , secretKeySize , signatureSize -- * Smart constructors , signature , publicKey , secretKey -- * Methods , toPublic , sign , verify , generateSecretKey ) where import Data.Word import Foreign.C.Types import Foreign.Ptr import Crypto.Error import Crypto.Internal.ByteArray (ByteArrayAccess, Bytes, ScrubbedBytes, withByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Random -- | An Ed448 Secret key newtype SecretKey = SecretKey ScrubbedBytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | An Ed448 public key newtype PublicKey = PublicKey Bytes deriving (Show,Eq,ByteArrayAccess,NFData) -- | An Ed448 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 -> decaf_ed448_derive_public_key result psec {-# 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 -> decaf_ed448_sign sig sec pub msg (fromIntegral msgLen) 0 no_context 0 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 <- decaf_ed448_verify sig pub msg (fromIntegral msgLen) 0 no_context 0 return (r /= 0) where !msgLen = B.length message -- | Generate a secret key generateSecretKey :: MonadRandom m => m SecretKey generateSecretKey = SecretKey <$> getRandomBytes secretKeySize -- | A public key is 57 bytes publicKeySize :: Int publicKeySize = 57 -- | A secret key is 57 bytes secretKeySize :: Int secretKeySize = 57 -- | A signature is 114 bytes signatureSize :: Int signatureSize = 114 no_context :: Ptr Word8 no_context = nullPtr -- not supported yet foreign import ccall "cryptonite_decaf_ed448_derive_public_key" decaf_ed448_derive_public_key :: Ptr PublicKey -- public key -> Ptr SecretKey -- secret key -> IO () foreign import ccall "cryptonite_decaf_ed448_sign" decaf_ed448_sign :: Ptr Signature -- signature -> Ptr SecretKey -- secret -> Ptr PublicKey -- public -> Ptr Word8 -- message -> CSize -- message len -> Word8 -- prehashed -> Ptr Word8 -- context -> Word8 -- context len -> IO () foreign import ccall "cryptonite_decaf_ed448_verify" decaf_ed448_verify :: Ptr Signature -- signature -> Ptr PublicKey -- public -> Ptr Word8 -- message -> CSize -- message len -> Word8 -- prehashed -> Ptr Word8 -- context -> Word8 -- context len -> IO CInt cryptonite-0.26/Crypto/PubKey/RSA.hs0000644000000000000000000000747013470442731015504 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.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 exponent '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 exponent '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.26/Crypto/PubKey/RSA/PKCS15.hs0000644000000000000000000002074113414232447016405 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 + 11 = 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 -- -- The message is returned un-padded. 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. -- The message should not be padded. 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.26/Crypto/PubKey/RSA/Prim.hs0000644000000000000000000000471313414232447016407 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.26/Crypto/PubKey/RSA/PSS.hs0000644000000000000000000002072613421720771016147 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 , signDigestWithSalt , sign , signDigest , signSafer , signDigestSafer , verify , verifyDigest ) 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 Crypto.Number.Basic (numBits) import Data.Bits (xor, shiftR, (.&.)) import Data.Word import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B (convert, eq) 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 signDigestWithSalt :: HashAlgorithm hash => ByteString -- ^ Salt to use -> Maybe Blinder -- ^ optional blinder to use -> PSSParams hash ByteString ByteString -- ^ PSS Parameters to use -> PrivateKey -- ^ RSA Private Key -> Digest hash -- ^ Message digest -> Either Error ByteString signDigestWithSalt salt blinder params pk digest | emLen < hashLen + saltLen + 2 = Left InvalidParameters | otherwise = Right $ dp blinder pk em where k = private_size pk emLen = if emTruncate pubBits then k - 1 else k mHash = B.convert digest dbLen = emLen - hashLen - 1 saltLen = B.length salt hashLen = hashDigestSize (pssHash params) pubBits = numBits (private_n pk) 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 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 = signDigestWithSalt salt blinder params pk mHash where mHash = hashWith (pssHash params) m -- | 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 signDigest :: (HashAlgorithm hash, MonadRandom m) => Maybe Blinder -- ^ optional blinder to use -> PSSParams hash ByteString ByteString -- ^ PSS Parameters to use -> PrivateKey -- ^ RSA Private Key -> Digest hash -- ^ Message digest -> m (Either Error ByteString) signDigest blinder params pk digest = do salt <- getRandomBytes (pssSaltLength params) return (signDigestWithSalt salt blinder params pk digest) -- | 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 -- | Sign using the PSS Parameters and an automatically generated blinder. signDigestSafer :: (HashAlgorithm hash, MonadRandom m) => PSSParams hash ByteString ByteString -- ^ PSS Parameters to use -> PrivateKey -- ^ private key -> Digest hash -- ^ message digst -> m (Either Error ByteString) signDigestSafer params pk digest = do blinder <- generateBlinder (private_n pk) signDigest (Just blinder) params pk digest -- | 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 = verifyDigest params pk mHash where mHash = hashWith (pssHash params) m -- | Verify a signature using the PSS Parameters verifyDigest :: 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 -> Digest hash -- ^ Digest to verify -> ByteString -- ^ Signature -> Bool verifyDigest params pk digest s | B.length s /= k = False | B.any (/= 0) pre = False | B.last em /= pssTrailerField params = False | B.any (/= 0) ps0 = False | b1 /= B.singleton 1 = False | otherwise = B.eq h h' where -- parameters hashLen = hashDigestSize (pssHash params) mHash = B.convert digest k = public_size pk emLen = if emTruncate pubBits then k - 1 else k dbLen = emLen - hashLen - 1 pubBits = numBits (public_n pk) -- unmarshall fields (pre, em) = B.splitAt (k - emLen) (ep pk s) -- drop 0..1 byte maskedDB = B.take dbLen 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 m' = B.concat [B.replicate 8 0,mHash,salt] h' = hashWith (pssHash params) m' -- When the modulus has bit length 1 modulo 8 we drop the first byte. emTruncate :: Int -> Bool emTruncate bits = ((bits-1) .&. 0x7) == 0 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.26/Crypto/PubKey/RSA/OAEP.hs0000644000000000000000000001437313414232447016227 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.26/Crypto/PubKey/RSA/Types.hs0000644000000000000000000000632313470442731016604 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 exponent e } deriving (Show,Read,Eq,Data) 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 exponent 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) 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,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.26/Crypto/PubKey/Rabin/OAEP.hs0000644000000000000000000001016013414232447016623 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Rabin.OAEP -- License : BSD-style -- Maintainer : Carlos Rodriguez-Vega -- Stability : experimental -- Portability : unknown -- -- OAEP padding scheme. -- See . -- module Crypto.PubKey.Rabin.OAEP ( OAEPParams(..) , defaultOAEPParams , pad , unpad ) where import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.Bits (xor) import Crypto.Hash import Crypto.Internal.ByteArray (ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B (convert) import Crypto.PubKey.MaskGenFunction import Crypto.PubKey.Internal (and') import Crypto.PubKey.Rabin.Types -- | Parameters for OAEP padding. 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 } -- | Pad a message using OAEP. pad :: HashAlgorithm hash => ByteString -- ^ Seed -> OAEPParams hash ByteString ByteString -- ^ OAEP params to use -> Int -- ^ size of public key in bytes -> ByteString -- ^ Message pad -> Either Error ByteString pad seed oaep k msg | k < 2*hashLen+2 = Left InvalidParameters | B.length seed /= hashLen = Left InvalidParameters | mLen > k - 2*hashLen-2 = Left MessageTooLong | otherwise = Right em where -- parameters 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] -- | Un-pad a OAEP encoded message. unpad :: HashAlgorithm hash => OAEPParams hash ByteString ByteString -- ^ OAEP params to use -> Int -- ^ size of public 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 ] cryptonite-0.26/Crypto/PubKey/Rabin/Basic.hs0000644000000000000000000002056213470442731017130 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Rabin.Basic -- License : BSD-style -- Maintainer : Carlos Rodriguez-Vega -- Stability : experimental -- Portability : unknown -- -- Rabin cryptosystem for public-key cryptography and digital signature. -- {-# LANGUAGE DeriveDataTypeable #-} module Crypto.PubKey.Rabin.Basic ( PublicKey(..) , PrivateKey(..) , Signature(..) , generate , encrypt , encryptWithSeed , decrypt , sign , signWith , verify ) where import Data.ByteString (ByteString) import qualified Data.ByteString as B import Data.Data import Data.Either (rights) import Crypto.Hash import Crypto.Number.Basic (gcde, numBytes) import Crypto.Number.ModArithmetic (expSafe, jacobi) import Crypto.Number.Serialize (i2osp, i2ospOf_, os2ip) import Crypto.PubKey.Rabin.OAEP import Crypto.PubKey.Rabin.Types import Crypto.Random (MonadRandom, getRandomBytes) -- | Represent a Rabin public key. data PublicKey = PublicKey { public_size :: Int -- ^ size of key in bytes , public_n :: Integer -- ^ public p*q } deriving (Show, Read, Eq, Data) -- | Represent a Rabin private key. data PrivateKey = PrivateKey { private_pub :: PublicKey , private_p :: Integer -- ^ p prime number , private_q :: Integer -- ^ q prime number , private_a :: Integer , private_b :: Integer } deriving (Show, Read, Eq, Data) -- | Rabin Signature. data Signature = Signature (Integer, Integer) deriving (Show, Read, Eq, Data) -- | Generate a pair of (private, public) key of size in bytes. -- Primes p and q are both congruent 3 mod 4. -- -- See algorithm 8.11 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. generate :: MonadRandom m => Int -> m (PublicKey, PrivateKey) generate size = do (p, q) <- generatePrimes size (\p -> p `mod` 4 == 3) (\q -> q `mod` 4 == 3) return $ generateKeys p q where generateKeys p q = let n = p*q (a, b, _) = gcde p q publicKey = PublicKey { public_size = size , public_n = n } privateKey = PrivateKey { private_pub = publicKey , private_p = p , private_q = q , private_a = a , private_b = b } in (publicKey, privateKey) -- | Encrypt plaintext using public key an a predefined OAEP seed. -- -- See algorithm 8.11 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. encryptWithSeed :: HashAlgorithm hash => ByteString -- ^ Seed -> OAEPParams hash ByteString ByteString -- ^ OAEP padding -> PublicKey -- ^ public key -> ByteString -- ^ plaintext -> Either Error ByteString encryptWithSeed seed oaep pk m = let n = public_n pk k = numBytes n in do m' <- pad seed oaep k m let m'' = os2ip m' return $ i2osp $ expSafe m'' 2 n -- | Encrypt plaintext using public key. encrypt :: (HashAlgorithm hash, MonadRandom m) => OAEPParams hash ByteString ByteString -- ^ OAEP padding parameters -> PublicKey -- ^ public key -> ByteString -- ^ plaintext -> m (Either Error ByteString) encrypt oaep pk m = do seed <- getRandomBytes hashLen return $ encryptWithSeed seed oaep pk m where hashLen = hashDigestSize (oaepHash oaep) -- | Decrypt ciphertext using private key. -- -- See algorithm 8.12 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. decrypt :: HashAlgorithm hash => OAEPParams hash ByteString ByteString -- ^ OAEP padding parameters -> PrivateKey -- ^ private key -> ByteString -- ^ ciphertext -> Maybe ByteString decrypt oaep pk c = let p = private_p pk q = private_q pk a = private_a pk b = private_b pk n = public_n $ private_pub pk k = numBytes n c' = os2ip c solutions = rights $ toList $ mapTuple (unpad oaep k . i2ospOf_ k) $ sqroot' c' p q a b n in if length solutions /= 1 then Nothing else Just $ head solutions where toList (w, x, y, z) = w:x:y:z:[] mapTuple f (w, x, y, z) = (f w, f x, f y, f z) -- | Sign message using padding, hash algorithm and private key. -- -- See . signWith :: HashAlgorithm hash => ByteString -- ^ padding -> PrivateKey -- ^ private key -> hash -- ^ hash function -> ByteString -- ^ message to sign -> Either Error Signature signWith padding pk hashAlg m = do h <- calculateHash padding pk hashAlg m signature <- calculateSignature h return signature where calculateSignature h = let p = private_p pk q = private_q pk a = private_a pk b = private_b pk n = public_n $ private_pub pk in if h >= n then Left MessageTooLong else let (r, _, _, _) = sqroot' h p q a b n in Right $ Signature (os2ip padding, r) -- | Sign message using hash algorithm and private key. -- -- See . sign :: (MonadRandom m, HashAlgorithm hash) => PrivateKey -- ^ private key -> hash -- ^ hash function -> ByteString -- ^ message to sign -> m (Either Error Signature) sign pk hashAlg m = do padding <- findPadding return $ signWith padding pk hashAlg m where findPadding = do padding <- getRandomBytes 8 case calculateHash padding pk hashAlg m of Right _ -> return padding _ -> findPadding -- | Calculate hash of message and padding. -- If the padding is valid, then the result of the hash operation is returned, otherwise an error. calculateHash :: HashAlgorithm hash => ByteString -- ^ padding -> PrivateKey -- ^ private key -> hash -- ^ hash function -> ByteString -- ^ message to sign -> Either Error Integer calculateHash padding pk hashAlg m = let p = private_p pk q = private_q pk h = os2ip $ hashWith hashAlg $ B.append padding m in case (jacobi (h `mod` p) p, jacobi (h `mod` q) q) of (Just 1, Just 1) -> Right h _ -> Left InvalidParameters -- | Verify signature using hash algorithm and public key. -- -- See . verify :: HashAlgorithm hash => PublicKey -- ^ private key -> hash -- ^ hash function -> ByteString -- ^ message -> Signature -- ^ signature -> Bool verify pk hashAlg m (Signature (padding, s)) = let n = public_n pk p = i2osp padding h = os2ip $ hashWith hashAlg $ B.append p m h' = expSafe s 2 n in h' == h -- | Square roots modulo prime p where p is congruent 3 mod 4 -- Value a must be a quadratic residue modulo p (i.e. jacobi symbol (a/n) = 1). -- -- See algorithm 3.36 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. sqroot :: Integer -> Integer -- ^ prime p -> (Integer, Integer) sqroot a p = let r = expSafe a ((p + 1) `div` 4) p in (r, -r) -- | Square roots modulo n given its prime factors p and q (both congruent 3 mod 4) -- Value a must be a quadratic residue of both modulo p and modulo q (i.e. jacobi symbols (a/p) = (a/q) = 1). -- -- See algorithm 3.44 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. sqroot' :: Integer -> Integer -- ^ prime p -> Integer -- ^ prime q -> Integer -- ^ c such that c*p + d*q = 1 -> Integer -- ^ d such that c*p + d*q = 1 -> Integer -- ^ n = p*q -> (Integer, Integer, Integer, Integer) sqroot' a p q c d n = let (r, _) = sqroot a p (s, _) = sqroot a q x = (r*d*q + s*c*p) `mod` n y = (r*d*q - s*c*p) `mod` n in (x, (-x) `mod` n, y, (-y) `mod` n) cryptonite-0.26/Crypto/PubKey/Rabin/Modified.hs0000644000000000000000000000655613470442731017636 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Rabin.Modified -- License : BSD-style -- Maintainer : Carlos Rodriguez-Vega -- Stability : experimental -- Portability : unknown -- -- Modified-Rabin public-key digital signature algorithm. -- See algorithm 11.30 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. -- {-# LANGUAGE DeriveDataTypeable #-} module Crypto.PubKey.Rabin.Modified ( PublicKey(..) , PrivateKey(..) , generate , sign , verify ) where import Data.ByteString import Data.Data import Crypto.Hash import Crypto.Number.ModArithmetic (expSafe, jacobi) import Crypto.Number.Serialize (os2ip) import Crypto.PubKey.Rabin.Types import Crypto.Random.Types -- | Represent a Modified-Rabin public key. data PublicKey = PublicKey { public_size :: Int -- ^ size of key in bytes , public_n :: Integer -- ^ public p*q } deriving (Show, Read, Eq, Data) -- | Represent a Modified-Rabin private key. data PrivateKey = PrivateKey { private_pub :: PublicKey , private_p :: Integer -- ^ p prime number , private_q :: Integer -- ^ q prime number , private_d :: Integer } deriving (Show, Read, Eq, Data) -- | Generate a pair of (private, public) key of size in bytes. -- Prime p is congruent 3 mod 8 and prime q is congruent 7 mod 8. generate :: MonadRandom m => Int -> m (PublicKey, PrivateKey) generate size = do (p, q) <- generatePrimes size (\p -> p `mod` 8 == 3) (\q -> q `mod` 8 == 7) return $ generateKeys p q where generateKeys p q = let n = p*q d = (n - p - q + 5) `div` 8 publicKey = PublicKey { public_size = size , public_n = n } privateKey = PrivateKey { private_pub = publicKey , private_p = p , private_q = q , private_d = d } in (publicKey, privateKey) -- | Sign message using hash algorithm and private key. sign :: HashAlgorithm hash => PrivateKey -- ^ private key -> hash -- ^ hash function -> ByteString -- ^ message to sign -> Either Error Integer sign pk hashAlg m = let d = private_d pk n = public_n $ private_pub pk h = os2ip $ hashWith hashAlg m limit = (n - 6) `div` 16 in if h > limit then Left MessageTooLong else let h' = 16*h + 6 in case jacobi h' n of Just 1 -> Right $ expSafe h' d n Just (-1) -> Right $ expSafe (h' `div` 2) d n _ -> Left InvalidParameters -- | Verify signature using hash algorithm and public key. verify :: HashAlgorithm hash => PublicKey -- ^ public key -> hash -- ^ hash function -> ByteString -- ^ message -> Integer -- ^ signature -> Bool verify pk hashAlg m s = let n = public_n pk h = os2ip $ hashWith hashAlg m s' = expSafe s 2 n s'' = case s' `mod` 8 of 6 -> s' 3 -> 2*s' 7 -> n - s' 2 -> 2*(n - s') _ -> 0 in case s'' `mod` 16 of 6 -> let h' = (s'' - 6) `div` 16 in h' == h _ -> False cryptonite-0.26/Crypto/PubKey/Rabin/RW.hs0000644000000000000000000001334113470442731016434 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Rabin.RW -- License : BSD-style -- Maintainer : Carlos Rodriguez-Vega -- Stability : experimental -- Portability : unknown -- -- Rabin-Williams cryptosystem for public-key encryption and digital signature. -- See pages 323 - 324 in "Computational Number Theory and Modern Cryptography" by Song Y. Yan. -- Also inspired by https://github.com/vanilala/vncrypt/blob/master/vncrypt/vnrw_gmp.c. -- {-# LANGUAGE DeriveDataTypeable #-} module Crypto.PubKey.Rabin.RW ( PublicKey(..) , PrivateKey(..) , generate , encrypt , encryptWithSeed , decrypt , sign , verify ) where import Data.ByteString import Data.Data import Crypto.Hash import Crypto.Number.Basic (numBytes) import Crypto.Number.ModArithmetic (expSafe, jacobi) import Crypto.Number.Serialize (i2osp, i2ospOf_, os2ip) import Crypto.PubKey.Rabin.OAEP import Crypto.PubKey.Rabin.Types import Crypto.Random.Types -- | Represent a Rabin-Williams public key. data PublicKey = PublicKey { public_size :: Int -- ^ size of key in bytes , public_n :: Integer -- ^ public p*q } deriving (Show, Read, Eq, Data) -- | Represent a Rabin-Williams private key. data PrivateKey = PrivateKey { private_pub :: PublicKey , private_p :: Integer -- ^ p prime number , private_q :: Integer -- ^ q prime number , private_d :: Integer } deriving (Show, Read, Eq, Data) -- | Generate a pair of (private, public) key of size in bytes. -- Prime p is congruent 3 mod 8 and prime q is congruent 7 mod 8. generate :: MonadRandom m => Int -> m (PublicKey, PrivateKey) generate size = do (p, q) <- generatePrimes size (\p -> p `mod` 8 == 3) (\q -> q `mod` 8 == 7) return (generateKeys p q) where generateKeys p q = let n = p*q d = ((p - 1)*(q - 1) `div` 4 + 1) `div` 2 publicKey = PublicKey { public_size = size , public_n = n } privateKey = PrivateKey { private_pub = publicKey , private_p = p , private_q = q , private_d = d } in (publicKey, privateKey) -- | Encrypt plaintext using public key an a predefined OAEP seed. -- -- See algorithm 8.11 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al. encryptWithSeed :: HashAlgorithm hash => ByteString -- ^ Seed -> OAEPParams hash ByteString ByteString -- ^ OAEP padding -> PublicKey -- ^ public key -> ByteString -- ^ plaintext -> Either Error ByteString encryptWithSeed seed oaep pk m = let n = public_n pk k = numBytes n in do m' <- pad seed oaep k m m'' <- ep1 n $ os2ip m' return $ i2osp $ ep2 n m'' -- | Encrypt plaintext using public key. encrypt :: (HashAlgorithm hash, MonadRandom m) => OAEPParams hash ByteString ByteString -- ^ OAEP padding parameters -> PublicKey -- ^ public key -> ByteString -- ^ plaintext -> m (Either Error ByteString) encrypt oaep pk m = do seed <- getRandomBytes hashLen return $ encryptWithSeed seed oaep pk m where hashLen = hashDigestSize (oaepHash oaep) -- | Decrypt ciphertext using private key. decrypt :: HashAlgorithm hash => OAEPParams hash ByteString ByteString -- ^ OAEP padding parameters -> PrivateKey -- ^ private key -> ByteString -- ^ ciphertext -> Maybe ByteString decrypt oaep pk c = let d = private_d pk n = public_n $ private_pub pk k = numBytes n c' = i2ospOf_ k $ dp2 n $ dp1 d n $ os2ip c in case unpad oaep k c' of Left _ -> Nothing Right p -> Just p -- | Sign message using hash algorithm and private key. sign :: HashAlgorithm hash => PrivateKey -- ^ private key -> hash -- ^ hash function -> ByteString -- ^ message to sign -> Either Error Integer sign pk hashAlg m = let d = private_d pk n = public_n $ private_pub pk in do m' <- ep1 n $ os2ip $ hashWith hashAlg m return $ dp1 d n m' -- | Verify signature using hash algorithm and public key. verify :: HashAlgorithm hash => PublicKey -- ^ public key -> hash -- ^ hash function -> ByteString -- ^ message -> Integer -- ^ signature -> Bool verify pk hashAlg m s = let n = public_n pk h = os2ip $ hashWith hashAlg m h' = dp2 n $ ep2 n s in h' == h -- | Encryption primitive 1 ep1 :: Integer -> Integer -> Either Error Integer ep1 n m = let m' = 2*m + 1 m'' = 2*m' m''' = 2*m'' in case jacobi m' n of Just (-1) | m'' < n -> Right m'' Just 1 | m''' < n -> Right m''' _ -> Left InvalidParameters -- | Encryption primitive 2 ep2 :: Integer -> Integer -> Integer ep2 n m = expSafe m 2 n -- | Decryption primitive 1 dp1 :: Integer -> Integer -> Integer -> Integer dp1 d n c = expSafe c d n -- | Decryption primitive 2 dp2 :: Integer -> Integer -> Integer dp2 n c = let c' = c `div` 2 c'' = (n - c) `div` 2 in case c `mod` 4 of 0 -> ((c' `div` 2 - 1) `div` 2) 1 -> ((c'' `div` 2 - 1) `div` 2) 2 -> ((c' - 1) `div` 2) _ -> ((c'' - 1) `div` 2) cryptonite-0.26/Crypto/PubKey/Rabin/Types.hs0000644000000000000000000000307113414232447017206 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Rabin.Types -- License : BSD-style -- Maintainer : Carlos Rodriguez-Vega -- Stability : experimental -- Portability : unknown -- module Crypto.PubKey.Rabin.Types ( Error(..) , generatePrimes ) where import Crypto.Number.Basic (numBits) import Crypto.Number.Prime (generatePrime, findPrimeFromWith) import Crypto.Random.Types type PrimeCondition = Integer -> Bool -- | Error possible during encryption, decryption or signing. data Error = MessageTooLong -- ^ the message to encrypt is too long | MessageNotRecognized -- ^ the message decrypted doesn't have a OAEP structure | InvalidParameters -- ^ some parameters lead to breaking assumptions deriving (Show, Eq) -- | Generate primes p & q generatePrimes :: MonadRandom m => Int -- ^ size in bytes -> PrimeCondition -- ^ condition prime p must satisfy -> PrimeCondition -- ^ condition prime q must satisfy -> m (Integer, Integer) -- ^ chosen distinct primes p and q generatePrimes size pCond qCond = let pBits = (8*(size `div` 2)) qBits = (8*(size - (size `div` 2))) in do p <- generatePrime' pBits pCond q <- generatePrime' qBits qCond return (p, q) where generatePrime' bits cond = do pr' <- generatePrime bits let pr = findPrimeFromWith cond pr' if numBits pr == bits then return pr else generatePrime' bits cond cryptonite-0.26/Crypto/Random.hs0000644000000000000000000000507713414232447015100 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 , seedFromBinary -- * Deterministic Random class , getSystemDRG , drgNew , drgNewSeed , drgNewTest , withDRG , withRandomBytes , DRG(..) -- * Random abstraction , MonadRandom(..) , MonadPseudoRandom ) where import Crypto.Error import Crypto.Random.Types import Crypto.Random.ChaChaDRG import Crypto.Random.SystemDRG import Data.ByteArray (ByteArray, ByteArrayAccess, ScrubbedBytes) import qualified Data.ByteArray as B 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)) -- | Convert a binary to a seed seedFromBinary :: ByteArrayAccess b => b -> CryptoFailable Seed seedFromBinary b | B.length b /= 40 = CryptoFailed (CryptoError_SeedSizeInvalid) | otherwise = CryptoPassed $ Seed $ B.convert b -- | 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.26/Crypto/Random/Types.hs0000644000000000000000000000363213470442731016200 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 -- | 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 = pure (>>=) 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.26/Crypto/Random/Entropy.hs0000644000000000000000000000122113414232447016523 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.26/Crypto/Random/EntropyPool.hs0000644000000000000000000000514113414232447017362 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.26/Crypto/Random/Entropy/Unsafe.hs0000644000000000000000000000240313414232447017747 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 replenished. -- -- 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.26/Crypto/Tutorial.hs0000644000000000000000000001357413414232447015464 0ustar0000000000000000-- | Examples of how to use @cryptonite@. module Crypto.Tutorial ( -- * API design -- $api_design -- * Hash algorithms -- $hash_algorithms -- * Symmetric block ciphers -- $symmetric_block_ciphers ) where -- $api_design -- -- APIs in cryptonite are often based on type classes from package -- , notably -- 'Data.ByteArray.ByteArrayAccess' and 'Data.ByteArray.ByteArray'. -- Module "Data.ByteArray" provides many primitives that are useful to -- work with cryptonite types. For example function 'Data.ByteArray.convert' -- can transform one 'Data.ByteArray.ByteArrayAccess' concrete type like -- 'Crypto.Hash.Digest' to a 'Data.ByteString.ByteString'. -- -- Algorithms and functions needing random bytes are based on type class -- 'Crypto.Random.Types.MonadRandom'. Implementation 'IO' uses a system source -- of entropy. It is also possible to use a 'Crypto.Random.Types.DRG' with -- 'Crypto.Random.Types.MonadPseudoRandom' -- -- Error conditions are returned with data type 'Crypto.Error.CryptoFailable'. -- Functions in module "Crypto.Error" can convert those values to runtime -- exceptions, 'Maybe' or 'Either' values. -- $hash_algorithms -- -- Hashing a complete message: -- -- > import Crypto.Hash -- > -- > import Data.ByteString (ByteString) -- > -- > exampleHashWith :: ByteString -> IO () -- > exampleHashWith msg = do -- > putStrLn $ " sha1(" ++ show msg ++ ") = " ++ show (hashWith SHA1 msg) -- > putStrLn $ "sha256(" ++ show msg ++ ") = " ++ show (hashWith SHA256 msg) -- -- Hashing incrementally, with intermediate context allocations: -- -- > {-# LANGUAGE OverloadedStrings #-} -- > -- > import Crypto.Hash -- > -- > import Data.ByteString (ByteString) -- > -- > exampleIncrWithAllocs :: IO () -- > exampleIncrWithAllocs = do -- > let ctx0 = hashInitWith SHA3_512 -- > ctx1 = hashUpdate ctx0 ("The " :: ByteString) -- > ctx2 = hashUpdate ctx1 ("quick " :: ByteString) -- > ctx3 = hashUpdate ctx2 ("brown " :: ByteString) -- > ctx4 = hashUpdate ctx3 ("fox " :: ByteString) -- > ctx5 = hashUpdate ctx4 ("jumps " :: ByteString) -- > ctx6 = hashUpdate ctx5 ("over " :: ByteString) -- > ctx7 = hashUpdate ctx6 ("the " :: ByteString) -- > ctx8 = hashUpdate ctx7 ("lazy " :: ByteString) -- > ctx9 = hashUpdate ctx8 ("dog" :: ByteString) -- > print (hashFinalize ctx9) -- -- Hashing incrementally, updating context in place: -- -- > {-# LANGUAGE OverloadedStrings #-} -- > -- > import Crypto.Hash.Algorithms -- > import Crypto.Hash.IO -- > -- > import Data.ByteString (ByteString) -- > -- > exampleIncrInPlace :: IO () -- > exampleIncrInPlace = do -- > ctx <- hashMutableInitWith SHA3_512 -- > hashMutableUpdate ctx ("The " :: ByteString) -- > hashMutableUpdate ctx ("quick " :: ByteString) -- > hashMutableUpdate ctx ("brown " :: ByteString) -- > hashMutableUpdate ctx ("fox " :: ByteString) -- > hashMutableUpdate ctx ("jumps " :: ByteString) -- > hashMutableUpdate ctx ("over " :: ByteString) -- > hashMutableUpdate ctx ("the " :: ByteString) -- > hashMutableUpdate ctx ("lazy " :: ByteString) -- > hashMutableUpdate ctx ("dog" :: ByteString) -- > hashMutableFinalize ctx >>= print -- $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 cryptonite-0.26/Crypto/Cipher/AES/Primitive.hs0000644000000000000000000006030013414232447017440 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 -- * Miscellanea , genCTR , genCounter -- * Encryption , encryptECB , encryptCBC , encryptCTR , encryptXTS -- * Decryption , decryptECB , decryptCBC , decryptCTR , decryptXTS -- * Incremental GCM , gcmMode , gcmInit -- * Incremental OCB , ocbMode , ocbInit -- * CCM , ccmMode , ccmInit ) 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 (AEAD_CCM n m l) aes iv = AEAD (ccmMode aes) <$> ccmInit aes iv n m l 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 } -- | Create an AES AEAD implementation for CCM ccmMode :: AES -> AEADModeImpl AESCCM ccmMode aes = AEADModeImpl { aeadImplAppendHeader = ccmAppendAAD aes , aeadImplEncrypt = ccmEncrypt aes , aeadImplDecrypt = ccmDecrypt aes , aeadImplFinalize = ccmFinish 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) -- | AESCCM State newtype AESCCM = AESCCM ScrubbedBytes deriving (NFData) sizeGCM :: Int sizeGCM = 80 sizeOCB :: Int sizeOCB = 160 sizeCCM :: Int sizeCCM = 80 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) withCCMKeyAndCopySt :: AES -> AESCCM -> (Ptr AESCCM -> Ptr AES -> IO a) -> IO (a, AESCCM) withCCMKeyAndCopySt aes (AESCCM ccmSt) f = keyToPtr aes $ \aesPtr -> do newSt <- B.copy ccmSt (\_ -> return ()) a <- withByteArray newSt $ \ccmStPtr -> f (castPtr ccmStPtr) aesPtr return (a, AESCCM 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 () ccmGetM :: CCM_M -> Int ccmGetL :: CCM_L -> Int ccmGetM m = case m of CCM_M4 -> 4 CCM_M6 -> 6 CCM_M8 -> 8 CCM_M10 -> 10 CCM_M12 -> 12 CCM_M14 -> 14 CCM_M16 -> 16 ccmGetL l = case l of CCM_L2 -> 2 CCM_L3 -> 3 CCM_L4 -> 4 -- | initialize a ccm context {-# NOINLINE ccmInit #-} ccmInit :: ByteArrayAccess iv => AES -> iv -> Int -> CCM_M -> CCM_L -> CryptoFailable AESCCM ccmInit ctx iv n m l | 15 - li /= B.length iv = CryptoFailed CryptoError_IvSizeInvalid | otherwise = unsafeDoIO $ do sm <- B.alloc sizeCCM $ \ccmStPtr -> withKeyAndIV ctx iv $ \k v -> c_aes_ccm_init (castPtr ccmStPtr) k v (fromIntegral $ B.length iv) (fromIntegral n) (fromIntegral mi) (fromIntegral li) return $ CryptoPassed (AESCCM sm) where mi = ccmGetM m li = ccmGetL l -- | append data which is only going to be authenticated to the CCM context. -- -- needs to happen after initialization and before appending encryption/decryption data. {-# NOINLINE ccmAppendAAD #-} ccmAppendAAD :: ByteArrayAccess aad => AES -> AESCCM -> aad -> AESCCM ccmAppendAAD ctx ccm input = unsafeDoIO $ snd <$> withCCMKeyAndCopySt ctx ccm doAppend where doAppend ccmStPtr aesPtr = withByteArray input $ \i -> c_aes_ccm_aad ccmStPtr aesPtr i (fromIntegral $ B.length input) -- | append data to encrypt and append to the CCM 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 ccmEncrypt #-} ccmEncrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM) ccmEncrypt ctx ccm input = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv where len = B.length input cbcmacAndIv ccmStPtr aesPtr = B.alloc len $ \o -> withByteArray input $ \i -> c_aes_ccm_encrypt (castPtr o) ccmStPtr aesPtr i (fromIntegral len) -- | append data to decrypt and append to the CCM 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 ccmDecrypt #-} ccmDecrypt :: ByteArray ba => AES -> AESCCM -> ba -> (ba, AESCCM) ccmDecrypt ctx ccm input = unsafeDoIO $ withCCMKeyAndCopySt ctx ccm cbcmacAndIv where len = B.length input cbcmacAndIv ccmStPtr aesPtr = B.alloc len $ \o -> withByteArray input $ \i -> c_aes_ccm_decrypt (castPtr o) ccmStPtr aesPtr i (fromIntegral len) -- | Generate the Tag from CCM context {-# NOINLINE ccmFinish #-} ccmFinish :: AES -> AESCCM -> Int -> AuthTag ccmFinish ctx ccm taglen = AuthTag $ B.take taglen computeTag where computeTag = B.allocAndFreeze 16 $ \t -> withCCMKeyAndCopySt ctx ccm (c_aes_ccm_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 () foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_init" c_aes_ccm_init :: Ptr AESCCM -> Ptr AES -> Ptr Word8 -> CUInt -> CUInt -> CInt -> CInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_aad" c_aes_ccm_aad :: Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_encrypt" c_aes_ccm_encrypt :: CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_decrypt" c_aes_ccm_decrypt :: CString -> Ptr AESCCM -> Ptr AES -> CString -> CUInt -> IO () foreign import ccall "cryptonite_aes.h cryptonite_aes_ccm_finish" c_aes_ccm_finish :: CString -> Ptr AESCCM -> Ptr AES -> IO () cryptonite-0.26/Crypto/Cipher/Blowfish/Box.hs0000644000000000000000000004634013470442731017376 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Blowfish.Box -- License : BSD-style -- Stability : experimental -- Portability : Good {-# LANGUAGE MagicHash #-} module Crypto.Cipher.Blowfish.Box ( KeySchedule(..) , createKeySchedule , copyKeySchedule ) where import Crypto.Internal.WordArray (MutableArray32, mutableArray32FromAddrBE, mutableArrayRead32, mutableArrayWrite32) newtype KeySchedule = KeySchedule MutableArray32 -- | Copy the state of one key schedule into the other. -- The first parameter is the destination and the second the source. copyKeySchedule :: KeySchedule -> KeySchedule -> IO () copyKeySchedule (KeySchedule dst) (KeySchedule src) = loop 0 where loop 1042 = return () loop i = do w32 <-mutableArrayRead32 src i mutableArrayWrite32 dst i w32 loop (i + 1) -- | Create a key schedule mutable array of the pbox followed by -- all the sboxes. createKeySchedule :: IO KeySchedule createKeySchedule = KeySchedule `fmap` 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.26/Crypto/Cipher/Blowfish/Primitive.hs0000644000000000000000000002375013470442731020616 0ustar0000000000000000-- | -- Module : Crypto.Cipher.Blowfish.Primitive -- License : BSD-style -- Stability : experimental -- Portability : Good -- Rewritten by Vincent Hanquez (c) 2015 -- Lars Petersen (c) 2018 -- -- 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) {-# LANGUAGE BangPatterns #-} module Crypto.Cipher.Blowfish.Primitive ( Context , initBlowfish , encrypt , decrypt , KeySchedule , createKeySchedule , freezeKeySchedule , expandKey , expandKeyWithSalt , cipherBlockMutable ) where import Control.Monad (when) import Data.Bits import Data.Memory.Endian import Data.Word import Crypto.Cipher.Blowfish.Box import Crypto.Error import Crypto.Internal.ByteArray (ByteArray, ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Compat import Crypto.Internal.Imports import Crypto.Internal.WordArray newtype Context = Context Array32 instance NFData Context where rnf a = a `seq` () -- | 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 | B.length key > (448 `div` 8) = CryptoFailed CryptoError_KeySizeInvalid | otherwise = CryptoPassed $ unsafeDoIO $ do ks <- createKeySchedule expandKey ks key freezeKeySchedule ks -- | Get an immutable Blowfish context by freezing a mutable key schedule. freezeKeySchedule :: KeySchedule -> IO Context freezeKeySchedule (KeySchedule ma) = Context `fmap` mutableArray32Freeze ma expandKey :: (ByteArrayAccess key) => KeySchedule -> key -> IO () expandKey ks@(KeySchedule ma) key = do when (B.length key > 0) $ iterKeyStream key 0 0 $ \i l r a0 a1 cont-> do mutableArrayWriteXor32 ma i l mutableArrayWriteXor32 ma (i + 1) r when (i + 2 < 18) (cont a0 a1) loop 0 0 0 where loop i l r = do n <- cipherBlockMutable ks (fromIntegral l `shiftL` 32 .|. fromIntegral r) let nl = fromIntegral (n `shiftR` 32) nr = fromIntegral (n .&. 0xffffffff) mutableArrayWrite32 ma i nl mutableArrayWrite32 ma (i + 1) nr when (i < 18 + 1024) (loop (i + 2) nl nr) expandKeyWithSalt :: (ByteArrayAccess key, ByteArrayAccess salt) => KeySchedule -> key -> salt -> IO () expandKeyWithSalt ks key salt | B.length salt == 16 = expandKeyWithSalt128 ks key (fromBE $ B.toW64BE salt 0) (fromBE $ B.toW64BE salt 8) | otherwise = expandKeyWithSaltAny ks key salt expandKeyWithSaltAny :: (ByteArrayAccess key, ByteArrayAccess salt) => KeySchedule -- ^ The key schedule -> key -- ^ The key -> salt -- ^ The salt -> IO () expandKeyWithSaltAny ks@(KeySchedule ma) key salt = do when (B.length key > 0) $ iterKeyStream key 0 0 $ \i l r a0 a1 cont-> do mutableArrayWriteXor32 ma i l mutableArrayWriteXor32 ma (i + 1) r when (i + 2 < 18) (cont a0 a1) -- Go through the entire key schedule overwriting the P-Array and S-Boxes when (B.length salt > 0) $ iterKeyStream salt 0 0 $ \i l r a0 a1 cont-> do let l' = xor l a0 let r' = xor r a1 n <- cipherBlockMutable ks (fromIntegral l' `shiftL` 32 .|. fromIntegral r') let nl = fromIntegral (n `shiftR` 32) nr = fromIntegral (n .&. 0xffffffff) mutableArrayWrite32 ma i nl mutableArrayWrite32 ma (i + 1) nr when (i + 2 < 18 + 1024) (cont nl nr) expandKeyWithSalt128 :: ByteArrayAccess ba => KeySchedule -- ^ The key schedule -> ba -- ^ The key -> Word64 -- ^ First word of the salt -> Word64 -- ^ Second word of the salt -> IO () expandKeyWithSalt128 ks@(KeySchedule ma) key salt1 salt2 = do when (B.length key > 0) $ iterKeyStream key 0 0 $ \i l r a0 a1 cont-> do mutableArrayWriteXor32 ma i l mutableArrayWriteXor32 ma (i + 1) r when (i + 2 < 18) (cont a0 a1) -- Go through the entire key schedule overwriting the P-Array and S-Boxes loop 0 salt1 salt1 salt2 where loop i input slt1 slt2 | i == 1042 = return () | otherwise = do n <- cipherBlockMutable ks input let nl = fromIntegral (n `shiftR` 32) nr = fromIntegral (n .&. 0xffffffff) mutableArrayWrite32 ma i nl mutableArrayWrite32 ma (i+1) nr loop (i+2) (n `xor` slt2) slt2 slt1 -- | Encrypt blocks -- -- Input need to be a multiple of 8 bytes encrypt :: ByteArray ba => Context -> ba -> ba encrypt ctx ba | B.length ba == 0 = B.empty | B.length ba `mod` 8 /= 0 = error "invalid data length" | otherwise = B.mapAsWord64 (cipherBlock ctx False) ba -- | Decrypt blocks -- -- Input need to be a multiple of 8 bytes decrypt :: ByteArray ba => Context -> ba -> ba decrypt ctx ba | B.length ba == 0 = B.empty | B.length ba `mod` 8 /= 0 = error "invalid data length" | otherwise = B.mapAsWord64 (cipherBlock ctx True) ba -- | Encrypt or decrypt a single block of 64 bits. -- -- The inverse argument decides whether to encrypt or decrypt. cipherBlock :: Context -> Bool -> Word64 -> Word64 cipherBlock (Context ar) inverse 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) -- | The Blowfish Feistel function F f :: Word32 -> Word64 f t = let a = s0 (0xff .&. (t `shiftR` 24)) b = s1 (0xff .&. (t `shiftR` 16)) c = s2 (0xff .&. (t `shiftR` 8)) d = s3 (0xff .&. t) in fromIntegral (((a + b) `xor` c) + d) `shiftL` 32 -- | S-Box arrays, each containing 256 32-bit words -- The first 18 words contain the P-Array of subkeys s0, s1, s2, s3 :: Word32 -> Word32 s0 i = arrayRead32 ar (fromIntegral i + 18) s1 i = arrayRead32 ar (fromIntegral i + 274) s2 i = arrayRead32 ar (fromIntegral i + 530) s3 i = arrayRead32 ar (fromIntegral i + 786) p :: Int -> Word32 p i | inverse = arrayRead32 ar (17 - i) | otherwise = arrayRead32 ar i -- | Blowfish encrypt a Word using the current state of the key schedule cipherBlockMutable :: KeySchedule -> Word64 -> IO Word64 cipherBlockMutable (KeySchedule ma) input = doRound input 0 where -- | Transform the input over 16 rounds doRound !i roundIndex | roundIndex == 16 = do pVal1 <- mutableArrayRead32 ma 16 pVal2 <- mutableArrayRead32 ma 17 let final = (fromIntegral pVal1 `shiftL` 32) .|. fromIntegral pVal2 return $ rotateL (i `xor` final) 32 | otherwise = do pVal <- mutableArrayRead32 ma 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 <- s0 (0xff .&. (t `shiftR` 24)) b <- s1 (0xff .&. (t `shiftR` 16)) c <- s2 (0xff .&. (t `shiftR` 8)) d <- s3 (0xff .&. t) return (fromIntegral (((a + b) `xor` c) + d) `shiftL` 32) -- | S-Box arrays, each containing 256 32-bit words -- The first 18 words contain the P-Array of subkeys s0, s1, s2, s3 :: Word32 -> IO Word32 s0 i = mutableArrayRead32 ma (fromIntegral i + 18) s1 i = mutableArrayRead32 ma (fromIntegral i + 274) s2 i = mutableArrayRead32 ma (fromIntegral i + 530) s3 i = mutableArrayRead32 ma (fromIntegral i + 786) iterKeyStream :: (ByteArrayAccess x) => x -> Word32 -> Word32 -> (Int -> Word32 -> Word32 -> Word32 -> Word32 -> (Word32 -> Word32 -> IO ()) -> IO ()) -> IO () iterKeyStream x a0 a1 g = f 0 0 a0 a1 where len = B.length x -- Avoiding the modulo operation when interating over the ring -- buffer is assumed to be more efficient here. All other -- implementations do this, too. The branch prediction shall prefer -- the branch with the increment. n j = if j + 1 >= len then 0 else j + 1 f i j0 b0 b1 = g i l r b0 b1 (f (i + 2) j8) where j1 = n j0 j2 = n j1 j3 = n j2 j4 = n j3 j5 = n j4 j6 = n j5 j7 = n j6 j8 = n j7 x0 = fromIntegral (B.index x j0) x1 = fromIntegral (B.index x j1) x2 = fromIntegral (B.index x j2) x3 = fromIntegral (B.index x j3) x4 = fromIntegral (B.index x j4) x5 = fromIntegral (B.index x j5) x6 = fromIntegral (B.index x j6) x7 = fromIntegral (B.index x j7) l = shiftL x0 24 .|. shiftL x1 16 .|. shiftL x2 8 .|. x3 r = shiftL x4 24 .|. shiftL x5 16 .|. shiftL x6 8 .|. x7 {-# INLINE iterKeyStream #-} -- Benchmarking shows that GHC considers this function too big to inline -- although forcing inlining causes an actual improvement. -- It is assumed that all function calls (especially the continuation) -- collapse into a tight loop after inlining. cryptonite-0.26/Crypto/Cipher/CAST5/Primitive.hs0000644000000000000000000013377413414232447017667 0ustar0000000000000000{-# LANGUAGE MagicHash #-} ----------------------------------------------------------------------------- -- | -- Module : Crypto.Cipher.CAST5.Primitive -- License : BSD-style -- -- Haskell implementation of the CAST-128 Encryption Algorithm -- ----------------------------------------------------------------------------- module Crypto.Cipher.CAST5.Primitive ( encrypt , decrypt , Key() , buildKey ) where import Control.Monad (void, (>=>)) import Data.Bits import Data.Memory.Endian import Data.Word import Crypto.Internal.ByteArray (ByteArrayAccess) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.WordArray -- Data Types data P = P {-# UNPACK #-} !Word32 -- left word {-# UNPACK #-} !Word32 -- right word data Q = Q {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32 {-# UNPACK #-} !Word32 -- | All subkeys for 12 or 16 rounds data Key = K12 {-# UNPACK #-} !Array32 -- [ km1, kr1, km2, kr2, ..., km12, kr12 ] | K16 {-# UNPACK #-} !Array32 -- [ km1, kr1, km2, kr2, ..., km16, kr16 ] -- Big-endian Transformations decomp64 :: Word64 -> P decomp64 x = P (fromIntegral (x `shiftR` 32)) (fromIntegral x) comp64 :: P -> Word64 comp64 (P l r) = (fromIntegral l `shiftL` 32) .|. fromIntegral r decomp32 :: Word32 -> (Word8, Word8, Word8, Word8) decomp32 x = let a = fromIntegral (x `shiftR` 24) b = fromIntegral (x `shiftR` 16) c = fromIntegral (x `shiftR` 8) d = fromIntegral x in (a, b, c, d) -- Encryption -- | Encrypts a block using the specified key encrypt :: Key -> Word64 -> Word64 encrypt k = comp64 . cast_enc k . decomp64 cast_enc :: Key -> P -> P cast_enc (K12 a) (P l0 r0) = P r12 r11 where r1 = type1 a 0 l0 r0 r2 = type2 a 2 r0 r1 r3 = type3 a 4 r1 r2 r4 = type1 a 6 r2 r3 r5 = type2 a 8 r3 r4 r6 = type3 a 10 r4 r5 r7 = type1 a 12 r5 r6 r8 = type2 a 14 r6 r7 r9 = type3 a 16 r7 r8 r10 = type1 a 18 r8 r9 r11 = type2 a 20 r9 r10 r12 = type3 a 22 r10 r11 cast_enc (K16 a) p = P r16 r15 where P r12 r11 = cast_enc (K12 a) p r13 = type1 a 24 r11 r12 r14 = type2 a 26 r12 r13 r15 = type3 a 28 r13 r14 r16 = type1 a 30 r14 r15 -- Decryption -- | Decrypts a block using the specified key decrypt :: Key -> Word64 -> Word64 decrypt k = comp64 . cast_dec k . decomp64 cast_dec :: Key -> P -> P cast_dec (K12 a) (P r12 r11) = P l0 r0 where r10 = type3 a 22 r12 r11 r9 = type2 a 20 r11 r10 r8 = type1 a 18 r10 r9 r7 = type3 a 16 r9 r8 r6 = type2 a 14 r8 r7 r5 = type1 a 12 r7 r6 r4 = type3 a 10 r6 r5 r3 = type2 a 8 r5 r4 r2 = type1 a 6 r4 r3 r1 = type3 a 4 r3 r2 r0 = type2 a 2 r2 r1 l0 = type1 a 0 r1 r0 cast_dec (K16 a) (P r16 r15) = cast_dec (K12 a) (P r12 r11) where r14 = type1 a 30 r16 r15 r13 = type3 a 28 r15 r14 r12 = type2 a 26 r14 r13 r11 = type1 a 24 r13 r12 -- Non-Identical Rounds type1 :: Array32 -> Int -> Word32 -> Word32 -> Word32 type1 arr idx l r = let km = arrayRead32 arr idx kr = arrayRead32 arr (idx + 1) j = (km + r) `rotateL` fromIntegral kr (ja, jb, jc, jd) = decomp32 j in l `xor` (((sbox_s1 ja `xor` sbox_s2 jb) - sbox_s3 jc) + sbox_s4 jd) type2 :: Array32 -> Int -> Word32 -> Word32 -> Word32 type2 arr idx l r = let km = arrayRead32 arr idx kr = arrayRead32 arr (idx + 1) j = (km `xor` r) `rotateL` fromIntegral kr (ja, jb, jc, jd) = decomp32 j in l `xor` (((sbox_s1 ja - sbox_s2 jb) + sbox_s3 jc) `xor` sbox_s4 jd) type3 :: Array32 -> Int -> Word32 -> Word32 -> Word32 type3 arr idx l r = let km = arrayRead32 arr idx kr = arrayRead32 arr (idx + 1) j = (km - r) `rotateL` fromIntegral kr (ja, jb, jc, jd) = decomp32 j in l `xor` (((sbox_s1 ja + sbox_s2 jb) `xor` sbox_s3 jc) - sbox_s4 jd) -- Key Schedule -- | Precompute "masking" and "rotation" subkeys buildKey :: ByteArrayAccess key => Bool -- ^ @True@ for short keys that only need 12 rounds -> key -- ^ Input key padded to 16 bytes -> Key -- ^ Output data structure buildKey isShort key = let P x0123 x4567 = decomp64 (fromBE $ B.toW64BE key 0) P x89AB xCDEF = decomp64 (fromBE $ B.toW64BE key 8) in keySchedule isShort (Q x0123 x4567 x89AB xCDEF) keySchedule :: Bool -> Q -> Key keySchedule isShort x | isShort = K12 $ allocArray32AndFreeze 24 $ \ma -> void (steps123 ma 0 x >>= skip4 >>= steps123 ma 1) | otherwise = K16 $ allocArray32AndFreeze 32 $ \ma -> void (steps123 ma 0 x >>= step4 ma 24 >>= steps123 ma 1 >>= step4 ma 25) where sbox_s56785 a b c d e = sbox_s5 a `xor` sbox_s6 b `xor` sbox_s7 c `xor` sbox_s8 d `xor` sbox_s5 e sbox_s56786 a b c d e = sbox_s5 a `xor` sbox_s6 b `xor` sbox_s7 c `xor` sbox_s8 d `xor` sbox_s6 e sbox_s56787 a b c d e = sbox_s5 a `xor` sbox_s6 b `xor` sbox_s7 c `xor` sbox_s8 d `xor` sbox_s7 e sbox_s56788 a b c d e = sbox_s5 a `xor` sbox_s6 b `xor` sbox_s7 c `xor` sbox_s8 d `xor` sbox_s8 e steps123 ma off = step1 ma off >=> step2 ma (off + 8) >=> step3 ma (off + 16) step1 :: MutableArray32 -> Int -> Q -> IO Q step1 ma off (Q x0123 x4567 x89AB xCDEF) = do let (x8, x9, xA, xB) = decomp32 x89AB (xC, xD, xE, xF) = decomp32 xCDEF z0123 = x0123 `xor` sbox_s56787 xD xF xC xE x8 z4567 = x89AB `xor` sbox_s56788 z0 z2 z1 z3 xA z89AB = xCDEF `xor` sbox_s56785 z7 z6 z5 z4 x9 zCDEF = x4567 `xor` sbox_s56786 zA z9 zB z8 xB (z0, z1, z2, z3) = decomp32 z0123 (z4, z5, z6, z7) = decomp32 z4567 (z8, z9, zA, zB) = decomp32 z89AB (zC, zD, zE, zF) = decomp32 zCDEF mutableArrayWrite32 ma (off + 0) $ sbox_s56785 z8 z9 z7 z6 z2 mutableArrayWrite32 ma (off + 2) $ sbox_s56786 zA zB z5 z4 z6 mutableArrayWrite32 ma (off + 4) $ sbox_s56787 zC zD z3 z2 z9 mutableArrayWrite32 ma (off + 6) $ sbox_s56788 zE zF z1 z0 zC return (Q z0123 z4567 z89AB zCDEF) step2 :: MutableArray32 -> Int -> Q -> IO Q step2 ma off (Q z0123 z4567 z89AB zCDEF) = do let (z0, z1, z2, z3) = decomp32 z0123 (z4, z5, z6, z7) = decomp32 z4567 x0123 = z89AB `xor` sbox_s56787 z5 z7 z4 z6 z0 x4567 = z0123 `xor` sbox_s56788 x0 x2 x1 x3 z2 x89AB = z4567 `xor` sbox_s56785 x7 x6 x5 x4 z1 xCDEF = zCDEF `xor` sbox_s56786 xA x9 xB x8 z3 (x0, x1, x2, x3) = decomp32 x0123 (x4, x5, x6, x7) = decomp32 x4567 (x8, x9, xA, xB) = decomp32 x89AB (xC, xD, xE, xF) = decomp32 xCDEF mutableArrayWrite32 ma (off + 0) $ sbox_s56785 x3 x2 xC xD x8 mutableArrayWrite32 ma (off + 2) $ sbox_s56786 x1 x0 xE xF xD mutableArrayWrite32 ma (off + 4) $ sbox_s56787 x7 x6 x8 x9 x3 mutableArrayWrite32 ma (off + 6) $ sbox_s56788 x5 x4 xA xB x7 return (Q x0123 x4567 x89AB xCDEF) step3 :: MutableArray32 -> Int -> Q -> IO Q step3 ma off (Q x0123 x4567 x89AB xCDEF) = do let (x8, x9, xA, xB) = decomp32 x89AB (xC, xD, xE, xF) = decomp32 xCDEF z0123 = x0123 `xor` sbox_s56787 xD xF xC xE x8 z4567 = x89AB `xor` sbox_s56788 z0 z2 z1 z3 xA z89AB = xCDEF `xor` sbox_s56785 z7 z6 z5 z4 x9 zCDEF = x4567 `xor` sbox_s56786 zA z9 zB z8 xB (z0, z1, z2, z3) = decomp32 z0123 (z4, z5, z6, z7) = decomp32 z4567 (z8, z9, zA, zB) = decomp32 z89AB (zC, zD, zE, zF) = decomp32 zCDEF mutableArrayWrite32 ma (off + 0) $ sbox_s56785 z3 z2 zC zD z9 mutableArrayWrite32 ma (off + 2) $ sbox_s56786 z1 z0 zE zF zC mutableArrayWrite32 ma (off + 4) $ sbox_s56787 z7 z6 z8 z9 z2 mutableArrayWrite32 ma (off + 6) $ sbox_s56788 z5 z4 zA zB z6 return (Q z0123 z4567 z89AB zCDEF) step4 :: MutableArray32 -> Int -> Q -> IO Q step4 ma off (Q z0123 z4567 z89AB zCDEF) = do let (z0, z1, z2, z3) = decomp32 z0123 (z4, z5, z6, z7) = decomp32 z4567 x0123 = z89AB `xor` sbox_s56787 z5 z7 z4 z6 z0 x4567 = z0123 `xor` sbox_s56788 x0 x2 x1 x3 z2 x89AB = z4567 `xor` sbox_s56785 x7 x6 x5 x4 z1 xCDEF = zCDEF `xor` sbox_s56786 xA x9 xB x8 z3 (x0, x1, x2, x3) = decomp32 x0123 (x4, x5, x6, x7) = decomp32 x4567 (x8, x9, xA, xB) = decomp32 x89AB (xC, xD, xE, xF) = decomp32 xCDEF mutableArrayWrite32 ma (off + 0) $ sbox_s56785 x8 x9 x7 x6 x3 mutableArrayWrite32 ma (off + 2) $ sbox_s56786 xA xB x5 x4 x7 mutableArrayWrite32 ma (off + 4) $ sbox_s56787 xC xD x3 x2 x8 mutableArrayWrite32 ma (off + 6) $ sbox_s56788 xE xF x1 x0 xD return (Q x0123 x4567 x89AB xCDEF) skip4 :: Q -> IO Q skip4 (Q z0123 z4567 z89AB zCDEF) = do let (z0, z1, z2, z3) = decomp32 z0123 (z4, z5, z6, z7) = decomp32 z4567 x0123 = z89AB `xor` sbox_s56787 z5 z7 z4 z6 z0 x4567 = z0123 `xor` sbox_s56788 x0 x2 x1 x3 z2 x89AB = z4567 `xor` sbox_s56785 x7 x6 x5 x4 z1 xCDEF = zCDEF `xor` sbox_s56786 xA x9 xB x8 z3 (x0, x1, x2, x3) = decomp32 x0123 (x4, x5, x6, x7) = decomp32 x4567 (x8, x9, xA, xB) = decomp32 x89AB return (Q x0123 x4567 x89AB xCDEF) -- S-Boxes sbox_s1 :: Word8 -> Word32 sbox_s1 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\x30\xfb\x40\xd4\x9f\xa0\xff\x0b\x6b\xec\xcd\x2f\x3f\x25\x8c\x7a\x1e\x21\x3f\x2f\x9c\x00\x4d\xd3\x60\x03\xe5\x40\xcf\x9f\xc9\x49\ \\xbf\xd4\xaf\x27\x88\xbb\xbd\xb5\xe2\x03\x40\x90\x98\xd0\x96\x75\x6e\x63\xa0\xe0\x15\xc3\x61\xd2\xc2\xe7\x66\x1d\x22\xd4\xff\x8e\ \\x28\x68\x3b\x6f\xc0\x7f\xd0\x59\xff\x23\x79\xc8\x77\x5f\x50\xe2\x43\xc3\x40\xd3\xdf\x2f\x86\x56\x88\x7c\xa4\x1a\xa2\xd2\xbd\x2d\ \\xa1\xc9\xe0\xd6\x34\x6c\x48\x19\x61\xb7\x6d\x87\x22\x54\x0f\x2f\x2a\xbe\x32\xe1\xaa\x54\x16\x6b\x22\x56\x8e\x3a\xa2\xd3\x41\xd0\ \\x66\xdb\x40\xc8\xa7\x84\x39\x2f\x00\x4d\xff\x2f\x2d\xb9\xd2\xde\x97\x94\x3f\xac\x4a\x97\xc1\xd8\x52\x76\x44\xb7\xb5\xf4\x37\xa7\ \\xb8\x2c\xba\xef\xd7\x51\xd1\x59\x6f\xf7\xf0\xed\x5a\x09\x7a\x1f\x82\x7b\x68\xd0\x90\xec\xf5\x2e\x22\xb0\xc0\x54\xbc\x8e\x59\x35\ \\x4b\x6d\x2f\x7f\x50\xbb\x64\xa2\xd2\x66\x49\x10\xbe\xe5\x81\x2d\xb7\x33\x22\x90\xe9\x3b\x15\x9f\xb4\x8e\xe4\x11\x4b\xff\x34\x5d\ \\xfd\x45\xc2\x40\xad\x31\x97\x3f\xc4\xf6\xd0\x2e\x55\xfc\x81\x65\xd5\xb1\xca\xad\xa1\xac\x2d\xae\xa2\xd4\xb7\x6d\xc1\x9b\x0c\x50\ \\x88\x22\x40\xf2\x0c\x6e\x4f\x38\xa4\xe4\xbf\xd7\x4f\x5b\xa2\x72\x56\x4c\x1d\x2f\xc5\x9c\x53\x19\xb9\x49\xe3\x54\xb0\x46\x69\xfe\ \\xb1\xb6\xab\x8a\xc7\x13\x58\xdd\x63\x85\xc5\x45\x11\x0f\x93\x5d\x57\x53\x8a\xd5\x6a\x39\x04\x93\xe6\x3d\x37\xe0\x2a\x54\xf6\xb3\ \\x3a\x78\x7d\x5f\x62\x76\xa0\xb5\x19\xa6\xfc\xdf\x7a\x42\x20\x6a\x29\xf9\xd4\xd5\xf6\x1b\x18\x91\xbb\x72\x27\x5e\xaa\x50\x81\x67\ \\x38\x90\x10\x91\xc6\xb5\x05\xeb\x84\xc7\xcb\x8c\x2a\xd7\x5a\x0f\x87\x4a\x14\x27\xa2\xd1\x93\x6b\x2a\xd2\x86\xaf\xaa\x56\xd2\x91\ \\xd7\x89\x43\x60\x42\x5c\x75\x0d\x93\xb3\x9e\x26\x18\x71\x84\xc9\x6c\x00\xb3\x2d\x73\xe2\xbb\x14\xa0\xbe\xbc\x3c\x54\x62\x37\x79\ \\x64\x45\x9e\xab\x3f\x32\x8b\x82\x77\x18\xcf\x82\x59\xa2\xce\xa6\x04\xee\x00\x2e\x89\xfe\x78\xe6\x3f\xab\x09\x50\x32\x5f\xf6\xc2\ \\x81\x38\x3f\x05\x69\x63\xc5\xc8\x76\xcb\x5a\xd6\xd4\x99\x74\xc9\xca\x18\x0d\xcf\x38\x07\x82\xd5\xc7\xfa\x5c\xf6\x8a\xc3\x15\x11\ \\x35\xe7\x9e\x13\x47\xda\x91\xd0\xf4\x0f\x90\x86\xa7\xe2\x41\x9e\x31\x36\x62\x41\x05\x1e\xf4\x95\xaa\x57\x3b\x04\x4a\x80\x5d\x8d\ \\x54\x83\x00\xd0\x00\x32\x2a\x3c\xbf\x64\xcd\xdf\xba\x57\xa6\x8e\x75\xc6\x37\x2b\x50\xaf\xd3\x41\xa7\xc1\x32\x75\x91\x5a\x0b\xf5\ \\x6b\x54\xbf\xab\x2b\x0b\x14\x26\xab\x4c\xc9\xd7\x44\x9c\xcd\x82\xf7\xfb\xf2\x65\xab\x85\xc5\xf3\x1b\x55\xdb\x94\xaa\xd4\xe3\x24\ \\xcf\xa4\xbd\x3f\x2d\xea\xa3\xe2\x9e\x20\x4d\x02\xc8\xbd\x25\xac\xea\xdf\x55\xb3\xd5\xbd\x9e\x98\xe3\x12\x31\xb2\x2a\xd5\xad\x6c\ \\x95\x43\x29\xde\xad\xbe\x45\x28\xd8\x71\x0f\x69\xaa\x51\xc9\x0f\xaa\x78\x6b\xf6\x22\x51\x3f\x1e\xaa\x51\xa7\x9b\x2a\xd3\x44\xcc\ \\x7b\x5a\x41\xf0\xd3\x7c\xfb\xad\x1b\x06\x95\x05\x41\xec\xe4\x91\xb4\xc3\x32\xe6\x03\x22\x68\xd4\xc9\x60\x0a\xcc\xce\x38\x7e\x6d\ \\xbf\x6b\xb1\x6c\x6a\x70\xfb\x78\x0d\x03\xd9\xc9\xd4\xdf\x39\xde\xe0\x10\x63\xda\x47\x36\xf4\x64\x5a\xd3\x28\xd8\xb3\x47\xcc\x96\ \\x75\xbb\x0f\xc3\x98\x51\x1b\xfb\x4f\xfb\xcc\x35\xb5\x8b\xcf\x6a\xe1\x1f\x0a\xbc\xbf\xc5\xfe\x4a\xa7\x0a\xec\x10\xac\x39\x57\x0a\ \\x3f\x04\x44\x2f\x61\x88\xb1\x53\xe0\x39\x7a\x2e\x57\x27\xcb\x79\x9c\xeb\x41\x8f\x1c\xac\xd6\x8d\x2a\xd3\x7c\x96\x01\x75\xcb\x9d\ \\xc6\x9d\xff\x09\xc7\x5b\x65\xf0\xd9\xdb\x40\xd8\xec\x0e\x77\x79\x47\x44\xea\xd4\xb1\x1c\x32\x74\xdd\x24\xcb\x9e\x7e\x1c\x54\xbd\ \\xf0\x11\x44\xf9\xd2\x24\x0e\xb1\x96\x75\xb3\xfd\xa3\xac\x37\x55\xd4\x7c\x27\xaf\x51\xc8\x5f\x4d\x56\x90\x75\x96\xa5\xbb\x15\xe6\ \\x58\x03\x04\xf0\xca\x04\x2c\xf1\x01\x1a\x37\xea\x8d\xbf\xaa\xdb\x35\xba\x3e\x4a\x35\x26\xff\xa0\xc3\x7b\x4d\x09\xbc\x30\x6e\xd9\ \\x98\xa5\x26\x66\x56\x48\xf7\x25\xff\x5e\x56\x9d\x0c\xed\x63\xd0\x7c\x63\xb2\xcf\x70\x0b\x45\xe1\xd5\xea\x50\xf1\x85\xa9\x28\x72\ \\xaf\x1f\xbd\xa7\xd4\x23\x48\x70\xa7\x87\x0b\xf3\x2d\x3b\x4d\x79\x42\xe0\x41\x98\x0c\xd0\xed\xe7\x26\x47\x0d\xb8\xf8\x81\x81\x4c\ \\x47\x4d\x6a\xd7\x7c\x0c\x5e\x5c\xd1\x23\x19\x59\x38\x1b\x72\x98\xf5\xd2\xf4\xdb\xab\x83\x86\x53\x6e\x2f\x1e\x23\x83\x71\x9c\x9e\ \\xbd\x91\xe0\x46\x9a\x56\x45\x6e\xdc\x39\x20\x0c\x20\xc8\xc5\x71\x96\x2b\xda\x1c\xe1\xe6\x96\xff\xb1\x41\xab\x08\x7c\xca\x89\xb9\ \\x1a\x69\xe7\x83\x02\xcc\x48\x43\xa2\xf7\xc5\x79\x42\x9e\xf4\x7d\x42\x7b\x16\x9c\x5a\xc9\xf0\x49\xdd\x8f\x0f\x00\x5c\x81\x65\xbf"# sbox_s2 :: Word8 -> Word32 sbox_s2 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\x1f\x20\x10\x94\xef\x0b\xa7\x5b\x69\xe3\xcf\x7e\x39\x3f\x43\x80\xfe\x61\xcf\x7a\xee\xc5\x20\x7a\x55\x88\x9c\x94\x72\xfc\x06\x51\ \\xad\xa7\xef\x79\x4e\x1d\x72\x35\xd5\x5a\x63\xce\xde\x04\x36\xba\x99\xc4\x30\xef\x5f\x0c\x07\x94\x18\xdc\xdb\x7d\xa1\xd6\xef\xf3\ \\xa0\xb5\x2f\x7b\x59\xe8\x36\x05\xee\x15\xb0\x94\xe9\xff\xd9\x09\xdc\x44\x00\x86\xef\x94\x44\x59\xba\x83\xcc\xb3\xe0\xc3\xcd\xfb\ \\xd1\xda\x41\x81\x3b\x09\x2a\xb1\xf9\x97\xf1\xc1\xa5\xe6\xcf\x7b\x01\x42\x0d\xdb\xe4\xe7\xef\x5b\x25\xa1\xff\x41\xe1\x80\xf8\x06\ \\x1f\xc4\x10\x80\x17\x9b\xee\x7a\xd3\x7a\xc6\xa9\xfe\x58\x30\xa4\x98\xde\x8b\x7f\x77\xe8\x3f\x4e\x79\x92\x92\x69\x24\xfa\x9f\x7b\ \\xe1\x13\xc8\x5b\xac\xc4\x00\x83\xd7\x50\x35\x25\xf7\xea\x61\x5f\x62\x14\x31\x54\x0d\x55\x4b\x63\x5d\x68\x11\x21\xc8\x66\xc3\x59\ \\x3d\x63\xcf\x73\xce\xe2\x34\xc0\xd4\xd8\x7e\x87\x5c\x67\x2b\x21\x07\x1f\x61\x81\x39\xf7\x62\x7f\x36\x1e\x30\x84\xe4\xeb\x57\x3b\ \\x60\x2f\x64\xa4\xd6\x3a\xcd\x9c\x1b\xbc\x46\x35\x9e\x81\x03\x2d\x27\x01\xf5\x0c\x99\x84\x7a\xb4\xa0\xe3\xdf\x79\xba\x6c\xf3\x8c\ \\x10\x84\x30\x94\x25\x37\xa9\x5e\xf4\x6f\x6f\xfe\xa1\xff\x3b\x1f\x20\x8c\xfb\x6a\x8f\x45\x8c\x74\xd9\xe0\xa2\x27\x4e\xc7\x3a\x34\ \\xfc\x88\x4f\x69\x3e\x4d\xe8\xdf\xef\x0e\x00\x88\x35\x59\x64\x8d\x8a\x45\x38\x8c\x1d\x80\x43\x66\x72\x1d\x9b\xfd\xa5\x86\x84\xbb\ \\xe8\x25\x63\x33\x84\x4e\x82\x12\x12\x8d\x80\x98\xfe\xd3\x3f\xb4\xce\x28\x0a\xe1\x27\xe1\x9b\xa5\xd5\xa6\xc2\x52\xe4\x97\x54\xbd\ \\xc5\xd6\x55\xdd\xeb\x66\x70\x64\x77\x84\x0b\x4d\xa1\xb6\xa8\x01\x84\xdb\x26\xa9\xe0\xb5\x67\x14\x21\xf0\x43\xb7\xe5\xd0\x58\x60\ \\x54\xf0\x30\x84\x06\x6f\xf4\x72\xa3\x1a\xa1\x53\xda\xdc\x47\x55\xb5\x62\x5d\xbf\x68\x56\x1b\xe6\x83\xca\x6b\x94\x2d\x6e\xd2\x3b\ \\xec\xcf\x01\xdb\xa6\xd3\xd0\xba\xb6\x80\x3d\x5c\xaf\x77\xa7\x09\x33\xb4\xa3\x4c\x39\x7b\xc8\xd6\x5e\xe2\x2b\x95\x5f\x0e\x53\x04\ \\x81\xed\x6f\x61\x20\xe7\x43\x64\xb4\x5e\x13\x78\xde\x18\x63\x9b\x88\x1c\xa1\x22\xb9\x67\x26\xd1\x80\x49\xa7\xe8\x22\xb7\xda\x7b\ \\x5e\x55\x2d\x25\x52\x72\xd2\x37\x79\xd2\x95\x1c\xc6\x0d\x89\x4c\x48\x8c\xb4\x02\x1b\xa4\xfe\x5b\xa4\xb0\x9f\x6b\x1c\xa8\x15\xcf\ \\xa2\x0c\x30\x05\x88\x71\xdf\x63\xb9\xde\x2f\xcb\x0c\xc6\xc9\xe9\x0b\xee\xff\x53\xe3\x21\x45\x17\xb4\x54\x28\x35\x9f\x63\x29\x3c\ \\xee\x41\xe7\x29\x6e\x1d\x2d\x7c\x50\x04\x52\x86\x1e\x66\x85\xf3\xf3\x34\x01\xc6\x30\xa2\x2c\x95\x31\xa7\x08\x50\x60\x93\x0f\x13\ \\x73\xf9\x84\x17\xa1\x26\x98\x59\xec\x64\x5c\x44\x52\xc8\x77\xa9\xcd\xff\x33\xa6\xa0\x2b\x17\x41\x7c\xba\xd9\xa2\x21\x80\x03\x6f\ \\x50\xd9\x9c\x08\xcb\x3f\x48\x61\xc2\x6b\xd7\x65\x64\xa3\xf6\xab\x80\x34\x26\x76\x25\xa7\x5e\x7b\xe4\xe6\xd1\xfc\x20\xc7\x10\xe6\ \\xcd\xf0\xb6\x80\x17\x84\x4d\x3b\x31\xee\xf8\x4d\x7e\x08\x24\xe4\x2c\xcb\x49\xeb\x84\x6a\x3b\xae\x8f\xf7\x78\x88\xee\x5d\x60\xf6\ \\x7a\xf7\x56\x73\x2f\xdd\x5c\xdb\xa1\x16\x31\xc1\x30\xf6\x6f\x43\xb3\xfa\xec\x54\x15\x7f\xd7\xfa\xef\x85\x79\xcc\xd1\x52\xde\x58\ \\xdb\x2f\xfd\x5e\x8f\x32\xce\x19\x30\x6a\xf9\x7a\x02\xf0\x3e\xf8\x99\x31\x9a\xd5\xc2\x42\xfa\x0f\xa7\xe3\xeb\xb0\xc6\x8e\x49\x06\ \\xb8\xda\x23\x0c\x80\x82\x30\x28\xdc\xde\xf3\xc8\xd3\x5f\xb1\x71\x08\x8a\x1b\xc8\xbe\xc0\xc5\x60\x61\xa3\xc9\xe8\xbc\xa8\xf5\x4d\ \\xc7\x2f\xef\xfa\x22\x82\x2e\x99\x82\xc5\x70\xb4\xd8\xd9\x4e\x89\x8b\x1c\x34\xbc\x30\x1e\x16\xe6\x27\x3b\xe9\x79\xb0\xff\xea\xa6\ \\x61\xd9\xb8\xc6\x00\xb2\x48\x69\xb7\xff\xce\x3f\x08\xdc\x28\x3b\x43\xda\xf6\x5a\xf7\xe1\x97\x98\x76\x19\xb7\x2f\x8f\x1c\x9b\xa4\ \\xdc\x86\x37\xa0\x16\xa7\xd3\xb1\x9f\xc3\x93\xb7\xa7\x13\x6e\xeb\xc6\xbc\xc6\x3e\x1a\x51\x37\x42\xef\x68\x28\xbc\x52\x03\x65\xd6\ \\x2d\x6a\x77\xab\x35\x27\xed\x4b\x82\x1f\xd2\x16\x09\x5c\x6e\x2e\xdb\x92\xf2\xfb\x5e\xea\x29\xcb\x14\x58\x92\xf5\x91\x58\x4f\x7f\ \\x54\x83\x69\x7b\x26\x67\xa8\xcc\x85\x19\x60\x48\x8c\x4b\xac\xea\x83\x38\x60\xd4\x0d\x23\xe0\xf9\x6c\x38\x7e\x8a\x0a\xe6\xd2\x49\ \\xb2\x84\x60\x0c\xd8\x35\x73\x1d\xdc\xb1\xc6\x47\xac\x4c\x56\xea\x3e\xbd\x81\xb3\x23\x0e\xab\xb0\x64\x38\xbc\x87\xf0\xb5\xb1\xfa\ \\x8f\x5e\xa2\xb3\xfc\x18\x46\x42\x0a\x03\x6b\x7a\x4f\xb0\x89\xbd\x64\x9d\xa5\x89\xa3\x45\x41\x5e\x5c\x03\x83\x23\x3e\x5d\x3b\xb9\ \\x43\xd7\x95\x72\x7e\x6d\xd0\x7c\x06\xdf\xdf\x1e\x6c\x6c\xc4\xef\x71\x60\xa5\x39\x73\xbf\xbe\x70\x83\x87\x76\x05\x45\x23\xec\xf1"# sbox_s3 :: Word8 -> Word32 sbox_s3 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\x8d\xef\xc2\x40\x25\xfa\x5d\x9f\xeb\x90\x3d\xbf\xe8\x10\xc9\x07\x47\x60\x7f\xff\x36\x9f\xe4\x4b\x8c\x1f\xc6\x44\xae\xce\xca\x90\ \\xbe\xb1\xf9\xbf\xee\xfb\xca\xea\xe8\xcf\x19\x50\x51\xdf\x07\xae\x92\x0e\x88\x06\xf0\xad\x05\x48\xe1\x3c\x8d\x83\x92\x70\x10\xd5\ \\x11\x10\x7d\x9f\x07\x64\x7d\xb9\xb2\xe3\xe4\xd4\x3d\x4f\x28\x5e\xb9\xaf\xa8\x20\xfa\xde\x82\xe0\xa0\x67\x26\x8b\x82\x72\x79\x2e\ \\x55\x3f\xb2\xc0\x48\x9a\xe2\x2b\xd4\xef\x97\x94\x12\x5e\x3f\xbc\x21\xff\xfc\xee\x82\x5b\x1b\xfd\x92\x55\xc5\xed\x12\x57\xa2\x40\ \\x4e\x1a\x83\x02\xba\xe0\x7f\xff\x52\x82\x46\xe7\x8e\x57\x14\x0e\x33\x73\xf7\xbf\x8c\x9f\x81\x88\xa6\xfc\x4e\xe8\xc9\x82\xb5\xa5\ \\xa8\xc0\x1d\xb7\x57\x9f\xc2\x64\x67\x09\x4f\x31\xf2\xbd\x3f\x5f\x40\xff\xf7\xc1\x1f\xb7\x8d\xfc\x8e\x6b\xd2\xc1\x43\x7b\xe5\x9b\ \\x99\xb0\x3d\xbf\xb5\xdb\xc6\x4b\x63\x8d\xc0\xe6\x55\x81\x9d\x99\xa1\x97\xc8\x1c\x4a\x01\x2d\x6e\xc5\x88\x4a\x28\xcc\xc3\x6f\x71\ \\xb8\x43\xc2\x13\x6c\x07\x43\xf1\x83\x09\x89\x3c\x0f\xed\xdd\x5f\x2f\x7f\xe8\x50\xd7\xc0\x7f\x7e\x02\x50\x7f\xbf\x5a\xfb\x9a\x04\ \\xa7\x47\xd2\xd0\x16\x51\x19\x2e\xaf\x70\xbf\x3e\x58\xc3\x13\x80\x5f\x98\x30\x2e\x72\x7c\xc3\xc4\x0a\x0f\xb4\x02\x0f\x7f\xef\x82\ \\x8c\x96\xfd\xad\x5d\x2c\x2a\xae\x8e\xe9\x9a\x49\x50\xda\x88\xb8\x84\x27\xf4\xa0\x1e\xac\x57\x90\x79\x6f\xb4\x49\x82\x52\xdc\x15\ \\xef\xbd\x7d\x9b\xa6\x72\x59\x7d\xad\xa8\x40\xd8\x45\xf5\x45\x04\xfa\x5d\x74\x03\xe8\x3e\xc3\x05\x4f\x91\x75\x1a\x92\x56\x69\xc2\ \\x23\xef\xe9\x41\xa9\x03\xf1\x2e\x60\x27\x0d\xf2\x02\x76\xe4\xb6\x94\xfd\x65\x74\x92\x79\x85\xb2\x82\x76\xdb\xcb\x02\x77\x81\x76\ \\xf8\xaf\x91\x8d\x4e\x48\xf7\x9e\x8f\x61\x6d\xdf\xe2\x9d\x84\x0e\x84\x2f\x7d\x83\x34\x0c\xe5\xc8\x96\xbb\xb6\x82\x93\xb4\xb1\x48\ \\xef\x30\x3c\xab\x98\x4f\xaf\x28\x77\x9f\xaf\x9b\x92\xdc\x56\x0d\x22\x4d\x1e\x20\x84\x37\xaa\x88\x7d\x29\xdc\x96\x27\x56\xd3\xdc\ \\x8b\x90\x7c\xee\xb5\x1f\xd2\x40\xe7\xc0\x7c\xe3\xe5\x66\xb4\xa1\xc3\xe9\x61\x5e\x3c\xf8\x20\x9d\x60\x94\xd1\xe3\xcd\x9c\xa3\x41\ \\x5c\x76\x46\x0e\x00\xea\x98\x3b\xd4\xd6\x78\x81\xfd\x47\x57\x2c\xf7\x6c\xed\xd9\xbd\xa8\x22\x9c\x12\x7d\xad\xaa\x43\x8a\x07\x4e\ \\x1f\x97\xc0\x90\x08\x1b\xdb\x8a\x93\xa0\x7e\xbe\xb9\x38\xca\x15\x97\xb0\x3c\xff\x3d\xc2\xc0\xf8\x8d\x1a\xb2\xec\x64\x38\x0e\x51\ \\x68\xcc\x7b\xfb\xd9\x0f\x27\x88\x12\x49\x01\x81\x5d\xe5\xff\xd4\xdd\x7e\xf8\x6a\x76\xa2\xe2\x14\xb9\xa4\x03\x68\x92\x5d\x95\x8f\ \\x4b\x39\xff\xfa\xba\x39\xae\xe9\xa4\xff\xd3\x0b\xfa\xf7\x93\x3b\x6d\x49\x86\x23\x19\x3c\xbc\xfa\x27\x62\x75\x45\x82\x5c\xf4\x7a\ \\x61\xbd\x8b\xa0\xd1\x1e\x42\xd1\xce\xad\x04\xf4\x12\x7e\xa3\x92\x10\x42\x8d\xb7\x82\x72\xa9\x72\x92\x70\xc4\xa8\x12\x7d\xe5\x0b\ \\x28\x5b\xa1\xc8\x3c\x62\xf4\x4f\x35\xc0\xea\xa5\xe8\x05\xd2\x31\x42\x89\x29\xfb\xb4\xfc\xdf\x82\x4f\xb6\x6a\x53\x0e\x7d\xc1\x5b\ \\x1f\x08\x1f\xab\x10\x86\x18\xae\xfc\xfd\x08\x6d\xf9\xff\x28\x89\x69\x4b\xcc\x11\x23\x6a\x5c\xae\x12\xde\xca\x4d\x2c\x3f\x8c\xc5\ \\xd2\xd0\x2d\xfe\xf8\xef\x58\x96\xe4\xcf\x52\xda\x95\x15\x5b\x67\x49\x4a\x48\x8c\xb9\xb6\xa8\x0c\x5c\x8f\x82\xbc\x89\xd3\x6b\x45\ \\x3a\x60\x94\x37\xec\x00\xc9\xa9\x44\x71\x52\x53\x0a\x87\x4b\x49\xd7\x73\xbc\x40\x7c\x34\x67\x1c\x02\x71\x7e\xf6\x4f\xeb\x55\x36\ \\xa2\xd0\x2f\xff\xd2\xbf\x60\xc4\xd4\x3f\x03\xc0\x50\xb4\xef\x6d\x07\x47\x8c\xd1\x00\x6e\x18\x88\xa2\xe5\x3f\x55\xb9\xe6\xd4\xbc\ \\xa2\x04\x80\x16\x97\x57\x38\x33\xd7\x20\x7d\x67\xde\x0f\x8f\x3d\x72\xf8\x7b\x33\xab\xcc\x4f\x33\x76\x88\xc5\x5d\x7b\x00\xa6\xb0\ \\x94\x7b\x00\x01\x57\x00\x75\xd2\xf9\xbb\x88\xf8\x89\x42\x01\x9e\x42\x64\xa5\xff\x85\x63\x02\xe0\x72\xdb\xd9\x2b\xee\x97\x1b\x69\ \\x6e\xa2\x2f\xde\x5f\x08\xae\x2b\xaf\x7a\x61\x6d\xe5\xc9\x87\x67\xcf\x1f\xeb\xd2\x61\xef\xc8\xc2\xf1\xac\x25\x71\xcc\x82\x39\xc2\ \\x67\x21\x4c\xb8\xb1\xe5\x83\xd1\xb7\xdc\x3e\x62\x7f\x10\xbd\xce\xf9\x0a\x5c\x38\x0f\xf0\x44\x3d\x60\x6e\x6d\xc6\x60\x54\x3a\x49\ \\x57\x27\xc1\x48\x2b\xe9\x8a\x1d\x8a\xb4\x17\x38\x20\xe1\xbe\x24\xaf\x96\xda\x0f\x68\x45\x84\x25\x99\x83\x3b\xe5\x60\x0d\x45\x7d\ \\x28\x2f\x93\x50\x83\x34\xb3\x62\xd9\x1d\x11\x20\x2b\x6d\x8d\xa0\x64\x2b\x1e\x31\x9c\x30\x5a\x00\x52\xbc\xe6\x88\x1b\x03\x58\x8a\ \\xf7\xba\xef\xd5\x41\x42\xed\x9c\xa4\x31\x5c\x11\x83\x32\x3e\xc5\xdf\xef\x46\x36\xa1\x33\xc5\x01\xe9\xd3\x53\x1c\xee\x35\x37\x83"# sbox_s4 :: Word8 -> Word32 sbox_s4 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\x9d\xb3\x04\x20\x1f\xb6\xe9\xde\xa7\xbe\x7b\xef\xd2\x73\xa2\x98\x4a\x4f\x7b\xdb\x64\xad\x8c\x57\x85\x51\x04\x43\xfa\x02\x0e\xd1\ \\x7e\x28\x7a\xff\xe6\x0f\xb6\x63\x09\x5f\x35\xa1\x79\xeb\xf1\x20\xfd\x05\x9d\x43\x64\x97\xb7\xb1\xf3\x64\x1f\x63\x24\x1e\x4a\xdf\ \\x28\x14\x7f\x5f\x4f\xa2\xb8\xcd\xc9\x43\x00\x40\x0c\xc3\x22\x20\xfd\xd3\x0b\x30\xc0\xa5\x37\x4f\x1d\x2d\x00\xd9\x24\x14\x7b\x15\ \\xee\x4d\x11\x1a\x0f\xca\x51\x67\x71\xff\x90\x4c\x2d\x19\x5f\xfe\x1a\x05\x64\x5f\x0c\x13\xfe\xfe\x08\x1b\x08\xca\x05\x17\x01\x21\ \\x80\x53\x01\x00\xe8\x3e\x5e\xfe\xac\x9a\xf4\xf8\x7f\xe7\x27\x01\xd2\xb8\xee\x5f\x06\xdf\x42\x61\xbb\x9e\x9b\x8a\x72\x93\xea\x25\ \\xce\x84\xff\xdf\xf5\x71\x88\x01\x3d\xd6\x4b\x04\xa2\x6f\x26\x3b\x7e\xd4\x84\x00\x54\x7e\xeb\xe6\x44\x6d\x4c\xa0\x6c\xf3\xd6\xf5\ \\x26\x49\xab\xdf\xae\xa0\xc7\xf5\x36\x33\x8c\xc1\x50\x3f\x7e\x93\xd3\x77\x20\x61\x11\xb6\x38\xe1\x72\x50\x0e\x03\xf8\x0e\xb2\xbb\ \\xab\xe0\x50\x2e\xec\x8d\x77\xde\x57\x97\x1e\x81\xe1\x4f\x67\x46\xc9\x33\x54\x00\x69\x20\x31\x8f\x08\x1d\xbb\x99\xff\xc3\x04\xa5\ \\x4d\x35\x18\x05\x7f\x3d\x5c\xe3\xa6\xc8\x66\xc6\x5d\x5b\xcc\xa9\xda\xec\x6f\xea\x9f\x92\x6f\x91\x9f\x46\x22\x2f\x39\x91\x46\x7d\ \\xa5\xbf\x6d\x8e\x11\x43\xc4\x4f\x43\x95\x83\x02\xd0\x21\x4e\xeb\x02\x20\x83\xb8\x3f\xb6\x18\x0c\x18\xf8\x93\x1e\x28\x16\x58\xe6\ \\x26\x48\x6e\x3e\x8b\xd7\x8a\x70\x74\x77\xe4\xc1\xb5\x06\xe0\x7c\xf3\x2d\x0a\x25\x79\x09\x8b\x02\xe4\xea\xbb\x81\x28\x12\x3b\x23\ \\x69\xde\xad\x38\x15\x74\xca\x16\xdf\x87\x1b\x62\x21\x1c\x40\xb7\xa5\x1a\x9e\xf9\x00\x14\x37\x7b\x04\x1e\x8a\xc8\x09\x11\x40\x03\ \\xbd\x59\xe4\xd2\xe3\xd1\x56\xd5\x4f\xe8\x76\xd5\x2f\x91\xa3\x40\x55\x7b\xe8\xde\x00\xea\xe4\xa7\x0c\xe5\xc2\xec\x4d\xb4\xbb\xa6\ \\xe7\x56\xbd\xff\xdd\x33\x69\xac\xec\x17\xb0\x35\x06\x57\x23\x27\x99\xaf\xc8\xb0\x56\xc8\xc3\x91\x6b\x65\x81\x1c\x5e\x14\x61\x19\ \\x6e\x85\xcb\x75\xbe\x07\xc0\x02\xc2\x32\x55\x77\x89\x3f\xf4\xec\x5b\xbf\xc9\x2d\xd0\xec\x3b\x25\xb7\x80\x1a\xb7\x8d\x6d\x3b\x24\ \\x20\xc7\x63\xef\xc3\x66\xa5\xfc\x9c\x38\x28\x80\x0a\xce\x32\x05\xaa\xc9\x54\x8a\xec\xa1\xd7\xc7\x04\x1a\xfa\x32\x1d\x16\x62\x5a\ \\x67\x01\x90\x2c\x9b\x75\x7a\x54\x31\xd4\x77\xf7\x91\x26\xb0\x31\x36\xcc\x6f\xdb\xc7\x0b\x8b\x46\xd9\xe6\x6a\x48\x56\xe5\x5a\x79\ \\x02\x6a\x4c\xeb\x52\x43\x7e\xff\x2f\x8f\x76\xb4\x0d\xf9\x80\xa5\x86\x74\xcd\xe3\xed\xda\x04\xeb\x17\xa9\xbe\x04\x2c\x18\xf4\xdf\ \\xb7\x74\x7f\x9d\xab\x2a\xf7\xb4\xef\xc3\x4d\x20\x2e\x09\x6b\x7c\x17\x41\xa2\x54\xe5\xb6\xa0\x35\x21\x3d\x42\xf6\x2c\x1c\x7c\x26\ \\x61\xc2\xf5\x0f\x65\x52\xda\xf9\xd2\xc2\x31\xf8\x25\x13\x0f\x69\xd8\x16\x7f\xa2\x04\x18\xf2\xc8\x00\x1a\x96\xa6\x0d\x15\x26\xab\ \\x63\x31\x5c\x21\x5e\x0a\x72\xec\x49\xba\xfe\xfd\x18\x79\x08\xd9\x8d\x0d\xbd\x86\x31\x11\x70\xa7\x3e\x9b\x64\x0c\xcc\x3e\x10\xd7\ \\xd5\xca\xd3\xb6\x0c\xae\xc3\x88\xf7\x30\x01\xe1\x6c\x72\x8a\xff\x71\xea\xe2\xa1\x1f\x9a\xf3\x6e\xcf\xcb\xd1\x2f\xc1\xde\x84\x17\ \\xac\x07\xbe\x6b\xcb\x44\xa1\xd8\x8b\x9b\x0f\x56\x01\x39\x88\xc3\xb1\xc5\x2f\xca\xb4\xbe\x31\xcd\xd8\x78\x28\x06\x12\xa3\xa4\xe2\ \\x6f\x7d\xe5\x32\x58\xfd\x7e\xb6\xd0\x1e\xe9\x00\x24\xad\xff\xc2\xf4\x99\x0f\xc5\x97\x11\xaa\xc5\x00\x1d\x7b\x95\x82\xe5\xe7\xd2\ \\x10\x98\x73\xf6\x00\x61\x30\x96\xc3\x2d\x95\x21\xad\xa1\x21\xff\x29\x90\x84\x15\x7f\xbb\x97\x7f\xaf\x9e\xb3\xdb\x29\xc9\xed\x2a\ \\x5c\xe2\xa4\x65\xa7\x30\xf3\x2c\xd0\xaa\x3f\xe8\x8a\x5c\xc0\x91\xd4\x9e\x2c\xe7\x0c\xe4\x54\xa9\xd6\x0a\xcd\x86\x01\x5f\x19\x19\ \\x77\x07\x91\x03\xde\xa0\x3a\xf6\x78\xa8\x56\x5e\xde\xe3\x56\xdf\x21\xf0\x5c\xbe\x8b\x75\xe3\x87\xb3\xc5\x06\x51\xb8\xa5\xc3\xef\ \\xd8\xee\xb6\xd2\xe5\x23\xbe\x77\xc2\x15\x45\x29\x2f\x69\xef\xdf\xaf\xe6\x7a\xfb\xf4\x70\xc4\xb2\xf3\xe0\xeb\x5b\xd6\xcc\x98\x76\ \\x39\xe4\x46\x0c\x1f\xda\x85\x38\x19\x87\x83\x2f\xca\x00\x73\x67\xa9\x91\x44\xf8\x29\x6b\x29\x9e\x49\x2f\xc2\x95\x92\x66\xbe\xab\ \\xb5\x67\x6e\x69\x9b\xd3\xdd\xda\xdf\x7e\x05\x2f\xdb\x25\x70\x1c\x1b\x5e\x51\xee\xf6\x53\x24\xe6\x6a\xfc\xe3\x6c\x03\x16\xcc\x04\ \\x86\x44\x21\x3e\xb7\xdc\x59\xd0\x79\x65\x29\x1f\xcc\xd6\xfd\x43\x41\x82\x39\x79\x93\x2b\xcd\xf6\xb6\x57\xc3\x4d\x4e\xdf\xd2\x82\ \\x7a\xe5\x29\x0c\x3c\xb9\x53\x6b\x85\x1e\x20\xfe\x98\x33\x55\x7e\x13\xec\xf0\xb0\xd3\xff\xb3\x72\x3f\x85\xc5\xc1\x0a\xef\x7e\xd2"# sbox_s5 :: Word8 -> Word32 sbox_s5 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\x7e\xc9\x0c\x04\x2c\x6e\x74\xb9\x9b\x0e\x66\xdf\xa6\x33\x79\x11\xb8\x6a\x7f\xff\x1d\xd3\x58\xf5\x44\xdd\x9d\x44\x17\x31\x16\x7f\ \\x08\xfb\xf1\xfa\xe7\xf5\x11\xcc\xd2\x05\x1b\x00\x73\x5a\xba\x00\x2a\xb7\x22\xd8\x38\x63\x81\xcb\xac\xf6\x24\x3a\x69\xbe\xfd\x7a\ \\xe6\xa2\xe7\x7f\xf0\xc7\x20\xcd\xc4\x49\x48\x16\xcc\xf5\xc1\x80\x38\x85\x16\x40\x15\xb0\xa8\x48\xe6\x8b\x18\xcb\x4c\xaa\xde\xff\ \\x5f\x48\x0a\x01\x04\x12\xb2\xaa\x25\x98\x14\xfc\x41\xd0\xef\xe2\x4e\x40\xb4\x8d\x24\x8e\xb6\xfb\x8d\xba\x1c\xfe\x41\xa9\x9b\x02\ \\x1a\x55\x0a\x04\xba\x8f\x65\xcb\x72\x51\xf4\xe7\x95\xa5\x17\x25\xc1\x06\xec\xd7\x97\xa5\x98\x0a\xc5\x39\xb9\xaa\x4d\x79\xfe\x6a\ \\xf2\xf3\xf7\x63\x68\xaf\x80\x40\xed\x0c\x9e\x56\x11\xb4\x95\x8b\xe1\xeb\x5a\x88\x87\x09\xe6\xb0\xd7\xe0\x71\x56\x4e\x29\xfe\xa7\ \\x63\x66\xe5\x2d\x02\xd1\xc0\x00\xc4\xac\x8e\x05\x93\x77\xf5\x71\x0c\x05\x37\x2a\x57\x85\x35\xf2\x22\x61\xbe\x02\xd6\x42\xa0\xc9\ \\xdf\x13\xa2\x80\x74\xb5\x5b\xd2\x68\x21\x99\xc0\xd4\x21\xe5\xec\x53\xfb\x3c\xe8\xc8\xad\xed\xb3\x28\xa8\x7f\xc9\x3d\x95\x99\x81\ \\x5c\x1f\xf9\x00\xfe\x38\xd3\x99\x0c\x4e\xff\x0b\x06\x24\x07\xea\xaa\x2f\x4f\xb1\x4f\xb9\x69\x76\x90\xc7\x95\x05\xb0\xa8\xa7\x74\ \\xef\x55\xa1\xff\xe5\x9c\xa2\xc2\xa6\xb6\x2d\x27\xe6\x6a\x42\x63\xdf\x65\x00\x1f\x0e\xc5\x09\x66\xdf\xdd\x55\xbc\x29\xde\x06\x55\ \\x91\x1e\x73\x9a\x17\xaf\x89\x75\x32\xc7\x91\x1c\x89\xf8\x94\x68\x0d\x01\xe9\x80\x52\x47\x55\xf4\x03\xb6\x3c\xc9\x0c\xc8\x44\xb2\ \\xbc\xf3\xf0\xaa\x87\xac\x36\xe9\xe5\x3a\x74\x26\x01\xb3\xd8\x2b\x1a\x9e\x74\x49\x64\xee\x2d\x7e\xcd\xdb\xb1\xda\x01\xc9\x49\x10\ \\xb8\x68\xbf\x80\x0d\x26\xf3\xfd\x93\x42\xed\xe7\x04\xa5\xc2\x84\x63\x67\x37\xb6\x50\xf5\xb6\x16\xf2\x47\x66\xe3\x8e\xca\x36\xc1\ \\x13\x6e\x05\xdb\xfe\xf1\x83\x91\xfb\x88\x7a\x37\xd6\xe7\xf7\xd4\xc7\xfb\x7d\xc9\x30\x63\xfc\xdf\xb6\xf5\x89\xde\xec\x29\x41\xda\ \\x26\xe4\x66\x95\xb7\x56\x64\x19\xf6\x54\xef\xc5\xd0\x8d\x58\xb7\x48\x92\x54\x01\xc1\xba\xcb\x7f\xe5\xff\x55\x0f\xb6\x08\x30\x49\ \\x5b\xb5\xd0\xe8\x87\xd7\x2e\x5a\xab\x6a\x6e\xe1\x22\x3a\x66\xce\xc6\x2b\xf3\xcd\x9e\x08\x85\xf9\x68\xcb\x3e\x47\x08\x6c\x01\x0f\ \\xa2\x1d\xe8\x20\xd1\x8b\x69\xde\xf3\xf6\x57\x77\xfa\x02\xc3\xf6\x40\x7e\xda\xc3\xcb\xb3\xd5\x50\x17\x93\x08\x4d\xb0\xd7\x0e\xba\ \\x0a\xb3\x78\xd5\xd9\x51\xfb\x0c\xde\xd7\xda\x56\x41\x24\xbb\xe4\x94\xca\x0b\x56\x0f\x57\x55\xd1\xe0\xe1\xe5\x6e\x61\x84\xb5\xbe\ \\x58\x0a\x24\x9f\x94\xf7\x4b\xc0\xe3\x27\x88\x8e\x9f\x7b\x55\x61\xc3\xdc\x02\x80\x05\x68\x77\x15\x64\x6c\x6b\xd7\x44\x90\x4d\xb3\ \\x66\xb4\xf0\xa3\xc0\xf1\x64\x8a\x69\x7e\xd5\xaf\x49\xe9\x2f\xf6\x30\x9e\x37\x4f\x2c\xb6\x35\x6a\x85\x80\x85\x73\x49\x91\xf8\x40\ \\x76\xf0\xae\x02\x08\x3b\xe8\x4d\x28\x42\x1c\x9a\x44\x48\x94\x06\x73\x6e\x4c\xb8\xc1\x09\x29\x10\x8b\xc9\x5f\xc6\x7d\x86\x9c\xf4\ \\x13\x4f\x61\x6f\x2e\x77\x11\x8d\xb3\x1b\x2b\xe1\xaa\x90\xb4\x72\x3c\xa5\xd7\x17\x7d\x16\x1b\xba\x9c\xad\x90\x10\xaf\x46\x2b\xa2\ \\x9f\xe4\x59\xd2\x45\xd3\x45\x59\xd9\xf2\xda\x13\xdb\xc6\x54\x87\xf3\xe4\xf9\x4e\x17\x6d\x48\x6f\x09\x7c\x13\xea\x63\x1d\xa5\xc7\ \\x44\x5f\x73\x82\x17\x56\x83\xf4\xcd\xc6\x6a\x97\x70\xbe\x02\x88\xb3\xcd\xcf\x72\x6e\x5d\xd2\xf3\x20\x93\x60\x79\x45\x9b\x80\xa5\ \\xbe\x60\xe2\xdb\xa9\xc2\x31\x01\xeb\xa5\x31\x5c\x22\x4e\x42\xf2\x1c\x5c\x15\x72\xf6\x72\x1b\x2c\x1a\xd2\xff\xf3\x8c\x25\x40\x4e\ \\x32\x4e\xd7\x2f\x40\x67\xb7\xfd\x05\x23\x13\x8e\x5c\xa3\xbc\x78\xdc\x0f\xd6\x6e\x75\x92\x22\x83\x78\x4d\x6b\x17\x58\xeb\xb1\x6e\ \\x44\x09\x4f\x85\x3f\x48\x1d\x87\xfc\xfe\xae\x7b\x77\xb5\xff\x76\x8c\x23\x02\xbf\xaa\xf4\x75\x56\x5f\x46\xb0\x2a\x2b\x09\x28\x01\ \\x3d\x38\xf5\xf7\x0c\xa8\x1f\x36\x52\xaf\x4a\x8a\x66\xd5\xe7\xc0\xdf\x3b\x08\x74\x95\x05\x51\x10\x1b\x5a\xd7\xa8\xf6\x1e\xd5\xad\ \\x6c\xf6\xe4\x79\x20\x75\x81\x84\xd0\xce\xfa\x65\x88\xf7\xbe\x58\x4a\x04\x68\x26\x0f\xf6\xf8\xf3\xa0\x9c\x7f\x70\x53\x46\xab\xa0\ \\x5c\xe9\x6c\x28\xe1\x76\xed\xa3\x6b\xac\x30\x7f\x37\x68\x29\xd2\x85\x36\x0f\xa9\x17\xe3\xfe\x2a\x24\xb7\x97\x67\xf5\xa9\x6b\x20\ \\xd6\xcd\x25\x95\x68\xff\x1e\xbf\x75\x55\x44\x2c\xf1\x9f\x06\xbe\xf9\xe0\x65\x9a\xee\xb9\x49\x1d\x34\x01\x07\x18\xbb\x30\xca\xb8\ \\xe8\x22\xfe\x15\x88\x57\x09\x83\x75\x0e\x62\x49\xda\x62\x7e\x55\x5e\x76\xff\xa8\xb1\x53\x45\x46\x6d\x47\xde\x08\xef\xe9\xe7\xd4"# sbox_s6 :: Word8 -> Word32 sbox_s6 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\xf6\xfa\x8f\x9d\x2c\xac\x6c\xe1\x4c\xa3\x48\x67\xe2\x33\x7f\x7c\x95\xdb\x08\xe7\x01\x68\x43\xb4\xec\xed\x5c\xbc\x32\x55\x53\xac\ \\xbf\x9f\x09\x60\xdf\xa1\xe2\xed\x83\xf0\x57\x9d\x63\xed\x86\xb9\x1a\xb6\xa6\xb8\xde\x5e\xbe\x39\xf3\x8f\xf7\x32\x89\x89\xb1\x38\ \\x33\xf1\x49\x61\xc0\x19\x37\xbd\xf5\x06\xc6\xda\xe4\x62\x5e\x7e\xa3\x08\xea\x99\x4e\x23\xe3\x3c\x79\xcb\xd7\xcc\x48\xa1\x43\x67\ \\xa3\x14\x96\x19\xfe\xc9\x4b\xd5\xa1\x14\x17\x4a\xea\xa0\x18\x66\xa0\x84\xdb\x2d\x09\xa8\x48\x6f\xa8\x88\x61\x4a\x29\x00\xaf\x98\ \\x01\x66\x59\x91\xe1\x99\x28\x63\xc8\xf3\x0c\x60\x2e\x78\xef\x3c\xd0\xd5\x19\x32\xcf\x0f\xec\x14\xf7\xca\x07\xd2\xd0\xa8\x20\x72\ \\xfd\x41\x19\x7e\x93\x05\xa6\xb0\xe8\x6b\xe3\xda\x74\xbe\xd3\xcd\x37\x2d\xa5\x3c\x4c\x7f\x44\x48\xda\xb5\xd4\x40\x6d\xba\x0e\xc3\ \\x08\x39\x19\xa7\x9f\xba\xee\xd9\x49\xdb\xcf\xb0\x4e\x67\x0c\x53\x5c\x3d\x9c\x01\x64\xbd\xb9\x41\x2c\x0e\x63\x6a\xba\x7d\xd9\xcd\ \\xea\x6f\x73\x88\xe7\x0b\xc7\x62\x35\xf2\x9a\xdb\x5c\x4c\xdd\x8d\xf0\xd4\x8d\x8c\xb8\x81\x53\xe2\x08\xa1\x98\x66\x1a\xe2\xea\xc8\ \\x28\x4c\xaf\x89\xaa\x92\x82\x23\x93\x34\xbe\x53\x3b\x3a\x21\xbf\x16\x43\x4b\xe3\x9a\xea\x39\x06\xef\xe8\xc3\x6e\xf8\x90\xcd\xd9\ \\x80\x22\x6d\xae\xc3\x40\xa4\xa3\xdf\x7e\x9c\x09\xa6\x94\xa8\x07\x5b\x7c\x5e\xcc\x22\x1d\xb3\xa6\x9a\x69\xa0\x2f\x68\x81\x8a\x54\ \\xce\xb2\x29\x6f\x53\xc0\x84\x3a\xfe\x89\x36\x55\x25\xbf\xe6\x8a\xb4\x62\x8a\xbc\xcf\x22\x2e\xbf\x25\xac\x6f\x48\xa9\xa9\x93\x87\ \\x53\xbd\xdb\x65\xe7\x6f\xfb\xe7\xe9\x67\xfd\x78\x0b\xa9\x35\x63\x8e\x34\x2b\xc1\xe8\xa1\x1b\xe9\x49\x80\x74\x0d\xc8\x08\x7d\xfc\ \\x8d\xe4\xbf\x99\xa1\x11\x01\xa0\x7f\xd3\x79\x75\xda\x5a\x26\xc0\xe8\x1f\x99\x4f\x95\x28\xcd\x89\xfd\x33\x9f\xed\xb8\x78\x34\xbf\ \\x5f\x04\x45\x6d\x22\x25\x86\x98\xc9\xc4\xc8\x3b\x2d\xc1\x56\xbe\x4f\x62\x8d\xaa\x57\xf5\x5e\xc5\xe2\x22\x0a\xbe\xd2\x91\x6e\xbf\ \\x4e\xc7\x5b\x95\x24\xf2\xc3\xc0\x42\xd1\x5d\x99\xcd\x0d\x7f\xa0\x7b\x6e\x27\xff\xa8\xdc\x8a\xf0\x73\x45\xc1\x06\xf4\x1e\x23\x2f\ \\x35\x16\x23\x86\xe6\xea\x89\x26\x33\x33\xb0\x94\x15\x7e\xc6\xf2\x37\x2b\x74\xaf\x69\x25\x73\xe4\xe9\xa9\xd8\x48\xf3\x16\x02\x89\ \\x3a\x62\xef\x1d\xa7\x87\xe2\x38\xf3\xa5\xf6\x76\x74\x36\x48\x53\x20\x95\x10\x63\x45\x76\x69\x8d\xb6\xfa\xd4\x07\x59\x2a\xf9\x50\ \\x36\xf7\x35\x23\x4c\xfb\x6e\x87\x7d\xa4\xce\xc0\x6c\x15\x2d\xaa\xcb\x03\x96\xa8\xc5\x0d\xfe\x5d\xfc\xd7\x07\xab\x09\x21\xc4\x2f\ \\x89\xdf\xf0\xbb\x5f\xe2\xbe\x78\x44\x8f\x4f\x33\x75\x46\x13\xc9\x2b\x05\xd0\x8d\x48\xb9\xd5\x85\xdc\x04\x94\x41\xc8\x09\x8f\x9b\ \\x7d\xed\xe7\x86\xc3\x9a\x33\x73\x42\x41\x00\x05\x6a\x09\x17\x51\x0e\xf3\xc8\xa6\x89\x00\x72\xd6\x28\x20\x76\x82\xa9\xa9\xf7\xbe\ \\xbf\x32\x67\x9d\xd4\x5b\x5b\x75\xb3\x53\xfd\x00\xcb\xb0\xe3\x58\x83\x0f\x22\x0a\x1f\x8f\xb2\x14\xd3\x72\xcf\x08\xcc\x3c\x4a\x13\ \\x8c\xf6\x31\x66\x06\x1c\x87\xbe\x88\xc9\x8f\x88\x60\x62\xe3\x97\x47\xcf\x8e\x7a\xb6\xc8\x52\x83\x3c\xc2\xac\xfb\x3f\xc0\x69\x76\ \\x4e\x8f\x02\x52\x64\xd8\x31\x4d\xda\x38\x70\xe3\x1e\x66\x54\x59\xc1\x09\x08\xf0\x51\x30\x21\xa5\x6c\x5b\x68\xb7\x82\x2f\x8a\xa0\ \\x30\x07\xcd\x3e\x74\x71\x9e\xef\xdc\x87\x26\x81\x07\x33\x40\xd4\x7e\x43\x2f\xd9\x0c\x5e\xc2\x41\x88\x09\x28\x6c\xf5\x92\xd8\x91\ \\x08\xa9\x30\xf6\x95\x7e\xf3\x05\xb7\xfb\xff\xbd\xc2\x66\xe9\x6f\x6f\xe4\xac\x98\xb1\x73\xec\xc0\xbc\x60\xb4\x2a\x95\x34\x98\xda\ \\xfb\xa1\xae\x12\x2d\x4b\xd7\x36\x0f\x25\xfa\xab\xa4\xf3\xfc\xeb\xe2\x96\x91\x23\x25\x7f\x0c\x3d\x93\x48\xaf\x49\x36\x14\x00\xbc\ \\xe8\x81\x6f\x4a\x38\x14\xf2\x00\xa3\xf9\x40\x43\x9c\x7a\x54\xc2\xbc\x70\x4f\x57\xda\x41\xe7\xf9\xc2\x5a\xd3\x3a\x54\xf4\xa0\x84\ \\xb1\x7f\x55\x05\x59\x35\x7c\xbe\xed\xbd\x15\xc8\x7f\x97\xc5\xab\xba\x5a\xc7\xb5\xb6\xf6\xde\xaf\x3a\x47\x9c\x3a\x53\x02\xda\x25\ \\x65\x3d\x7e\x6a\x54\x26\x8d\x49\x51\xa4\x77\xea\x50\x17\xd5\x5b\xd7\xd2\x5d\x88\x44\x13\x6c\x76\x04\x04\xa8\xc8\xb8\xe5\xa1\x21\ \\xb8\x1a\x92\x8a\x60\xed\x58\x69\x97\xc5\x5b\x96\xea\xec\x99\x1b\x29\x93\x59\x13\x01\xfd\xb7\xf1\x08\x8e\x8d\xfa\x9a\xb6\xf6\xf5\ \\x3b\x4c\xbf\x9f\x4a\x5d\xe3\xab\xe6\x05\x1d\x35\xa0\xe1\xd8\x55\xd3\x6b\x4c\xf1\xf5\x44\xed\xeb\xb0\xe9\x35\x24\xbe\xbb\x8f\xbd\ \\xa2\xd7\x62\xcf\x49\xc9\x2f\x54\x38\xb5\xf3\x31\x71\x28\xa4\x54\x48\x39\x29\x05\xa6\x5b\x1d\xb8\x85\x1c\x97\xbd\xd6\x75\xcf\x2f"# sbox_s7 :: Word8 -> Word32 sbox_s7 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\x85\xe0\x40\x19\x33\x2b\xf5\x67\x66\x2d\xbf\xff\xcf\xc6\x56\x93\x2a\x8d\x7f\x6f\xab\x9b\xc9\x12\xde\x60\x08\xa1\x20\x28\xda\x1f\ \\x02\x27\xbc\xe7\x4d\x64\x29\x16\x18\xfa\xc3\x00\x50\xf1\x8b\x82\x2c\xb2\xcb\x11\xb2\x32\xe7\x5c\x4b\x36\x95\xf2\xb2\x87\x07\xde\ \\xa0\x5f\xbc\xf6\xcd\x41\x81\xe9\xe1\x50\x21\x0c\xe2\x4e\xf1\xbd\xb1\x68\xc3\x81\xfd\xe4\xe7\x89\x5c\x79\xb0\xd8\x1e\x8b\xfd\x43\ \\x4d\x49\x50\x01\x38\xbe\x43\x41\x91\x3c\xee\x1d\x92\xa7\x9c\x3f\x08\x97\x66\xbe\xba\xee\xad\xf4\x12\x86\xbe\xcf\xb6\xea\xcb\x19\ \\x26\x60\xc2\x00\x75\x65\xbd\xe4\x64\x24\x1f\x7a\x82\x48\xdc\xa9\xc3\xb3\xad\x66\x28\x13\x60\x86\x0b\xd8\xdf\xa8\x35\x6d\x1c\xf2\ \\x10\x77\x89\xbe\xb3\xb2\xe9\xce\x05\x02\xaa\x8f\x0b\xc0\x35\x1e\x16\x6b\xf5\x2a\xeb\x12\xff\x82\xe3\x48\x69\x11\xd3\x4d\x75\x16\ \\x4e\x7b\x3a\xff\x5f\x43\x67\x1b\x9c\xf6\xe0\x37\x49\x81\xac\x83\x33\x42\x66\xce\x8c\x93\x41\xb7\xd0\xd8\x54\xc0\xcb\x3a\x6c\x88\ \\x47\xbc\x28\x29\x47\x25\xba\x37\xa6\x6a\xd2\x2b\x7a\xd6\x1f\x1e\x0c\x5c\xba\xfa\x44\x37\xf1\x07\xb6\xe7\x99\x62\x42\xd2\xd8\x16\ \\x0a\x96\x12\x88\xe1\xa5\xc0\x6e\x13\x74\x9e\x67\x72\xfc\x08\x1a\xb1\xd1\x39\xf7\xf9\x58\x37\x45\xcf\x19\xdf\x58\xbe\xc3\xf7\x56\ \\xc0\x6e\xba\x30\x07\x21\x1b\x24\x45\xc2\x88\x29\xc9\x5e\x31\x7f\xbc\x8e\xc5\x11\x38\xbc\x46\xe9\xc6\xe6\xfa\x14\xba\xe8\x58\x4a\ \\xad\x4e\xbc\x46\x46\x8f\x50\x8b\x78\x29\x43\x5f\xf1\x24\x18\x3b\x82\x1d\xba\x9f\xaf\xf6\x0f\xf4\xea\x2c\x4e\x6d\x16\xe3\x92\x64\ \\x92\x54\x4a\x8b\x00\x9b\x4f\xc3\xab\xa6\x8c\xed\x9a\xc9\x6f\x78\x06\xa5\xb7\x9a\xb2\x85\x6e\x6e\x1a\xec\x3c\xa9\xbe\x83\x86\x88\ \\x0e\x08\x04\xe9\x55\xf1\xbe\x56\xe7\xe5\x36\x3b\xb3\xa1\xf2\x5d\xf7\xde\xbb\x85\x61\xfe\x03\x3c\x16\x74\x62\x33\x3c\x03\x4c\x28\ \\xda\x6d\x0c\x74\x79\xaa\xc5\x6c\x3c\xe4\xe1\xad\x51\xf0\xc8\x02\x98\xf8\xf3\x5a\x16\x26\xa4\x9f\xee\xd8\x2b\x29\x1d\x38\x2f\xe3\ \\x0c\x4f\xb9\x9a\xbb\x32\x57\x78\x3e\xc6\xd9\x7b\x6e\x77\xa6\xa9\xcb\x65\x8b\x5c\xd4\x52\x30\xc7\x2b\xd1\x40\x8b\x60\xc0\x3e\xb7\ \\xb9\x06\x8d\x78\xa3\x37\x54\xf4\xf4\x30\xc8\x7d\xc8\xa7\x13\x02\xb9\x6d\x8c\x32\xeb\xd4\xe7\xbe\xbe\x8b\x9d\x2d\x79\x79\xfb\x06\ \\xe7\x22\x53\x08\x8b\x75\xcf\x77\x11\xef\x8d\xa4\xe0\x83\xc8\x58\x8d\x6b\x78\x6f\x5a\x63\x17\xa6\xfa\x5c\xf7\xa0\x5d\xda\x00\x33\ \\xf2\x8e\xbf\xb0\xf5\xb9\xc3\x10\xa0\xea\xc2\x80\x08\xb9\x76\x7a\xa3\xd9\xd2\xb0\x79\xd3\x42\x17\x02\x1a\x71\x8d\x9a\xc6\x33\x6a\ \\x27\x11\xfd\x60\x43\x80\x50\xe3\x06\x99\x08\xa8\x3d\x7f\xed\xc4\x82\x6d\x2b\xef\x4e\xeb\x84\x76\x48\x8d\xcf\x25\x36\xc9\xd5\x66\ \\x28\xe7\x4e\x41\xc2\x61\x0a\xca\x3d\x49\xa9\xcf\xba\xe3\xb9\xdf\xb6\x5f\x8d\xe6\x92\xae\xaf\x64\x3a\xc7\xd5\xe6\x9e\xa8\x05\x09\ \\xf2\x2b\x01\x7d\xa4\x17\x3f\x70\xdd\x1e\x16\xc3\x15\xe0\xd7\xf9\x50\xb1\xb8\x87\x2b\x9f\x4f\xd5\x62\x5a\xba\x82\x6a\x01\x79\x62\ \\x2e\xc0\x1b\x9c\x15\x48\x8a\xa9\xd7\x16\xe7\x40\x40\x05\x5a\x2c\x93\xd2\x9a\x22\xe3\x2d\xbf\x9a\x05\x87\x45\xb9\x34\x53\xdc\x1e\ \\xd6\x99\x29\x6e\x49\x6c\xff\x6f\x1c\x9f\x49\x86\xdf\xe2\xed\x07\xb8\x72\x42\xd1\x19\xde\x7e\xae\x05\x3e\x56\x1a\x15\xad\x6f\x8c\ \\x66\x62\x6c\x1c\x71\x54\xc2\x4c\xea\x08\x2b\x2a\x93\xeb\x29\x39\x17\xdc\xb0\xf0\x58\xd4\xf2\xae\x9e\xa2\x94\xfb\x52\xcf\x56\x4c\ \\x98\x83\xfe\x66\x2e\xc4\x05\x81\x76\x39\x53\xc3\x01\xd6\x69\x2e\xd3\xa0\xc1\x08\xa1\xe7\x16\x0e\xe4\xf2\xdf\xa6\x69\x3e\xd2\x85\ \\x74\x90\x46\x98\x4c\x2b\x0e\xdd\x4f\x75\x76\x56\x5d\x39\x33\x78\xa1\x32\x23\x4f\x3d\x32\x1c\x5d\xc3\xf5\xe1\x94\x4b\x26\x93\x01\ \\xc7\x9f\x02\x2f\x3c\x99\x7e\x7e\x5e\x4f\x95\x04\x3f\xfa\xfb\xbd\x76\xf7\xad\x0e\x29\x66\x93\xf4\x3d\x1f\xce\x6f\xc6\x1e\x45\xbe\ \\xd3\xb5\xab\x34\xf7\x2b\xf9\xb7\x1b\x04\x34\xc0\x4e\x72\xb5\x67\x55\x92\xa3\x3d\xb5\x22\x93\x01\xcf\xd2\xa8\x7f\x60\xae\xb7\x67\ \\x18\x14\x38\x6b\x30\xbc\xc3\x3d\x38\xa0\xc0\x7d\xfd\x16\x06\xf2\xc3\x63\x51\x9b\x58\x9d\xd3\x90\x54\x79\xf8\xe6\x1c\xb8\xd6\x47\ \\x97\xfd\x61\xa9\xea\x77\x59\xf4\x2d\x57\x53\x9d\x56\x9a\x58\xcf\xe8\x4e\x63\xad\x46\x2e\x1b\x78\x65\x80\xf8\x7e\xf3\x81\x79\x14\ \\x91\xda\x55\xf4\x40\xa2\x30\xf3\xd1\x98\x8f\x35\xb6\xe3\x18\xd2\x3f\xfa\x50\xbc\x3d\x40\xf0\x21\xc3\xc0\xbd\xae\x49\x58\xc2\x4c\ \\x51\x8f\x36\xb2\x84\xb1\xd3\x70\x0f\xed\xce\x83\x87\x8d\xda\xda\xf2\xa2\x79\xc7\x94\xe0\x1b\xe8\x90\x71\x6f\x4b\x95\x4b\x8a\xa3"# sbox_s8 :: Word8 -> Word32 sbox_s8 i = arrayRead32 t (fromIntegral i) where t = array32FromAddrBE 256 "\xe2\x16\x30\x0d\xbb\xdd\xff\xfc\xa7\xeb\xda\xbd\x35\x64\x80\x95\x77\x89\xf8\xb7\xe6\xc1\x12\x1b\x0e\x24\x16\x00\x05\x2c\xe8\xb5\ \\x11\xa9\xcf\xb0\xe5\x95\x2f\x11\xec\xe7\x99\x0a\x93\x86\xd1\x74\x2a\x42\x93\x1c\x76\xe3\x81\x11\xb1\x2d\xef\x3a\x37\xdd\xdd\xfc\ \\xde\x9a\xde\xb1\x0a\x0c\xc3\x2c\xbe\x19\x70\x29\x84\xa0\x09\x40\xbb\x24\x3a\x0f\xb4\xd1\x37\xcf\xb4\x4e\x79\xf0\x04\x9e\xed\xfd\ \\x0b\x15\xa1\x5d\x48\x0d\x31\x68\x8b\xbb\xde\x5a\x66\x9d\xed\x42\xc7\xec\xe8\x31\x3f\x8f\x95\xe7\x72\xdf\x19\x1b\x75\x80\x33\x0d\ \\x94\x07\x42\x51\x5c\x7d\xcd\xfa\xab\xbe\x6d\x63\xaa\x40\x21\x64\xb3\x01\xd4\x0a\x02\xe7\xd1\xca\x53\x57\x1d\xae\x7a\x31\x82\xa2\ \\x12\xa8\xdd\xec\xfd\xaa\x33\x5d\x17\x6f\x43\xe8\x71\xfb\x46\xd4\x38\x12\x90\x22\xce\x94\x9a\xd4\xb8\x47\x69\xad\x96\x5b\xd8\x62\ \\x82\xf3\xd0\x55\x66\xfb\x97\x67\x15\xb8\x0b\x4e\x1d\x5b\x47\xa0\x4c\xfd\xe0\x6f\xc2\x8e\xc4\xb8\x57\xe8\x72\x6e\x64\x7a\x78\xfc\ \\x99\x86\x5d\x44\x60\x8b\xd5\x93\x6c\x20\x0e\x03\x39\xdc\x5f\xf6\x5d\x0b\x00\xa3\xae\x63\xaf\xf2\x7e\x8b\xd6\x32\x70\x10\x8c\x0c\ \\xbb\xd3\x50\x49\x29\x98\xdf\x04\x98\x0c\xf4\x2a\x9b\x6d\xf4\x91\x9e\x7e\xdd\x53\x06\x91\x85\x48\x58\xcb\x7e\x07\x3b\x74\xef\x2e\ \\x52\x2f\xff\xb1\xd2\x47\x08\xcc\x1c\x7e\x27\xcd\xa4\xeb\x21\x5b\x3c\xf1\xd2\xe2\x19\xb4\x7a\x38\x42\x4f\x76\x18\x35\x85\x60\x39\ \\x9d\x17\xde\xe7\x27\xeb\x35\xe6\xc9\xaf\xf6\x7b\x36\xba\xf5\xb8\x09\xc4\x67\xcd\xc1\x89\x10\xb1\xe1\x1d\xbf\x7b\x06\xcd\x1a\xf8\ \\x71\x70\xc6\x08\x2d\x5e\x33\x54\xd4\xde\x49\x5a\x64\xc6\xd0\x06\xbc\xc0\xc6\x2c\x3d\xd0\x0d\xb3\x70\x8f\x8f\x34\x77\xd5\x1b\x42\ \\x26\x4f\x62\x0f\x24\xb8\xd2\xbf\x15\xc1\xb7\x9e\x46\xa5\x25\x64\xf8\xd7\xe5\x4e\x3e\x37\x81\x60\x78\x95\xcd\xa5\x85\x9c\x15\xa5\ \\xe6\x45\x97\x88\xc3\x7b\xc7\x5f\xdb\x07\xba\x0c\x06\x76\xa3\xab\x7f\x22\x9b\x1e\x31\x84\x2e\x7b\x24\x25\x9f\xd7\xf8\xbe\xf4\x72\ \\x83\x5f\xfc\xb8\x6d\xf4\xc1\xf2\x96\xf5\xb1\x95\xfd\x0a\xf0\xfc\xb0\xfe\x13\x4c\xe2\x50\x6d\x3d\x4f\x9b\x12\xea\xf2\x15\xf2\x25\ \\xa2\x23\x73\x6f\x9f\xb4\xc4\x28\x25\xd0\x49\x79\x34\xc7\x13\xf8\xc4\x61\x81\x87\xea\x7a\x6e\x98\x7c\xd1\x6e\xfc\x14\x36\x87\x6c\ \\xf1\x54\x41\x07\xbe\xde\xee\x14\x56\xe9\xaf\x27\xa0\x4a\xa4\x41\x3c\xf7\xc8\x99\x92\xec\xba\xe6\xdd\x67\x01\x6d\x15\x16\x82\xeb\ \\xa8\x42\xee\xdf\xfd\xba\x60\xb4\xf1\x90\x7b\x75\x20\xe3\x03\x0f\x24\xd8\xc2\x9e\xe1\x39\x67\x3b\xef\xa6\x3f\xb8\x71\x87\x30\x54\ \\xb6\xf2\xcf\x3b\x9f\x32\x64\x42\xcb\x15\xa4\xcc\xb0\x1a\x45\x04\xf1\xe4\x7d\x8d\x84\x4a\x1b\xe5\xba\xe7\xdf\xdc\x42\xcb\xda\x70\ \\xcd\x7d\xae\x0a\x57\xe8\x5b\x7a\xd5\x3f\x5a\xf6\x20\xcf\x4d\x8c\xce\xa4\xd4\x28\x79\xd1\x30\xa4\x34\x86\xeb\xfb\x33\xd3\xcd\xdc\ \\x77\x85\x3b\x53\x37\xef\xfc\xb5\xc5\x06\x87\x78\xe5\x80\xb3\xe6\x4e\x68\xb8\xf4\xc5\xc8\xb3\x7e\x0d\x80\x9e\xa2\x39\x8f\xeb\x7c\ \\x13\x2a\x4f\x94\x43\xb7\x95\x0e\x2f\xee\x7d\x1c\x22\x36\x13\xbd\xdd\x06\xca\xa2\x37\xdf\x93\x2b\xc4\x24\x82\x89\xac\xf3\xeb\xc3\ \\x57\x15\xf6\xb7\xef\x34\x78\xdd\xf2\x67\x61\x6f\xc1\x48\xcb\xe4\x90\x52\x81\x5e\x5e\x41\x0f\xab\xb4\x8a\x24\x65\x2e\xda\x7f\xa4\ \\xe8\x7b\x40\xe4\xe9\x8e\xa0\x84\x58\x89\xe9\xe1\xef\xd3\x90\xfc\xdd\x07\xd3\x5b\xdb\x48\x56\x94\x38\xd7\xe5\xb2\x57\x72\x01\x01\ \\x73\x0e\xde\xbc\x5b\x64\x31\x13\x94\x91\x7e\x4f\x50\x3c\x2f\xba\x64\x6f\x12\x82\x75\x23\xd2\x4a\xe0\x77\x96\x95\xf9\xc1\x7a\x8f\ \\x7a\x5b\x21\x21\xd1\x87\xb8\x96\x29\x26\x3a\x4d\xba\x51\x0c\xdf\x81\xf4\x7c\x9f\xad\x11\x63\xed\xea\x7b\x59\x65\x1a\x00\x72\x6e\ \\x11\x40\x30\x92\x00\xda\x6d\x77\x4a\x0c\xdd\x61\xad\x1f\x46\x03\x60\x5b\xdf\xb0\x9e\xed\xc3\x64\x22\xeb\xe6\xa8\xce\xe7\xd2\x8a\ \\xa0\xe7\x36\xa0\x55\x64\xa6\xb9\x10\x85\x32\x09\xc7\xeb\x8f\x37\x2d\xe7\x05\xca\x89\x51\x57\x0f\xdf\x09\x82\x2b\xbd\x69\x1a\x6c\ \\xaa\x12\xe4\xf2\x87\x45\x1c\x0f\xe0\xf6\xa2\x7a\x3a\xda\x48\x19\x4c\xf1\x76\x4f\x0d\x77\x1c\x2b\x67\xcd\xb1\x56\x35\x0d\x83\x84\ \\x59\x38\xfa\x0f\x42\x39\x9e\xf3\x36\x99\x7b\x07\x0e\x84\x09\x3d\x4a\xa9\x3e\x61\x83\x60\xd8\x7b\x1f\xa9\x8b\x0c\x11\x49\x38\x2c\ \\xe9\x76\x25\xa5\x06\x14\xd1\xb7\x0e\x25\x24\x4b\x0c\x76\x83\x47\x58\x9e\x8d\x82\x0d\x20\x59\xd1\xa4\x66\xbb\x1e\xf8\xda\x0a\x82\ \\x04\xf1\x91\x30\xba\x6e\x4e\xc0\x99\x26\x51\x64\x1e\xe7\x23\x0d\x50\xb2\xad\x80\xea\xee\x68\x01\x8d\xb2\xa2\x83\xea\x8b\xf5\x9e"# cryptonite-0.26/Crypto/Cipher/Camellia/Primitive.hs0000644000000000000000000002512313414232447020543 0ustar0000000000000000 -- | -- Module : Crypto.Cipher.Camellia.Primitive -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- -- This only cover Camellia 128 bits for now. The 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.26/Crypto/Cipher/DES/Primitive.hs0000644000000000000000000002137613414232447017455 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.26/Crypto/Cipher/Twofish/Primitive.hs0000644000000000000000000004256213470442731020466 0ustar0000000000000000{-# LANGUAGE MagicHash #-} {-# LANGUAGE BangPatterns #-} module Crypto.Cipher.Twofish.Primitive ( Twofish , initTwofish , encrypt , decrypt ) where import Crypto.Error import Crypto.Internal.ByteArray (ByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.WordArray import Data.Word import Data.Bits import Data.List -- 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 :: 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.26/Crypto/Cipher/Types/AEAD.hs0000644000000000000000000000614713414232447016667 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.26/Crypto/Cipher/Types/Base.hs0000644000000000000000000000365213470442731017046 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(..) , CCM_M(..) , CCM_L(..) , DataUnitOffset ) where import Data.Word import Crypto.Internal.ByteArray (Bytes, ByteArrayAccess, ByteArray) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.DeepSeq 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, NFData) instance Eq AuthTag where (AuthTag a) == (AuthTag b) = B.constEq a b data CCM_M = CCM_M4 | CCM_M6 | CCM_M8 | CCM_M10 | CCM_M12 | CCM_M14 | CCM_M16 deriving (Show, Eq) data CCM_L = CCM_L2 | CCM_L3 | CCM_L4 deriving (Show, Eq) -- | AEAD Mode data AEADMode = AEAD_OCB -- OCB3 | AEAD_CCM Int CCM_M CCM_L | 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.26/Crypto/Cipher/Types/Block.hs0000644000000000000000000002372713470442731017233 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 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 :: IV c -> Int -> IV c ivAdd (IV b) i = IV $ copy b where copy :: ByteArray bs => bs -> bs copy bs = B.copyAndFreeze bs $ loop i (B.length bs - 1) loop :: Int -> Int -> Ptr Word8 -> IO () loop acc ofs p | ofs < 0 = return () | otherwise = 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) 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.26/Crypto/Cipher/Types/GF.hs0000644000000000000000000000323013414232447016457 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.26/Crypto/Cipher/Types/Stream.hs0000644000000000000000000000105213414232447017416 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.26/Crypto/Cipher/Types/Utils.hs0000644000000000000000000000124313414232447017265 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.26/Crypto/Error/Types.hs0000644000000000000000000000760713470442731016057 0ustar0000000000000000-- | -- Module : Crypto.Error.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- Cryptographic Error enumeration and handling -- {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Error.Types ( CryptoError(..) , CryptoFailable(..) , throwCryptoErrorIO , throwCryptoError , onCryptoFailure , eitherCryptoError , maybeCryptoError ) where import qualified Control.Exception as E import Data.Data import Basement.Monad (MonadFailure(..)) -- | Enumeration of all possible errors that can be found in this library data CryptoError = -- symmetric cipher errors CryptoError_KeySizeInvalid | CryptoError_IvSizeInvalid | CryptoError_SeedSizeInvalid | 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 | CryptoError_ScalarMultiplicationInvalid -- 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) 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 = pure (>>=) m1 m2 = do case m1 of CryptoPassed a -> m2 a CryptoFailed e -> CryptoFailed e instance MonadFailure CryptoFailable where type Failure CryptoFailable = CryptoError mFail = CryptoFailed -- | 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.26/Crypto/Number/Compat.hs0000644000000000000000000001340013470442731016321 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 , gmpExportIntegerLE , gmpImportInteger , gmpImportIntegerLE ) 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,2) gmpPowModSecInteger b e m = GmpSupported (powModSecInteger b e m) #elif 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 (big-endian) 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 -- | Export an integer to a memory (little-endian) gmpExportIntegerLE :: Integer -> Ptr Word8 -> GmpSupported (IO ()) #if MIN_VERSION_integer_gmp(1,0,0) gmpExportIntegerLE n (Ptr addr) = GmpSupported $ do _ <- exportIntegerToAddr n addr 0# return () #elif MIN_VERSION_integer_gmp(0,5,1) gmpExportIntegerLE n (Ptr addr) = GmpSupported $ IO $ \s -> case exportIntegerToAddr n addr 0# s of (# s2, _ #) -> (# s2, () #) #else gmpExportIntegerLE _ _ = GmpUnsupported #endif -- | Import an integer from a memory (big-endian) 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 -- | Import an integer from a memory (little-endian) gmpImportIntegerLE :: Int -> Ptr Word8 -> GmpSupported (IO Integer) #if MIN_VERSION_integer_gmp(1,0,0) gmpImportIntegerLE (I# n) (Ptr addr) = GmpSupported $ importIntegerFromAddr addr (int2Word# n) 0# #elif MIN_VERSION_integer_gmp(0,5,1) gmpImportIntegerLE (I# n) (Ptr addr) = GmpSupported $ IO $ \s -> importIntegerFromAddr addr (int2Word# n) 0# s #else gmpImportIntegerLE _ _ = GmpUnsupported #endif cryptonite-0.26/Crypto/Hash/Types.hs0000644000000000000000000000775713414232447015656 0ustar0000000000000000-- | -- Module : Crypto.Hash.Types -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : unknown -- -- Crypto hash types definitions -- {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} 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 Control.Monad.ST import Data.Char (digitToInt, isHexDigit) import Foreign.Ptr (Ptr) import Basement.Block (Block, unsafeFreeze) import Basement.Block.Mutable (MutableBlock, new, unsafeWrite) import Basement.NormalForm (deepseq) import Basement.Types.OffsetSize (CountOf(..), Offset(..)) import GHC.TypeLits (Nat) import Data.Data (Data) -- | 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 -- | Associated type for the block size of the hash algorithm type HashBlockSize a :: Nat -- | Associated type for the digest size of the hash algorithm type HashDigestSize a :: Nat -- | Associated type for the internal context size of the hash algorithm type HashInternalContextSize a :: Nat -- | 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. -- -- This type is an instance of 'ByteArrayAccess' from package -- . -- Module "Data.ByteArray" provides many primitives to work with those values -- including conversion to other types. -- -- Creating a digest from a bytearray is also possible with function -- 'Crypto.Hash.digestFromByteString'. newtype Digest a = Digest (Block Word8) deriving (Eq,Ord,ByteArrayAccess, Data) instance NFData (Digest a) where rnf (Digest u) = u `deepseq` () instance Show (Digest a) where show (Digest bs) = map (toEnum . fromIntegral) $ B.unpack (B.convertToBase B.Base16 bs :: Bytes) instance HashAlgorithm a => Read (Digest a) where readsPrec _ str = runST $ do mut <- new (CountOf len) loop mut len str where len = hashDigestSize (undefined :: a) loop :: MutableBlock Word8 s -> Int -> String -> ST s [(Digest a, String)] loop mut 0 cs = (\b -> [(Digest b, cs)]) <$> unsafeFreeze mut loop _ _ [] = return [] loop _ _ [_] = return [] loop mut n (c:(d:ds)) | not (isHexDigit c) = return [] | not (isHexDigit d) = return [] | otherwise = do let w8 = fromIntegral $ digitToInt c * 16 + digitToInt d unsafeWrite mut (Offset $ len - n) w8 loop mut (n - 1) ds cryptonite-0.26/Crypto/Hash/Blake2.hs0000644000000000000000000001500313470442731015632 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.Word (Word8, Word32) import GHC.TypeLits (Nat, KnownNat) 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,Data) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256) => HashAlgorithm (Blake2s bitlen) where type HashBlockSize (Blake2s bitlen) = 64 type HashDigestSize (Blake2s bitlen) = Div8 bitlen type HashInternalContextSize (Blake2s bitlen) = 136 hashBlockSize _ = 64 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) hashInternalContextSize _ = 136 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,Data) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512) => HashAlgorithm (Blake2b bitlen) where type HashBlockSize (Blake2b bitlen) = 128 type HashDigestSize (Blake2b bitlen) = Div8 bitlen type HashInternalContextSize (Blake2b bitlen) = 248 hashBlockSize _ = 128 hashDigestSize _ = byteLen (Proxy :: Proxy bitlen) hashInternalContextSize _ = 248 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,Data) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 256) => HashAlgorithm (Blake2sp bitlen) where type HashBlockSize (Blake2sp bitlen) = 64 type HashDigestSize (Blake2sp bitlen) = Div8 bitlen type HashInternalContextSize (Blake2sp bitlen) = 2185 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,Data) instance (IsDivisibleBy8 bitlen, KnownNat bitlen, IsAtLeast bitlen 8, IsAtMost bitlen 512) => HashAlgorithm (Blake2bp bitlen) where type HashBlockSize (Blake2bp bitlen) = 128 type HashDigestSize (Blake2bp bitlen) = Div8 bitlen type HashInternalContextSize (Blake2bp bitlen) = 2325 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.26/Crypto/Hash/Blake2s.hs0000644000000000000000000000524713470442731016026 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Blake2s ( Blake2s_160 (..), Blake2s_224 (..), Blake2s_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | Blake2s (160 bits) cryptographic hash algorithm data Blake2s_160 = Blake2s_160 deriving (Show,Data) instance HashAlgorithm Blake2s_160 where type HashBlockSize Blake2s_160 = 64 type HashDigestSize Blake2s_160 = 20 type HashInternalContextSize Blake2s_160 = 136 hashBlockSize _ = 64 hashDigestSize _ = 20 hashInternalContextSize _ = 136 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) instance HashAlgorithm Blake2s_224 where type HashBlockSize Blake2s_224 = 64 type HashDigestSize Blake2s_224 = 28 type HashInternalContextSize Blake2s_224 = 136 hashBlockSize _ = 64 hashDigestSize _ = 28 hashInternalContextSize _ = 136 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) instance HashAlgorithm Blake2s_256 where type HashBlockSize Blake2s_256 = 64 type HashDigestSize Blake2s_256 = 32 type HashInternalContextSize Blake2s_256 = 136 hashBlockSize _ = 64 hashDigestSize _ = 32 hashInternalContextSize _ = 136 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.26/Crypto/Hash/Blake2sp.hs0000644000000000000000000000420013470442731016172 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Blake2sp ( Blake2sp_224 (..), Blake2sp_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | Blake2sp (224 bits) cryptographic hash algorithm data Blake2sp_224 = Blake2sp_224 deriving (Show,Data) instance HashAlgorithm Blake2sp_224 where type HashBlockSize Blake2sp_224 = 64 type HashDigestSize Blake2sp_224 = 28 type HashInternalContextSize Blake2sp_224 = 1752 hashBlockSize _ = 64 hashDigestSize _ = 28 hashInternalContextSize _ = 1752 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) instance HashAlgorithm Blake2sp_256 where type HashBlockSize Blake2sp_256 = 64 type HashDigestSize Blake2sp_256 = 32 type HashInternalContextSize Blake2sp_256 = 1752 hashBlockSize _ = 64 hashDigestSize _ = 32 hashInternalContextSize _ = 1752 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.26/Crypto/Hash/Blake2b.hs0000644000000000000000000000750513470442731016004 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} 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.Word (Word8, Word32) -- | Blake2b (160 bits) cryptographic hash algorithm data Blake2b_160 = Blake2b_160 deriving (Show,Data) instance HashAlgorithm Blake2b_160 where type HashBlockSize Blake2b_160 = 128 type HashDigestSize Blake2b_160 = 20 type HashInternalContextSize Blake2b_160 = 248 hashBlockSize _ = 128 hashDigestSize _ = 20 hashInternalContextSize _ = 248 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) instance HashAlgorithm Blake2b_224 where type HashBlockSize Blake2b_224 = 128 type HashDigestSize Blake2b_224 = 28 type HashInternalContextSize Blake2b_224 = 248 hashBlockSize _ = 128 hashDigestSize _ = 28 hashInternalContextSize _ = 248 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) instance HashAlgorithm Blake2b_256 where type HashBlockSize Blake2b_256 = 128 type HashDigestSize Blake2b_256 = 32 type HashInternalContextSize Blake2b_256 = 248 hashBlockSize _ = 128 hashDigestSize _ = 32 hashInternalContextSize _ = 248 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) instance HashAlgorithm Blake2b_384 where type HashBlockSize Blake2b_384 = 128 type HashDigestSize Blake2b_384 = 48 type HashInternalContextSize Blake2b_384 = 248 hashBlockSize _ = 128 hashDigestSize _ = 48 hashInternalContextSize _ = 248 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) instance HashAlgorithm Blake2b_512 where type HashBlockSize Blake2b_512 = 128 type HashDigestSize Blake2b_512 = 64 type HashInternalContextSize Blake2b_512 = 248 hashBlockSize _ = 128 hashDigestSize _ = 64 hashInternalContextSize _ = 248 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.26/Crypto/Hash/Blake2bp.hs0000644000000000000000000000305313470442731016156 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Blake2bp ( Blake2bp_512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | Blake2bp (512 bits) cryptographic hash algorithm data Blake2bp_512 = Blake2bp_512 deriving (Show,Data) instance HashAlgorithm Blake2bp_512 where type HashBlockSize Blake2bp_512 = 128 type HashDigestSize Blake2bp_512 = 64 type HashInternalContextSize Blake2bp_512 = 1768 hashBlockSize _ = 128 hashDigestSize _ = 64 hashInternalContextSize _ = 1768 hashInternalInit p = c_blake2bp_init p 512 hashInternalUpdate = c_blake2bp_update hashInternalFinalize p = c_blake2bp_finalize p 512 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.26/Crypto/Hash/SHA1.hs0000644000000000000000000000260213470442731015227 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.SHA1 ( SHA1 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | SHA1 cryptographic hash algorithm data SHA1 = SHA1 deriving (Show,Data) instance HashAlgorithm SHA1 where type HashBlockSize SHA1 = 64 type HashDigestSize SHA1 = 20 type HashInternalContextSize SHA1 = 96 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.26/Crypto/Hash/SHA224.hs0000644000000000000000000000265413470442731015405 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.SHA224 ( SHA224 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | SHA224 cryptographic hash algorithm data SHA224 = SHA224 deriving (Show,Data) instance HashAlgorithm SHA224 where type HashBlockSize SHA224 = 64 type HashDigestSize SHA224 = 28 type HashInternalContextSize SHA224 = 192 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.26/Crypto/Hash/SHA256.hs0000644000000000000000000000265413470442731015412 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.SHA256 ( SHA256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | SHA256 cryptographic hash algorithm data SHA256 = SHA256 deriving (Show,Data) instance HashAlgorithm SHA256 where type HashBlockSize SHA256 = 64 type HashDigestSize SHA256 = 32 type HashInternalContextSize SHA256 = 192 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.26/Crypto/Hash/SHA384.hs0000644000000000000000000000265613470442731015416 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.SHA384 ( SHA384 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | SHA384 cryptographic hash algorithm data SHA384 = SHA384 deriving (Show,Data) instance HashAlgorithm SHA384 where type HashBlockSize SHA384 = 128 type HashDigestSize SHA384 = 48 type HashInternalContextSize SHA384 = 256 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.26/Crypto/Hash/SHA512.hs0000644000000000000000000000265613470442731015407 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.SHA512 ( SHA512 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | SHA512 cryptographic hash algorithm data SHA512 = SHA512 deriving (Show,Data) instance HashAlgorithm SHA512 where type HashBlockSize SHA512 = 128 type HashDigestSize SHA512 = 64 type HashInternalContextSize SHA512 = 256 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.26/Crypto/Hash/SHA512t.hs0000644000000000000000000000414113470442731015562 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.SHA512t ( SHA512t_224 (..), SHA512t_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | SHA512t (224 bits) cryptographic hash algorithm data SHA512t_224 = SHA512t_224 deriving (Show,Data) instance HashAlgorithm SHA512t_224 where type HashBlockSize SHA512t_224 = 128 type HashDigestSize SHA512t_224 = 28 type HashInternalContextSize SHA512t_224 = 256 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) instance HashAlgorithm SHA512t_256 where type HashBlockSize SHA512t_256 = 128 type HashDigestSize SHA512t_256 = 32 type HashInternalContextSize SHA512t_256 = 256 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.26/Crypto/Hash/SHA3.hs0000644000000000000000000000613013470442731015231 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} 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.Word (Word8, Word32) -- | SHA3 (224 bits) cryptographic hash algorithm data SHA3_224 = SHA3_224 deriving (Show,Data) instance HashAlgorithm SHA3_224 where type HashBlockSize SHA3_224 = 144 type HashDigestSize SHA3_224 = 28 type HashInternalContextSize SHA3_224 = 352 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) instance HashAlgorithm SHA3_256 where type HashBlockSize SHA3_256 = 136 type HashDigestSize SHA3_256 = 32 type HashInternalContextSize SHA3_256 = 344 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) instance HashAlgorithm SHA3_384 where type HashBlockSize SHA3_384 = 104 type HashDigestSize SHA3_384 = 48 type HashInternalContextSize SHA3_384 = 312 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) instance HashAlgorithm SHA3_512 where type HashBlockSize SHA3_512 = 72 type HashDigestSize SHA3_512 = 64 type HashInternalContextSize SHA3_512 = 280 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.26/Crypto/Hash/SHAKE.hs0000644000000000000000000001176613470442731015401 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 ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} module Crypto.Hash.SHAKE ( SHAKE128 (..), SHAKE256 (..), HashSHAKE (..) ) where import Control.Monad (when) import Crypto.Hash.Types import Foreign.Ptr (Ptr, castPtr) import Foreign.Storable (Storable(..)) import Data.Bits import Data.Data import Data.Word (Word8, Word32) import GHC.TypeLits (Nat, KnownNat, type (+)) import Crypto.Internal.Nat -- | Type class of SHAKE algorithms. class HashAlgorithm a => HashSHAKE a where -- | Alternate finalization needed for cSHAKE cshakeInternalFinalize :: Ptr (Context a) -> Ptr (Digest a) -> IO () -- | Get the digest bit length cshakeOutputLength :: a -> Int -- | SHAKE128 (128 bits) extendable output function. Supports an arbitrary -- digest size, 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, Data) instance KnownNat bitlen => HashAlgorithm (SHAKE128 bitlen) where type HashBlockSize (SHAKE128 bitlen) = 168 type HashDigestSize (SHAKE128 bitlen) = Div8 (bitlen + 7) type HashInternalContextSize (SHAKE128 bitlen) = 376 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) instance KnownNat bitlen => HashSHAKE (SHAKE128 bitlen) where cshakeInternalFinalize = cshakeFinalizeOutput (Proxy :: Proxy bitlen) cshakeOutputLength _ = integralNatVal (Proxy :: Proxy bitlen) -- | SHAKE256 (256 bits) extendable output function. Supports an arbitrary -- digest size, 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, Data) instance KnownNat bitlen => HashAlgorithm (SHAKE256 bitlen) where type HashBlockSize (SHAKE256 bitlen) = 136 type HashDigestSize (SHAKE256 bitlen) = Div8 (bitlen + 7) type HashInternalContextSize (SHAKE256 bitlen) = 344 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) instance KnownNat bitlen => HashSHAKE (SHAKE256 bitlen) where cshakeInternalFinalize = cshakeFinalizeOutput (Proxy :: Proxy bitlen) cshakeOutputLength _ = integralNatVal (Proxy :: Proxy bitlen) shakeFinalizeOutput :: 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) shakeTruncate d (castPtr dig) cshakeFinalizeOutput :: KnownNat bitlen => proxy bitlen -> Ptr (Context a) -> Ptr (Digest a) -> IO () cshakeFinalizeOutput d ctx dig = do c_sha3_finalize_cshake ctx c_sha3_output ctx dig (byteLen d) shakeTruncate d (castPtr dig) shakeTruncate :: KnownNat bitlen => proxy bitlen -> Ptr Word8 -> IO () shakeTruncate d ptr = when (bits > 0) $ do byte <- peekElemOff ptr index pokeElemOff ptr index (byte .&. mask) where mask = (1 `shiftL` bits) - 1 (index, bits) = integralNatVal d `divMod` 8 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_finalize_cshake" c_sha3_finalize_cshake :: Ptr (Context a) -> IO () foreign import ccall unsafe "cryptonite_sha3_output" c_sha3_output :: Ptr (Context a) -> Ptr (Digest a) -> Word32 -> IO () cryptonite-0.26/Crypto/Hash/Keccak.hs0000644000000000000000000000630213470442731015715 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} 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.Word (Word8, Word32) -- | Keccak (224 bits) cryptographic hash algorithm data Keccak_224 = Keccak_224 deriving (Show,Data) instance HashAlgorithm Keccak_224 where type HashBlockSize Keccak_224 = 144 type HashDigestSize Keccak_224 = 28 type HashInternalContextSize Keccak_224 = 352 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) instance HashAlgorithm Keccak_256 where type HashBlockSize Keccak_256 = 136 type HashDigestSize Keccak_256 = 32 type HashInternalContextSize Keccak_256 = 344 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) instance HashAlgorithm Keccak_384 where type HashBlockSize Keccak_384 = 104 type HashDigestSize Keccak_384 = 48 type HashInternalContextSize Keccak_384 = 312 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) instance HashAlgorithm Keccak_512 where type HashBlockSize Keccak_512 = 72 type HashDigestSize Keccak_512 = 64 type HashInternalContextSize Keccak_512 = 280 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.26/Crypto/Hash/MD2.hs0000644000000000000000000000255613470442731015125 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.MD2 ( MD2 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | MD2 cryptographic hash algorithm data MD2 = MD2 deriving (Show,Data) instance HashAlgorithm MD2 where type HashBlockSize MD2 = 16 type HashDigestSize MD2 = 16 type HashInternalContextSize MD2 = 96 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.26/Crypto/Hash/MD4.hs0000644000000000000000000000255613470442731015127 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.MD4 ( MD4 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | MD4 cryptographic hash algorithm data MD4 = MD4 deriving (Show,Data) instance HashAlgorithm MD4 where type HashBlockSize MD4 = 64 type HashDigestSize MD4 = 16 type HashInternalContextSize MD4 = 96 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.26/Crypto/Hash/MD5.hs0000644000000000000000000000255613470442731015130 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.MD5 ( MD5 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | MD5 cryptographic hash algorithm data MD5 = MD5 deriving (Show,Data) instance HashAlgorithm MD5 where type HashBlockSize MD5 = 64 type HashDigestSize MD5 = 16 type HashInternalContextSize MD5 = 96 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.26/Crypto/Hash/RIPEMD160.hs0000644000000000000000000000275013470442731015746 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.RIPEMD160 ( RIPEMD160 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | RIPEMD160 cryptographic hash algorithm data RIPEMD160 = RIPEMD160 deriving (Show,Data) instance HashAlgorithm RIPEMD160 where type HashBlockSize RIPEMD160 = 64 type HashDigestSize RIPEMD160 = 20 type HashInternalContextSize RIPEMD160 = 128 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.26/Crypto/Hash/Skein256.hs0000644000000000000000000000417013470442731016043 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Skein256 ( Skein256_224 (..), Skein256_256 (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | Skein256 (224 bits) cryptographic hash algorithm data Skein256_224 = Skein256_224 deriving (Show,Data) instance HashAlgorithm Skein256_224 where type HashBlockSize Skein256_224 = 32 type HashDigestSize Skein256_224 = 28 type HashInternalContextSize Skein256_224 = 96 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) instance HashAlgorithm Skein256_256 where type HashBlockSize Skein256_256 = 32 type HashDigestSize Skein256_256 = 32 type HashInternalContextSize Skein256_256 = 96 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.26/Crypto/Hash/Skein512.hs0000644000000000000000000000644613470442731016046 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} 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.Word (Word8, Word32) -- | Skein512 (224 bits) cryptographic hash algorithm data Skein512_224 = Skein512_224 deriving (Show,Data) instance HashAlgorithm Skein512_224 where type HashBlockSize Skein512_224 = 64 type HashDigestSize Skein512_224 = 28 type HashInternalContextSize Skein512_224 = 160 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) instance HashAlgorithm Skein512_256 where type HashBlockSize Skein512_256 = 64 type HashDigestSize Skein512_256 = 32 type HashInternalContextSize Skein512_256 = 160 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) instance HashAlgorithm Skein512_384 where type HashBlockSize Skein512_384 = 64 type HashDigestSize Skein512_384 = 48 type HashInternalContextSize Skein512_384 = 160 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) instance HashAlgorithm Skein512_512 where type HashBlockSize Skein512_512 = 64 type HashDigestSize Skein512_512 = 64 type HashInternalContextSize Skein512_512 = 160 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.26/Crypto/Hash/Tiger.hs0000644000000000000000000000262613470442731015613 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Tiger ( Tiger (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | Tiger cryptographic hash algorithm data Tiger = Tiger deriving (Show,Data) instance HashAlgorithm Tiger where type HashBlockSize Tiger = 64 type HashDigestSize Tiger = 24 type HashInternalContextSize Tiger = 96 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.26/Crypto/Hash/Whirlpool.hs0000644000000000000000000000275013470442731016516 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 #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE TypeFamilies #-} module Crypto.Hash.Whirlpool ( Whirlpool (..) ) where import Crypto.Hash.Types import Foreign.Ptr (Ptr) import Data.Data import Data.Word (Word8, Word32) -- | Whirlpool cryptographic hash algorithm data Whirlpool = Whirlpool deriving (Show,Data) instance HashAlgorithm Whirlpool where type HashBlockSize Whirlpool = 64 type HashDigestSize Whirlpool = 64 type HashInternalContextSize Whirlpool = 168 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.26/Crypto/Random/Entropy/Source.hs0000644000000000000000000000127613414232447017775 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.26/Crypto/Random/Entropy/Backend.hs0000644000000000000000000000324113470442731020057 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.Proxy 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 (Proxy :: Proxy RDRand), #endif #ifdef WINDOWS openBackend (Proxy :: Proxy WinCryptoAPI) #else openBackend (Proxy :: Proxy DevRandom), openBackend (Proxy :: Proxy DevURandom) #endif ] -- | Any Entropy Backend data EntropyBackend = forall b . EntropySource b => EntropyBackend b -- | Open a backend handle openBackend :: EntropySource b => Proxy b -> IO (Maybe EntropyBackend) openBackend b = fmap EntropyBackend `fmap` callOpen b where callOpen :: EntropySource b => Proxy 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.26/Crypto/Random/ChaChaDRG.hs0000644000000000000000000000331513470442731016536 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, ByteArrayAccess, 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 :: ByteArrayAccess 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.26/Crypto/Random/SystemDRG.hs0000644000000000000000000000451213470442731016713 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 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.26/Crypto/Random/Probabilistic.hs0000644000000000000000000000156113414232447017660 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 advised 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.26/Crypto/PubKey/Internal.hs0000644000000000000000000000237313470442731016630 0ustar0000000000000000-- | -- Module : Crypto.PubKey.Internal -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : experimental -- Portability : Good -- module Crypto.PubKey.Internal ( and' , (&&!) , dsaTruncHash , dsaTruncHashDigest ) where import Data.Bits (shiftR) import Data.List (foldl') import Crypto.Hash import Crypto.Internal.ByteArray (ByteArrayAccess) import Crypto.Number.Basic (numBits) import Crypto.Number.Serialize -- | 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 -- | Truncate and hash for DSA and ECDSA. dsaTruncHash :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> msg -> Integer -> Integer dsaTruncHash hashAlg = dsaTruncHashDigest . hashWith hashAlg -- | Truncate a digest for DSA and ECDSA. dsaTruncHashDigest :: HashAlgorithm hash => Digest hash -> Integer -> Integer dsaTruncHashDigest digest n | d > 0 = shiftR e d | otherwise = e where e = os2ip digest d = hashDigestSize (getHashAlg digest) * 8 - numBits n getHashAlg :: Digest hash -> hash getHashAlg _ = undefined cryptonite-0.26/Crypto/PubKey/ElGamal.hs0000644000000000000000000001245213414232447016354 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.26/Crypto/ECC/Simple/Types.hs0000644000000000000000000007033113470442731016603 0ustar0000000000000000{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | -- 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) newtype CurveBinaryParam = CurveBinaryParam Integer deriving (Show,Read,Eq,Data) newtype CurvePrimeParam = CurvePrimeParam Integer deriving (Show,Read,Eq,Data) data CurveType = CurveBinary CurveBinaryParam | CurvePrime CurvePrimeParam deriving (Show,Read,Eq,Data) -- | ECC Private Number newtype Scalar curve = Scalar Integer deriving (Show,Read,Eq,Data,NFData) -- | Define a point on a curve. data Point curve = Point Integer Integer | PointO -- ^ Point at Infinity deriving (Show,Read,Eq,Data) 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.26/Crypto/ECC/Simple/Prim.hs0000644000000000000000000001634313470442731016411 0ustar0000000000000000-- | Elliptic Curve Arithmetic. -- -- /WARNING:/ These functions are vulnerable to timing attacks. {-# LANGUAGE ScopedTypeVariables #-} module Crypto.ECC.Simple.Prim ( scalarGenerate , scalarFromInteger , pointAdd , pointNegate , pointDouble , pointBaseMul , pointMul , pointAddTwoMuls , pointFromIntegers , isPointAtInfinity , isPointValid ) where import Data.Maybe import Data.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 (CurvePrimeParam p) -> Point x (p - 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.26/Crypto/Internal/ByteArray.hs0000644000000000000000000000202313414232447017322 0ustar0000000000000000-- | -- Module : Crypto.Internal.ByteArray -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- Simple and efficient byte array types -- {-# LANGUAGE BangPatterns #-} {-# OPTIONS_HADDOCK hide #-} module Crypto.Internal.ByteArray ( module Data.ByteArray , module Data.ByteArray.Mapping , module Data.ByteArray.Encoding , constAllZero ) where import Data.ByteArray import Data.ByteArray.Mapping import Data.ByteArray.Encoding import Data.Bits ((.|.)) import Data.Word (Word8) import Foreign.Ptr (Ptr) import Foreign.Storable (peekByteOff) import Crypto.Internal.Compat (unsafeDoIO) constAllZero :: ByteArrayAccess ba => ba -> Bool constAllZero b = unsafeDoIO $ withByteArray b $ \p -> loop p 0 0 where loop :: Ptr b -> Int -> Word8 -> IO Bool loop p i !acc | i == len = return $! acc == 0 | otherwise = do e <- peekByteOff p i loop p (i+1) (acc .|. e) len = Data.ByteArray.length b cryptonite-0.26/Crypto/Internal/Compat.hs0000644000000000000000000000263513414232447016654 0ustar0000000000000000-- | -- Module : Crypto.Internal.Compat -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Good -- -- This module tries 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.26/Crypto/Internal/CompatPrim.hs0000644000000000000000000000645413414232447017507 0ustar0000000000000000-- | -- Module : Crypto.Internal.CompatPrim -- License : BSD-style -- Maintainer : Vincent Hanquez -- Stability : stable -- Portability : Compat -- -- This module tries 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.26/Crypto/Internal/DeepSeq.hs0000644000000000000000000000160413414232447016752 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` () instance NFData Integer where rnf i = i `seq` () #endif cryptonite-0.26/Crypto/Internal/Imports.hs0000644000000000000000000000071313414232447017061 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.26/Crypto/Internal/Nat.hs0000644000000000000000000001176213470442731016155 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 , type IsDiv8 , type Div8 , type Mod8 ) where import GHC.TypeLits byteLen :: (KnownNat bitlen, Num a) => proxy bitlen -> a byteLen d = fromInteger ((natVal d + 7) `div` 8) integralNatVal :: (KnownNat bitlen, Num a) => proxy bitlen -> a integralNatVal = fromInteger . natVal type family IsLE (bitlen :: Nat) (n :: Nat) (c :: Bool) where IsLE _ _ '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 _ _ '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 Div8 (bitLen :: Nat) where Div8 0 = 0 Div8 1 = 0 Div8 2 = 0 Div8 3 = 0 Div8 4 = 0 Div8 5 = 0 Div8 6 = 0 Div8 7 = 0 Div8 8 = 1 Div8 9 = 1 Div8 10 = 1 Div8 11 = 1 Div8 12 = 1 Div8 13 = 1 Div8 14 = 1 Div8 15 = 1 Div8 16 = 2 Div8 17 = 2 Div8 18 = 2 Div8 19 = 2 Div8 20 = 2 Div8 21 = 2 Div8 22 = 2 Div8 23 = 2 Div8 24 = 3 Div8 25 = 3 Div8 26 = 3 Div8 27 = 3 Div8 28 = 3 Div8 29 = 3 Div8 30 = 3 Div8 31 = 3 Div8 32 = 4 Div8 33 = 4 Div8 34 = 4 Div8 35 = 4 Div8 36 = 4 Div8 37 = 4 Div8 38 = 4 Div8 39 = 4 Div8 40 = 5 Div8 41 = 5 Div8 42 = 5 Div8 43 = 5 Div8 44 = 5 Div8 45 = 5 Div8 46 = 5 Div8 47 = 5 Div8 48 = 6 Div8 49 = 6 Div8 50 = 6 Div8 51 = 6 Div8 52 = 6 Div8 53 = 6 Div8 54 = 6 Div8 55 = 6 Div8 56 = 7 Div8 57 = 7 Div8 58 = 7 Div8 59 = 7 Div8 60 = 7 Div8 61 = 7 Div8 62 = 7 Div8 63 = 7 Div8 64 = 8 Div8 n = 8 + Div8 (n - 64) type family IsDiv8 (bitLen :: Nat) (n :: Nat) where IsDiv8 _ 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 _ 1 = 'False IsDiv8 _ 2 = 'False IsDiv8 _ 3 = 'False IsDiv8 _ 4 = 'False IsDiv8 _ 5 = 'False IsDiv8 _ 6 = 'False IsDiv8 _ 7 = 'False #endif IsDiv8 _ 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) -- | ensure the given `bitlen` is divisible by 8 -- type IsDivisibleBy8 bitLen = IsDiv8 bitLen bitLen ~ 'True cryptonite-0.26/Crypto/Internal/Words.hs0000644000000000000000000000124213414232447016520 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.26/Crypto/Internal/WordArray.hs0000644000000000000000000001250113414232447017334 0ustar0000000000000000-- | -- Module : Crypto.Internal.WordArray -- 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 , array32FromAddrBE , allocArray32AndFreeze , 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 n l = unsafeDoIO (mutableArray32 n l >>= mutableArray32Freeze) {-# NOINLINE array32 #-} -- | Create an Array of BE Word32 aliasing an Addr array32FromAddrBE :: Int -> Addr# -> Array32 array32FromAddrBE n a = unsafeDoIO (mutableArray32FromAddrBE n a >>= mutableArray32Freeze) {-# NOINLINE array32FromAddrBE #-} -- | Create an Array of Word32 using an initializer allocArray32AndFreeze :: Int -> (MutableArray32 -> IO ()) -> Array32 allocArray32AndFreeze n f = unsafeDoIO (mutableArray32 n [] >>= \m -> f m >> mutableArray32Freeze m) {-# NOINLINE allocArray32AndFreeze #-} -- | 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.26/Crypto/Random/Entropy/RDRand.hs0000644000000000000000000000207013414232447017640 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.26/Crypto/Random/Entropy/Windows.hs0000644000000000000000000000604613414232447020167 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.26/Crypto/Random/Entropy/Unix.hs0000644000000000000000000000445113414232447017456 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 `E.finally` closeDev fd 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.26/cbits/cryptonite_chacha.c0000644000000000000000000002027313414232447016776 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.26/cbits/cryptonite_salsa.c0000644000000000000000000002065513414232447016676 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" #include "cryptonite_align.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 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] = load_le32_aligned(constants + 0); st->d[5] = load_le32_aligned(constants + 4); st->d[10] = load_le32_aligned(constants + 8); st->d[15] = load_le32_aligned(constants + 12); st->d[1] = load_le32(key + 0); st->d[2] = load_le32(key + 4); st->d[3] = load_le32(key + 8); st->d[4] = load_le32(key + 12); /* we repeat the key on 128 bits */ if (keylen == 32) key += 16; st->d[11] = load_le32(key + 0); st->d[12] = load_le32(key + 4); st->d[13] = load_le32(key + 8); st->d[14] = load_le32(key + 12); st->d[9] = 0; switch (ivlen) { case 8: st->d[6] = load_le32(iv + 0); st->d[7] = load_le32(iv + 4); st->d[8] = 0; break; case 12: st->d[6] = load_le32(iv + 0); st->d[7] = load_le32(iv + 4); st->d[8] = load_le32(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.26/cbits/cryptonite_xsalsa.c0000644000000000000000000000662013414232447017062 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_align.h" #include "cryptonite_bitfn.h" /* 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] = load_le32(iv + 8); ctx->st.d[ 9] = load_le32(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] = load_le32(iv + 16); ctx->st.d[ 7] = load_le32(iv + 20); ctx->st.d[ 8] = 0; ctx->st.d[ 9] = 0; } cryptonite-0.26/cbits/cryptonite_rc4.c0000644000000000000000000000260513414232447016256 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.26/cbits/cryptonite_cpu.c0000644000000000000000000000460313414232447016355 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.26/cbits/p256/p256.c0000644000000000000000000003376613470442731014513 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; } } /* "p256e" functions are not part of the original source */ #define MSB_COMPLEMENT(x) (((x) >> (P256_BITSPERDIGIT - 1)) - 1) // c = a + b mod MOD void cryptonite_p256e_modadd(const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, const cryptonite_p256_int* b, cryptonite_p256_int* c) { cryptonite_p256_digit top = cryptonite_p256_add(a, b, c); top = subM(MOD, top, P256_DIGITS(c), -1); top = subM(MOD, top, P256_DIGITS(c), MSB_COMPLEMENT(top)); addM(MOD, 0, P256_DIGITS(c), top); } // c = a - b mod MOD void cryptonite_p256e_modsub(const cryptonite_p256_int* MOD, const cryptonite_p256_int* a, const cryptonite_p256_int* b, cryptonite_p256_int* c) { cryptonite_p256_digit top = cryptonite_p256_sub(a, b, c); top = addM(MOD, top, P256_DIGITS(c), ~MSB_COMPLEMENT(top)); top = subM(MOD, top, P256_DIGITS(c), MSB_COMPLEMENT(top)); addM(MOD, 0, P256_DIGITS(c), top); } cryptonite-0.26/cbits/p256/p256_ec.c0000644000000000000000000014061713414232447015153 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); } /* this function is not part of the original source negate a point, i.e. (out_x, out_y) = (in_x, -in_y) */ void cryptonite_p256e_point_negate( const cryptonite_p256_int *in_x, const cryptonite_p256_int *in_y, cryptonite_p256_int *out_x, cryptonite_p256_int *out_y) { memcpy(out_x, in_x, P256_NBYTES); cryptonite_p256_sub(&cryptonite_SECP256r1_p, in_y, out_y); } cryptonite-0.26/cbits/cryptonite_blake2s.c0000644000000000000000000000060013414232447017102 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.26/cbits/cryptonite_blake2sp.c0000644000000000000000000000061213414232447017265 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.26/cbits/cryptonite_blake2b.c0000644000000000000000000000060013414232447017061 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.26/cbits/cryptonite_blake2bp.c0000644000000000000000000000061213414232447017244 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.26/cbits/cryptonite_poly1305.c0000644000000000000000000001600713414232447017063 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" #include "cryptonite_align.h" 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 += (load_le32(data+ 0) ) & 0x3ffffff; h1 += (load_le32(data+ 3) >> 2) & 0x3ffffff; h2 += (load_le32(data+ 6) >> 4) & 0x3ffffff; h3 += (load_le32(data+ 9) >> 6) & 0x3ffffff; h4 += (load_le32(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] = (load_le32(&k[ 0]) ) & 0x3ffffff; ctx->r[1] = (load_le32(&k[ 3]) >> 2) & 0x3ffff03; ctx->r[2] = (load_le32(&k[ 6]) >> 4) & 0x3ffc0ff; ctx->r[3] = (load_le32(&k[ 9]) >> 6) & 0x3f03fff; ctx->r[4] = (load_le32(&k[12]) >> 8) & 0x00fffff; ctx->pad[0] = load_le32(&k[16]); ctx->pad[1] = load_le32(&k[20]); ctx->pad[2] = load_le32(&k[24]); ctx->pad[3] = load_le32(&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.26/cbits/cryptonite_sha1.c0000644000000000000000000001524113414232447016422 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" #include "cryptonite_align.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; } if (need_alignment(data, 4)) { uint32_t tramp[16]; ASSERT_ALIGNMENT(tramp, 4); for (; len >= 64; len -= 64, data += 64) { memcpy(tramp, data, 64); sha1_do_chunk(ctx, tramp); } } else { /* 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; /* 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 */ 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]); } cryptonite-0.26/cbits/cryptonite_sha256.c0000644000000000000000000001365613414232447016606 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" #include "cryptonite_align.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; } if (need_alignment(data, 4)) { uint32_t tramp[16]; ASSERT_ALIGNMENT(tramp, 4); for (; len >= 64; len -= 64, data += 64) { memcpy(tramp, data, 64); sha256_do_chunk(ctx, tramp); } } else { /* 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; /* 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++) store_be32(out+4*i, ctx->h[i]); } cryptonite-0.26/cbits/cryptonite_sha512.c0000644000000000000000000002164313414232447016574 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_align.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; } if (need_alignment(data, 8)) { uint64_t tramp[16]; ASSERT_ALIGNMENT(tramp, 8); for (; len >= 128; len -= 128, data += 128) { memcpy(tramp, data, 128); sha512_do_chunk(ctx, tramp); } } else { /* 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]; /* 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++) store_be64(out+8*i, 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.26/cbits/cryptonite_sha3.c0000644000000000000000000001740013470442731016424 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 / cSHAKE context: hashlen is the security level * (and half the capacity) in bits. * * In case of cSHAKE, the message prefix with encoded N and S must be added with * cryptonite_sha3_update. */ 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 / cSHAKE 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); sha3_do_chunk(ctx->state, tramp, 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 / cSHAKE 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); } /* Finalize a cSHAKE context. Output is read using cryptonite_sha3_output. */ void cryptonite_sha3_finalize_cshake(struct sha3_ctx *ctx) { cryptonite_sha3_finalize_with_pad_byte(ctx, 0x04); } 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.26/cbits/cryptonite_md2.c0000644000000000000000000001174613414232447016256 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.26/cbits/cryptonite_md4.c0000644000000000000000000001202013414232447016242 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_align.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; } if (need_alignment(data, 4)) { uint32_t tramp[16]; ASSERT_ALIGNMENT(tramp, 4); for (; len >= 64; len -= 64, data += 64) { memcpy(tramp, data, 64); md4_do_chunk(ctx, tramp); } } else { /* 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 */ store_le32(out , ctx->h[0]); store_le32(out+ 4, ctx->h[1]); store_le32(out+ 8, ctx->h[2]); store_le32(out+12, ctx->h[3]); } cryptonite-0.26/cbits/cryptonite_md5.c0000644000000000000000000001373413414232447016260 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_align.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; } if (need_alignment(data, 4)) { uint32_t tramp[16]; ASSERT_ALIGNMENT(tramp, 4); for (; len >= 64; len -= 64, data += 64) { memcpy(tramp, data, 64); md5_do_chunk(ctx, tramp); } } else { /* 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; /* 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 */ store_le32(out , ctx->h[0]); store_le32(out+ 4, ctx->h[1]); store_le32(out+ 8, ctx->h[2]); store_le32(out+12, ctx->h[3]); } cryptonite-0.26/cbits/cryptonite_ripemd.c0000644000000000000000000002443413414232447017052 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 "cryptonite_align.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; } if (need_alignment(data, 4)) { uint32_t tramp[16]; ASSERT_ALIGNMENT(tramp, 4); for (; len >= 64; len -= 64, data += 64) { memcpy(tramp, data, 64); ripemd160_do_chunk(ctx, tramp); } } else { /* process as much 64-block as possible */ for (; len >= 64; len -= 64, data += 64) ripemd160_do_chunk(ctx, (uint32_t *) data); } /* append data into buf */ 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; /* 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 */ store_le32(out , ctx->h[0]); store_le32(out+ 4, ctx->h[1]); store_le32(out+ 8, ctx->h[2]); store_le32(out+12, ctx->h[3]); store_le32(out+16, ctx->h[4]); } cryptonite-0.26/cbits/cryptonite_skein256.c0000644000000000000000000001364213414232447017137 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" #include "cryptonite_align.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; } if (need_alignment(data, 8)) { uint64_t tramp[4]; ASSERT_ALIGNMENT(tramp, 8); for (; len > 32; len -= 32, data += 32) { memcpy(tramp, data, 32); skein256_do_chunk(ctx, tramp, 32); } } else { /* 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.26/cbits/cryptonite_skein512.c0000644000000000000000000001552313414232447017132 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" #include "cryptonite_align.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; } if (need_alignment(data, 8)) { uint64_t tramp[8]; ASSERT_ALIGNMENT(tramp, 8); for (; len > 64; len -= 64, data += 64) { memcpy(tramp, data, 64); skein512_do_chunk(ctx, tramp, 64); } } else { /* 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.26/cbits/cryptonite_tiger.c0000644000000000000000000006672513414232447016715 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" #include "cryptonite_align.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; } if (need_alignment(data, 8)) { uint64_t tramp[8]; ASSERT_ALIGNMENT(tramp, 8); for (; len >= 64; len -= 64, data += 64) { memcpy(tramp, data, 64); tiger_do_chunk(ctx, tramp); } } else { /* 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; /* 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 */ store_le64(out , ctx->h[0]); store_le64(out+ 8, ctx->h[1]); store_le64(out+16, ctx->h[2]); } cryptonite-0.26/cbits/cryptonite_whirlpool.c0000644000000000000000000016726313414232447017621 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.26/cbits/cryptonite_scrypt.c0000644000000000000000000000536313414232447017116 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_align.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; } 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] = load_le32_aligned(&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++) store_le32_aligned(&B[4*k], X[k]); } cryptonite-0.26/cbits/cryptonite_pbkdf2.c0000644000000000000000000004422513414232447016742 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.26/cbits/ed25519/ed25519.c0000644000000000000000000000661513414232447015307 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" #include "ed25519-cryptonite-exts.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.26/cbits/argon2/argon2.c0000644000000000000000000000772313414232447015674 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.26/cbits/decaf/p448/arch_ref64/f_impl.c0000644000000000000000000001704113414232447020240 0ustar0000000000000000/* Copyright (c) 2014 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ #include "f_field.h" void cryptonite_gf_mul (cryptonite_gf_s *__restrict__ cs, const gf as, const gf bs) { const uint64_t *a = as->limb, *b = bs->limb; uint64_t *c = cs->limb; __uint128_t accum0 = 0, accum1 = 0, accum2; uint64_t mask = (1ull<<56) - 1; uint64_t aa[4], bb[4], bbb[4]; unsigned int i; for (i=0; i<4; i++) { aa[i] = a[i] + a[i+4]; bb[i] = b[i] + b[i+4]; bbb[i] = bb[i] + b[i+4]; } int I_HATE_UNROLLED_LOOPS = 0; if (I_HATE_UNROLLED_LOOPS) { /* The compiler probably won't unroll this, * so it's like 80% slower. */ for (i=0; i<4; i++) { accum2 = 0; unsigned int j; for (j=0; j<=i; j++) { accum2 += widemul(a[j], b[i-j]); accum1 += widemul(aa[j], bb[i-j]); accum0 += widemul(a[j+4], b[i-j+4]); } for (; j<4; j++) { accum2 += widemul(a[j], b[i-j+8]); accum1 += widemul(aa[j], bbb[i-j+4]); accum0 += widemul(a[j+4], bb[i-j+4]); } accum1 -= accum2; accum0 += accum2; c[i] = ((uint64_t)(accum0)) & mask; c[i+4] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; } } else { accum2 = widemul(a[0], b[0]); accum1 += widemul(aa[0], bb[0]); accum0 += widemul(a[4], b[4]); accum2 += widemul(a[1], b[7]); accum1 += widemul(aa[1], bbb[3]); accum0 += widemul(a[5], bb[3]); accum2 += widemul(a[2], b[6]); accum1 += widemul(aa[2], bbb[2]); accum0 += widemul(a[6], bb[2]); accum2 += widemul(a[3], b[5]); accum1 += widemul(aa[3], bbb[1]); accum0 += widemul(a[7], bb[1]); accum1 -= accum2; accum0 += accum2; c[0] = ((uint64_t)(accum0)) & mask; c[4] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; accum2 = widemul(a[0], b[1]); accum1 += widemul(aa[0], bb[1]); accum0 += widemul(a[4], b[5]); accum2 += widemul(a[1], b[0]); accum1 += widemul(aa[1], bb[0]); accum0 += widemul(a[5], b[4]); accum2 += widemul(a[2], b[7]); accum1 += widemul(aa[2], bbb[3]); accum0 += widemul(a[6], bb[3]); accum2 += widemul(a[3], b[6]); accum1 += widemul(aa[3], bbb[2]); accum0 += widemul(a[7], bb[2]); accum1 -= accum2; accum0 += accum2; c[1] = ((uint64_t)(accum0)) & mask; c[5] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; accum2 = widemul(a[0], b[2]); accum1 += widemul(aa[0], bb[2]); accum0 += widemul(a[4], b[6]); accum2 += widemul(a[1], b[1]); accum1 += widemul(aa[1], bb[1]); accum0 += widemul(a[5], b[5]); accum2 += widemul(a[2], b[0]); accum1 += widemul(aa[2], bb[0]); accum0 += widemul(a[6], b[4]); accum2 += widemul(a[3], b[7]); accum1 += widemul(aa[3], bbb[3]); accum0 += widemul(a[7], bb[3]); accum1 -= accum2; accum0 += accum2; c[2] = ((uint64_t)(accum0)) & mask; c[6] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; accum2 = widemul(a[0], b[3]); accum1 += widemul(aa[0], bb[3]); accum0 += widemul(a[4], b[7]); accum2 += widemul(a[1], b[2]); accum1 += widemul(aa[1], bb[2]); accum0 += widemul(a[5], b[6]); accum2 += widemul(a[2], b[1]); accum1 += widemul(aa[2], bb[1]); accum0 += widemul(a[6], b[5]); accum2 += widemul(a[3], b[0]); accum1 += widemul(aa[3], bb[0]); accum0 += widemul(a[7], b[4]); accum1 -= accum2; accum0 += accum2; c[3] = ((uint64_t)(accum0)) & mask; c[7] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; } /* !I_HATE_UNROLLED_LOOPS */ accum0 += accum1; accum0 += c[4]; accum1 += c[0]; c[4] = ((uint64_t)(accum0)) & mask; c[0] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; c[5] += ((uint64_t)(accum0)); c[1] += ((uint64_t)(accum1)); } void cryptonite_gf_mulw_unsigned (cryptonite_gf_s *__restrict__ cs, const gf as, uint32_t b) { const uint64_t *a = as->limb; uint64_t *c = cs->limb; __uint128_t accum0 = 0, accum4 = 0; uint64_t mask = (1ull<<56) - 1; int i; for (i=0; i<4; i++) { accum0 += widemul(b, a[i]); accum4 += widemul(b, a[i+4]); c[i] = accum0 & mask; accum0 >>= 56; c[i+4] = accum4 & mask; accum4 >>= 56; } accum0 += accum4 + c[4]; c[4] = accum0 & mask; c[5] += accum0 >> 56; accum4 += c[0]; c[0] = accum4 & mask; c[1] += accum4 >> 56; } void cryptonite_gf_sqr (cryptonite_gf_s *__restrict__ cs, const gf as) { const uint64_t *a = as->limb; uint64_t *c = cs->limb; __uint128_t accum0 = 0, accum1 = 0, accum2; uint64_t mask = (1ull<<56) - 1; uint64_t aa[4]; /* For some reason clang doesn't vectorize this without prompting? */ unsigned int i; for (i=0; i<4; i++) { aa[i] = a[i] + a[i+4]; } accum2 = widemul(a[0],a[3]); accum0 = widemul(aa[0],aa[3]); accum1 = widemul(a[4],a[7]); accum2 += widemul(a[1], a[2]); accum0 += widemul(aa[1], aa[2]); accum1 += widemul(a[5], a[6]); accum0 -= accum2; accum1 += accum2; c[3] = ((uint64_t)(accum1))<<1 & mask; c[7] = ((uint64_t)(accum0))<<1 & mask; accum0 >>= 55; accum1 >>= 55; accum0 += widemul(2*aa[1],aa[3]); accum1 += widemul(2*a[5], a[7]); accum0 += widemul(aa[2], aa[2]); accum1 += accum0; accum0 -= widemul(2*a[1], a[3]); accum1 += widemul(a[6], a[6]); accum2 = widemul(a[0],a[0]); accum1 -= accum2; accum0 += accum2; accum0 -= widemul(a[2], a[2]); accum1 += widemul(aa[0], aa[0]); accum0 += widemul(a[4], a[4]); c[0] = ((uint64_t)(accum0)) & mask; c[4] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; accum2 = widemul(2*aa[2],aa[3]); accum0 -= widemul(2*a[2], a[3]); accum1 += widemul(2*a[6], a[7]); accum1 += accum2; accum0 += accum2; accum2 = widemul(2*a[0],a[1]); accum1 += widemul(2*aa[0], aa[1]); accum0 += widemul(2*a[4], a[5]); accum1 -= accum2; accum0 += accum2; c[1] = ((uint64_t)(accum0)) & mask; c[5] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; accum2 = widemul(aa[3],aa[3]); accum0 -= widemul(a[3], a[3]); accum1 += widemul(a[7], a[7]); accum1 += accum2; accum0 += accum2; accum2 = widemul(2*a[0],a[2]); accum1 += widemul(2*aa[0], aa[2]); accum0 += widemul(2*a[4], a[6]); accum2 += widemul(a[1], a[1]); accum1 += widemul(aa[1], aa[1]); accum0 += widemul(a[5], a[5]); accum1 -= accum2; accum0 += accum2; c[2] = ((uint64_t)(accum0)) & mask; c[6] = ((uint64_t)(accum1)) & mask; accum0 >>= 56; accum1 >>= 56; accum0 += c[3]; accum1 += c[7]; c[3] = ((uint64_t)(accum0)) & mask; c[7] = ((uint64_t)(accum1)) & mask; /* we could almost stop here, but it wouldn't be stable, so... */ accum0 >>= 56; accum1 >>= 56; c[4] += ((uint64_t)(accum0)) + ((uint64_t)(accum1)); c[0] += ((uint64_t)(accum1)); } cryptonite-0.26/cbits/decaf/p448/f_generic.c0000644000000000000000000001041213414232447016763 0ustar0000000000000000/** * @file p448/f_generic.c * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @brief Generic arithmetic which has to be compiled per field. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #include "field.h" static const gf MODULUS = {FIELD_LITERAL( 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff, 0xfffffffffffffe, 0xffffffffffffff, 0xffffffffffffff, 0xffffffffffffff )}; #if P_MOD_8 == 5 const gf SQRT_MINUS_ONE = {FIELD_LITERAL( /* NOPE */ )}; #endif /** Serialize to wire format. */ void cryptonite_gf_serialize (uint8_t serial[SER_BYTES], const gf x, int with_hibit) { gf red; cryptonite_gf_copy(red, x); cryptonite_gf_strong_reduce(red); if (!with_hibit) { assert(cryptonite_gf_hibit(red) == 0); } unsigned int j=0, fill=0; dword_t buffer = 0; UNROLL for (unsigned int i=0; i<(with_hibit ? X_SER_BYTES : SER_BYTES); i++) { if (fill < 8 && j < NLIMBS) { buffer |= ((dword_t)red->limb[LIMBPERM(j)]) << fill; fill += LIMB_PLACE_VALUE(LIMBPERM(j)); j++; } serial[i] = buffer; fill -= 8; buffer >>= 8; } } /** Return high bit of x = low bit of 2x mod p */ mask_t cryptonite_gf_hibit(const gf x) { gf y; cryptonite_gf_add(y,x,x); cryptonite_gf_strong_reduce(y); return -(y->limb[0]&1); } /** Deserialize from wire format; return -1 on success and 0 on failure. */ mask_t cryptonite_gf_deserialize (gf x, const uint8_t serial[SER_BYTES], int with_hibit) { unsigned int j=0, fill=0; dword_t buffer = 0; dsword_t scarry = 0; UNROLL for (unsigned int i=0; ilimb[LIMBPERM(i)] = (i>= LIMB_PLACE_VALUE(LIMBPERM(i)); scarry = (scarry + x->limb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]) >> (8*sizeof(word_t)); } mask_t succ = with_hibit ? -(mask_t)1 : ~cryptonite_gf_hibit(x); return succ & word_is_zero(buffer) & ~word_is_zero(scarry); } /** Reduce to canonical form. */ void cryptonite_gf_strong_reduce (gf a) { /* first, clear high */ cryptonite_gf_weak_reduce(a); /* Determined to have negligible perf impact. */ /* now the total is less than 2p */ /* compute total_value - p. No need to reduce mod p. */ dsword_t scarry = 0; for (unsigned int i=0; ilimb[LIMBPERM(i)] - MODULUS->limb[LIMBPERM(i)]; a->limb[LIMBPERM(i)] = scarry & LIMB_MASK(LIMBPERM(i)); scarry >>= LIMB_PLACE_VALUE(LIMBPERM(i)); } /* uncommon case: it was >= p, so now scarry = 0 and this = x * common case: it was < p, so now scarry = -1 and this = x - p + 2^255 * so let's add back in p. will carry back off the top for 2^255. */ assert(word_is_zero(scarry) | word_is_zero(scarry+1)); word_t scarry_0 = scarry; dword_t carry = 0; /* add it back */ for (unsigned int i=0; ilimb[LIMBPERM(i)] + (scarry_0 & MODULUS->limb[LIMBPERM(i)]); a->limb[LIMBPERM(i)] = carry & LIMB_MASK(LIMBPERM(i)); carry >>= LIMB_PLACE_VALUE(LIMBPERM(i)); } assert(word_is_zero(carry + scarry_0)); } /** Subtract two gf elements d=a-b */ void cryptonite_gf_sub (gf d, const gf a, const gf b) { cryptonite_gf_sub_RAW ( d, a, b ); cryptonite_gf_bias( d, 2 ); cryptonite_gf_weak_reduce ( d ); } /** Add two field elements d = a+b */ void cryptonite_gf_add (gf d, const gf a, const gf b) { cryptonite_gf_add_RAW ( d, a, b ); cryptonite_gf_weak_reduce ( d ); } /** Compare a==b */ mask_t cryptonite_gf_eq(const gf a, const gf b) { gf c; cryptonite_gf_sub(c,a,b); cryptonite_gf_strong_reduce(c); mask_t ret=0; for (unsigned int i=0; ilimb[LIMBPERM(i)]; } return word_is_zero(ret); } cryptonite-0.26/cbits/decaf/p448/f_arithmetic.c0000644000000000000000000000272313414232447017506 0ustar0000000000000000/** * @cond internal * @file f_arithmetic.c * @copyright * Copyright (c) 2014 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * @author Mike Hamburg * @brief Field-specific arithmetic. */ #include "field.h" mask_t cryptonite_gf_isr ( gf a, const gf x ) { gf L0, L1, L2; cryptonite_gf_sqr (L1, x ); cryptonite_gf_mul (L2, x, L1 ); cryptonite_gf_sqr (L1, L2 ); cryptonite_gf_mul (L2, x, L1 ); cryptonite_gf_sqrn (L1, L2, 3 ); cryptonite_gf_mul (L0, L2, L1 ); cryptonite_gf_sqrn (L1, L0, 3 ); cryptonite_gf_mul (L0, L2, L1 ); cryptonite_gf_sqrn (L2, L0, 9 ); cryptonite_gf_mul (L1, L0, L2 ); cryptonite_gf_sqr (L0, L1 ); cryptonite_gf_mul (L2, x, L0 ); cryptonite_gf_sqrn (L0, L2, 18 ); cryptonite_gf_mul (L2, L1, L0 ); cryptonite_gf_sqrn (L0, L2, 37 ); cryptonite_gf_mul (L1, L2, L0 ); cryptonite_gf_sqrn (L0, L1, 37 ); cryptonite_gf_mul (L1, L2, L0 ); cryptonite_gf_sqrn (L0, L1, 111 ); cryptonite_gf_mul (L2, L1, L0 ); cryptonite_gf_sqr (L0, L2 ); cryptonite_gf_mul (L1, x, L0 ); cryptonite_gf_sqrn (L0, L1, 223 ); cryptonite_gf_mul (L1, L2, L0 ); cryptonite_gf_sqr (L2, L1); cryptonite_gf_mul (L0, L2, x); cryptonite_gf_copy(a,L1); return cryptonite_gf_eq(L0,ONE); } cryptonite-0.26/cbits/decaf/utils.c0000644000000000000000000000217613414232447015513 0ustar0000000000000000/* Copyright (c) 2015 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ /** * @file utils.c * @author Mike Hamburg * @brief Decaf utility functions. */ #include void cryptonite_decaf_bzero ( void *s, size_t size ) { #ifdef __STDC_LIB_EXT1__ memset_s(s, size, 0, size); #else const size_t sw = sizeof(cryptonite_decaf_word_t); volatile uint8_t *destroy = (volatile uint8_t *)s; for (; size && ((uintptr_t)destroy)%sw; size--, destroy++) *destroy = 0; for (; size >= sw; size -= sw, destroy += sw) *(volatile cryptonite_decaf_word_t *)destroy = 0; for (; size; size--, destroy++) *destroy = 0; #endif } cryptonite_decaf_bool_t cryptonite_decaf_memeq ( const void *data1_, const void *data2_, size_t size ) { const unsigned char *data1 = (const unsigned char *)data1_; const unsigned char *data2 = (const unsigned char *)data2_; unsigned char ret = 0; for (; size; size--, data1++, data2++) { ret |= *data1 ^ *data2; } return (((cryptonite_decaf_dword_t)ret) - 1) >> 8; } cryptonite-0.26/cbits/decaf/ed448goldilocks/scalar.c0000644000000000000000000002242413414232447020521 0ustar0000000000000000/** * @file ed448goldilocks/scalar.c * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @brief Decaf high-level functions. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #include "word.h" #include "constant_time.h" #include /* Template stuff */ #define API_NS(_id) cryptonite_decaf_448_##_id #define SCALAR_BITS CRYPTONITE_DECAF_448_SCALAR_BITS #define SCALAR_SER_BYTES CRYPTONITE_DECAF_448_SCALAR_BYTES #define SCALAR_LIMBS CRYPTONITE_DECAF_448_SCALAR_LIMBS #define scalar_t API_NS(scalar_t) static const cryptonite_decaf_word_t MONTGOMERY_FACTOR = (cryptonite_decaf_word_t)0x3bd440fae918bc5ull; static const scalar_t sc_p = {{{ SC_LIMB(0x2378c292ab5844f3), SC_LIMB(0x216cc2728dc58f55), SC_LIMB(0xc44edb49aed63690), SC_LIMB(0xffffffff7cca23e9), SC_LIMB(0xffffffffffffffff), SC_LIMB(0xffffffffffffffff), SC_LIMB(0x3fffffffffffffff) }}}, sc_r2 = {{{ SC_LIMB(0xe3539257049b9b60), SC_LIMB(0x7af32c4bc1b195d9), SC_LIMB(0x0d66de2388ea1859), SC_LIMB(0xae17cf725ee4d838), SC_LIMB(0x1a9cc14ba3c47c44), SC_LIMB(0x2052bcb7e4d070af), SC_LIMB(0x3402a939f823b729) }}}; /* End of template stuff */ #define WBITS CRYPTONITE_DECAF_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */ const scalar_t API_NS(scalar_one) = {{{1}}}, API_NS(scalar_zero) = {{{0}}}; /** {extra,accum} - sub +? p * Must have extra <= 1 */ static CRYPTONITE_DECAF_NOINLINE void sc_subx( scalar_t out, const cryptonite_decaf_word_t accum[SCALAR_LIMBS], const scalar_t sub, const scalar_t p, cryptonite_decaf_word_t extra ) { cryptonite_decaf_dsword_t chain = 0; unsigned int i; for (i=0; ilimb[i]; out->limb[i] = chain; chain >>= WBITS; } cryptonite_decaf_word_t borrow = chain+extra; /* = 0 or -1 */ chain = 0; for (i=0; ilimb[i]) + (p->limb[i] & borrow); out->limb[i] = chain; chain >>= WBITS; } } static CRYPTONITE_DECAF_NOINLINE void sc_montmul ( scalar_t out, const scalar_t a, const scalar_t b ) { unsigned int i,j; cryptonite_decaf_word_t accum[SCALAR_LIMBS+1] = {0}; cryptonite_decaf_word_t hi_carry = 0; for (i=0; ilimb[i]; const cryptonite_decaf_word_t *mier = b->limb; cryptonite_decaf_dword_t chain = 0; for (j=0; j>= WBITS; } accum[j] = chain; mand = accum[0] * MONTGOMERY_FACTOR; chain = 0; mier = sc_p->limb; for (j=0; j>= WBITS; } chain += accum[j]; chain += hi_carry; accum[j-1] = chain; hi_carry = chain >> WBITS; } sc_subx(out, accum, sc_p, sc_p, hi_carry); } void API_NS(scalar_mul) ( scalar_t out, const scalar_t a, const scalar_t b ) { sc_montmul(out,a,b); sc_montmul(out,out,sc_r2); } /* PERF: could implement this */ static CRYPTONITE_DECAF_INLINE void sc_montsqr (scalar_t out, const scalar_t a) { sc_montmul(out,a,a); } cryptonite_decaf_error_t API_NS(scalar_invert) ( scalar_t out, const scalar_t a ) { /* Fermat's little theorem, sliding window. * Sliding window is fine here because the modulus isn't secret. */ const int SCALAR_WINDOW_BITS = 3; scalar_t precmp[1< 0) sc_montmul(precmp[LAST],precmp[0],precmp[0]); int i; for (i=1; i<=LAST; i++) { sc_montmul(precmp[i],precmp[i-1],precmp[LAST]); } /* Sliding window */ unsigned residue = 0, trailing = 0, started = 0; for (i=SCALAR_BITS-1; i>=-SCALAR_WINDOW_BITS; i--) { if (started) sc_montsqr(out,out); cryptonite_decaf_word_t w = (i>=0) ? sc_p->limb[i/WBITS] : 0; if (i >= 0 && i= 2); w-=2; } residue = (residue<<1) | ((w>>(i%WBITS))&1); if (residue>>SCALAR_WINDOW_BITS != 0) { assert(trailing == 0); trailing = residue; residue = 0; } if (trailing > 0 && (trailing & ((1<>(SCALAR_WINDOW_BITS+1)]); } else { API_NS(scalar_copy)(out,precmp[trailing>>(SCALAR_WINDOW_BITS+1)]); started = 1; } trailing = 0; } trailing <<= 1; } assert(residue==0); assert(trailing==0); /* Demontgomerize */ sc_montmul(out,out,API_NS(scalar_one)); cryptonite_decaf_bzero(precmp, sizeof(precmp)); return cryptonite_decaf_succeed_if(~API_NS(scalar_eq)(out,API_NS(scalar_zero))); } void API_NS(scalar_sub) ( scalar_t out, const scalar_t a, const scalar_t b ) { sc_subx(out, a->limb, b, sc_p, 0); } void API_NS(scalar_add) ( scalar_t out, const scalar_t a, const scalar_t b ) { cryptonite_decaf_dword_t chain = 0; unsigned int i; for (i=0; ilimb[i]) + b->limb[i]; out->limb[i] = chain; chain >>= WBITS; } sc_subx(out, out->limb, sc_p, sc_p, chain); } void API_NS(scalar_set_unsigned) ( scalar_t out, uint64_t w ) { memset(out,0,sizeof(scalar_t)); unsigned int i = 0; for (; ilimb[i] = w; #if CRYPTONITE_DECAF_WORD_BITS < 64 w >>= 8*sizeof(cryptonite_decaf_word_t); #endif } } cryptonite_decaf_bool_t API_NS(scalar_eq) ( const scalar_t a, const scalar_t b ) { cryptonite_decaf_word_t diff = 0; unsigned int i; for (i=0; ilimb[i] ^ b->limb[i]; } return mask_to_bool(word_is_zero(diff)); } static CRYPTONITE_DECAF_INLINE void scalar_decode_short ( scalar_t s, const unsigned char *ser, unsigned int nbytes ) { unsigned int i,j,k=0; for (i=0; ilimb[i] = out; } } cryptonite_decaf_error_t API_NS(scalar_decode)( scalar_t s, const unsigned char ser[SCALAR_SER_BYTES] ) { unsigned int i; scalar_decode_short(s, ser, SCALAR_SER_BYTES); cryptonite_decaf_dsword_t accum = 0; for (i=0; ilimb[i] - sc_p->limb[i]) >> WBITS; } /* Here accum == 0 or -1 */ API_NS(scalar_mul)(s,s,API_NS(scalar_one)); /* ham-handed reduce */ return cryptonite_decaf_succeed_if(~word_is_zero(accum)); } void API_NS(scalar_destroy) ( scalar_t scalar ) { cryptonite_decaf_bzero(scalar, sizeof(scalar_t)); } void API_NS(scalar_decode_long)( scalar_t s, const unsigned char *ser, size_t ser_len ) { if (ser_len == 0) { API_NS(scalar_copy)(s, API_NS(scalar_zero)); return; } size_t i; scalar_t t1, t2; i = ser_len - (ser_len%SCALAR_SER_BYTES); if (i==ser_len) i -= SCALAR_SER_BYTES; scalar_decode_short(t1, &ser[i], ser_len-i); if (ser_len == sizeof(scalar_t)) { assert(i==0); /* ham-handed reduce */ API_NS(scalar_mul)(s,t1,API_NS(scalar_one)); API_NS(scalar_destroy)(t1); return; } while (i) { i -= SCALAR_SER_BYTES; sc_montmul(t1,t1,sc_r2); ignore_result( API_NS(scalar_decode)(t2, ser+i) ); API_NS(scalar_add)(t1, t1, t2); } API_NS(scalar_copy)(s, t1); API_NS(scalar_destroy)(t1); API_NS(scalar_destroy)(t2); } void API_NS(scalar_encode)( unsigned char ser[SCALAR_SER_BYTES], const scalar_t s ) { unsigned int i,j,k=0; for (i=0; ilimb[i] >> (8*j); } } } void API_NS(scalar_cond_sel) ( scalar_t out, const scalar_t a, const scalar_t b, cryptonite_decaf_bool_t pick_b ) { constant_time_select(out,a,b,sizeof(scalar_t),bool_to_mask(pick_b),sizeof(out->limb[0])); } void API_NS(scalar_halve) ( scalar_t out, const scalar_t a ) { cryptonite_decaf_word_t mask = -(a->limb[0] & 1); cryptonite_decaf_dword_t chain = 0; unsigned int i; for (i=0; ilimb[i]) + (sc_p->limb[i] & mask); out->limb[i] = chain; chain >>= CRYPTONITE_DECAF_WORD_BITS; } for (i=0; ilimb[i] = out->limb[i]>>1 | out->limb[i+1]<<(WBITS-1); } out->limb[i] = out->limb[i]>>1 | chain<<(WBITS-1); } cryptonite-0.26/cbits/decaf/ed448goldilocks/decaf_all.c0000644000000000000000000000017513414232447021145 0ustar0000000000000000/* Combined to avoid link failure on OpenBSD with --strip-unneeded, see #186 */ #include "decaf.c" #include "decaf_tables.c" cryptonite-0.26/cbits/decaf/ed448goldilocks/eddsa.c0000644000000000000000000002705213414232447020336 0ustar0000000000000000/** * @file ed448goldilocks/eddsa.c * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @cond internal * @brief EdDSA routines. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #include "word.h" #include #include #include #include #define API_NAME "cryptonite_decaf_448" #define API_NS(_id) cryptonite_decaf_448_##_id #define hash_ctx_t cryptonite_decaf_shake256_ctx_t #define hash_init cryptonite_decaf_shake256_init #define hash_update cryptonite_decaf_shake256_update #define hash_final cryptonite_decaf_shake256_final #define hash_destroy cryptonite_decaf_shake256_destroy #define hash_hash cryptonite_decaf_shake256_hash #define NO_CONTEXT CRYPTONITE_DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS #define EDDSA_USE_SIGMA_ISOGENY 0 #define COFACTOR 4 #if NO_CONTEXT const uint8_t CRYPTONITE_NO_CONTEXT_POINTS_HERE = 0; const uint8_t * const CRYPTONITE_DECAF_ED448_NO_CONTEXT = &CRYPTONITE_NO_CONTEXT_POINTS_HERE; #endif /* EDDSA_BASE_POINT_RATIO = 1 or 2 * Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d, * its base point is twice ours. */ #define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) static void clamp ( uint8_t secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES] ) { /* Blarg */ secret_scalar_ser[0] &= -COFACTOR; uint8_t hibit = (1<<0)>>1; if (hibit == 0) { secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES - 1] = 0; secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES - 2] |= 0x80; } else { secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES - 1] &= hibit-1; secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES - 1] |= hibit; } } static void hash_init_with_dom( hash_ctx_t hash, uint8_t prehashed, uint8_t for_prehash, const uint8_t *context, uint8_t context_len ) { hash_init(hash); #if NO_CONTEXT if (context_len == 0 && context == CRYPTONITE_DECAF_ED448_NO_CONTEXT) { (void)prehashed; (void)for_prehash; (void)context; (void)context_len; return; } #endif const char *dom_s = "SigEd448"; const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len}; hash_update(hash,(const unsigned char *)dom_s, strlen(dom_s)); hash_update(hash,dom,2); hash_update(hash,context,context_len); } void cryptonite_decaf_ed448_prehash_init ( hash_ctx_t hash ) { hash_init(hash); } /* In this file because it uses the hash */ void cryptonite_decaf_ed448_convert_private_key_to_x448 ( uint8_t x[CRYPTONITE_DECAF_X448_PRIVATE_BYTES], const uint8_t ed[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES] ) { /* pass the private key through hash_hash function */ /* and keep the first CRYPTONITE_DECAF_X448_PRIVATE_BYTES bytes */ hash_hash( x, CRYPTONITE_DECAF_X448_PRIVATE_BYTES, ed, CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES ); } void cryptonite_decaf_ed448_derive_public_key ( uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const uint8_t privkey[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES] ) { /* only this much used for keygen */ uint8_t secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES]; hash_hash( secret_scalar_ser, sizeof(secret_scalar_ser), privkey, CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES ); clamp(secret_scalar_ser); API_NS(scalar_t) secret_scalar; API_NS(scalar_decode_long)(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser)); /* Since we are going to mul_by_cofactor during encoding, divide by it here. * However, the EdDSA base point is not the same as the decaf base point if * the sigma isogeny is in use: the EdDSA base point is on Etwist_d/(1-d) and * the decaf base point is on Etwist_d, and when converted it effectively * picks up a factor of 2 from the isogenies. So we might start at 2 instead of 1. */ for (unsigned int c = EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) { API_NS(scalar_halve)(secret_scalar,secret_scalar); } API_NS(point_t) p; API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar); API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(pubkey, p); /* Cleanup */ API_NS(scalar_destroy)(secret_scalar); API_NS(point_destroy)(p); cryptonite_decaf_bzero(secret_scalar_ser, sizeof(secret_scalar_ser)); } void cryptonite_decaf_ed448_sign ( uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, uint8_t context_len ) { API_NS(scalar_t) secret_scalar; hash_ctx_t hash; { /* Schedule the secret key */ struct { uint8_t secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES]; uint8_t seed[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES]; } __attribute__((packed)) expanded; hash_hash( (uint8_t *)&expanded, sizeof(expanded), privkey, CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES ); clamp(expanded.secret_scalar_ser); API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser)); /* Hash to create the nonce */ hash_init_with_dom(hash,prehashed,0,context,context_len); hash_update(hash,expanded.seed,sizeof(expanded.seed)); hash_update(hash,message,message_len); cryptonite_decaf_bzero(&expanded, sizeof(expanded)); } /* Decode the nonce */ API_NS(scalar_t) nonce_scalar; { uint8_t nonce[2*CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES]; hash_final(hash,nonce,sizeof(nonce)); API_NS(scalar_decode_long)(nonce_scalar, nonce, sizeof(nonce)); cryptonite_decaf_bzero(nonce, sizeof(nonce)); } uint8_t nonce_point[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES] = {0}; { /* Scalarmul to create the nonce-point */ API_NS(scalar_t) nonce_scalar_2; API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar); for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) { API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2); } API_NS(point_t) p; API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2); API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p); API_NS(point_destroy)(p); API_NS(scalar_destroy)(nonce_scalar_2); } API_NS(scalar_t) challenge_scalar; { /* Compute the challenge */ hash_init_with_dom(hash,prehashed,0,context,context_len); hash_update(hash,nonce_point,sizeof(nonce_point)); hash_update(hash,pubkey,CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES); hash_update(hash,message,message_len); uint8_t challenge[2*CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES]; hash_final(hash,challenge,sizeof(challenge)); hash_destroy(hash); API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); cryptonite_decaf_bzero(challenge,sizeof(challenge)); } API_NS(scalar_mul)(challenge_scalar,challenge_scalar,secret_scalar); API_NS(scalar_add)(challenge_scalar,challenge_scalar,nonce_scalar); cryptonite_decaf_bzero(signature,CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES); memcpy(signature,nonce_point,sizeof(nonce_point)); API_NS(scalar_encode)(&signature[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES],challenge_scalar); API_NS(scalar_destroy)(secret_scalar); API_NS(scalar_destroy)(nonce_scalar); API_NS(scalar_destroy)(challenge_scalar); } void cryptonite_decaf_ed448_sign_prehash ( uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const cryptonite_decaf_ed448_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len ) { uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */ { cryptonite_decaf_ed448_prehash_ctx_t hash_too; memcpy(hash_too,hash,sizeof(hash_too)); hash_final(hash_too,hash_output,sizeof(hash_output)); hash_destroy(hash_too); } cryptonite_decaf_ed448_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len); cryptonite_decaf_bzero(hash_output,sizeof(hash_output)); } cryptonite_decaf_error_t cryptonite_decaf_ed448_verify ( const uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, uint8_t context_len ) { API_NS(point_t) pk_point, r_point; cryptonite_decaf_error_t error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(pk_point,pubkey); if (CRYPTONITE_DECAF_SUCCESS != error) { return error; } error = API_NS(point_decode_like_eddsa_and_ignore_cofactor)(r_point,signature); if (CRYPTONITE_DECAF_SUCCESS != error) { return error; } API_NS(scalar_t) challenge_scalar; { /* Compute the challenge */ hash_ctx_t hash; hash_init_with_dom(hash,prehashed,0,context,context_len); hash_update(hash,signature,CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES); hash_update(hash,pubkey,CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES); hash_update(hash,message,message_len); uint8_t challenge[2*CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES]; hash_final(hash,challenge,sizeof(challenge)); hash_destroy(hash); API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge)); cryptonite_decaf_bzero(challenge,sizeof(challenge)); } API_NS(scalar_sub)(challenge_scalar, API_NS(scalar_zero), challenge_scalar); API_NS(scalar_t) response_scalar; API_NS(scalar_decode_long)( response_scalar, &signature[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES ); #if EDDSA_BASE_POINT_RATIO == 2 API_NS(scalar_add)(response_scalar,response_scalar,response_scalar); #endif /* pk_point = -c(x(P)) + (cx + k)G = kG */ API_NS(base_double_scalarmul_non_secret)( pk_point, response_scalar, pk_point, challenge_scalar ); return cryptonite_decaf_succeed_if(API_NS(point_eq(pk_point,r_point))); } cryptonite_decaf_error_t cryptonite_decaf_ed448_verify_prehash ( const uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const cryptonite_decaf_ed448_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len ) { cryptonite_decaf_error_t ret; uint8_t hash_output[64]; /* MAGIC but true for all existing schemes */ { cryptonite_decaf_ed448_prehash_ctx_t hash_too; memcpy(hash_too,hash,sizeof(hash_too)); hash_final(hash_too,hash_output,sizeof(hash_output)); hash_destroy(hash_too); } ret = cryptonite_decaf_ed448_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len); return ret; } cryptonite-0.26/cbits/decaf/p448/arch_32/f_impl.c0000644000000000000000000000515013414232447017534 0ustar0000000000000000/* Copyright (c) 2014 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ #include "f_field.h" #if (defined(__OPTIMIZE__) && !defined(__OPTIMIZE_SIZE__) && !I_HATE_UNROLLED_LOOPS) \ || defined(CRYPTONITE_DECAF_FORCE_UNROLL) #define REPEAT8(_x) _x _x _x _x _x _x _x _x #define FOR_LIMB(_i,_start,_end,_x) do { _i=_start; REPEAT8( if (_i<_end) { _x; } _i++;) } while (0) #else #define FOR_LIMB(_i,_start,_end,_x) do { for (_i=_start; _i<_end; _i++) _x; } while (0) #endif void cryptonite_gf_mul (cryptonite_gf_s *__restrict__ cs, const gf as, const gf bs) { const uint32_t *a = as->limb, *b = bs->limb; uint32_t *c = cs->limb; uint64_t accum0 = 0, accum1 = 0, accum2 = 0; uint32_t mask = (1<<28) - 1; uint32_t aa[8], bb[8]; int i,j; for (i=0; i<8; i++) { aa[i] = a[i] + a[i+8]; bb[i] = b[i] + b[i+8]; } FOR_LIMB(j,0,8,{ accum2 = 0; FOR_LIMB (i,0,j+1,{ accum2 += widemul(a[j-i],b[i]); accum1 += widemul(aa[j-i],bb[i]); accum0 += widemul(a[8+j-i], b[8+i]); }); accum1 -= accum2; accum0 += accum2; accum2 = 0; FOR_LIMB (i,j+1,8,{ accum0 -= widemul(a[8+j-i], b[i]); accum2 += widemul(aa[8+j-i], bb[i]); accum1 += widemul(a[16+j-i], b[8+i]); }); accum1 += accum2; accum0 += accum2; c[j] = ((uint32_t)(accum0)) & mask; c[j+8] = ((uint32_t)(accum1)) & mask; accum0 >>= 28; accum1 >>= 28; }); accum0 += accum1; accum0 += c[8]; accum1 += c[0]; c[8] = ((uint32_t)(accum0)) & mask; c[0] = ((uint32_t)(accum1)) & mask; accum0 >>= 28; accum1 >>= 28; c[9] += ((uint32_t)(accum0)); c[1] += ((uint32_t)(accum1)); } void cryptonite_gf_mulw_unsigned (cryptonite_gf_s *__restrict__ cs, const gf as, uint32_t b) { assert(b<1<<28); const uint32_t *a = as->limb; uint32_t *c = cs->limb; uint64_t accum0 = 0, accum8 = 0; uint32_t mask = (1ull<<28)-1; int i; FOR_LIMB(i,0,8,{ accum0 += widemul(b, a[i]); accum8 += widemul(b, a[i+8]); c[i] = accum0 & mask; accum0 >>= 28; c[i+8] = accum8 & mask; accum8 >>= 28; }); accum0 += accum8 + c[8]; c[8] = accum0 & mask; c[9] += accum0 >> 28; accum8 += c[0]; c[0] = accum8 & mask; c[1] += accum8 >> 28; } void cryptonite_gf_sqr (cryptonite_gf_s *__restrict__ cs, const gf as) { cryptonite_gf_mul(cs,as,as); /* Performs better with a dedicated square */ } cryptonite-0.26/cbits/curve25519/curve25519-donna-c64.c0000644000000000000000000003227113414232447020263 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.26/cbits/curve25519/curve25519-donna.c0000644000000000000000000007573613414232447017706 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.26/cbits/cryptonite_rdrand.c0000644000000000000000000000771713414232447017051 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.26/cbits/aes/x86ni.c0000644000000000000000000003155713470442731015043 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 #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 __m128i gfmul_generic(__m128i tag, __m128i h) { aes_block _t, _h; _mm_store_si128((__m128i *) &_t, tag); _mm_store_si128((__m128i *) &_h, h); cryptonite_aes_generic_gf_mul(&_t, &_h); tag = _mm_load_si128((__m128i *) &_t); return tag; } #ifdef WITH_PCLMUL __m128i (*gfmul_branch_ptr)(__m128i a, __m128i b) = gfmul_generic; #define gfmul(a,b) ((*gfmul_branch_ptr)(a,b)) /* See Intel carry-less-multiplication-instruction-in-gcm-mode-paper.pdf * * Adapted from figure 5, with additional byte swapping so that interface * is simimar to cryptonite_aes_generic_gf_mul. */ static __m128i gfmul_pclmuldq(__m128i a, __m128i b) { __m128i tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; __m128i bswap_mask = _mm_set_epi8(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); a = _mm_shuffle_epi8(a, bswap_mask); b = _mm_shuffle_epi8(b, bswap_mask); tmp3 = _mm_clmulepi64_si128(a, b, 0x00); tmp4 = _mm_clmulepi64_si128(a, b, 0x10); tmp5 = _mm_clmulepi64_si128(a, b, 0x01); tmp6 = _mm_clmulepi64_si128(a, b, 0x11); tmp4 = _mm_xor_si128(tmp4, tmp5); tmp5 = _mm_slli_si128(tmp4, 8); tmp4 = _mm_srli_si128(tmp4, 8); tmp3 = _mm_xor_si128(tmp3, tmp5); tmp6 = _mm_xor_si128(tmp6, tmp4); tmp7 = _mm_srli_epi32(tmp3, 31); tmp8 = _mm_srli_epi32(tmp6, 31); tmp3 = _mm_slli_epi32(tmp3, 1); tmp6 = _mm_slli_epi32(tmp6, 1); tmp9 = _mm_srli_si128(tmp7, 12); tmp8 = _mm_slli_si128(tmp8, 4); tmp7 = _mm_slli_si128(tmp7, 4); tmp3 = _mm_or_si128(tmp3, tmp7); tmp6 = _mm_or_si128(tmp6, tmp8); tmp6 = _mm_or_si128(tmp6, tmp9); tmp7 = _mm_slli_epi32(tmp3, 31); tmp8 = _mm_slli_epi32(tmp3, 30); tmp9 = _mm_slli_epi32(tmp3, 25); tmp7 = _mm_xor_si128(tmp7, tmp8); tmp7 = _mm_xor_si128(tmp7, tmp9); tmp8 = _mm_srli_si128(tmp7, 4); tmp7 = _mm_slli_si128(tmp7, 12); tmp3 = _mm_xor_si128(tmp3, tmp7); tmp2 = _mm_srli_epi32(tmp3, 1); tmp4 = _mm_srli_epi32(tmp3, 2); tmp5 = _mm_srli_epi32(tmp3, 7); tmp2 = _mm_xor_si128(tmp2, tmp4); tmp2 = _mm_xor_si128(tmp2, tmp5); tmp2 = _mm_xor_si128(tmp2, tmp8); tmp3 = _mm_xor_si128(tmp3, tmp2); tmp6 = _mm_xor_si128(tmp6, tmp3); return _mm_shuffle_epi8(tmp6, bswap_mask); } void cryptonite_aesni_gf_mul(block128 *a, block128 *b) { __m128i _a, _b, _c; _a = _mm_loadu_si128((__m128i *) a); _b = _mm_loadu_si128((__m128i *) b); _c = gfmul_pclmuldq(_a, _b); _mm_storeu_si128((__m128i *) a, _c); } void cryptonite_aesni_init_pclmul() { gfmul_branch_ptr = gfmul_pclmuldq; } #else #define gfmul(a,b) (gfmul_generic(a,b)) #endif static inline __m128i ghash_add(__m128i tag, __m128i h, __m128i m) { tag = _mm_xor_si128(tag, m); return gfmul(tag, h); } #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.26/cbits/aes/generic.c0000644000000000000000000005037213414232447015476 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; uint32_t rk[4]; uint8_t *rkptr = (uint8_t *) rk; create_round_key(key->data, rkptr); add_round_key(state, rkptr); for (i = 1; i < key->nbr; i++) { create_round_key(key->data + 16 * i, rkptr); shift_rows(state); mix_columns(state); add_round_key(state, rkptr); } create_round_key(key->data + 16 * key->nbr, rkptr); shift_rows(state); add_round_key(state, rkptr); } 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; uint32_t rk[4]; uint8_t *rkptr = (uint8_t *) rk; create_round_key(key->data + 16 * key->nbr, rkptr); add_round_key(state, rkptr); for (i = key->nbr - 1; i > 0; i--) { create_round_key(key->data + 16 * i, rkptr); shift_rows_inv(state); add_round_key(state, rkptr); mix_columns_inv(state); } create_round_key(key->data, rkptr); shift_rows_inv(state); add_round_key(state, rkptr); } /* 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) { uint32_t block[4]; uint8_t *iptr, *optr, *bptr; iptr = (uint8_t *) input; optr = (uint8_t *) output; bptr = (uint8_t *) block; swap_block(bptr, iptr); aes_main(key, bptr); swap_block(optr, bptr); } void cryptonite_aes_generic_decrypt_block(aes_block *output, aes_key *key, aes_block *input) { uint32_t block[4]; uint8_t *iptr, *optr, *bptr; iptr = (uint8_t *) input; optr = (uint8_t *) output; bptr = (uint8_t *) block; swap_block(bptr, iptr); aes_main_inv(key, bptr); swap_block(optr, bptr); } 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.26/cbits/aes/gf.c0000644000000000000000000000520213470442731014447 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_aes_generic_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_aes_generic_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.26/cbits/cryptonite_aes.c0000644000000000000000000010302313470442731016333 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); void cryptonite_aes_generic_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_generic_ccm_decrypt(uint8_t *output, aes_ccm *ccm, 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, /* ccm */ ENCRYPT_CCM_128, ENCRYPT_CCM_192, ENCRYPT_CCM_256, DECRYPT_CCM_128, DECRYPT_CCM_192, DECRYPT_CCM_256, /* ghash */ GHASH_GF_MUL, }; 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, /* CCM */ [ENCRYPT_CCM_128] = cryptonite_aes_generic_ccm_encrypt, [ENCRYPT_CCM_192] = cryptonite_aes_generic_ccm_encrypt, [ENCRYPT_CCM_256] = cryptonite_aes_generic_ccm_encrypt, [DECRYPT_CCM_128] = cryptonite_aes_generic_ccm_decrypt, [DECRYPT_CCM_192] = cryptonite_aes_generic_ccm_decrypt, [DECRYPT_CCM_256] = cryptonite_aes_generic_ccm_decrypt, /* GHASH */ [GHASH_GF_MUL] = cryptonite_aes_generic_gf_mul, }; 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 (*ccm_crypt_f)(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length); typedef void (*block_f)(aes_block *output, aes_key *key, aes_block *input); typedef void (*gf_mul_f)(aes_block *a, aes_block *b); #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 GET_CCM_ENCRYPT(strength) \ ((ccm_crypt_f) (cryptonite_aes_branch_table[ENCRYPT_CCM_128 + strength])) #define GET_CCM_DECRYPT(strength) \ ((ccm_crypt_f) (cryptonite_aes_branch_table[DECRYPT_CCM_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)) #define cryptonite_gf_mul(a,b) \ (((gf_mul_f) (cryptonite_aes_branch_table[GHASH_GF_MUL]))(a,b)) #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 GET_CCM_ENCRYPT(strength) cryptonite_aes_generic_ccm_encrypt #define GET_CCM_DECRYPT(strength) cryptonite_aes_generic_ccm_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) #define cryptonite_gf_mul(a,b) cryptonite_aes_generic_gf_mul(a,b) #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; */ #ifdef WITH_PCLMUL if (!pclmul) return; /* GHASH */ cryptonite_aes_branch_table[GHASH_GF_MUL] = cryptonite_aesni_gf_mul; cryptonite_aesni_init_pclmul(); #endif } #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_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length) { ccm_crypt_f e = GET_CCM_ENCRYPT(key->strength); e(output, ccm, key, input, length); } void cryptonite_aes_ccm_decrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length) { ccm_crypt_f d = GET_CCM_DECRYPT(key->strength); d(output, ccm, 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_aligned(&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_aligned(&gcm->tag, &lblock); for (i = 0; i < 16; i++) { tag[i] = gcm->tag.b[i]; } } static inline uint8_t ccm_b0_flags(uint32_t has_adata, uint32_t m, uint32_t l) { return 8*m + l + (has_adata? 64: 0); } /* depends on input size */ static void ccm_encode_b0(block128* output, aes_ccm* ccm, uint32_t has_adata) { int last = 15; uint32_t m = ccm->length_M; uint32_t l = ccm->length_L; uint32_t msg_len = ccm->length_input; block128_zero(output); block128_copy_aligned(output, &ccm->nonce); output->b[0] = ccm_b0_flags(has_adata, (m-2)/2, l-1); while (msg_len > 0) { output->b[last--] = msg_len & 0xff; msg_len >>= 8; } } /* encode adata length */ static int ccm_encode_la(block128* output, uint32_t la) { if (la < ( (1 << 16) - (1 << 8)) ) { output->b[0] = (la >> 8) & 0xff; output->b[1] = la & 0xff; return 2; } else { output->b[0] = 0xff; output->b[1] = 0xfe; output->b[2] = (la >> 24) & 0xff; output->b[3] = (la >> 16) & 0xff; output->b[4] = (la >> 8) & 0xff; output->b[5] = la & 0xff; return 6; } } static void ccm_encode_ctr(block128* out, aes_ccm* ccm, unsigned int cnt) { int last = 15; block128_copy_aligned(out, &ccm->nonce); out->b[0] = ccm->length_L - 1; while (cnt > 0) { out->b[last--] = cnt & 0xff; cnt >>= 8; } } static void ccm_cbcmac_add(aes_ccm* ccm, aes_key* key, block128* bi) { block128_xor_aligned(&ccm->xi, bi); cryptonite_aes_generic_encrypt_block(&ccm->xi, key, &ccm->xi); } /* even though it is possible to support message size as large as 2^64, we support up to 2^32 only */ void cryptonite_aes_ccm_init(aes_ccm *ccm, aes_key *key, uint8_t *nonce, uint32_t nonce_len, uint32_t input_size, int m, int l) { memset(ccm, 0, sizeof(aes_ccm)); if (l < 2 || l > 4) return; if (m != 4 && m != 6 && m != 8 && m != 10 && m != 12 && m != 14 && m != 16) return; if (nonce_len > 15 - l) { nonce_len = 15 - l; } if (l <= 4) { if (input_size >= (1ull << (8*l))) return; } ccm->length_L = l; ccm->length_M = m; ccm->length_input = input_size; memcpy(&ccm->nonce.b[1], nonce, nonce_len); ccm_encode_b0(&ccm->b0, ccm, 1); /* assume aad is present */ cryptonite_aes_encrypt_block(&ccm->xi, key, &ccm->b0); } /* even though l(a) can be as large as 2^64, we only handle aad up to 2 ^ 32 for practical reasons. Also we don't support incremental aad add, because the 1st encoded adata has length information */ void cryptonite_aes_ccm_aad(aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length) { block128 tmp; if (ccm->length_aad != 0) return; ccm->length_aad = length; int len_len; block128_zero(&tmp); len_len = ccm_encode_la(&tmp, length); if (length < 16 - len_len) { memcpy(&tmp.b[len_len], input, length); length = 0; } else { memcpy(&tmp.b[len_len], input, 16 - len_len); input += 16 - len_len; length -= 16 - len_len; } ccm_cbcmac_add(ccm, key, &tmp); for (; length >= 16; input += 16, length -= 16) { block128_copy(&tmp, (block128*)input); ccm_cbcmac_add(ccm, key, &tmp); } if (length > 0) { block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); ccm_cbcmac_add(ccm, key, &tmp); } block128_copy_aligned(&ccm->header_cbcmac, &ccm->xi); } void cryptonite_aes_ccm_finish(uint8_t *tag, aes_ccm *ccm, aes_key *key) { block128 iv, s0; block128_zero(&iv); ccm_encode_ctr(&iv, ccm, 0); cryptonite_aes_encrypt_block(&s0, key, &iv); block128_vxor((block128*)tag, &ccm->xi, &s0); } 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_aligned(&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_aligned(&ocb->offset_aad, &tmp); block128_vxor(&tmp, &ocb->offset_aad, (block128 *) input); cryptonite_aes_encrypt_block(&tmp, key, &tmp); block128_xor_aligned(&ocb->sum_aad, &tmp); } length = length % 16; /* Bytes in final block */ if (length > 0) { block128_xor_aligned(&ocb->offset_aad, &ocb->lstar); block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); tmp.b[length] = 0x80; block128_xor_aligned(&tmp, &ocb->offset_aad); cryptonite_aes_encrypt_block(&tmp, key, &tmp); block128_xor_aligned(&ocb->sum_aad, &tmp); } } void cryptonite_aes_ocb_finish(uint8_t *tag, aes_ocb *ocb, aes_key *key) { block128 tmp; block128_vxor_aligned(&tmp, &ocb->sum_enc, &ocb->offset_enc); block128_xor_aligned(&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_aes_generic_gf_mulx(&tweak); for ( ; nb_blocks-- > 0; input++, output++, cryptonite_aes_generic_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_aes_generic_gf_mulx(&tweak); for ( ; nb_blocks-- > 0; input++, output++, cryptonite_aes_generic_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_aligned(&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_aligned(&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_aligned(&ocb->sum_enc, &tmp); block128_xor_aligned(&pad, &tmp); memcpy(output, pad.b, length); output += length; } else { block128_copy_aligned(&tmp, &pad); block128_copy_bytes(&tmp, input, length); block128_xor_aligned(&tmp, &pad); tmp.b[length] = 0x80; memcpy(output, tmp.b, length); block128_xor_aligned(&ocb->sum_enc, &tmp); input += length; } } } void cryptonite_aes_generic_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length) { block128 tmp, ctr; /* when aad is absent, reset b0 block */ if (ccm->length_aad == 0) { ccm_encode_b0(&ccm->b0, ccm, 0); /* assume aad is present */ cryptonite_aes_encrypt_block(&ccm->xi, key, &ccm->b0); block128_copy_aligned(&ccm->header_cbcmac, &ccm->xi); } if (length != ccm->length_input) { return; } ccm_encode_ctr(&ctr, ccm, 1); cryptonite_aes_encrypt_ctr(output, key, &ctr, input, length); for (;length >= 16; input += 16, length -= 16) { block128_copy(&tmp, (block128*)input); ccm_cbcmac_add(ccm, key, &tmp); } if (length > 0) { block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); ccm_cbcmac_add(ccm, key, &tmp); } } void cryptonite_aes_generic_ccm_decrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length) { block128 tmp, ctr; if (length != ccm->length_input) { return; } /* when aad is absent, reset b0 block */ if (ccm->length_aad == 0) { ccm_encode_b0(&ccm->b0, ccm, 0); /* assume aad is present */ cryptonite_aes_encrypt_block(&ccm->xi, key, &ccm->b0); block128_copy_aligned(&ccm->header_cbcmac, &ccm->xi); } ccm_encode_ctr(&ctr, ccm, 1); cryptonite_aes_encrypt_ctr(output, key, &ctr, input, length); block128_copy_aligned(&ccm->xi, &ccm->header_cbcmac); input = output; for (;length >= 16; input += 16, length -= 16) { block128_copy(&tmp, (block128*)input); ccm_cbcmac_add(ccm, key, &tmp); } if (length > 0) { block128_zero(&tmp); block128_copy_bytes(&tmp, input, length); ccm_cbcmac_add(ccm, key, &tmp); } } 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.26/cbits/blake2/sse/blake2s.c0000644000000000000000000002343113414232447016563 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.26/cbits/blake2/sse/blake2sp.c0000644000000000000000000002200313414232447016735 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.26/cbits/blake2/sse/blake2b.c0000644000000000000000000002421713414232447016545 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.26/cbits/blake2/sse/blake2bp.c0000644000000000000000000002222413414232447016721 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.26/cbits/blake2/ref/blake2s-ref.c0000644000000000000000000002270513470442731017323 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.26/cbits/blake2/ref/blake2sp-ref.c0000644000000000000000000002210613414232447017475 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.26/cbits/blake2/ref/blake2b-ref.c0000644000000000000000000002351113414232447017275 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.26/cbits/blake2/ref/blake2bp-ref.c0000644000000000000000000002232513414232447017457 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.26/tests/Tests.hs0000644000000000000000000000434713470442731014644 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Main where import Imports import qualified Number import qualified Number.F2m import qualified BCrypt import qualified BCryptPBKDF import qualified ECC import qualified ECC.Edwards25519 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_KMAC 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_Ed448 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_CAST5 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_KMAC.tests ] , KAT_Curve25519.tests , KAT_Curve448.tests , KAT_Ed25519.tests , KAT_Ed448.tests , KAT_PubKey.tests , KAT_OTP.tests , testGroup "KDF" [ KAT_PBKDF2.tests , KAT_Scrypt.tests , BCrypt.tests , BCryptPBKDF.tests , KAT_HKDF.tests , KAT_Argon2.tests ] , testGroup "block-cipher" [ KAT_AES.tests , KAT_Blowfish.tests , KAT_CAST5.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 , ECC.tests , ECC.Edwards25519.tests ] main = defaultMain tests cryptonite-0.26/tests/BlockCipher.hs0000644000000000000000000004772513414232447015735 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, length) import qualified Data.ByteString as B hiding (all, take, replicate) ------------------------------------------------------------------------ -- 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 = cipherInitNoErr (cipherMakeKey cipher $ xtsKey1 d) ctx2 = cipherInitNoErr (cipherMakeKey cipher $ xtsKey2 d) ctx = (ctx1, ctx2) iv = cipherMakeIV cipher $ xtsIV d -} makeAEADTest i d = [ testCase ("AE" ++ i) (etag @?= AuthTag (B.convert (aeadTag d))) , testCase ("AD" ++ i) (dtag @?= AuthTag (B.convert (aeadTag d))) , testCase ("E" ++ i) (ebs @?= aeadCiphertext d) , testCase ("D" ++ i) (dbs @?= aeadPlaintext d) ] where ctx = cipherInitNoErr (cipherMakeKey cipher $ aeadKey d) aead = aeadInitNoErr (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) aeadInitNoErr :: (ByteArrayAccess iv, BlockCipher cipher) => AEADMode -> cipher -> iv -> AEAD cipher aeadInitNoErr mode ct iv = case aeadInit mode ct iv of CryptoPassed a -> a CryptoFailed _ -> error $ "cipher doesn't support aead mode: " ++ show mode ------------------------------------------------------------------------ -- 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 0 CCM_M16 CCM_L2)) , 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 iv' 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) where (mode', iv') = updateCcmInputSize mode (B.length plaintext) testIV updateCcmInputSize aeadmode k iv = case aeadmode of AEAD_CCM _ m l -> (AEAD_CCM k m l, B.take 13 (iv <> (B.replicate 15 0))) aeadOther -> (aeadOther, iv) 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) ] -- | Test IV arithmetic (based on the cipher block size) testIvArith :: BlockCipher a => a -> [TestTree] testIvArith cipher = [ testCase "nullIV is null" $ True @=? B.all (== 0) (ivNull cipher) , testProperty "ivAdd is linear" $ \a b -> do iv <- generateIvFromCipher cipher return $ ivAdd iv (a + b) `propertyEq` ivAdd (ivAdd iv a) b ] where ivNull :: BlockCipher a => a -> IV a ivNull = const nullIV -- uses IV pattern <00 .. 00 FF .. FF> to test carry propagation generateIvFromCipher :: BlockCipher a => a -> Gen (IV a) generateIvFromCipher c = do let n = blockSize c i <- choose (0, n) let zeros = Prelude.replicate (n - i) 0x00 ones = Prelude.replicate i 0xFF return $ cipherMakeIV c (B.pack $ zeros ++ ones) -- | 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 ++ testIvArith 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.26/tests/ChaCha.hs0000644000000000000000000001504213414232447014642 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.26/tests/BCrypt.hs0000644000000000000000000001037513414232447014742 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))) , testCase "Hash and validate" (assertBool "Hashed password should validate" (validatePassword somePassword (bcrypt 5 aSalt somePassword :: B.ByteString))) ] where somePassword = "some password" :: B.ByteString aSalt = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" :: B.ByteString cryptonite-0.26/tests/BCryptPBKDF.hs0000644000000000000000000000575113470442731015514 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module BCryptPBKDF (tests) where import qualified Data.ByteString as B import Test.Tasty import Test.Tasty.HUnit import Crypto.KDF.BCryptPBKDF (Parameters (..), generate, hashInternal) tests :: TestTree tests = testGroup "BCryptPBKDF" [ testGroup "generate" [ testCase "1" generate1 , testCase "2" generate2 , testCase "3" generate3 ] , testGroup "hashInternal" [ testCase "1" hashInternal1 ] ] where -- test vector taken from the go implementation by @dchest generate1 = expected @=? generate params pass salt where params = Parameters 12 32 pass = "password" :: B.ByteString salt = "salt" :: B.ByteString expected = B.pack [ 0x1a, 0xe4, 0x2c, 0x05, 0xd4, 0x87, 0xbc, 0x02 , 0xf6, 0x49, 0x21, 0xa4, 0xeb, 0xe4, 0xea, 0x93 , 0xbc, 0xac, 0xfe, 0x13, 0x5f, 0xda, 0x99, 0x97 , 0x4c, 0x06, 0xb7, 0xb0, 0x1f, 0xae, 0x14, 0x9a ] :: B.ByteString -- test vector generated with the go implemenation by @dchest generate2 = expected @=? generate params pass salt where params = Parameters 7 71 pass = "DieWuerdeDesMenschenIstUnantastbar" :: B.ByteString salt = "Tafelsalz" :: B.ByteString expected = B.pack [ 0x17, 0xb4, 0x76, 0xaa, 0xd7, 0x42, 0x33, 0x49 , 0x5c, 0xe8, 0x79, 0x49, 0x15, 0x74, 0x4c, 0x71 , 0xf9, 0x99, 0x66, 0x89, 0x7a, 0x60, 0xc3, 0x70 , 0xb4, 0x3c, 0xa8, 0x83, 0x80, 0x5a, 0x56, 0xde , 0x38, 0xbc, 0x51, 0x8c, 0xd4, 0xeb, 0xd1, 0xcf , 0x46, 0x0a, 0x68, 0x3d, 0xc8, 0x12, 0xcf, 0xf8 , 0x43, 0xce, 0x21, 0x9d, 0x98, 0x81, 0x20, 0x26 , 0x6e, 0x42, 0x0f, 0xaa, 0x75, 0x5d, 0x09, 0x8d , 0x45, 0xda, 0xd5, 0x15, 0x6e, 0x65, 0x1d ] :: B.ByteString -- test vector generated with the go implemenation by @dchest generate3 = expected @=? generate params pass salt where params = Parameters 5 5 pass = "ABC" :: B.ByteString salt = "DEF" :: B.ByteString expected = B.pack [ 0xdd, 0x6e, 0xa0, 0x69, 0x29 ] :: B.ByteString hashInternal1 = expected @=? hashInternal passHash saltHash where passHash = B.pack [ 0 .. 63 ] :: B.ByteString saltHash = B.pack [ 64 .. 127 ] :: B.ByteString expected = B.pack [ 0x87, 0x90, 0x48, 0x70, 0xee, 0xf9, 0xde, 0xdd , 0xf8, 0xe7, 0x61, 0x1a, 0x14, 0x01, 0x06, 0xe6 , 0xaa, 0xf1, 0xa3, 0x63, 0xd9, 0xa2, 0xc5, 0x04 , 0xdb, 0x35, 0x64, 0x43, 0x72, 0x1e, 0xb5, 0x55 ] :: B.ByteString cryptonite-0.26/tests/ECC.hs0000644000000000000000000003513413470442731014132 0ustar0000000000000000{-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} module ECC (tests) where import Crypto.Error import qualified Crypto.ECC as ECC import Data.ByteArray.Encoding import Imports data Curve = forall curve. (ECC.EllipticCurveDH curve, Show curve, Eq (ECC.Point curve)) => Curve curve instance Show Curve where showsPrec d (Curve curve) = showsPrec d curve instance Arbitrary Curve where arbitrary = elements [ Curve ECC.Curve_P256R1 , Curve ECC.Curve_P384R1 , Curve ECC.Curve_P521R1 , Curve ECC.Curve_X25519 , Curve ECC.Curve_X448 ] data VectorPoint = VectorPoint { vpCurve :: Curve , vpHex :: ByteString , vpError :: Maybe CryptoError } vectorsPoint = [ VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "" , vpError = Just CryptoError_PointSizeInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "00" , vpError = Just CryptoError_PointFormatInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "0408edd7b50085a952172228aca391beebe9ba942a0ae9eb15bcc8d50795d1a5505221c7b9b3bb4310f165fc3ac3114339db8170ceae6697e0f9736698b33551b8" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "04216f25b00717d46deef3402628f6abf265bfa12aea515ae8f100ce415e251e72cd5cd8f47f613a0f4e0f4f9410dd9c85c149cffcb320c2d52bf550a397ec92e5" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "0421eba6080610926609bb8d52afd3331ed1b07e0ba4c1441a118b62497d3e85f39a50c865027cdd84298cdf094b7818f2a65ae59f46c971a32ab4ea3c2c93c959" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "0400d7fc4050dfe73475502d5d1fadc105d7725508f48da2cd4729bf191fd6490a0001a16f417a27530e756efeb4a228f02db878072b9f833e99a2821d85fa78fc" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "040000fc4050dfe73475502d5d1fadc105d7725508f48da2cd4729bf191fd6490a0001a16f417a27530e756efeb4a228f02db878072b9f833e99a2821d85fa78fc" , vpError = Just CryptoError_PointCoordinatesInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "04d7fc4050dfe73475502d5d1fadc105d7725508f48da2cd4729bf191fd6490a01a16f417a27530e756efeb4a228f02db878072b9f833e99a2821d85fa78fc" , vpError = Just CryptoError_PublicKeySizeInvalid -- tests leading zeros } , VectorPoint { vpCurve = Curve ECC.Curve_P256R1 , vpHex = "040000d7fc4050dfe73475502d5d1fadc105d7725508f48da2cd4729bf191fd6490a000001a16f417a27530e756efeb4a228f02db878072b9f833e99a2821d85fa78fc" , vpError = Just CryptoError_PublicKeySizeInvalid -- tests leading zeros } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "" , vpError = Just CryptoError_PointSizeInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "00" , vpError = Just CryptoError_PointFormatInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "0409281a103fb1773445e16eec86adb095e32928ccc9c806bd210c649712813bdb6cab40163a8cb163b578ea8dda5eb32cfb5208ebf0d31a6c590fa92f5a61f32dbc0d518b166ea5a9adf9dd21c1bd09932ca21c6a5725ca89542ac57b6a9eca6f" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "040c7b3fb575c1db7bc61fe7a456cc34a8289f41e167938a56e5ba2787723f3de2c645112705e13ed24f477730173935ca4e0ff468e7e0acf78a9f59dadff8193a0e23789eb3737730c089b27a0f94de7d95b8db4466d017fb21a5710d6ca85775" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "0438e7705220b60460194be63d21c8945be2a211957168fa60f26b2ad4e8f5cd96a7779e7edff4deda9ded63243c2127e273d4444edaaba03b79b6caafc5033432af13776f851c0c7e1080c60d7ee3b61740720ab98461813dab5fb8c31bfa9ed9" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "04000836bf09614bf5b3c0ffe9b0822a2cc109a90b13d4d3510ce14f766e7d90875ec4bc8d6bee11fc1fdf97473a67884c00b1e2685367bdb846c95181b0f35a35cfbee04451122cc55a1e363acaa6c002e71b0b6ff7d0f5dc830a32f0e5086189" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "04000036bf09614bf5b3c0ffe9b0822a2cc109a90b13d4d3510ce14f766e7d90875ec4bc8d6bee11fc1fdf97473a67884c00b1e2685367bdb846c95181b0f35a35cfbee04451122cc55a1e363acaa6c002e71b0b6ff7d0f5dc830a32f0e5086189" , vpError = Just CryptoError_PointCoordinatesInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "040836bf09614bf5b3c0ffe9b0822a2cc109a90b13d4d3510ce14f766e7d90875ec4bc8d6bee11fc1fdf97473a67884cb1e2685367bdb846c95181b0f35a35cfbee04451122cc55a1e363acaa6c002e71b0b6ff7d0f5dc830a32f0e5086189" , vpError = Nothing -- ignores leading zeros } , VectorPoint { vpCurve = Curve ECC.Curve_P384R1 , vpHex = "0400000836bf09614bf5b3c0ffe9b0822a2cc109a90b13d4d3510ce14f766e7d90875ec4bc8d6bee11fc1fdf97473a67884c0000b1e2685367bdb846c95181b0f35a35cfbee04451122cc55a1e363acaa6c002e71b0b6ff7d0f5dc830a32f0e5086189" , vpError = Nothing -- ignores leading zeros } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "" , vpError = Just CryptoError_PointSizeInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "00" , vpError = Just CryptoError_PointFormatInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "04000ce5c207335134567026063743df82c1b551a009cf616471f0e23fa9767a50cc7f8771ef13a65c49ce7e1cd1ac3ad721dcc3ddd35f98ae5d380a0832f87a9f0ca4012914911d6bea7f3c481d694fb1645be27c7b66b09b28e261f8030b3fb8206f6a95f6ad73db755765b64f592a799234f8f451cb787abe95b1a54991a799ad0d69da" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "04003a5e6c1ce3a6a323757005da17b357db991bd1ad835e6201411f458b5c2edb3c66786b727b7e15fbad7dd74a4b0eb542183b5242e5952061cb85e7229353eb0dc300aac2dbd5232d582481ba7a59a993eb04c4466a1b17ba0015b65c616ce8703e70880969d8d58e633acb29c3ca017eb1b88649387b867466090ce1a57c2b4f8376bb" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "04003e0659fe9498695a3d8c88b8e25fa8133c30ab10eccbe9094344c99924f89fb69d9b3acf03bf438328f9cba55fa28a05be9a7e18780706b3728abfee2592aeb86d0001ea5ff64f2ca7a6453c79f80550e971843e073f4f8fec75bad2e52a4483ebf1f16f43d0de27e1967ea22f9722527652fa74439fdc03a569fba29e2d6f7c012db6" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "040043f91fd92d9ccd6d5584b265a2a775d222f4a41ff98190677d985e0889737cbe631d525835fe04faffcdebeccb783538280f4600ae82347b0470583abd9def306000a2e9bdc34f42b134517fc1e961befea0affd1f9666361a039192082a892dd722931d5865b62b69d7369e74895120e540cb10030cccb6049d809fbcf3f54537b378" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "040000f91fd92d9ccd6d5584b265a2a775d222f4a41ff98190677d985e0889737cbe631d525835fe04faffcdebeccb783538280f4600ae82347b0470583abd9def306000a2e9bdc34f42b134517fc1e961befea0affd1f9666361a039192082a892dd722931d5865b62b69d7369e74895120e540cb10030cccb6049d809fbcf3f54537b378" , vpError = Just CryptoError_PointCoordinatesInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "0443f91fd92d9ccd6d5584b265a2a775d222f4a41ff98190677d985e0889737cbe631d525835fe04faffcdebeccb783538280f4600ae82347b0470583abd9def3060a2e9bdc34f42b134517fc1e961befea0affd1f9666361a039192082a892dd722931d5865b62b69d7369e74895120e540cb10030cccb6049d809fbcf3f54537b378" , vpError = Nothing -- ignores leading zeros } , VectorPoint { vpCurve = Curve ECC.Curve_P521R1 , vpHex = "04000043f91fd92d9ccd6d5584b265a2a775d222f4a41ff98190677d985e0889737cbe631d525835fe04faffcdebeccb783538280f4600ae82347b0470583abd9def30600000a2e9bdc34f42b134517fc1e961befea0affd1f9666361a039192082a892dd722931d5865b62b69d7369e74895120e540cb10030cccb6049d809fbcf3f54537b378" , vpError = Nothing -- ignores leading zeros } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "" , vpError = Just CryptoError_PublicKeySizeInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "22cd98c65fb50db3be0d6d359456c0cd3516952a6e7229ff672893944f703f10" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "23cd98c65fb50db3be0d6d359456c0cd3516952a6e7229ff672893944f703f10" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "0023cd98c65fb50db3be0d6d359456c0cd3516952a6e7229ff672893944f703f10" , vpError = Just CryptoError_PublicKeySizeInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X448 , vpHex = "" , vpError = Just CryptoError_PublicKeySizeInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X448 , vpHex = "2b162c2fef165ecbb203e40975ae4424f0f8db25ab582cb96b2e5ffe90a31798b35480b594c99dc32b437e61a74f792d8ecf5fc3e8cfeb75" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_X448 , vpHex = "2c162c2fef165ecbb203e40975ae4424f0f8db25ab582cb96b2e5ffe90a31798b35480b594c99dc32b437e61a74f792d8ecf5fc3e8cfeb75" , vpError = Nothing } , VectorPoint { vpCurve = Curve ECC.Curve_X448 , vpHex = "002c162c2fef165ecbb203e40975ae4424f0f8db25ab582cb96b2e5ffe90a31798b35480b594c99dc32b437e61a74f792d8ecf5fc3e8cfeb75" , vpError = Just CryptoError_PublicKeySizeInvalid } ] vectorsWeakPoint = [ VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "0000000000000000000000000000000000000000000000000000000000000000" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "0100000000000000000000000000000000000000000000000000000000000000" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X25519 , vpHex = "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X448 , vpHex = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" , vpError = Just CryptoError_ScalarMultiplicationInvalid } , VectorPoint { vpCurve = Curve ECC.Curve_X448 , vpHex = "0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" , vpError = Just CryptoError_ScalarMultiplicationInvalid } ] vpEncodedPoint :: VectorPoint -> ByteString vpEncodedPoint vector = let Right bs = convertFromBase Base16 (vpHex vector) in bs cryptoError :: CryptoFailable a -> Maybe CryptoError cryptoError = onCryptoFailure Just (const Nothing) doPointDecodeTest (i, vector) = case vpCurve vector of Curve curve -> let prx = Just curve -- using Maybe as Proxy in testCase (show i) (vpError vector @=? cryptoError (ECC.decodePoint prx $ vpEncodedPoint vector)) doWeakPointECDHTest (i, vector) = case vpCurve vector of Curve curve -> testCase (show i) $ do let prx = Just curve -- using Maybe as Proxy CryptoPassed public = ECC.decodePoint prx $ vpEncodedPoint vector keyPair <- ECC.curveGenerateKeyPair prx vpError vector @=? cryptoError (ECC.ecdh prx (ECC.keypairGetPrivate keyPair) public) tests = testGroup "ECC" [ testGroup "decodePoint" $ map doPointDecodeTest (zip [katZero..] vectorsPoint) , testGroup "ECDH weak points" $ map doWeakPointECDHTest (zip [katZero..] vectorsWeakPoint) , testGroup "property" [ testProperty "decodePoint.encodePoint==id" $ \testDRG (Curve curve) -> do let prx = Just curve -- using Maybe as Proxy keyPair = withTestDRG testDRG $ ECC.curveGenerateKeyPair prx p1 = ECC.keypairGetPublic keyPair bs = ECC.encodePoint prx p1 :: ByteString p2 = ECC.decodePoint prx bs in CryptoPassed p1 == p2 , localOption (QuickCheckTests 20) $ testProperty "ECDH commutes" $ \testDRG (Curve curve) -> let prx = Just curve -- using Maybe as Proxy (alice, bob) = withTestDRG testDRG $ (,) <$> ECC.curveGenerateKeyPair prx <*> ECC.curveGenerateKeyPair prx aliceShared = ECC.ecdh prx (ECC.keypairGetPrivate alice) (ECC.keypairGetPublic bob) bobShared = ECC.ecdh prx (ECC.keypairGetPrivate bob) (ECC.keypairGetPublic alice) aliceShared' = ECC.ecdhRaw prx (ECC.keypairGetPrivate alice) (ECC.keypairGetPublic bob) bobShared' = ECC.ecdhRaw prx (ECC.keypairGetPrivate bob) (ECC.keypairGetPublic alice) in aliceShared == bobShared && aliceShared == CryptoPassed aliceShared' && bobShared == CryptoPassed bobShared' ] ] cryptonite-0.26/tests/ECC/Edwards25519.hs0000644000000000000000000001656513414232447016137 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module ECC.Edwards25519 ( tests ) where import Crypto.Error import Crypto.ECC.Edwards25519 import qualified Data.ByteString as B import Data.Word (Word8) import Imports instance Arbitrary Scalar where arbitrary = fmap (throwCryptoError . scalarDecodeLong) (arbitraryBS 64) smallScalar :: Word8 -> Scalar smallScalar = throwCryptoError . scalarDecodeLong . B.singleton newtype PrimeOrder = PrimeOrder Point deriving Show -- points in the prime-order subgroup instance Arbitrary PrimeOrder where arbitrary = (PrimeOrder . toPoint) `fmap` arbitrary -- arbitrary curve point, including points with a torsion component instance Arbitrary Point where arbitrary = do a <- arbitrary b <- elements $ map smallScalar [0 .. 7] return (pointsMulVarTime a b torsion8) -- an 8-torsion point torsion8 :: Point torsion8 = throwCryptoError $ pointDecode ("\199\ETBjp=M\216O\186<\vv\r\DLEg\SI* S\250,9\204\198N\199\253w\146\172\ETXz" :: ByteString) tests = testGroup "ECC.Edwards25519" [ testGroup "vectors" [ testCase "11*G" $ p011 @=? toPoint s011 , testCase "123*G" $ p123 @=? toPoint s123 , testCase "134*G" $ p134 @=? toPoint s134 , testCase "123*G + 11*G" $ p134 @=? pointAdd p123 p011 ] , testGroup "scalar arithmetic" [ testProperty "scalarDecodeLong.scalarEncode==id" $ \s -> let bs = scalarEncode s :: ByteString ss = scalarDecodeLong bs in CryptoPassed s `propertyEq` ss , testCase "curve order" $ s0 @=? sN , testProperty "addition with zero" $ \s -> propertyHold [ eqTest "zero left" s (scalarAdd s0 s) , eqTest "zero right" s (scalarAdd s s0) ] , testProperty "addition associative" $ \sa sb sc -> scalarAdd sa (scalarAdd sb sc) === scalarAdd (scalarAdd sa sb) sc , testProperty "addition commutative" $ \sa sb -> scalarAdd sa sb === scalarAdd sb sa , testProperty "multiplication with zero" $ \s -> propertyHold [ eqTest "zero left" s0 (scalarMul s0 s) , eqTest "zero right" s0 (scalarMul s s0) ] , testProperty "multiplication with one" $ \s -> propertyHold [ eqTest "one left" s (scalarMul s1 s) , eqTest "one right" s (scalarMul s s1) ] , testProperty "multiplication associative" $ \sa sb sc -> scalarMul sa (scalarMul sb sc) === scalarMul (scalarMul sa sb) sc , testProperty "multiplication commutative" $ \sa sb -> scalarMul sa sb === scalarMul sb sa , testProperty "multiplication distributive" $ \sa sb sc -> propertyHold [ eqTest "distributive left" ((sa `scalarMul` sb) `scalarAdd` (sa `scalarMul` sc)) (sa `scalarMul` (sb `scalarAdd` sc)) , eqTest "distributive right" ((sb `scalarMul` sa) `scalarAdd` (sc `scalarMul` sa)) ((sb `scalarAdd` sc) `scalarMul` sa) ] ] , testGroup "point arithmetic" [ testProperty "pointDecode.pointEncode==id" $ \p -> let bs = pointEncode p :: ByteString p' = pointDecode bs in CryptoPassed p `propertyEq` p' , testProperty "pointEncode.pointDecode==id" $ \p -> let b = pointEncode p :: ByteString p' = pointDecode b b' = pointEncode `fmap` p' in CryptoPassed b `propertyEq` b' , testProperty "addition with identity" $ \p -> propertyHold [ eqTest "identity left" p (pointAdd p0 p) , eqTest "identity right" p (pointAdd p p0) ] , testProperty "addition associative" $ \pa pb pc -> pointAdd pa (pointAdd pb pc) === pointAdd (pointAdd pa pb) pc , testProperty "addition commutative" $ \pa pb -> pointAdd pa pb === pointAdd pb pa , testProperty "negation" $ \p -> p0 `propertyEq` pointAdd p (pointNegate p) , testProperty "doubling" $ \p -> pointAdd p p `propertyEq` pointDouble p , testProperty "multiplication by cofactor" $ \p -> pointMul s8 p `propertyEq` pointMulByCofactor p , testProperty "prime order" $ \(PrimeOrder p) -> True `propertyEq` pointHasPrimeOrder p , testCase "8-torsion point" $ do assertBool "mul by 4" $ p0 /= pointMul s4 torsion8 assertBool "mul by 8" $ p0 == pointMul s8 torsion8 , testProperty "scalarmult with zero" $ \p -> p0 `propertyEq` pointMul s0 p , testProperty "scalarmult with one" $ \p -> p `propertyEq` pointMul s1 p , testProperty "scalarmult with two" $ \p -> pointDouble p `propertyEq` pointMul s2 p , testProperty "scalarmult with curve order - 1" $ \p -> pointHasPrimeOrder p === (pointNegate p == pointMul sI p) , testProperty "scalarmult commutative" $ \a b -> pointMul a (toPoint b) === pointMul b (toPoint a) , testProperty "scalarmult distributive" $ \x y (PrimeOrder p) -> let pR = pointMul x p `pointAdd` pointMul y p in pR `propertyEq` pointMul (x `scalarAdd` y) p , testProperty "double scalarmult" $ \n1 n2 p -> let pR = pointAdd (toPoint n1) (pointMul n2 p) in pR `propertyEq` pointsMulVarTime n1 n2 p ] ] where p0 = toPoint s0 s0 = smallScalar 0 s1 = smallScalar 1 s2 = smallScalar 2 s4 = smallScalar 4 s8 = smallScalar 8 sI = throwCryptoError $ scalarDecodeLong ("\236\211\245\\\SUBc\DC2X\214\156\247\162\222\249\222\DC4\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\DLE" :: ByteString) sN = throwCryptoError $ scalarDecodeLong ("\237\211\245\\\SUBc\DC2X\214\156\247\162\222\249\222\DC4\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\NUL\DLE" :: ByteString) s011 = throwCryptoError $ scalarDecodeLong ("\011" :: ByteString) s123 = throwCryptoError $ scalarDecodeLong ("\123" :: ByteString) s134 = throwCryptoError $ scalarDecodeLong ("\134" :: ByteString) p011 = throwCryptoError $ pointDecode ("\x13\x37\x03\x6a\xc3\x2d\x8f\x30\xd4\x58\x9c\x3c\x1c\x59\x58\x12\xce\x0f\xff\x40\xe3\x7c\x6f\x5a\x97\xab\x21\x3f\x31\x82\x90\xad" :: ByteString) p123 = throwCryptoError $ pointDecode ("\xc4\xb8\x00\xc8\x70\x10\xf9\x46\x83\x03\xde\xea\x87\x65\x03\xe8\x86\xbf\xde\x19\x00\xe9\xe8\x46\xfd\x4c\x3c\xd0\x9c\x1c\xbc\x9f" :: ByteString) p134 = throwCryptoError $ pointDecode ("\x51\x20\xab\xe0\x3c\xa2\xaf\x66\xc7\x7c\xa3\x20\xf0\xb2\x1f\xb5\x56\xf6\xb6\x5f\xdd\x7e\x32\x64\xc1\x4a\x30\xd9\x7b\xf7\xa7\x6f" :: ByteString) -- Using : -- -- >>> import ed25519 -- >>> encodepoint(scalarmult(B, 11)).encode('hex') -- '1337036ac32d8f30d4589c3c1c595812ce0fff40e37c6f5a97ab213f318290ad' -- >>> encodepoint(scalarmult(B, 123)).encode('hex') -- 'c4b800c87010f9468303deea876503e886bfde1900e9e846fd4c3cd09c1cbc9f' -- >>> encodepoint(scalarmult(B, 134)).encode('hex') -- '5120abe03ca2af66c77ca320f0b21fb556f6b65fdd7e3264c14a30d97bf7a76f' cryptonite-0.26/tests/Hash.hs0000644000000000000000000005253313414232447014424 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE DataKinds #-} module Hash ( tests ) where import Crypto.Hash import qualified Data.ByteString as B import Data.ByteArray (convert) import qualified Data.ByteArray.Encoding as B (convertToBase, Base(..)) import GHC.TypeLits 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" ]) , ("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" ]) ] 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) ] -- SHAKE128 truncation example with expected byte at final position -- shake128TruncationBytes = [0x01, 0x03, 0x07, 0x0f, 0x0f, 0x2f, 0x6f, 0x6f] makeTestSHAKE128Truncation i byte = testCase (show i) $ xof 4088 `B.snoc` byte @=? xof (4088 + i) where hashEmpty :: KnownNat n => proxy n -> Digest (SHAKE128 n) hashEmpty _ = hash B.empty xof n = case someNatVal n of Nothing -> error ("invalid Nat: " ++ show n) Just (SomeNat p) -> convert (hashEmpty p) tests = testGroup "hash" [ testGroup "KATs" (map makeTestAlg expected) , testGroup "Chunking" (concatMap makeTestChunk expected) , testGroup "Truncating" [ testGroup "SHAKE128" (zipWith makeTestSHAKE128Truncation [1..] shake128TruncationBytes) ] ] cryptonite-0.26/tests/Imports.hs0000644000000000000000000000075413414232447015174 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.26/tests/KAT_AES/KATCBC.hs0000644000000000000000000005477013414232447015604 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.26/tests/KAT_AES/KATECB.hs0000644000000000000000000001202113414232447015565 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.26/tests/KAT_AES/KATGCM.hs0000644000000000000000000001316213414232447015611 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.26/tests/KAT_AES/KATCCM.hs0000644000000000000000000003150113414232447015602 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES.KATCCM where import qualified Data.ByteString as B -- (key, iv, header, in, out+atag, taglen) type KATCCM = (B.ByteString, B.ByteString, B.ByteString, B.ByteString, B.ByteString, Int) vectors_aes128_enc :: [KATCCM] vectors_aes128_enc = [ ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x03\x02\x01\x00\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07" , {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x58\x8c\x97\x9a\x61\xc6\x63\xd2\xf0\x66\xd0\xc2\xc0\xf9\x89\x80\x6d\x5f\x6b\x61\xda\xc3\x84\x17\xe8\xd1\x2c\xfd\xf9\x26\xe0" , {- M = -} 8) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x04\x03\x02\x01\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07" , {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x72\xc9\x1a\x36\xe1\x35\xf8\xcf\x29\x1c\xa8\x94\x08\x5c\x87\xe3\xcc\x15\xc4\x39\xc9\xe4\x3a\x3b\xa0\x91\xd5\x6e\x10\x40\x09\x16" , {- M = -} 8) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x05\x04\x03\x02\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07" , {- in = -} "\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" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x51\xb1\xe5\xf4\x4a\x19\x7d\x1d\xa4\x6b\x0f\x8e\x2d\x28\x2a\xe8\x71\xe8\x38\xbb\x64\xda\x85\x96\x57\x4a\xda\xa7\x6f\xbd\x9f\xb0\xc5" , {- M = -} 8) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x06\x05\x04\x03\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" , {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xa2\x8c\x68\x65\x93\x9a\x9a\x79\xfa\xaa\x5c\x4c\x2a\x9d\x4a\x91\xcd\xac\x8c\x96\xc8\x61\xb9\xc9\xe6\x1e\xf1" , {- M = -} 8) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x07\x06\x05\x04\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" , {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xdc\xf1\xfb\x7b\x5d\x9e\x23\xfb\x9d\x4e\x13\x12\x53\x65\x8a\xd8\x6e\xbd\xca\x3e\x51\xe8\x3f\x07\x7d\x9c\x2d\x93" , {- M = -} 8) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x08\x07\x06\x05\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" , {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x6f\xc1\xb0\x11\xf0\x06\x56\x8b\x51\x71\xa4\x2d\x95\x3d\x46\x9b\x25\x70\xa4\xbd\x87\x40\x5a\x04\x43\xac\x91\xcb\x94" , {- M = -} 8) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x09\x08\x07\x06\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07" , {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x01\x35\xd1\xb2\xc9\x5f\x41\xd5\xd1\xd4\xfe\xc1\x85\xd1\x66\xb8\x09\x4e\x99\x9d\xfe\xd9\x6c\x04\x8c\x56\x60\x2c\x97\xac\xbb\x74\x90" , {- M = -} 10) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x0a\x09\x08\x07\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07" , {- in = -} "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x7b\x75\x39\x9a\xc0\x83\x1d\xd2\xf0\xbb\xd7\x58\x79\xa2\xfd\x8f\x6c\xae\x6b\x6c\xd9\xb7\xdb\x24\xc1\x7b\x44\x33\xf4\x34\x96\x3f\x34\xb4" , {- M = -} 10) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x0b\x0a\x09\x08\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07" , {- in = -} "\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" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x82\x53\x1a\x60\xcc\x24\x94\x5a\x4b\x82\x79\x18\x1a\xb5\xc8\x4d\xf2\x1c\xe7\xf9\xb7\x3f\x42\xe1\x97\xea\x9c\x07\xe5\x6b\x5e\xb1\x7e\x5f\x4e" , {- M = -} 10) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x0c\x0b\x0a\x09\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" , {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x07\x34\x25\x94\x15\x77\x85\x15\x2b\x07\x40\x98\x33\x0a\xbb\x14\x1b\x94\x7b\x56\x6a\xa9\x40\x6b\x4d\x99\x99\x88\xdd" , {- M = -} 10) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x0d\x0c\x0b\x0a\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" , {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x67\x6b\xb2\x03\x80\xb0\xe3\x01\xe8\xab\x79\x59\x0a\x39\x6d\xa7\x8b\x83\x49\x34\xf5\x3a\xa2\xe9\x10\x7a\x8b\x6c\x02\x2c" , {- M = -} 10) , ( {- key = -} "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf" , {- iv = -} "\x00\x00\x00\x0e\x0d\x0c\x0b\xa0\xa1\xa2\xa3\xa4\xa5" , {- hdr = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b" , {- in = -} "\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20" , {- out = -} "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\xc0\xff\xa0\xd6\xf0\x5b\xdb\x67\xf2\x4d\x43\xa4\x33\x8d\x2a\xa4\xbe\xd7\xb2\x0e\x43\xcd\x1a\xa3\x16\x62\xe7\xad\x65\xd6\xdb" , {- M = -} 10) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x41\x2b\x4e\xa9\xcd\xbe\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\x0b\xe1\xa8\x8b\xac\xe0\x18\xb1" , {- in = -} "\x08\xe8\xcf\x97\xd8\x20\xea\x25\x84\x60\xe9\x6a\xd9\xcf\x52\x89\x05\x4d\x89\x5c\xea\xc4\x7c" , {- out = -} "\x0b\xe1\xa8\x8b\xac\xe0\x18\xb1\x4c\xb9\x7f\x86\xa2\xa4\x68\x9a\x87\x79\x47\xab\x80\x91\xef\x53\x86\xa6\xff\xbd\xd0\x80\xf8\xe7\x8c\xf7\xcb\x0c\xdd\xd7\xb3" , {- M = -} 8) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x33\x56\x8e\xf7\xb2\x63\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb" , {- in = -} "\x90\x20\xea\x6f\x91\xbd\xd8\x5a\xfa\x00\x39\xba\x4b\xaf\xf9\xbf\xb7\x9c\x70\x28\x94\x9c\xd0\xec" , {- out = -} "\x63\x01\x8f\x76\xdc\x8a\x1b\xcb\x4c\xcb\x1e\x7c\xa9\x81\xbe\xfa\xa0\x72\x6c\x55\xd3\x78\x06\x12\x98\xc8\x5c\x92\x81\x4a\xbc\x33\xc5\x2e\xe8\x1d\x7d\x77\xc0\x8a" , {- M = -} 8) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x10\x3f\xe4\x13\x36\x71\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\xaa\x6c\xfa\x36\xca\xe8\x6b\x40" , {- in = -} "\xb9\x16\xe0\xea\xcc\x1c\x00\xd7\xdc\xec\x68\xec\x0b\x3b\xbb\x1a\x02\xde\x8a\x2d\x1a\xa3\x46\x13\x2e" , {- out = -} "\xaa\x6c\xfa\x36\xca\xe8\x6b\x40\xb1\xd2\x3a\x22\x20\xdd\xc0\xac\x90\x0d\x9a\xa0\x3c\x61\xfc\xf4\xa5\x59\xa4\x41\x77\x67\x08\x97\x08\xa7\x76\x79\x6e\xdb\x72\x35\x06" , {- M = -} 8) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x76\x4c\x63\xb8\x05\x8e\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\xd0\xd0\x73\x5c\x53\x1e\x1b\xec\xf0\x49\xc2\x44" , {- in = -} "\x12\xda\xac\x56\x30\xef\xa5\x39\x6f\x77\x0c\xe1\xa6\x6b\x21\xf7\xb2\x10\x1c" , {- out = -} "\xd0\xd0\x73\x5c\x53\x1e\x1b\xec\xf0\x49\xc2\x44\x14\xd2\x53\xc3\x96\x7b\x70\x60\x9b\x7c\xbb\x7c\x49\x91\x60\x28\x32\x45\x26\x9a\x6f\x49\x97\x5b\xca\xde\xaf" , {- M = -} 8) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\xf8\xb6\x78\x09\x4e\x3b\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\x77\xb6\x0f\x01\x1c\x03\xe1\x52\x58\x99\xbc\xae" , {- in = -} "\xe8\x8b\x6a\x46\xc7\x8d\x63\xe5\x2e\xb8\xc5\x46\xef\xb5\xde\x6f\x75\xe9\xcc\x0d" , {- out = -} "\x77\xb6\x0f\x01\x1c\x03\xe1\x52\x58\x99\xbc\xae\x55\x45\xff\x1a\x08\x5e\xe2\xef\xbf\x52\xb2\xe0\x4b\xee\x1e\x23\x36\xc7\x3e\x3f\x76\x2c\x0c\x77\x44\xfe\x7e\x3c" , {- M = -} 8) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\xd5\x60\x91\x2d\x3f\x70\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81\x20\xea\x60\xc0" , {- in = -} "\x64\x35\xac\xba\xfb\x11\xa8\x2e\x2f\x07\x1d\x7c\xa4\xa5\xeb\xd9\x3a\x80\x3b\xa8\x7f" , {- out = -} "\xcd\x90\x44\xd2\xb7\x1f\xdb\x81\x20\xea\x60\xc0\x00\x97\x69\xec\xab\xdf\x48\x62\x55\x94\xc5\x92\x51\xe6\x03\x57\x22\x67\x5e\x04\xc8\x47\x09\x9e\x5a\xe0\x70\x45\x51" , {- M = -} 8) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x42\xff\xf8\xf1\x95\x1c\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8" , {- in = -} "\x8a\x19\xb9\x50\xbc\xf7\x1a\x01\x8e\x5e\x67\x01\xc9\x17\x87\x65\x98\x09\xd6\x7d\xbe\xdd\x18" , {- out = -} "\xd8\x5b\xc7\xe6\x9f\x94\x4f\xb8\xbc\x21\x8d\xaa\x94\x74\x27\xb6\xdb\x38\x6a\x99\xac\x1a\xef\x23\xad\xe0\xb5\x29\x39\xcb\x6a\x63\x7c\xf9\xbe\xc2\x40\x88\x97\xc6\xba" , {- M = -} 10) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x92\x0f\x40\xe5\x6c\xdc\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\x74\xa0\xeb\xc9\x06\x9f\x5b\x37" , {- in = -} "\x17\x61\x43\x3c\x37\xc5\xa3\x5f\xc1\xf3\x9f\x40\x63\x02\xeb\x90\x7c\x61\x63\xbe\x38\xc9\x84\x37" , {- out = -} "\x74\xa0\xeb\xc9\x06\x9f\x5b\x37\x58\x10\xe6\xfd\x25\x87\x40\x22\xe8\x03\x61\xa4\x78\xe3\xe9\xcf\x48\x4a\xb0\x4f\x44\x7e\xff\xf6\xf0\xa4\x77\xcc\x2f\xc9\xbf\x54\x89\x44" , {- M = -} 10) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x27\xca\x0c\x71\x20\xbc\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\x44\xa3\xaa\x3a\xae\x64\x75\xca" , {- in = -} "\xa4\x34\xa8\xe5\x85\x00\xc6\xe4\x15\x30\x53\x88\x62\xd6\x86\xea\x9e\x81\x30\x1b\x5a\xe4\x22\x6b\xfa" , {- out = -} "\x44\xa3\xaa\x3a\xae\x64\x75\xca\xf2\xbe\xed\x7b\xc5\x09\x8e\x83\xfe\xb5\xb3\x16\x08\xf8\xe2\x9c\x38\x81\x9a\x89\xc8\xe7\x76\xf1\x54\x4d\x41\x51\xa4\xed\x3a\x8b\x87\xb9\xce" , {- M = -} 10) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x5b\x8c\xcb\xcd\x9a\xf8\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\xec\x46\xbb\x63\xb0\x25\x20\xc3\x3c\x49\xfd\x70" , {- in = -} "\xb9\x6b\x49\xe2\x1d\x62\x17\x41\x63\x28\x75\xdb\x7f\x6c\x92\x43\xd2\xd7\xc2" , {- out = -} "\xec\x46\xbb\x63\xb0\x25\x20\xc3\x3c\x49\xfd\x70\x31\xd7\x50\xa0\x9d\xa3\xed\x7f\xdd\xd4\x9a\x20\x32\xaa\xbf\x17\xec\x8e\xbf\x7d\x22\xc8\x08\x8c\x66\x6b\xe5\xc1\x97" , {- M = -} 10) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x3e\xbe\x94\x04\x4b\x9a\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\x47\xa6\x5a\xc7\x8b\x3d\x59\x42\x27\xe8\x5e\x71" , {- in = -} "\xe2\xfc\xfb\xb8\x80\x44\x2c\x73\x1b\xf9\x51\x67\xc8\xff\xd7\x89\x5e\x33\x70\x76" , {- out = -} "\x47\xa6\x5a\xc7\x8b\x3d\x59\x42\x27\xe8\x5e\x71\xe8\x82\xf1\xdb\xd3\x8c\xe3\xed\xa7\xc2\x3f\x04\xdd\x65\x07\x1e\xb4\x13\x42\xac\xdf\x7e\x00\xdc\xce\xc7\xae\x52\x98\x7d" , {- M = -} 10) , ( {- key = -} "\xd7\x82\x8d\x13\xb2\xb0\xbd\xc3\x25\xa7\x62\x36\xdf\x93\xcc\x6b" , {- iv = -} "\x00\x8d\x49\x3b\x30\xae\x8b\x3c\x96\x96\x76\x6c\xfa" , {- hdr = -} "\x6e\x37\xa6\xef\x54\x6d\x95\x5d\x34\xab\x60\x59" , {- in = -} "\xab\xf2\x1c\x0b\x02\xfe\xb8\x8f\x85\x6d\xf4\xa3\x73\x81\xbc\xe3\xcc\x12\x85\x17\xd4" , {- out = -} "\x6e\x37\xa6\xef\x54\x6d\x95\x5d\x34\xab\x60\x59\xf3\x29\x05\xb8\x8a\x64\x1b\x04\xb9\xc9\xff\xb5\x8c\xc3\x90\x90\x0f\x3d\xa1\x2a\xb1\x6d\xce\x9e\x82\xef\xa1\x6d\xa6\x20\x59" , {- M = -} 10) ] cryptonite-0.26/tests/KAT_AES/KATOCB3.hs0000644000000000000000000000316713414232447015675 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.26/tests/KAT_AES/KATXTS.hs0000644000000000000000000002611113414232447015657 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.26/tests/KAT_AES.hs0000644000000000000000000000740613414232447014647 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_AES (tests) where import Imports import BlockCipher import Data.Maybe import Crypto.Cipher.Types import qualified Crypto.Cipher.AES as AES import qualified Data.ByteString as B 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.KATCCM as KATCCM 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 toKatCCM (k,iv,h,i,o,m) = KAT_AEAD { aeadMode = AEAD_CCM (B.length i) (ccmMVal m) CCM_L2 , aeadKey = k , aeadIV = iv , aeadHeader = h , aeadPlaintext = i , aeadCiphertext = ct , aeadTaglen = m , aeadTag = at } where ccmMVal x = fromMaybe (error $ "unsupported CCM tag length: " ++ show x) $ lookup x [ (4, CCM_M4), (6, CCM_M6), (8, CCM_M8), (10, CCM_M10) , (12, CCM_M12), (14, CCM_M14), (16, CCM_M16) ] ctWithTag = B.drop (B.length h) o (ct, at) = B.splitAt (B.length ctWithTag - m) ctWithTag 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 ++ map toKatCCM KATCCM.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.26/tests/KAT_AFIS.hs0000644000000000000000000000360513414232447014756 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.26/tests/KAT_Argon2.hs0000644000000000000000000000232013414232447015355 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.26/tests/KAT_Blowfish.hs0000644000000000000000000001034213414232447016005 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.26/tests/KAT_CAST5.hs0000644000000000000000000000134113470442731015047 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_CAST5 (tests) where import BlockCipher import qualified Crypto.Cipher.CAST5 as CAST5 vectors_ecb = -- key plaintext ciphertext [ KAT_ECB "\x01\x23\x45\x67\x12\x34\x56\x78\x23\x45\x67\x89\x34\x56\x78\x9A" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x23\x8B\x4F\xE5\x84\x7E\x44\xB2" , KAT_ECB "\x01\x23\x45\x67\x12\x34\x56\x78\x23\x45" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\xEB\x6A\x71\x1A\x2C\x02\x27\x1B" , KAT_ECB "\x01\x23\x45\x67\x12" "\x01\x23\x45\x67\x89\xAB\xCD\xEF" "\x7A\xC8\x16\xD1\x6E\x9B\x30\x2E" ] kats = defaultKATs { kat_ECB = vectors_ecb } tests = testBlockCipher kats (undefined :: CAST5.CAST5) cryptonite-0.26/tests/KAT_Camellia.hs0000644000000000000000000000337713414232447015751 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.26/tests/KAT_Curve25519.hs0000644000000000000000000000312013414232447015716 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)) , testCase "2" (alicePublic @=? Curve25519.toPublic alicePrivate) , testCase "3" (bobPublic @=? Curve25519.toPublic bobPrivate) ] tests = testGroup "Curve25519" [ testGroup "KATs" katTests ] cryptonite-0.26/tests/KAT_Curve448.hs0000644000000000000000000000403013414232447015551 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.26/tests/KAT_DES.hs0000644000000000000000000001046513414232447014651 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.26/tests/KAT_Ed25519.hs0000644000000000000000000002132313414232447015167 0ustar0000000000000000{-# LANGUAGE BangPatterns #-} {-# LANGUAGE OverloadedStrings #-} 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) vectors = [ Vec { vecSec = "\x9d\x61\xb1\x9d\xef\xfd\x5a\x60\xba\x84\x4a\xf4\x92\xec\x2c\xc4\x44\x49\xc5\x69\x7b\x32\x69\x19\x70\x3b\xac\x03\x1c\xae\x7f\x60" , vecPub = "\xd7\x5a\x98\x01\x82\xb1\x0a\xb7\xd5\x4b\xfe\xd3\xc9\x64\x07\x3a\x0e\xe1\x72\xf3\xda\xa6\x23\x25\xaf\x02\x1a\x68\xf7\x07\x51\x1a" , vecMsg = "" , vecSig = "\xe5\x56\x43\x00\xc3\x60\xac\x72\x90\x86\xe2\xcc\x80\x6e\x82\x8a\x84\x87\x7f\x1e\xb8\xe5\xd9\x74\xd8\x73\xe0\x65\x22\x49\x01\x55\x5f\xb8\x82\x15\x90\xa3\x3b\xac\xc6\x1e\x39\x70\x1c\xf9\xb4\x6b\xd2\x5b\xf5\xf0\x59\x5b\xbe\x24\x65\x51\x41\x43\x8e\x7a\x10\x0b" } , 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" } , Vec { vecSec = "\xc5\xaa\x8d\xf4\x3f\x9f\x83\x7b\xed\xb7\x44\x2f\x31\xdc\xb7\xb1\x66\xd3\x85\x35\x07\x6f\x09\x4b\x85\xce\x3a\x2e\x0b\x44\x58\xf7" , vecPub = "\xfc\x51\xcd\x8e\x62\x18\xa1\xa3\x8d\xa4\x7e\xd0\x02\x30\xf0\x58\x08\x16\xed\x13\xba\x33\x03\xac\x5d\xeb\x91\x15\x48\x90\x80\x25" , vecMsg = "\xaf\x82" , vecSig = "\x62\x91\xd6\x57\xde\xec\x24\x02\x48\x27\xe6\x9c\x3a\xbe\x01\xa3\x0c\xe5\x48\xa2\x84\x74\x3a\x44\x5e\x36\x80\xd7\xdb\x5a\xc3\xac\x18\xff\x9b\x53\x8d\x16\xf2\x90\xae\x67\xf7\x60\x98\x4d\xc6\x59\x4a\x7c\x15\xe9\x71\x6e\xd2\x8d\xc0\x27\xbe\xce\xea\x1e\xc4\x0a" } , Vec { vecSec = "\xf5\xe5\x76\x7c\xf1\x53\x31\x95\x17\x63\x0f\x22\x68\x76\xb8\x6c\x81\x60\xcc\x58\x3b\xc0\x13\x74\x4c\x6b\xf2\x55\xf5\xcc\x0e\xe5" , vecPub = "\x27\x81\x17\xfc\x14\x4c\x72\x34\x0f\x67\xd0\xf2\x31\x6e\x83\x86\xce\xff\xbf\x2b\x24\x28\xc9\xc5\x1f\xef\x7c\x59\x7f\x1d\x42\x6e" , vecMsg = "\x08\xb8\xb2\xb7\x33\x42\x42\x43\x76\x0f\xe4\x26\xa4\xb5\x49\x08\x63\x21\x10\xa6\x6c\x2f\x65\x91\xea\xbd\x33\x45\xe3\xe4\xeb\x98\xfa\x6e\x26\x4b\xf0\x9e\xfe\x12\xee\x50\xf8\xf5\x4e\x9f\x77\xb1\xe3\x55\xf6\xc5\x05\x44\xe2\x3f\xb1\x43\x3d\xdf\x73\xbe\x84\xd8\x79\xde\x7c\x00\x46\xdc\x49\x96\xd9\xe7\x73\xf4\xbc\x9e\xfe\x57\x38\x82\x9a\xdb\x26\xc8\x1b\x37\xc9\x3a\x1b\x27\x0b\x20\x32\x9d\x65\x86\x75\xfc\x6e\xa5\x34\xe0\x81\x0a\x44\x32\x82\x6b\xf5\x8c\x94\x1e\xfb\x65\xd5\x7a\x33\x8b\xbd\x2e\x26\x64\x0f\x89\xff\xbc\x1a\x85\x8e\xfc\xb8\x55\x0e\xe3\xa5\xe1\x99\x8b\xd1\x77\xe9\x3a\x73\x63\xc3\x44\xfe\x6b\x19\x9e\xe5\xd0\x2e\x82\xd5\x22\xc4\xfe\xba\x15\x45\x2f\x80\x28\x8a\x82\x1a\x57\x91\x16\xec\x6d\xad\x2b\x3b\x31\x0d\xa9\x03\x40\x1a\xa6\x21\x00\xab\x5d\x1a\x36\x55\x3e\x06\x20\x3b\x33\x89\x0c\xc9\xb8\x32\xf7\x9e\xf8\x05\x60\xcc\xb9\xa3\x9c\xe7\x67\x96\x7e\xd6\x28\xc6\xad\x57\x3c\xb1\x16\xdb\xef\xef\xd7\x54\x99\xda\x96\xbd\x68\xa8\xa9\x7b\x92\x8a\x8b\xbc\x10\x3b\x66\x21\xfc\xde\x2b\xec\xa1\x23\x1d\x20\x6b\xe6\xcd\x9e\xc7\xaf\xf6\xf6\xc9\x4f\xcd\x72\x04\xed\x34\x55\xc6\x8c\x83\xf4\xa4\x1d\xa4\xaf\x2b\x74\xef\x5c\x53\xf1\xd8\xac\x70\xbd\xcb\x7e\xd1\x85\xce\x81\xbd\x84\x35\x9d\x44\x25\x4d\x95\x62\x9e\x98\x55\xa9\x4a\x7c\x19\x58\xd1\xf8\xad\xa5\xd0\x53\x2e\xd8\xa5\xaa\x3f\xb2\xd1\x7b\xa7\x0e\xb6\x24\x8e\x59\x4e\x1a\x22\x97\xac\xbb\xb3\x9d\x50\x2f\x1a\x8c\x6e\xb6\xf1\xce\x22\xb3\xde\x1a\x1f\x40\xcc\x24\x55\x41\x19\xa8\x31\xa9\xaa\xd6\x07\x9c\xad\x88\x42\x5d\xe6\xbd\xe1\xa9\x18\x7e\xbb\x60\x92\xcf\x67\xbf\x2b\x13\xfd\x65\xf2\x70\x88\xd7\x8b\x7e\x88\x3c\x87\x59\xd2\xc4\xf5\xc6\x5a\xdb\x75\x53\x87\x8a\xd5\x75\xf9\xfa\xd8\x78\xe8\x0a\x0c\x9b\xa6\x3b\xcb\xcc\x27\x32\xe6\x94\x85\xbb\xc9\xc9\x0b\xfb\xd6\x24\x81\xd9\x08\x9b\xec\xcf\x80\xcf\xe2\xdf\x16\xa2\xcf\x65\xbd\x92\xdd\x59\x7b\x07\x07\xe0\x91\x7a\xf4\x8b\xbb\x75\xfe\xd4\x13\xd2\x38\xf5\x55\x5a\x7a\x56\x9d\x80\xc3\x41\x4a\x8d\x08\x59\xdc\x65\xa4\x61\x28\xba\xb2\x7a\xf8\x7a\x71\x31\x4f\x31\x8c\x78\x2b\x23\xeb\xfe\x80\x8b\x82\xb0\xce\x26\x40\x1d\x2e\x22\xf0\x4d\x83\xd1\x25\x5d\xc5\x1a\xdd\xd3\xb7\x5a\x2b\x1a\xe0\x78\x45\x04\xdf\x54\x3a\xf8\x96\x9b\xe3\xea\x70\x82\xff\x7f\xc9\x88\x8c\x14\x4d\xa2\xaf\x58\x42\x9e\xc9\x60\x31\xdb\xca\xd3\xda\xd9\xaf\x0d\xcb\xaa\xaf\x26\x8c\xb8\xfc\xff\xea\xd9\x4f\x3c\x7c\xa4\x95\xe0\x56\xa9\xb4\x7a\xcd\xb7\x51\xfb\x73\xe6\x66\xc6\xc6\x55\xad\xe8\x29\x72\x97\xd0\x7a\xd1\xba\x5e\x43\xf1\xbc\xa3\x23\x01\x65\x13\x39\xe2\x29\x04\xcc\x8c\x42\xf5\x8c\x30\xc0\x4a\xaf\xdb\x03\x8d\xda\x08\x47\xdd\x98\x8d\xcd\xa6\xf3\xbf\xd1\x5c\x4b\x4c\x45\x25\x00\x4a\xa0\x6e\xef\xf8\xca\x61\x78\x3a\xac\xec\x57\xfb\x3d\x1f\x92\xb0\xfe\x2f\xd1\xa8\x5f\x67\x24\x51\x7b\x65\xe6\x14\xad\x68\x08\xd6\xf6\xee\x34\xdf\xf7\x31\x0f\xdc\x82\xae\xbf\xd9\x04\xb0\x1e\x1d\xc5\x4b\x29\x27\x09\x4b\x2d\xb6\x8d\x6f\x90\x3b\x68\x40\x1a\xde\xbf\x5a\x7e\x08\xd7\x8f\xf4\xef\x5d\x63\x65\x3a\x65\x04\x0c\xf9\xbf\xd4\xac\xa7\x98\x4a\x74\xd3\x71\x45\x98\x67\x80\xfc\x0b\x16\xac\x45\x16\x49\xde\x61\x88\xa7\xdb\xdf\x19\x1f\x64\xb5\xfc\x5e\x2a\xb4\x7b\x57\xf7\xf7\x27\x6c\xd4\x19\xc1\x7a\x3c\xa8\xe1\xb9\x39\xae\x49\xe4\x88\xac\xba\x6b\x96\x56\x10\xb5\x48\x01\x09\xc8\xb1\x7b\x80\xe1\xb7\xb7\x50\xdf\xc7\x59\x8d\x5d\x50\x11\xfd\x2d\xcc\x56\x00\xa3\x2e\xf5\xb5\x2a\x1e\xcc\x82\x0e\x30\x8a\xa3\x42\x72\x1a\xac\x09\x43\xbf\x66\x86\xb6\x4b\x25\x79\x37\x65\x04\xcc\xc4\x93\xd9\x7e\x6a\xed\x3f\xb0\xf9\xcd\x71\xa4\x3d\xd4\x97\xf0\x1f\x17\xc0\xe2\xcb\x37\x97\xaa\x2a\x2f\x25\x66\x56\x16\x8e\x6c\x49\x6a\xfc\x5f\xb9\x32\x46\xf6\xb1\x11\x63\x98\xa3\x46\xf1\xa6\x41\xf3\xb0\x41\xe9\x89\xf7\x91\x4f\x90\xcc\x2c\x7f\xff\x35\x78\x76\xe5\x06\xb5\x0d\x33\x4b\xa7\x7c\x22\x5b\xc3\x07\xba\x53\x71\x52\xf3\xf1\x61\x0e\x4e\xaf\xe5\x95\xf6\xd9\xd9\x0d\x11\xfa\xa9\x33\xa1\x5e\xf1\x36\x95\x46\x86\x8a\x7f\x3a\x45\xa9\x67\x68\xd4\x0f\xd9\xd0\x34\x12\xc0\x91\xc6\x31\x5c\xf4\xfd\xe7\xcb\x68\x60\x69\x37\x38\x0d\xb2\xea\xaa\x70\x7b\x4c\x41\x85\xc3\x2e\xdd\xcd\xd3\x06\x70\x5e\x4d\xc1\xff\xc8\x72\xee\xee\x47\x5a\x64\xdf\xac\x86\xab\xa4\x1c\x06\x18\x98\x3f\x87\x41\xc5\xef\x68\xd3\xa1\x01\xe8\xa3\xb8\xca\xc6\x0c\x90\x5c\x15\xfc\x91\x08\x40\xb9\x4c\x00\xa0\xb9\xd0" , vecSig = "\x0a\xab\x4c\x90\x05\x01\xb3\xe2\x4d\x7c\xdf\x46\x63\x32\x6a\x3a\x87\xdf\x5e\x48\x43\xb2\xcb\xdb\x67\xcb\xf6\xe4\x60\xfe\xc3\x50\xaa\x53\x71\xb1\x50\x8f\x9f\x45\x28\xec\xea\x23\xc4\x36\xd9\x4b\x5e\x8f\xcd\x4f\x68\x1e\x30\xa6\xac\x00\xa9\x70\x4a\x18\x8a\x03" } , Vec { vecSec = "\x83\x3f\xe6\x24\x09\x23\x7b\x9d\x62\xec\x77\x58\x75\x20\x91\x1e\x9a\x75\x9c\xec\x1d\x19\x75\x5b\x7d\xa9\x01\xb9\x6d\xca\x3d\x42" , vecPub = "\xec\x17\x2b\x93\xad\x5e\x56\x3b\xf4\x93\x2c\x70\xe1\x24\x50\x34\xc3\x54\x67\xef\x2e\xfd\x4d\x64\xeb\xf8\x19\x68\x34\x67\xe2\xbf" , vecMsg = "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f\xa5\x4c\xa4\x9f" , vecSig = "\xdc\x2a\x44\x59\xe7\x36\x96\x33\xa5\x2b\x1b\xf2\x77\x83\x9a\x00\x20\x10\x09\xa3\xef\xbf\x3e\xcb\x69\xbe\xa2\x18\x6c\x26\xb5\x89\x09\x35\x1f\xc9\xac\x90\xb3\xec\xfd\xfb\xc7\xc6\x64\x31\xe0\x30\x3d\xca\x17\x9c\x13\x8a\xc1\x7a\xd9\xbe\xf1\x17\x73\x31\xa7\x04" } ] doPublicKeyTest (i, vec) = testCase (show i) (pub @=? Ed25519.toPublic sec) where !pub = throwCryptoError $ Ed25519.publicKey (vecPub vec) !sec = throwCryptoError $ Ed25519.secretKey (vecSec vec) doSignatureTest (i, vec) = testCase (show i) (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) doVerifyTest (i, vec) = testCase (show i) (True @=? Ed25519.verify pub (vecMsg vec) sig) where !sig = throwCryptoError $ Ed25519.signature (vecSig vec) !pub = throwCryptoError $ Ed25519.publicKey (vecPub vec) tests = testGroup "Ed25519" [ testCase "gen secretkey" (Ed25519.generateSecretKey *> pure ()) , testGroup "gen publickey" $ map doPublicKeyTest (zip [katZero..] vectors) , testGroup "gen signature" $ map doSignatureTest (zip [katZero..] vectors) , testGroup "verify sig" $ map doVerifyTest (zip [katZero..] vectors) ] cryptonite-0.26/tests/KAT_Ed448.hs0000644000000000000000000003537413414232447015034 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE BangPatterns #-} module KAT_Ed448 ( tests ) where import Crypto.Error import qualified Crypto.PubKey.Ed448 as Ed448 import Imports data Vec = Vec { vecSec :: ByteString , vecPub :: ByteString , vecMsg :: ByteString , vecSig :: ByteString } deriving (Show,Eq) vectors = [ Vec { vecSec = "\x6c\x82\xa5\x62\xcb\x80\x8d\x10\xd6\x32\xbe\x89\xc8\x51\x3e\xbf\x6c\x92\x9f\x34\xdd\xfa\x8c\x9f\x63\xc9\x96\x0e\xf6\xe3\x48\xa3\x52\x8c\x8a\x3f\xcc\x2f\x04\x4e\x39\xa3\xfc\x5b\x94\x49\x2f\x8f\x03\x2e\x75\x49\xa2\x00\x98\xf9\x5b" , vecPub = "\x5f\xd7\x44\x9b\x59\xb4\x61\xfd\x2c\xe7\x87\xec\x61\x6a\xd4\x6a\x1d\xa1\x34\x24\x85\xa7\x0e\x1f\x8a\x0e\xa7\x5d\x80\xe9\x67\x78\xed\xf1\x24\x76\x9b\x46\xc7\x06\x1b\xd6\x78\x3d\xf1\xe5\x0f\x6c\xd1\xfa\x1a\xbe\xaf\xe8\x25\x61\x80" , vecMsg = "" , vecSig = "\x53\x3a\x37\xf6\xbb\xe4\x57\x25\x1f\x02\x3c\x0d\x88\xf9\x76\xae\x2d\xfb\x50\x4a\x84\x3e\x34\xd2\x07\x4f\xd8\x23\xd4\x1a\x59\x1f\x2b\x23\x3f\x03\x4f\x62\x82\x81\xf2\xfd\x7a\x22\xdd\xd4\x7d\x78\x28\xc5\x9b\xd0\xa2\x1b\xfd\x39\x80\xff\x0d\x20\x28\xd4\xb1\x8a\x9d\xf6\x3e\x00\x6c\x5d\x1c\x2d\x34\x5b\x92\x5d\x8d\xc0\x0b\x41\x04\x85\x2d\xb9\x9a\xc5\xc7\xcd\xda\x85\x30\xa1\x13\xa0\xf4\xdb\xb6\x11\x49\xf0\x5a\x73\x63\x26\x8c\x71\xd9\x58\x08\xff\x2e\x65\x26\x00" } , Vec { vecSec = "\xc4\xea\xb0\x5d\x35\x70\x07\xc6\x32\xf3\xdb\xb4\x84\x89\x92\x4d\x55\x2b\x08\xfe\x0c\x35\x3a\x0d\x4a\x1f\x00\xac\xda\x2c\x46\x3a\xfb\xea\x67\xc5\xe8\xd2\x87\x7c\x5e\x3b\xc3\x97\xa6\x59\x94\x9e\xf8\x02\x1e\x95\x4e\x0a\x12\x27\x4e" , vecPub = "\x43\xba\x28\xf4\x30\xcd\xff\x45\x6a\xe5\x31\x54\x5f\x7e\xcd\x0a\xc8\x34\xa5\x5d\x93\x58\xc0\x37\x2b\xfa\x0c\x6c\x67\x98\xc0\x86\x6a\xea\x01\xeb\x00\x74\x28\x02\xb8\x43\x8e\xa4\xcb\x82\x16\x9c\x23\x51\x60\x62\x7b\x4c\x3a\x94\x80" , vecMsg = "\x03" , vecSig = "\x26\xb8\xf9\x17\x27\xbd\x62\x89\x7a\xf1\x5e\x41\xeb\x43\xc3\x77\xef\xb9\xc6\x10\xd4\x8f\x23\x35\xcb\x0b\xd0\x08\x78\x10\xf4\x35\x25\x41\xb1\x43\xc4\xb9\x81\xb7\xe1\x8f\x62\xde\x8c\xcd\xf6\x33\xfc\x1b\xf0\x37\xab\x7c\xd7\x79\x80\x5e\x0d\xbc\xc0\xaa\xe1\xcb\xce\xe1\xaf\xb2\xe0\x27\xdf\x36\xbc\x04\xdc\xec\xbf\x15\x43\x36\xc1\x9f\x0a\xf7\xe0\xa6\x47\x29\x05\xe7\x99\xf1\x95\x3d\x2a\x0f\xf3\x34\x8a\xb2\x1a\xa4\xad\xaf\xd1\xd2\x34\x44\x1c\xf8\x07\xc0\x3a\x00" } , Vec { vecSec = "\xcd\x23\xd2\x4f\x71\x42\x74\xe7\x44\x34\x32\x37\xb9\x32\x90\xf5\x11\xf6\x42\x5f\x98\xe6\x44\x59\xff\x20\x3e\x89\x85\x08\x3f\xfd\xf6\x05\x00\x55\x3a\xbc\x0e\x05\xcd\x02\x18\x4b\xdb\x89\xc4\xcc\xd6\x7e\x18\x79\x51\x26\x7e\xb3\x28" , vecPub = "\xdc\xea\x9e\x78\xf3\x5a\x1b\xf3\x49\x9a\x83\x1b\x10\xb8\x6c\x90\xaa\xc0\x1c\xd8\x4b\x67\xa0\x10\x9b\x55\xa3\x6e\x93\x28\xb1\xe3\x65\xfc\xe1\x61\xd7\x1c\xe7\x13\x1a\x54\x3e\xa4\xcb\x5f\x7e\x9f\x1d\x8b\x00\x69\x64\x47\x00\x14\x00" , vecMsg = "\x0c\x3e\x54\x40\x74\xec\x63\xb0\x26\x5e\x0c" , vecSig = "\x1f\x0a\x88\x88\xce\x25\xe8\xd4\x58\xa2\x11\x30\x87\x9b\x84\x0a\x90\x89\xd9\x99\xaa\xba\x03\x9e\xaf\x3e\x3a\xfa\x09\x0a\x09\xd3\x89\xdb\xa8\x2c\x4f\xf2\xae\x8a\xc5\xcd\xfb\x7c\x55\xe9\x4d\x5d\x96\x1a\x29\xfe\x01\x09\x94\x1e\x00\xb8\xdb\xde\xea\x6d\x3b\x05\x10\x68\xdf\x72\x54\xc0\xcd\xc1\x29\xcb\xe6\x2d\xb2\xdc\x95\x7d\xbb\x47\xb5\x1f\xd3\xf2\x13\xfb\x86\x98\xf0\x64\x77\x42\x50\xa5\x02\x89\x61\xc9\xbf\x8f\xfd\x97\x3f\xe5\xd5\xc2\x06\x49\x2b\x14\x0e\x00" } , Vec { vecSec = "\x25\x8c\xdd\x4a\xda\x32\xed\x9c\x9f\xf5\x4e\x63\x75\x6a\xe5\x82\xfb\x8f\xab\x2a\xc7\x21\xf2\xc8\xe6\x76\xa7\x27\x68\x51\x3d\x93\x9f\x63\xdd\xdb\x55\x60\x91\x33\xf2\x9a\xdf\x86\xec\x99\x29\xdc\xcb\x52\xc1\xc5\xfd\x2f\xf7\xe2\x1b" , vecPub = "\x3b\xa1\x6d\xa0\xc6\xf2\xcc\x1f\x30\x18\x77\x40\x75\x6f\x5e\x79\x8d\x6b\xc5\xfc\x01\x5d\x7c\x63\xcc\x95\x10\xee\x3f\xd4\x4a\xdc\x24\xd8\xe9\x68\xb6\xe4\x6e\x6f\x94\xd1\x9b\x94\x53\x61\x72\x6b\xd7\x5e\x14\x9e\xf0\x98\x17\xf5\x80" , vecMsg = "\x64\xa6\x5f\x3c\xde\xdc\xdd\x66\x81\x1e\x29\x15" , vecSig = "\x7e\xee\xab\x7c\x4e\x50\xfb\x79\x9b\x41\x8e\xe5\xe3\x19\x7f\xf6\xbf\x15\xd4\x3a\x14\xc3\x43\x89\xb5\x9d\xd1\xa7\xb1\xb8\x5b\x4a\xe9\x04\x38\xac\xa6\x34\xbe\xa4\x5e\x3a\x26\x95\xf1\x27\x0f\x07\xfd\xcd\xf7\xc6\x2b\x8e\xfe\xaf\x00\xb4\x5c\x2c\x96\xba\x45\x7e\xb1\xa8\xbf\x07\x5a\x3d\xb2\x8e\x5c\x24\xf6\xb9\x23\xed\x4a\xd7\x47\xc3\xc9\xe0\x3c\x70\x79\xef\xb8\x7c\xb1\x10\xd3\xa9\x98\x61\xe7\x20\x03\xcb\xae\x6d\x6b\x8b\x82\x7e\x4e\x6c\x14\x30\x64\xff\x3c\x00" } , Vec { vecSec = "\x7e\xf4\xe8\x45\x44\x23\x67\x52\xfb\xb5\x6b\x8f\x31\xa2\x3a\x10\xe4\x28\x14\xf5\xf5\x5c\xa0\x37\xcd\xcc\x11\xc6\x4c\x9a\x3b\x29\x49\xc1\xbb\x60\x70\x03\x14\x61\x17\x32\xa6\xc2\xfe\xa9\x8e\xeb\xc0\x26\x6a\x11\xa9\x39\x70\x10\x0e" , vecPub = "\xb3\xda\x07\x9b\x0a\xa4\x93\xa5\x77\x20\x29\xf0\x46\x7b\xae\xbe\xe5\xa8\x11\x2d\x9d\x3a\x22\x53\x23\x61\xda\x29\x4f\x7b\xb3\x81\x5c\x5d\xc5\x9e\x17\x6b\x4d\x9f\x38\x1c\xa0\x93\x8e\x13\xc6\xc0\x7b\x17\x4b\xe6\x5d\xfa\x57\x8e\x80" , vecMsg = "\x64\xa6\x5f\x3c\xde\xdc\xdd\x66\x81\x1e\x29\x15\xe7" , vecSig = "\x6a\x12\x06\x6f\x55\x33\x1b\x6c\x22\xac\xd5\xd5\xbf\xc5\xd7\x12\x28\xfb\xda\x80\xae\x8d\xec\x26\xbd\xd3\x06\x74\x3c\x50\x27\xcb\x48\x90\x81\x0c\x16\x2c\x02\x74\x68\x67\x5e\xcf\x64\x5a\x83\x17\x6c\x0d\x73\x23\xa2\xcc\xde\x2d\x80\xef\xe5\xa1\x26\x8e\x8a\xca\x1d\x6f\xbc\x19\x4d\x3f\x77\xc4\x49\x86\xeb\x4a\xb4\x17\x79\x19\xad\x8b\xec\x33\xeb\x47\xbb\xb5\xfc\x6e\x28\x19\x6f\xd1\xca\xf5\x6b\x4e\x7e\x0b\xa5\x51\x92\x34\xd0\x47\x15\x5a\xc7\x27\xa1\x05\x31\x00" } , Vec { vecSec = "\xd6\x5d\xf3\x41\xad\x13\xe0\x08\x56\x76\x88\xba\xed\xda\x8e\x9d\xcd\xc1\x7d\xc0\x24\x97\x4e\xa5\xb4\x22\x7b\x65\x30\xe3\x39\xbf\xf2\x1f\x99\xe6\x8c\xa6\x96\x8f\x3c\xca\x6d\xfe\x0f\xb9\xf4\xfa\xb4\xfa\x13\x5d\x55\x42\xea\x3f\x01" , vecPub = "\xdf\x97\x05\xf5\x8e\xdb\xab\x80\x2c\x7f\x83\x63\xcf\xe5\x56\x0a\xb1\xc6\x13\x2c\x20\xa9\xf1\xdd\x16\x34\x83\xa2\x6f\x8a\xc5\x3a\x39\xd6\x80\x8b\xf4\xa1\xdf\xbd\x26\x1b\x09\x9b\xb0\x3b\x3f\xb5\x09\x06\xcb\x28\xbd\x8a\x08\x1f\x00" , vecMsg = "\xbd\x0f\x6a\x37\x47\xcd\x56\x1b\xdd\xdf\x46\x40\xa3\x32\x46\x1a\x4a\x30\xa1\x2a\x43\x4c\xd0\xbf\x40\xd7\x66\xd9\xc6\xd4\x58\xe5\x51\x22\x04\xa3\x0c\x17\xd1\xf5\x0b\x50\x79\x63\x1f\x64\xeb\x31\x12\x18\x2d\xa3\x00\x58\x35\x46\x11\x13\x71\x8d\x1a\x5e\xf9\x44" , vecSig = "\x55\x4b\xc2\x48\x08\x60\xb4\x9e\xab\x85\x32\xd2\xa5\x33\xb7\xd5\x78\xef\x47\x3e\xeb\x58\xc9\x8b\xb2\xd0\xe1\xce\x48\x8a\x98\xb1\x8d\xfd\xe9\xb9\xb9\x07\x75\xe6\x7f\x47\xd4\xa1\xc3\x48\x20\x58\xef\xc9\xf4\x0d\x2c\xa0\x33\xa0\x80\x1b\x63\xd4\x5b\x3b\x72\x2e\xf5\x52\xba\xd3\xb4\xcc\xb6\x67\xda\x35\x01\x92\xb6\x1c\x50\x8c\xf7\xb6\xb5\xad\xad\xc2\xc8\xd9\xa4\x46\xef\x00\x3f\xb0\x5c\xba\x5f\x30\xe8\x8e\x36\xec\x27\x03\xb3\x49\xca\x22\x9c\x26\x70\x83\x39\x00" } , Vec { vecSec = "\x2e\xc5\xfe\x3c\x17\x04\x5a\xbd\xb1\x36\xa5\xe6\xa9\x13\xe3\x2a\xb7\x5a\xe6\x8b\x53\xd2\xfc\x14\x9b\x77\xe5\x04\x13\x2d\x37\x56\x9b\x7e\x76\x6b\xa7\x4a\x19\xbd\x61\x62\x34\x3a\x21\xc8\x59\x0a\xa9\xce\xbc\xa9\x01\x4c\x63\x6d\xf5" , vecPub = "\x79\x75\x6f\x01\x4d\xcf\xe2\x07\x9f\x5d\xd9\xe7\x18\xbe\x41\x71\xe2\xef\x24\x86\xa0\x8f\x25\x18\x6f\x6b\xff\x43\xa9\x93\x6b\x9b\xfe\x12\x40\x2b\x08\xae\x65\x79\x8a\x3d\x81\xe2\x2e\x9e\xc8\x0e\x76\x90\x86\x2e\xf3\xd4\xed\x3a\x00" , vecMsg = "\x15\x77\x75\x32\xb0\xbd\xd0\xd1\x38\x9f\x63\x6c\x5f\x6b\x9b\xa7\x34\xc9\x0a\xf5\x72\x87\x7e\x2d\x27\x2d\xd0\x78\xaa\x1e\x56\x7c\xfa\x80\xe1\x29\x28\xbb\x54\x23\x30\xe8\x40\x9f\x31\x74\x50\x41\x07\xec\xd5\xef\xac\x61\xae\x75\x04\xda\xbe\x2a\x60\x2e\xde\x89\xe5\xcc\xa6\x25\x7a\x7c\x77\xe2\x7a\x70\x2b\x3a\xe3\x9f\xc7\x69\xfc\x54\xf2\x39\x5a\xe6\xa1\x17\x8c\xab\x47\x38\xe5\x43\x07\x2f\xc1\xc1\x77\xfe\x71\xe9\x2e\x25\xbf\x03\xe4\xec\xb7\x2f\x47\xb6\x4d\x04\x65\xaa\xea\x4c\x7f\xad\x37\x25\x36\xc8\xba\x51\x6a\x60\x39\xc3\xc2\xa3\x9f\x0e\x4d\x83\x2b\xe4\x32\xdf\xa9\xa7\x06\xa6\xe5\xc7\xe1\x9f\x39\x79\x64\xca\x42\x58\x00\x2f\x7c\x05\x41\xb5\x90\x31\x6d\xbc\x56\x22\xb6\xb2\xa6\xfe\x7a\x4a\xbf\xfd\x96\x10\x5e\xca\x76\xea\x7b\x98\x81\x6a\xf0\x74\x8c\x10\xdf\x04\x8c\xe0\x12\xd9\x01\x01\x5a\x51\xf1\x89\xf3\x88\x81\x45\xc0\x36\x50\xaa\x23\xce\x89\x4c\x3b\xd8\x89\xe0\x30\xd5\x65\x07\x1c\x59\xf4\x09\xa9\x98\x1b\x51\x87\x8f\xd6\xfc\x11\x06\x24\xdc\xbc\xde\x0b\xf7\xa6\x9c\xcc\xe3\x8f\xab\xdf\x86\xf3\xbe\xf6\x04\x48\x19\xde\x11" , vecSig = "\xc6\x50\xdd\xbb\x06\x01\xc1\x9c\xa1\x14\x39\xe1\x64\x0d\xd9\x31\xf4\x3c\x51\x8e\xa5\xbe\xa7\x0d\x3d\xcd\xe5\xf4\x19\x1f\xe5\x3f\x00\xcf\x96\x65\x46\xb7\x2b\xcc\x7d\x58\xbe\x2b\x9b\xad\xef\x28\x74\x39\x54\xe3\xa4\x4a\x23\xf8\x80\xe8\xd4\xf1\xcf\xce\x2d\x7a\x61\x45\x2d\x26\xda\x05\x89\x6f\x0a\x50\xda\x66\xa2\x39\xa8\xa1\x88\xb6\xd8\x25\xb3\x30\x5a\xd7\x7b\x73\xfb\xac\x08\x36\xec\xc6\x09\x87\xfd\x08\x52\x7c\x1a\x8e\x80\xd5\x82\x3e\x65\xca\xfe\x2a\x3d\x00" } , Vec { vecSec = "\x87\x2d\x09\x37\x80\xf5\xd3\x73\x0d\xf7\xc2\x12\x66\x4b\x37\xb8\xa0\xf2\x4f\x56\x81\x0d\xaa\x83\x82\xcd\x4f\xa3\xf7\x76\x34\xec\x44\xdc\x54\xf1\xc2\xed\x9b\xea\x86\xfa\xfb\x76\x32\xd8\xbe\x19\x9e\xa1\x65\xf5\xad\x55\xdd\x9c\xe8" , vecPub = "\xa8\x1b\x2e\x8a\x70\xa5\xac\x94\xff\xdb\xcc\x9b\xad\xfc\x3f\xeb\x08\x01\xf2\x58\x57\x8b\xb1\x14\xad\x44\xec\xe1\xec\x0e\x79\x9d\xa0\x8e\xff\xb8\x1c\x5d\x68\x5c\x0c\x56\xf6\x4e\xec\xae\xf8\xcd\xf1\x1c\xc3\x87\x37\x83\x8c\xf4\x00" , vecMsg = "\x6d\xdf\x80\x2e\x1a\xae\x49\x86\x93\x5f\x7f\x98\x1b\xa3\xf0\x35\x1d\x62\x73\xc0\xa0\xc2\x2c\x9c\x0e\x83\x39\x16\x8e\x67\x54\x12\xa3\xde\xbf\xaf\x43\x5e\xd6\x51\x55\x80\x07\xdb\x43\x84\xb6\x50\xfc\xc0\x7e\x3b\x58\x6a\x27\xa4\xf7\xa0\x0a\xc8\xa6\xfe\xc2\xcd\x86\xae\x4b\xf1\x57\x0c\x41\xe6\xa4\x0c\x93\x1d\xb2\x7b\x2f\xaa\x15\xa8\xce\xdd\x52\xcf\xf7\x36\x2c\x4e\x6e\x23\xda\xec\x0f\xbc\x3a\x79\xb6\x80\x6e\x31\x6e\xfc\xc7\xb6\x81\x19\xbf\x46\xbc\x76\xa2\x60\x67\xa5\x3f\x29\x6d\xaf\xdb\xdc\x11\xc7\x7f\x77\x77\xe9\x72\x66\x0c\xf4\xb6\xa9\xb3\x69\xa6\x66\x5f\x02\xe0\xcc\x9b\x6e\xdf\xad\x13\x6b\x4f\xab\xe7\x23\xd2\x81\x3d\xb3\x13\x6c\xfd\xe9\xb6\xd0\x44\x32\x2f\xee\x29\x47\x95\x2e\x03\x1b\x73\xab\x5c\x60\x33\x49\xb3\x07\xbd\xc2\x7b\xc6\xcb\x8b\x8b\xbd\x7b\xd3\x23\x21\x9b\x80\x33\xa5\x81\xb5\x9e\xad\xeb\xb0\x9b\x3c\x4f\x3d\x22\x77\xd4\xf0\x34\x36\x24\xac\xc8\x17\x80\x47\x28\xb2\x5a\xb7\x97\x17\x2b\x4c\x5c\x21\xa2\x2f\x9c\x78\x39\xd6\x43\x00\x23\x2e\xb6\x6e\x53\xf3\x1c\x72\x3f\xa3\x7f\xe3\x87\xc7\xd3\xe5\x0b\xdf\x98\x13\xa3\x0e\x5b\xb1\x2c\xf4\xcd\x93\x0c\x40\xcf\xb4\xe1\xfc\x62\x25\x92\xa4\x95\x88\x79\x44\x94\xd5\x6d\x24\xea\x4b\x40\xc8\x9f\xc0\x59\x6c\xc9\xeb\xb9\x61\xc8\xcb\x10\xad\xde\x97\x6a\x5d\x60\x2b\x1c\x3f\x85\xb9\xb9\xa0\x01\xed\x3c\x6a\x4d\x3b\x14\x37\xf5\x20\x96\xcd\x19\x56\xd0\x42\xa5\x97\xd5\x61\xa5\x96\xec\xd3\xd1\x73\x5a\x8d\x57\x0e\xa0\xec\x27\x22\x5a\x2c\x4a\xaf\xf2\x63\x06\xd1\x52\x6c\x1a\xf3\xca\x6d\x9c\xf5\xa2\xc9\x8f\x47\xe1\xc4\x6d\xb9\xa3\x32\x34\xcf\xd4\xd8\x1f\x2c\x98\x53\x8a\x09\xeb\xe7\x69\x98\xd0\xd8\xfd\x25\x99\x7c\x7d\x25\x5c\x6d\x66\xec\xe6\xfa\x56\xf1\x11\x44\x95\x0f\x02\x77\x95\xe6\x53\x00\x8f\x4b\xd7\xca\x2d\xee\x85\xd8\xe9\x0f\x3d\xc3\x15\x13\x0c\xe2\xa0\x03\x75\xa3\x18\xc7\xc3\xd9\x7b\xe2\xc8\xce\x5b\x6d\xb4\x1a\x62\x54\xff\x26\x4f\xa6\x15\x5b\xae\xe3\xb0\x77\x3c\x0f\x49\x7c\x57\x3f\x19\xbb\x4f\x42\x40\x28\x1f\x0b\x1f\x4f\x7b\xe8\x57\xa4\xe5\x9d\x41\x6c\x06\xb4\xc5\x0f\xa0\x9e\x18\x10\xdd\xc6\xb1\x46\x7b\xae\xac\x5a\x36\x68\xd1\x1b\x6e\xca\xa9\x01\x44\x00\x16\xf3\x89\xf8\x0a\xcc\x4d\xb9\x77\x02\x5e\x7f\x59\x24\x38\x8c\x7e\x34\x0a\x73\x2e\x55\x44\x40\xe7\x65\x70\xf8\xdd\x71\xb7\xd6\x40\xb3\x45\x0d\x1f\xd5\xf0\x41\x0a\x18\xf9\xa3\x49\x4f\x70\x7c\x71\x7b\x79\xb4\xbf\x75\xc9\x84\x00\xb0\x96\xb2\x16\x53\xb5\xd2\x17\xcf\x35\x65\xc9\x59\x74\x56\xf7\x07\x03\x49\x7a\x07\x87\x63\x82\x9b\xc0\x1b\xb1\xcb\xc8\xfa\x04\xea\xdc\x9a\x6e\x3f\x66\x99\x58\x7a\x9e\x75\xc9\x4e\x5b\xab\x00\x36\xe0\xb2\xe7\x11\x39\x2c\xff\x00\x47\xd0\xd6\xb0\x5b\xd2\xa5\x88\xbc\x10\x97\x18\x95\x42\x59\xf1\xd8\x66\x78\xa5\x79\xa3\x12\x0f\x19\xcf\xb2\x96\x3f\x17\x7a\xeb\x70\xf2\xd4\x84\x48\x26\x26\x2e\x51\xb8\x02\x71\x27\x20\x68\xef\x5b\x38\x56\xfa\x85\x35\xaa\x2a\x88\xb2\xd4\x1f\x2a\x0e\x2f\xda\x76\x24\xc2\x85\x02\x72\xac\x4a\x2f\x56\x1f\x8f\x2f\x7a\x31\x8b\xfd\x5c\xaf\x96\x96\x14\x9e\x4a\xc8\x24\xad\x34\x60\x53\x8f\xdc\x25\x42\x1b\xee\xc2\xcc\x68\x18\x16\x2d\x06\xbb\xed\x0c\x40\xa3\x87\x19\x23\x49\xdb\x67\xa1\x18\xba\xda\x6c\xd5\xab\x01\x40\xee\x27\x32\x04\xf6\x28\xaa\xd1\xc1\x35\xf7\x70\x27\x9a\x65\x1e\x24\xd8\xc1\x4d\x75\xa6\x05\x9d\x76\xb9\x6a\x6f\xd8\x57\xde\xf5\xe0\xb3\x54\xb2\x7a\xb9\x37\xa5\x81\x5d\x16\xb5\xfa\xe4\x07\xff\x18\x22\x2c\x6d\x1e\xd2\x63\xbe\x68\xc9\x5f\x32\xd9\x08\xbd\x89\x5c\xd7\x62\x07\xae\x72\x64\x87\x56\x7f\x9a\x67\xda\xd7\x9a\xbe\xc3\x16\xf6\x83\xb1\x7f\x2d\x02\xbf\x07\xe0\xac\x8b\x5b\xc6\x16\x2c\xf9\x46\x97\xb3\xc2\x7c\xd1\xfe\xa4\x9b\x27\xf2\x3b\xa2\x90\x18\x71\x96\x25\x06\x52\x0c\x39\x2d\xa8\xb6\xad\x0d\x99\xf7\x01\x3f\xbc\x06\xc2\xc1\x7a\x56\x95\x00\xc8\xa7\x69\x64\x81\xc1\xcd\x33\xe9\xb1\x4e\x40\xb8\x2e\x79\xa5\xf5\xdb\x82\x57\x1b\xa9\x7b\xae\x3a\xd3\xe0\x47\x95\x15\xbb\x0e\x2b\x0f\x3b\xfc\xd1\xfd\x33\x03\x4e\xfc\x62\x45\xed\xdd\x7e\xe2\x08\x6d\xda\xe2\x60\x0d\x8c\xa7\x3e\x21\x4e\x8c\x2b\x0b\xdb\x2b\x04\x7c\x6a\x46\x4a\x56\x2e\xd7\x7b\x73\xd2\xd8\x41\xc4\xb3\x49\x73\x55\x12\x57\x71\x3b\x75\x36\x32\xef\xba\x34\x81\x69\xab\xc9\x0a\x68\xf4\x26\x11\xa4\x01\x26\xd7\xcb\x21\xb5\x86\x95\x56\x81\x86\xf7\xe5\x69\xd2\xff\x0f\x9e\x74\x5d\x04\x87\xdd\x2e\xb9\x97\xca\xfc\x5a\xbf\x9d\xd1\x02\xe6\x2f\xf6\x6c\xba\x87" , vecSig = "\xe3\x01\x34\x5a\x41\xa3\x9a\x4d\x72\xff\xf8\xdf\x69\xc9\x80\x75\xa0\xcc\x08\x2b\x80\x2f\xc9\xb2\xb6\xbc\x50\x3f\x92\x6b\x65\xbd\xdf\x7f\x4c\x8f\x1c\xb4\x9f\x63\x96\xaf\xc8\xa7\x0a\xbe\x6d\x8a\xef\x0d\xb4\x78\xd4\xc6\xb2\x97\x00\x76\xc6\xa0\x48\x4f\xe7\x6d\x76\xb3\xa9\x76\x25\xd7\x9f\x1c\xe2\x40\xe7\xc5\x76\x75\x0d\x29\x55\x28\x28\x6f\x71\x9b\x41\x3d\xe9\xad\xa3\xe8\xeb\x78\xed\x57\x36\x03\xce\x30\xd8\xbb\x76\x17\x85\xdc\x30\xdb\xc3\x20\x86\x9e\x1a\x00" } ] doPublicKeyTest (i, vec) = testCase (show i) (pub @=? Ed448.toPublic sec) where !pub = throwCryptoError $ Ed448.publicKey (vecPub vec) !sec = throwCryptoError $ Ed448.secretKey (vecSec vec) doSignatureTest (i, vec) = testCase (show i) (sig @=? Ed448.sign sec pub (vecMsg vec)) where !sig = throwCryptoError $ Ed448.signature (vecSig vec) !pub = throwCryptoError $ Ed448.publicKey (vecPub vec) !sec = throwCryptoError $ Ed448.secretKey (vecSec vec) doVerifyTest (i, vec) = testCase (show i) (True @=? Ed448.verify pub (vecMsg vec) sig) where !sig = throwCryptoError $ Ed448.signature (vecSig vec) !pub = throwCryptoError $ Ed448.publicKey (vecPub vec) tests = testGroup "Ed448" [ testCase "gen secretkey" (Ed448.generateSecretKey *> pure ()) , testGroup "gen publickey" $ map doPublicKeyTest (zip [katZero..] vectors) , testGroup "gen signature" $ map doSignatureTest (zip [katZero..] vectors) , testGroup "verify sig" $ map doVerifyTest (zip [katZero..] vectors) ] cryptonite-0.26/tests/KAT_CMAC.hs0000644000000000000000000001426713414232447014745 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.26/tests/KAT_HKDF.hs0000644000000000000000000000611113470442731014744 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_HKDF (tests) where import qualified Crypto.KDF.HKDF as HKDF import Crypto.Hash (SHA256(..), HashAlgorithm) 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.26/tests/KAT_HMAC.hs0000644000000000000000000001671013414232447014745 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 = [ testIncrProperties MD5 , testIncrProperties SHA1 , testIncrProperties SHA256 , testIncrProperties SHA3_224 , testIncrProperties SHA3_256 , testIncrProperties SHA3_384 , testIncrProperties SHA3_512 ] where --testIncrProperties :: HashAlgorithm a => a -> [Property] testIncrProperties 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.26/tests/KAT_KMAC.hs0000644000000000000000000001264513470442731014754 0ustar0000000000000000{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} module KAT_KMAC (tests) where import Crypto.Hash (SHAKE128(..), SHAKE256(..), HashAlgorithm, digestFromByteString) import qualified Crypto.MAC.KMAC as KMAC import qualified Data.ByteString as B import Imports data MACVector hash = MACVector { macString :: ByteString , macKey :: ByteString , macSecret :: ByteString , macResult :: KMAC.KMAC hash } instance Show (KMAC.KMAC a) where show (KMAC.KMAC d) = show d digest :: HashAlgorithm hash => ByteString -> KMAC.KMAC hash digest = maybe (error "cannot get digest") KMAC.KMAC . digestFromByteString vectors128 :: [MACVector (SHAKE128 256)] vectors128 = [ MACVector { macString = "" , macKey = B.pack [ 0x40 .. 0x5f ] , macSecret = B.pack [ 0x00 .. 0x03 ] , macResult = digest "\xe5\x78\x0b\x0d\x3e\xa6\xf7\xd3\xa4\x29\xc5\x70\x6a\xa4\x3a\x00\xfa\xdb\xd7\xd4\x96\x28\x83\x9e\x31\x87\x24\x3f\x45\x6e\xe1\x4e" } , MACVector { macString = "My Tagged Application" , macKey = B.pack [ 0x40 .. 0x5f ] , macSecret = B.pack [ 0x00 .. 0x03 ] , macResult = digest "\x3b\x1f\xba\x96\x3c\xd8\xb0\xb5\x9e\x8c\x1a\x6d\x71\x88\x8b\x71\x43\x65\x1a\xf8\xba\x0a\x70\x70\xc0\x97\x9e\x28\x11\x32\x4a\xa5" } , MACVector { macString = "My Tagged Application" , macKey = B.pack [ 0x40 .. 0x5f ] , macSecret = B.pack [ 0x00 .. 0xc7 ] , macResult = digest "\x1f\x5b\x4e\x6c\xca\x02\x20\x9e\x0d\xcb\x5c\xa6\x35\xb8\x9a\x15\xe2\x71\xec\xc7\x60\x07\x1d\xfd\x80\x5f\xaa\x38\xf9\x72\x92\x30" } ] vectors256 :: [MACVector (SHAKE256 512)] vectors256 = [ MACVector { macString = "My Tagged Application" , macKey = B.pack [ 0x40 .. 0x5f ] , macSecret = B.pack [ 0x00 .. 0x03 ] , macResult = digest "\x20\xc5\x70\xc3\x13\x46\xf7\x03\xc9\xac\x36\xc6\x1c\x03\xcb\x64\xc3\x97\x0d\x0c\xfc\x78\x7e\x9b\x79\x59\x9d\x27\x3a\x68\xd2\xf7\xf6\x9d\x4c\xc3\xde\x9d\x10\x4a\x35\x16\x89\xf2\x7c\xf6\xf5\x95\x1f\x01\x03\xf3\x3f\x4f\x24\x87\x10\x24\xd9\xc2\x77\x73\xa8\xdd" } , MACVector { macString = "" , macKey = B.pack [ 0x40 .. 0x5f ] , macSecret = B.pack [ 0x00 .. 0xc7 ] , macResult = digest "\x75\x35\x8c\xf3\x9e\x41\x49\x4e\x94\x97\x07\x92\x7c\xee\x0a\xf2\x0a\x3f\xf5\x53\x90\x4c\x86\xb0\x8f\x21\xcc\x41\x4b\xcf\xd6\x91\x58\x9d\x27\xcf\x5e\x15\x36\x9c\xbb\xff\x8b\x9a\x4c\x2e\xb1\x78\x00\x85\x5d\x02\x35\xff\x63\x5d\xa8\x25\x33\xec\x6b\x75\x9b\x69" } , MACVector { macString = "My Tagged Application" , macKey = B.pack [ 0x40 .. 0x5f ] , macSecret = B.pack [ 0x00 .. 0xc7 ] , macResult = digest "\xb5\x86\x18\xf7\x1f\x92\xe1\xd5\x6c\x1b\x8c\x55\xdd\xd7\xcd\x18\x8b\x97\xb4\xca\x4d\x99\x83\x1e\xb2\x69\x9a\x83\x7d\xa2\xe4\xd9\x70\xfb\xac\xfd\xe5\x00\x33\xae\xa5\x85\xf1\xa2\x70\x85\x10\xc3\x2d\x07\x88\x08\x01\xbd\x18\x28\x98\xfe\x47\x68\x76\xfc\x89\x65" } ] macTests :: [TestTree] macTests = [ testGroup "SHAKE128" (concatMap toMACTest $ zip is vectors128) , testGroup "SHAKE256" (concatMap toMACTest $ zip is vectors256) ] where toMACTest (i, MACVector{..}) = [ testCase (show i) (macResult @=? KMAC.kmac macString macKey macSecret) , testCase ("incr-" ++ show i) (macResult @=? KMAC.finalize (KMAC.update (KMAC.initialize macString macKey) macSecret)) ] is :: [Int] is = [1..] data MacIncremental a = MacIncremental ByteString ByteString ByteString (KMAC.KMAC a) deriving (Show,Eq) instance KMAC.HashSHAKE a => Arbitrary (MacIncremental a) where arbitrary = do str <- arbitraryBSof 0 49 key <- arbitraryBSof 1 89 msg <- arbitraryBSof 1 99 return $ MacIncremental str key msg (KMAC.kmac str key msg) data MacIncrementalList a = MacIncrementalList ByteString ByteString [ByteString] (KMAC.KMAC a) deriving (Show,Eq) instance KMAC.HashSHAKE a => Arbitrary (MacIncrementalList a) where arbitrary = do str <- arbitraryBSof 0 49 key <- arbitraryBSof 1 89 msgs <- choose (1,20) >>= \n -> replicateM n (arbitraryBSof 1 99) return $ MacIncrementalList str key msgs (KMAC.kmac str key (B.concat msgs)) macIncrementalTests :: [TestTree] macIncrementalTests = [ testIncrProperties "SHAKE128_256" (SHAKE128 :: SHAKE128 256) , testIncrProperties "SHAKE256_512" (SHAKE256 :: SHAKE256 512) ] where testIncrProperties :: KMAC.HashSHAKE a => TestName -> a -> TestTree testIncrProperties name a = testGroup name [ testProperty "list-one" (prop_inc0 a) , testProperty "list-multi" (prop_inc1 a) ] prop_inc0 :: KMAC.HashSHAKE a => a -> MacIncremental a -> Bool prop_inc0 _ (MacIncremental str secret msg result) = result `assertEq` KMAC.finalize (KMAC.update (KMAC.initialize str secret) msg) prop_inc1 :: KMAC.HashSHAKE a => a -> MacIncrementalList a -> Bool prop_inc1 _ (MacIncrementalList str secret msgs result) = result `assertEq` KMAC.finalize (foldl' KMAC.update (KMAC.initialize str secret) msgs) tests = testGroup "KMAC" [ testGroup "KATs" macTests , testGroup "properties" macIncrementalTests ] cryptonite-0.26/tests/KAT_MiyaguchiPreneel.hs0000644000000000000000000000257513470442731017474 0ustar0000000000000000 module KAT_MiyaguchiPreneel (tests) where import Crypto.Cipher.AES (AES128) import Crypto.ConstructHash.MiyaguchiPreneel as MiyaguchiPreneel import Imports 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.26/tests/KAT_PBKDF2.hs0000644000000000000000000001030413414232447015136 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.26/tests/KAT_OTP.hs0000644000000000000000000000556213470442731014703 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_OTP ( tests ) where import Crypto.Hash.Algorithms (SHA1(..), SHA256(..), SHA512(..)) import Crypto.OTP 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) totpSHA1Expected) , testGroup "SHA256" (makeKATs (totp totpSHA256Params totpSHA256Key) totpSHA256Expected) , testGroup "SHA512" (makeKATs (totp totpSHA512Params totpSHA512Key) totpSHA512Expected) ] ] ] cryptonite-0.26/tests/KAT_PubKey/DSA.hs0000644000000000000000000007463213470442731016053 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 } , VectorDSA -- 1024-bit example from RFC 6979 with SHA-1 { msg = "sample" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x7BDB6B0FF756E1BB5D53583EF979082F9AD5BD5B , r = 0x2E1A0C2562B2912CAAF89186FB0F42001585DA55 , s = 0x29EFB6B0AFF2D7A68EB70CA313022253B9A88DF5 , pgq = rfc6979Params1024 } , VectorDSA -- 1024-bit example from RFC 6979 with SHA-1 { msg = "test" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x5C842DF4F9E344EE09F056838B42C7A17F4A6433 , r = 0x42AB2052FD43E123F0607F115052A67DCD9C5C77 , s = 0x183916B0230D45B9931491D4C6B0BD2FB4AAF088 , pgq = rfc6979Params1024 } , VectorDSA -- 2048-bit example from RFC 6979 with SHA-1 { msg = "sample" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0x888FA6F7738A41BDC9846466ABDB8174C0338250AE50CE955CA16230F9CBD53E , r = 0x3A1B2DBD7489D6ED7E608FD036C83AF396E290DBD602408E8677DAABD6E7445A , s = 0xD26FCBA19FA3E3058FFC02CA1596CDBB6E0D20CB37B06054F7E36DED0CDBBCCF , pgq = rfc6979Params2048 } , VectorDSA -- 2048-bit example from RFC 6979 with SHA-1 { msg = "test" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0x6EEA486F9D41A037B2C640BC5645694FF8FF4B98D066A25F76BE641CCB24BA4F , r = 0xC18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0 , s = 0x414F22E5F31A8B6D33295C7539C1C1BA3A6160D7D68D50AC0D3A5BEAC2884FAA , pgq = rfc6979Params2048 } ] where -- (p,g,q) dsaParams = DSA.Params { DSA.params_p = 0xa8f9cd201e5e35d892f85f80e4db2599a5676a3b1d4f190330ed3256b26d0e80a0e49a8fffaaad2a24f472d2573241d4d6d6c7480c80b4c67bb4479c15ada7ea8424d2502fa01472e760241713dab025ae1b02e1703a1435f62ddf4ee4c1b664066eb22f2e3bf28bb70a2a76e4fd5ebe2d1229681b5b06439ac9c7e9d8bde283 , DSA.params_g = 0x2b3152ff6c62f14622b8f48e59f8af46883b38e79b8c74deeae9df131f8b856e3ad6c8455dab87cc0da8ac973417ce4f7878557d6cdf40b35b4a0ca3eb310c6a95d68ce284ad4e25ea28591611ee08b8444bd64b25f3f7c572410ddfb39cc728b9c936f85f419129869929cdb909a6a3a99bbe089216368171bd0ba81de4fe33 , DSA.params_q = 0xf85f0f83ac4df7ea0cdf8f469bfeeaea14156495 } vectorsSHA224 = [ VectorDSA { msg = "sample" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x562097C06782D60C3037BA7BE104774344687649 , r = 0x4BC3B686AEA70145856814A6F1BB53346F02101E , s = 0x410697B92295D994D21EDD2F4ADA85566F6F94C1 , pgq = rfc6979Params1024 } , VectorDSA { msg = "test" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x4598B8EFC1A53BC8AECD58D1ABBB0C0C71E67297 , r = 0x6868E9964E36C1689F6037F91F28D5F2C30610F2 , s = 0x49CEC3ACDC83018C5BD2674ECAAD35B8CD22940F , pgq = rfc6979Params1024 } , VectorDSA { msg = "sample" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0xBC372967702082E1AA4FCE892209F71AE4AD25A6DFD869334E6F153BD0C4D806 , r = 0xDC9F4DEADA8D8FF588E98FED0AB690FFCE858DC8C79376450EB6B76C24537E2C , s = 0xA65A9C3BC7BABE286B195D5DA68616DA8D47FA0097F36DD19F517327DC848CEC , pgq = rfc6979Params2048 } , VectorDSA { msg = "test" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0x06BD4C05ED74719106223BE33F2D95DA6B3B541DAD7BFBD7AC508213B6DA6670 , r = 0x272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3 , s = 0xE9CC286A52CCE201586722D36D1E917EB96A4EBDB47932F9576AC645B3A60806 , pgq = rfc6979Params2048 } ] vectorsSHA256 = [ VectorDSA { msg = "sample" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x519BA0546D0C39202A7D34D7DFA5E760B318BCFB , r = 0x81F2F5850BE5BC123C43F71A3033E9384611C545 , s = 0x4CDD914B65EB6C66A8AAAD27299BEE6B035F5E89 , pgq = rfc6979Params1024 } , VectorDSA { msg = "test" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x5A67592E8128E03A417B0484410FB72C0B630E1A , r = 0x22518C127299B0F6FDC9872B282B9E70D0790812 , s = 0x6837EC18F150D55DE95B5E29BE7AF5D01E4FE160 , pgq = rfc6979Params1024 } , VectorDSA { msg = "sample" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0x8926A27C40484216F052F4427CFD5647338B7B3939BC6573AF4333569D597C52 , r = 0xEACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809 , s = 0x7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53 , pgq = rfc6979Params2048 } , VectorDSA { msg = "test" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0x1D6CE6DDA1C5D37307839CD03AB0A5CBB18E60D800937D67DFB4479AAC8DEAD7 , r = 0x8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0 , s = 0x7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E , pgq = rfc6979Params2048 } ] vectorsSHA384 = [ VectorDSA { msg = "sample" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x95897CD7BBB944AA932DBC579C1C09EB6FCFC595 , r = 0x07F2108557EE0E3921BC1774F1CA9B410B4CE65A , s = 0x54DF70456C86FAC10FAB47C1949AB83F2C6F7595 , pgq = rfc6979Params1024 } , VectorDSA { msg = "test" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x220156B761F6CA5E6C9F1B9CF9C24BE25F98CD89 , r = 0x854CF929B58D73C3CBFDC421E8D5430CD6DB5E66 , s = 0x91D0E0F53E22F898D158380676A871A157CDA622 , pgq = rfc6979Params1024 } , VectorDSA { msg = "sample" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0xC345D5AB3DA0A5BCB7EC8F8FB7A7E96069E03B206371EF7D83E39068EC564920 , r = 0xB2DA945E91858834FD9BF616EBAC151EDBC4B45D27D0DD4A7F6A22739F45C00B , s = 0x19048B63D9FD6BCA1D9BAE3664E1BCB97F7276C306130969F63F38FA8319021B , pgq = rfc6979Params2048 } , VectorDSA { msg = "test" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0x206E61F73DBE1B2DC8BE736B22B079E9DACD974DB00EEBBC5B64CAD39CF9F91C , r = 0x239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE , s = 0x6BD737513D5E72FE85D1C750E0F73921FE299B945AAD1C802F15C26A43D34961 , pgq = rfc6979Params2048 } ] vectorsSHA512 = [ VectorDSA { msg = "sample" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x09ECE7CA27D0F5A4DD4E556C9DF1D21D28104F8B , r = 0x16C3491F9B8C3FBBDD5E7A7B667057F0D8EE8E1B , s = 0x02C36A127A7B89EDBB72E4FFBC71DABC7D4FC69C , pgq = rfc6979Params1024 } , VectorDSA { msg = "test" , x = 0x411602CB19A6CCC34494D79D98EF1E7ED5AF25F7 , y = 0x5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B , k = 0x65D2C2EEB175E370F28C75BFCDC028D22C7DBE9C , r = 0x8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A0 , s = 0x7C670C7AD72B6C050C109E1790008097125433E8 , pgq = rfc6979Params1024 } , VectorDSA { msg = "sample" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0x5A12994431785485B3F5F067221517791B85A597B7A9436995C89ED0374668FC , r = 0x2016ED092DC5FB669B8EFB3D1F31A91EECB199879BE0CF78F02BA062CB4C942E , s = 0xD0C76F84B5F091E141572A639A4FB8C230807EEA7D55C8A154A224400AFF2351 , pgq = rfc6979Params2048 } , VectorDSA { msg = "test" , x = 0x69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC , y = 0x667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF , k = 0xAFF1651E4CD6036D57AA8B2A05CCF1A9D5A40166340ECBBDC55BE10B568AA0AA , r = 0x89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307 , s = 0xC9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1 , pgq = rfc6979Params2048 } ] rfc6979Params1024 = DSA.Params { DSA.params_p = 0x86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED8873ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779 , DSA.params_g = 0x07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA417BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD , DSA.params_q = 0x996F967F6C8E388D9E28D01E205FBA957A5698B1 } rfc6979Params2048 = DSA.Params { DSA.params_p = 0x9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B , DSA.params_g = 0x5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7 , DSA.params_q = 0xF2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F } 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 hashAlg (i, vector) = testCase (show i) (expected @=? actual) where expected = Just $ DSA.Signature (r vector) (s vector) actual = DSA.signWith (k vector) (vectorToPrivate vector) hashAlg (msg vector) doVerifyTest hashAlg (i, vector) = testCase (show i) (True @=? actual) where actual = DSA.verify hashAlg (vectorToPublic vector) (DSA.Signature (r vector) (s vector)) (msg vector) dsaTests = testGroup "DSA" [ 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..] vectorsSHA224) , testGroup "verify" $ map (doVerifyTest SHA224) (zip [katZero..] vectorsSHA224) ] , testGroup "SHA256" [ testGroup "signature" $ map (doSignatureTest SHA256) (zip [katZero..] vectorsSHA256) , testGroup "verify" $ map (doVerifyTest SHA256) (zip [katZero..] vectorsSHA256) ] , testGroup "SHA384" [ testGroup "signature" $ map (doSignatureTest SHA384) (zip [katZero..] vectorsSHA384) , testGroup "verify" $ map (doVerifyTest SHA384) (zip [katZero..] vectorsSHA384) ] , testGroup "SHA512" [ testGroup "signature" $ map (doSignatureTest SHA512) (zip [katZero..] vectorsSHA512) , testGroup "verify" $ map (doVerifyTest SHA512) (zip [katZero..] vectorsSHA512) ] ] cryptonite-0.26/tests/KAT_PubKey/ECC.hs0000644000000000000000000002007313414232447016023 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) , localOption (QuickCheckTests 20) $ 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 , testProperty "point-negate-add" $ \aCurve -> do p <- arbitraryPoint aCurve let o = ECC.pointAdd aCurve p (ECC.pointNegate aCurve p) return $ ECC.PointO `propertyEq` o , testProperty "point-negate-negate" $ \aCurve -> do p <- arbitraryPoint aCurve return $ p `propertyEq` ECC.pointNegate aCurve (ECC.pointNegate aCurve p) , 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 , 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.26/tests/KAT_PubKey/ECDSA.hs0000644000000000000000000010456713414232447016263 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.26/tests/KAT_PubKey/OAEP.hs0000644000000000000000000002262313414232447016160 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.26/tests/KAT_PubKey/PSS.hs0000644000000000000000000011632513421720771016104 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.PSS (pssTests) where import Crypto.PubKey.RSA import qualified Crypto.PubKey.RSA.PSS as PSS import Imports -- Module contains one vector generated by the implementation itself and other -- vectors from 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 2: A 1025-bit RSA Key Pair -- ================================== rsaKey2 = PrivateKey { private_pub = PublicKey { public_n = 0x01d40c1bcf97a68ae7cdbd8a7bf3e34fa19dcca4ef75a47454375f94514d88fed006fb829f8419ff87d6315da68a1ff3a0938e9abb3464011c303ad99199cf0c7c7a8b477dce829e8844f625b115e5e9c4a59cf8f8113b6834336a2fd2689b472cbb5e5cabe674350c59b6c17e176874fb42f8fc3d176a017edc61fd326c4b33c9 , public_e = 0x010001 , public_size = 129 } , private_d = 0x027d147e4673057377fd1ea201565772176a7dc38358d376045685a2e787c23c15576bc16b9f444402d6bfc5d98a3e88ea13ef67c353eca0c0ddba9255bd7b8bb50a644afdfd1dd51695b252d22e7318d1b6687a1c10ff75545f3db0fe602d5f2b7f294e3601eab7b9d1cecd767f64692e3e536ca2846cb0c2dd486a39fa75b1 , private_p = 0x016601e926a0f8c9e26ecab769ea65a5e7c52cc9e080ef519457c644da6891c5a104d3ea7955929a22e7c68a7af9fcad777c3ccc2b9e3d3650bce404399b7e59d1 , private_q = 0x014eafa1d4d0184da7e31f877d1281ddda625664869e8379e67ad3b75eae74a580e9827abd6eb7a002cb5411f5266797768fb8e95ae40e3e8a01f35ff89e56c079 , private_dP = 0xe247cce504939b8f0a36090de200938755e2444b29539a7da7a902f6056835c0db7b52559497cfe2c61a8086d0213c472c78851800b171f6401de2e9c2756f31 , private_dQ = 0xb12fba757855e586e46f64c38a70c68b3f548d93d787b399999d4c8f0bbd2581c21e19ed0018a6d5d3df86424b3abcad40199d31495b61309f27c1bf55d487c1 , private_qinv = 0x564b1e1fa003bda91e89090425aac05b91da9ee25061e7628d5f51304a84992fdc33762bd378a59f030a334d532bd0dae8f298ea9ed844636ad5fb8cbdc03cad } vectorsKey2 = [ -- Example 2.1 VectorPSS { message = "\xda\xba\x03\x20\x66\x26\x3f\xae\xdb\x65\x98\x48\x11\x52\x78\xa5\x2c\x44\xfa\xa3\xa7\x6f\x37\x51\x5e\xd3\x36\x32\x10\x72\xc4\x0a\x9d\x9b\x53\xbc\x05\x01\x40\x78\xad\xf5\x20\x87\x51\x46\xaa\xe7\x0f\xf0\x60\x22\x6d\xcb\x7b\x1f\x1f\xc2\x7e\x93\x60" , salt = "\x57\xbf\x16\x0b\xcb\x02\xbb\x1d\xc7\x28\x0c\xf0\x45\x85\x30\xb7\xd2\x83\x2f\xf7" , signature = "\x01\x4c\x5b\xa5\x33\x83\x28\xcc\xc6\xe7\xa9\x0b\xf1\xc0\xab\x3f\xd6\x06\xff\x47\x96\xd3\xc1\x2e\x4b\x63\x9e\xd9\x13\x6a\x5f\xec\x6c\x16\xd8\x88\x4b\xdd\x99\xcf\xdc\x52\x14\x56\xb0\x74\x2b\x73\x68\x68\xcf\x90\xde\x09\x9a\xdb\x8d\x5f\xfd\x1d\xef\xf3\x9b\xa4\x00\x7a\xb7\x46\xce\xfd\xb2\x2d\x7d\xf0\xe2\x25\xf5\x46\x27\xdc\x65\x46\x61\x31\x72\x1b\x90\xaf\x44\x53\x63\xa8\x35\x8b\x9f\x60\x76\x42\xf7\x8f\xab\x0a\xb0\xf4\x3b\x71\x68\xd6\x4b\xae\x70\xd8\x82\x78\x48\xd8\xef\x1e\x42\x1c\x57\x54\xdd\xf4\x2c\x25\x89\xb5\xb3" } -- Example 2.2 , VectorPSS { message = "\xe4\xf8\x60\x1a\x8a\x6d\xa1\xbe\x34\x44\x7c\x09\x59\xc0\x58\x57\x0c\x36\x68\xcf\xd5\x1d\xd5\xf9\xcc\xd6\xad\x44\x11\xfe\x82\x13\x48\x6d\x78\xa6\xc4\x9f\x93\xef\xc2\xca\x22\x88\xce\xbc\x2b\x9b\x60\xbd\x04\xb1\xe2\x20\xd8\x6e\x3d\x48\x48\xd7\x09\xd0\x32\xd1\xe8\xc6\xa0\x70\xc6\xaf\x9a\x49\x9f\xcf\x95\x35\x4b\x14\xba\x61\x27\xc7\x39\xde\x1b\xb0\xfd\x16\x43\x1e\x46\x93\x8a\xec\x0c\xf8\xad\x9e\xb7\x2e\x83\x2a\x70\x35\xde\x9b\x78\x07\xbd\xc0\xed\x8b\x68\xeb\x0f\x5a\xc2\x21\x6b\xe4\x0c\xe9\x20\xc0\xdb\x0e\xdd\xd3\x86\x0e\xd7\x88\xef\xac\xca\xca\x50\x2d\x8f\x2b\xd6\xd1\xa7\xc1\xf4\x1f\xf4\x6f\x16\x81\xc8\xf1\xf8\x18\xe9\xc4\xf6\xd9\x1a\x0c\x78\x03\xcc\xc6\x3d\x76\xa6\x54\x4d\x84\x3e\x08\x4e\x36\x3b\x8a\xcc\x55\xaa\x53\x17\x33\xed\xb5\xde\xe5\xb5\x19\x6e\x9f\x03\xe8\xb7\x31\xb3\x77\x64\x28\xd9\xe4\x57\xfe\x3f\xbc\xb3\xdb\x72\x74\x44\x2d\x78\x58\x90\xe9\xcb\x08\x54\xb6\x44\x4d\xac\xe7\x91\xd7\x27\x3d\xe1\x88\x97\x19\x33\x8a\x77\xfe" , salt = "\x7f\x6d\xd3\x59\xe6\x04\xe6\x08\x70\xe8\x98\xe4\x7b\x19\xbf\x2e\x5a\x7b\x2a\x90" , signature = "\x01\x09\x91\x65\x6c\xca\x18\x2b\x7f\x29\xd2\xdb\xc0\x07\xe7\xae\x0f\xec\x15\x8e\xb6\x75\x9c\xb9\xc4\x5c\x5f\xf8\x7c\x76\x35\xdd\x46\xd1\x50\x88\x2f\x4d\xe1\xe9\xae\x65\xe7\xf7\xd9\x01\x8f\x68\x36\x95\x4a\x47\xc0\xa8\x1a\x8a\x6b\x6f\x83\xf2\x94\x4d\x60\x81\xb1\xaa\x7c\x75\x9b\x25\x4b\x2c\x34\xb6\x91\xda\x67\xcc\x02\x26\xe2\x0b\x2f\x18\xb4\x22\x12\x76\x1d\xcd\x4b\x90\x8a\x62\xb3\x71\xb5\x91\x8c\x57\x42\xaf\x4b\x53\x7e\x29\x69\x17\x67\x4f\xb9\x14\x19\x47\x61\x62\x1c\xc1\x9a\x41\xf6\xfb\x95\x3f\xbc\xbb\x64\x9d\xea" } -- Example 2.3 , VectorPSS { message = "\x52\xa1\xd9\x6c\x8a\xc3\x9e\x41\xe4\x55\x80\x98\x01\xb9\x27\xa5\xb4\x45\xc1\x0d\x90\x2a\x0d\xcd\x38\x50\xd2\x2a\x66\xd2\xbb\x07\x03\xe6\x7d\x58\x67\x11\x45\x95\xaa\xbf\x5a\x7a\xeb\x5a\x8f\x87\x03\x4b\xbb\x30\xe1\x3c\xfd\x48\x17\xa9\xbe\x76\x23\x00\x23\x60\x6d\x02\x86\xa3\xfa\xf8\xa4\xd2\x2b\x72\x8e\xc5\x18\x07\x9f\x9e\x64\x52\x6e\x3a\x0c\xc7\x94\x1a\xa3\x38\xc4\x37\x99\x7c\x68\x0c\xca\xc6\x7c\x66\xbf\xa1" , salt = "\xfc\xa8\x62\x06\x8b\xce\x22\x46\x72\x4b\x70\x8a\x05\x19\xda\x17\xe6\x48\x68\x8c" , signature = "\x00\x7f\x00\x30\x01\x8f\x53\xcd\xc7\x1f\x23\xd0\x36\x59\xfd\xe5\x4d\x42\x41\xf7\x58\xa7\x50\xb4\x2f\x18\x5f\x87\x57\x85\x20\xc3\x07\x42\xaf\xd8\x43\x59\xb6\xe6\xe8\xd3\xed\x95\x9d\xc6\xfe\x48\x6b\xed\xc8\xe2\xcf\x00\x1f\x63\xa7\xab\xe1\x62\x56\xa1\xb8\x4d\xf0\xd2\x49\xfc\x05\xd3\x19\x4c\xe5\xf0\x91\x27\x42\xdb\xbf\x80\xdd\x17\x4f\x6c\x51\xf6\xba\xd7\xf1\x6c\xf3\x36\x4e\xba\x09\x5a\x06\x26\x7d\xc3\x79\x38\x03\xac\x75\x26\xae\xbe\x0a\x47\x5d\x38\xb8\xc2\x24\x7a\xb5\x1c\x48\x98\xdf\x70\x47\xdc\x6a\xdf\x52\xc6\xc4" } -- Example 2.4 , VectorPSS { message = "\xa7\x18\x2c\x83\xac\x18\xbe\x65\x70\xa1\x06\xaa\x9d\x5c\x4e\x3d\xbb\xd4\xaf\xae\xb0\xc6\x0c\x4a\x23\xe1\x96\x9d\x79\xff" , salt = "\x80\x70\xef\x2d\xe9\x45\xc0\x23\x87\x68\x4b\xa0\xd3\x30\x96\x73\x22\x35\xd4\x40" , signature = "\x00\x9c\xd2\xf4\xed\xbe\x23\xe1\x23\x46\xae\x8c\x76\xdd\x9a\xd3\x23\x0a\x62\x07\x61\x41\xf1\x6c\x15\x2b\xa1\x85\x13\xa4\x8e\xf6\xf0\x10\xe0\xe3\x7f\xd3\xdf\x10\xa1\xec\x62\x9a\x0c\xb5\xa3\xb5\xd2\x89\x30\x07\x29\x8c\x30\x93\x6a\x95\x90\x3b\x6b\xa8\x55\x55\xd9\xec\x36\x73\xa0\x61\x08\xfd\x62\xa2\xfd\xa5\x6d\x1c\xe2\xe8\x5c\x4d\xb6\xb2\x4a\x81\xca\x3b\x49\x6c\x36\xd4\xfd\x06\xeb\x7c\x91\x66\xd8\xe9\x48\x77\xc4\x2b\xea\x62\x2b\x3b\xfe\x92\x51\xfd\xc2\x1d\x8d\x53\x71\xba\xda\xd7\x8a\x48\x82\x14\x79\x63\x35\xb4\x0b" } -- Example 2.5 , VectorPSS { message = "\x86\xa8\x3d\x4a\x72\xee\x93\x2a\x4f\x56\x30\xaf\x65\x79\xa3\x86\xb7\x8f\xe8\x89\x99\xe0\xab\xd2\xd4\x90\x34\xa4\xbf\xc8\x54\xdd\x94\xf1\x09\x4e\x2e\x8c\xd7\xa1\x79\xd1\x95\x88\xe4\xae\xfc\x1b\x1b\xd2\x5e\x95\xe3\xdd\x46\x1f" , salt = "\x17\x63\x9a\x4e\x88\xd7\x22\xc4\xfc\xa2\x4d\x07\x9a\x8b\x29\xc3\x24\x33\xb0\xc9" , signature = "\x00\xec\x43\x08\x24\x93\x1e\xbd\x3b\xaa\x43\x03\x4d\xae\x98\xba\x64\x6b\x8c\x36\x01\x3d\x16\x71\xc3\xcf\x1c\xf8\x26\x0c\x37\x4b\x19\xf8\xe1\xcc\x8d\x96\x50\x12\x40\x5e\x7e\x9b\xf7\x37\x86\x12\xdf\xcc\x85\xfc\xe1\x2c\xda\x11\xf9\x50\xbd\x0b\xa8\x87\x67\x40\x43\x6c\x1d\x25\x95\xa6\x4a\x1b\x32\xef\xcf\xb7\x4a\x21\xc8\x73\xb3\xcc\x33\xaa\xf4\xe3\xdc\x39\x53\xde\x67\xf0\x67\x4c\x04\x53\xb4\xfd\x9f\x60\x44\x06\xd4\x41\xb8\x16\x09\x8c\xb1\x06\xfe\x34\x72\xbc\x25\x1f\x81\x5f\x59\xdb\x2e\x43\x78\xa3\xad\xdc\x18\x1e\xcf" } -- Example 2.6 , VectorPSS { message = "\x04\x9f\x91\x54\xd8\x71\xac\x4a\x7c\x7a\xb4\x53\x25\xba\x75\x45\xa1\xed\x08\xf7\x05\x25\xb2\x66\x7c\xf1" , salt = "\x37\x81\x0d\xef\x10\x55\xed\x92\x2b\x06\x3d\xf7\x98\xde\x5d\x0a\xab\xf8\x86\xee" , signature = "\x00\x47\x5b\x16\x48\xf8\x14\xa8\xdc\x0a\xbd\xc3\x7b\x55\x27\xf5\x43\xb6\x66\xbb\x6e\x39\xd3\x0e\x5b\x49\xd3\xb8\x76\xdc\xcc\x58\xea\xc1\x4e\x32\xa2\xd5\x5c\x26\x16\x01\x44\x56\xad\x2f\x24\x6f\xc8\xe3\xd5\x60\xda\x3d\xdf\x37\x9a\x1c\x0b\xd2\x00\xf1\x02\x21\xdf\x07\x8c\x21\x9a\x15\x1b\xc8\xd4\xec\x9d\x2f\xc2\x56\x44\x67\x81\x10\x14\xef\x15\xd8\xea\x01\xc2\xeb\xbf\xf8\xc2\xc8\xef\xab\x38\x09\x6e\x55\xfc\xbe\x32\x85\xc7\xaa\x55\x88\x51\x25\x4f\xaf\xfa\x92\xc1\xc7\x2b\x78\x75\x86\x63\xef\x45\x82\x84\x31\x39\xd7\xa6" } ] -- ================================== -- Example 3: A 1026-bit RSA Key Pair -- ================================== rsaKey3 = PrivateKey { private_pub = PublicKey { public_n = 0x02f246ef451ed3eebb9a310200cc25859c048e4be798302991112eb68ce6db674e280da21feded1ae74880ca522b18db249385012827c515f0e466a1ffa691d98170574e9d0eadb087586ca48933da3cc953d95bd0ed50de10ddcb6736107d6c831c7f663e833ca4c097e700ce0fb945f88fb85fe8e5a773172565b914a471a443 , public_e = 0x010001 , public_size = 129 } , private_d = 0x651451733b56de5ac0a689a4aeb6e6894a69014e076c88dd7a667eab3232bbccd2fc44ba2fa9c31db46f21edd1fdb23c5c128a5da5bab91e7f952b67759c7cff705415ac9fa0907c7ca6178f668fb948d869da4cc3b7356f4008dfd5449d32ee02d9a477eb69fc29266e5d9070512375a50fbbcc27e238ad98425f6ebbf88991 , private_p = 0x01bd36e18ece4b0fdb2e9c9d548bd1a7d6e2c21c6fdc35074a1d05b1c6c8b3d558ea2639c9a9a421680169317252558bd148ad215aac550e2dcf12a82d0ebfe853 , private_q = 0x01b1b656ad86d8e19d5dc86292b3a192fdf6e0dd37877bad14822fa00190cab265f90d3f02057b6f54d6ecb14491e5adeacebc48bf0ebd2a2ad26d402e54f61651 , private_dP = 0x1f2779fd2e3e5e6bae05539518fba0cd0ead1aa4513a7cba18f1cf10e3f68195693d278a0f0ee72f89f9bc760d80e2f9d0261d516501c6ae39f14a476ce2ccf5 , private_dQ = 0x011a0d36794b04a854aab4b2462d439a5046c91d940b2bc6f75b62956fef35a2a6e63c5309817f307bbff9d59e7e331bd363f6d66849b18346adea169f0ae9aec1 , private_qinv = 0x0b30f0ecf558752fb3a6ce4ba2b8c675f659eba6c376585a1b39712d038ae3d2b46fcb418ae15d0905da6440e1513a30b9b7d6668fbc5e88e5ab7a175e73ba35 } vectorsKey3 = [ -- Example 3.1 VectorPSS { message = "\x59\x4b\x37\x33\x3b\xbb\x2c\x84\x52\x4a\x87\xc1\xa0\x1f\x75\xfc\xec\x0e\x32\x56\xf1\x08\xe3\x8d\xca\x36\xd7\x0d\x00\x57" , salt = "\xf3\x1a\xd6\xc8\xcf\x89\xdf\x78\xed\x77\xfe\xac\xbc\xc2\xf8\xb0\xa8\xe4\xcf\xaa" , signature = "\x00\x88\xb1\x35\xfb\x17\x94\xb6\xb9\x6c\x4a\x3e\x67\x81\x97\xf8\xca\xc5\x2b\x64\xb2\xfe\x90\x7d\x6f\x27\xde\x76\x11\x24\x96\x4a\x99\xa0\x1a\x88\x27\x40\xec\xfa\xed\x6c\x01\xa4\x74\x64\xbb\x05\x18\x23\x13\xc0\x13\x38\xa8\xcd\x09\x72\x14\xcd\x68\xca\x10\x3b\xd5\x7d\x3b\xc9\xe8\x16\x21\x3e\x61\xd7\x84\xf1\x82\x46\x7a\xbf\x8a\x01\xcf\x25\x3e\x99\xa1\x56\xea\xa8\xe3\xe1\xf9\x0e\x3c\x6e\x4e\x3a\xa2\xd8\x3e\xd0\x34\x5b\x89\xfa\xfc\x9c\x26\x07\x7c\x14\xb6\xac\x51\x45\x4f\xa2\x6e\x44\x6e\x3a\x2f\x15\x3b\x2b\x16\x79\x7f" } -- Example 3.2 , VectorPSS { message = "\x8b\x76\x95\x28\x88\x4a\x0d\x1f\xfd\x09\x0c\xf1\x02\x99\x3e\x79\x6d\xad\xcf\xbd\xdd\x38\xe4\x4f\xf6\x32\x4c\xa4\x51" , salt = "\xfc\xf9\xf0\xe1\xf1\x99\xa3\xd1\xd0\xda\x68\x1c\x5b\x86\x06\xfc\x64\x29\x39\xf7" , signature = "\x02\xa5\xf0\xa8\x58\xa0\x86\x4a\x4f\x65\x01\x7a\x7d\x69\x45\x4f\x3f\x97\x3a\x29\x99\x83\x9b\x7b\xbc\x48\xbf\x78\x64\x11\x69\x17\x95\x56\xf5\x95\xfa\x41\xf6\xff\x18\xe2\x86\xc2\x78\x30\x79\xbc\x09\x10\xee\x9c\xc3\x4f\x49\xba\x68\x11\x24\xf9\x23\xdf\xa8\x8f\x42\x61\x41\xa3\x68\xa5\xf5\xa9\x30\xc6\x28\xc2\xc3\xc2\x00\xe1\x8a\x76\x44\x72\x1a\x0c\xbe\xc6\xdd\x3f\x62\x79\xbd\xe3\xe8\xf2\xbe\x5e\x2d\x4e\xe5\x6f\x97\xe7\xce\xaf\x33\x05\x4b\xe7\x04\x2b\xd9\x1a\x63\xbb\x09\xf8\x97\xbd\x41\xe8\x11\x97\xde\xe9\x9b\x11\xaf" } -- Example 3.3 , VectorPSS { message = "\x1a\xbd\xba\x48\x9c\x5a\xda\x2f\x99\x5e\xd1\x6f\x19\xd5\xa9\x4d\x9e\x6e\xc3\x4a\x8d\x84\xf8\x45\x57\xd2\x6e\x5e\xf9\xb0\x2b\x22\x88\x7e\x3f\x9a\x4b\x69\x0a\xd1\x14\x92\x09\xc2\x0c\x61\x43\x1f\x0c\x01\x7c\x36\xc2\x65\x7b\x35\xd7\xb0\x7d\x3f\x5a\xd8\x70\x85\x07\xa9\xc1\xb8\x31\xdf\x83\x5a\x56\xf8\x31\x07\x18\x14\xea\x5d\x3d\x8d\x8f\x6a\xde\x40\xcb\xa3\x8b\x42\xdb\x7a\x2d\x3d\x7a\x29\xc8\xf0\xa7\x9a\x78\x38\xcf\x58\xa9\x75\x7f\xa2\xfe\x4c\x40\xdf\x9b\xaa\x19\x3b\xfc\x6f\x92\xb1\x23\xad\x57\xb0\x7a\xce\x3e\x6a\xc0\x68\xc9\xf1\x06\xaf\xd9\xee\xb0\x3b\x4f\x37\xc2\x5d\xbf\xbc\xfb\x30\x71\xf6\xf9\x77\x17\x66\xd0\x72\xf3\xbb\x07\x0a\xf6\x60\x55\x32\x97\x3a\xe2\x50\x51" , salt = "\x98\x6e\x7c\x43\xdb\xb6\x71\xbd\x41\xb9\xa7\xf4\xb6\xaf\xc8\x0e\x80\x5f\x24\x23" , signature = "\x02\x44\xbc\xd1\xc8\xc1\x69\x55\x73\x6c\x80\x3b\xe4\x01\x27\x2e\x18\xcb\x99\x08\x11\xb1\x4f\x72\xdb\x96\x41\x24\xd5\xfa\x76\x06\x49\xcb\xb5\x7a\xfb\x87\x55\xdb\xb6\x2b\xf5\x1f\x46\x6c\xf2\x3a\x0a\x16\x07\x57\x6e\x98\x3d\x77\x8f\xce\xff\xa9\x2d\xf7\x54\x8a\xea\x8e\xa4\xec\xad\x2c\x29\xdd\x9f\x95\xbc\x07\xfe\x91\xec\xf8\xbe\xe2\x55\xbf\xe8\x76\x2f\xd7\x69\x0a\xa9\xbf\xa4\xfa\x08\x49\xef\x72\x8c\x2c\x42\xc4\x53\x23\x64\x52\x2d\xf2\xab\x7f\x9f\x8a\x03\xb6\x3f\x7a\x49\x91\x75\x82\x86\x68\xf5\xef\x5a\x29\xe3\x80\x2c" } -- Example 3.4 , VectorPSS { message = "\x8f\xb4\x31\xf5\xee\x79\x2b\x6c\x2a\xc7\xdb\x53\xcc\x42\x86\x55\xae\xb3\x2d\x03\xf4\xe8\x89\xc5\xc2\x5d\xe6\x83\xc4\x61\xb5\x3a\xcf\x89\xf9\xf8\xd3\xaa\xbd\xf6\xb9\xf0\xc2\xa1\xde\x12\xe1\x5b\x49\xed\xb3\x91\x9a\x65\x2f\xe9\x49\x1c\x25\xa7\xfc\xe1\xf7\x22\xc2\x54\x36\x08\xb6\x9d\xc3\x75\xec" , salt = "\xf8\x31\x2d\x9c\x8e\xea\x13\xec\x0a\x4c\x7b\x98\x12\x0c\x87\x50\x90\x87\xc4\x78" , signature = "\x01\x96\xf1\x2a\x00\x5b\x98\x12\x9c\x8d\xf1\x3c\x4c\xb1\x6f\x8a\xa8\x87\xd3\xc4\x0d\x96\xdf\x3a\x88\xe7\x53\x2e\xf3\x9c\xd9\x92\xf2\x73\xab\xc3\x70\xbc\x1b\xe6\xf0\x97\xcf\xeb\xbf\x01\x18\xfd\x9e\xf4\xb9\x27\x15\x5f\x3d\xf2\x2b\x90\x4d\x90\x70\x2d\x1f\x7b\xa7\xa5\x2b\xed\x8b\x89\x42\xf4\x12\xcd\x7b\xd6\x76\xc9\xd1\x8e\x17\x03\x91\xdc\xd3\x45\xc0\x6a\x73\x09\x64\xb3\xf3\x0b\xcc\xe0\xbb\x20\xba\x10\x6f\x9a\xb0\xee\xb3\x9c\xf8\xa6\x60\x7f\x75\xc0\x34\x7f\x0a\xf7\x9f\x16\xaf\xa0\x81\xd2\xc9\x2d\x1e\xe6\xf8\x36\xb8" } -- Example 3.5 , VectorPSS { message = "\xfe\xf4\x16\x1d\xfa\xaf\x9c\x52\x95\x05\x1d\xfc\x1f\xf3\x81\x0c\x8c\x9e\xc2\xe8\x66\xf7\x07\x54\x22\xc8\xec\x42\x16\xa9\xc4\xff\x49\x42\x7d\x48\x3c\xae\x10\xc8\x53\x4a\x41\xb2\xfd\x15\xfe\xe0\x69\x60\xec\x6f\xb3\xf7\xa7\xe9\x4a\x2f\x8a\x2e\x3e\x43\xdc\x4a\x40\x57\x6c\x30\x97\xac\x95\x3b\x1d\xe8\x6f\x0b\x4e\xd3\x6d\x64\x4f\x23\xae\x14\x42\x55\x29\x62\x24\x64\xca\x0c\xbf\x0b\x17\x41\x34\x72\x38\x15\x7f\xab\x59\xe4\xde\x55\x24\x09\x6d\x62\xba\xec\x63\xac\x64" , salt = "\x50\x32\x7e\xfe\xc6\x29\x2f\x98\x01\x9f\xc6\x7a\x2a\x66\x38\x56\x3e\x9b\x6e\x2d" , signature = "\x02\x1e\xca\x3a\xb4\x89\x22\x64\xec\x22\x41\x1a\x75\x2d\x92\x22\x10\x76\xd4\xe0\x1c\x0e\x6f\x0d\xde\x9a\xfd\x26\xba\x5a\xcf\x6d\x73\x9e\xf9\x87\x54\x5d\x16\x68\x3e\x56\x74\xc9\xe7\x0f\x1d\xe6\x49\xd7\xe6\x1d\x48\xd0\xca\xeb\x4f\xb4\xd8\xb2\x4f\xba\x84\xa6\xe3\x10\x8f\xee\x7d\x07\x05\x97\x32\x66\xac\x52\x4b\x4a\xd2\x80\xf7\xae\x17\xdc\x59\xd9\x6d\x33\x51\x58\x6b\x5a\x3b\xdb\x89\x5d\x1e\x1f\x78\x20\xac\x61\x35\xd8\x75\x34\x80\x99\x83\x82\xba\x32\xb7\x34\x95\x59\x60\x8c\x38\x74\x52\x90\xa8\x5e\xf4\xe9\xf9\xbd\x83" } -- Example 3.6 , VectorPSS { message = "\xef\xd2\x37\xbb\x09\x8a\x44\x3a\xee\xb2\xbf\x6c\x3f\x8c\x81\xb8\xc0\x1b\x7f\xcb\x3f\xeb" , salt = "\xb0\xde\x3f\xc2\x5b\x65\xf5\xaf\x96\xb1\xd5\xcc\x3b\x27\xd0\xc6\x05\x30\x87\xb3" , signature = "\x01\x2f\xaf\xec\x86\x2f\x56\xe9\xe9\x2f\x60\xab\x0c\x77\x82\x4f\x42\x99\xa0\xca\x73\x4e\xd2\x6e\x06\x44\xd5\xd2\x22\xc7\xf0\xbd\xe0\x39\x64\xf8\xe7\x0a\x5c\xb6\x5e\xd4\x4e\x44\xd5\x6a\xe0\xed\xf1\xff\x86\xca\x03\x2c\xc5\xdd\x44\x04\xdb\xb7\x6a\xb8\x54\x58\x6c\x44\xee\xd8\x33\x6d\x08\xd4\x57\xce\x6c\x03\x69\x3b\x45\xc0\xf1\xef\xef\x93\x62\x4b\x95\xb8\xec\x16\x9c\x61\x6d\x20\xe5\x53\x8e\xbc\x0b\x67\x37\xa6\xf8\x2b\x4b\xc0\x57\x09\x24\xfc\x6b\x35\x75\x9a\x33\x48\x42\x62\x79\xf8\xb3\xd7\x74\x4e\x2d\x22\x24\x26\xce" } ] -- ================================== -- Example 8: A 1031-bit RSA Key Pair -- ================================== rsaKey8 = PrivateKey { private_pub = PublicKey { public_n = 0x495370a1fb18543c16d3631e3163255df62be6eee890d5f25509e4f778a8ea6fbbbcdf85dff64e0d972003ab3681fbba6dd41fd541829b2e582de9f2a4a4e0a2d0900bef4753db3cee0ee06c7dfae8b1d53b5953218f9cceea695b08668edeaadced9463b1d790d5ebf27e9115b46cad4d9a2b8efab0561b0810344739ada0733f , public_e = 0x010001 , public_size = 129 } , private_d = 0x6c66ffe98980c38fcdeab5159898836165f4b4b817c4f6a8d486ee4ea9130fe9b9092bd136d184f95f504a607eac565846d2fdd6597a8967c7396ef95a6eeebb4578a643966dca4d8ee3de842de63279c618159c1ab54a89437b6a6120e4930afb52a4ba6ced8a4947ac64b30a3497cbe701c2d6266d517219ad0ec6d347dbe9 , private_p = 0x08dad7f11363faa623d5d6d5e8a319328d82190d7127d2846c439b0ab72619b0a43a95320e4ec34fc3a9cea876422305bd76c5ba7be9e2f410c8060645a1d29edb , private_q = 0x0847e732376fc7900f898ea82eb2b0fc418565fdae62f7d9ec4ce2217b97990dd272db157f99f63c0dcbb9fbacdbd4c4dadb6df67756358ca4174825b48f49706d , private_dP = 0x05c2a83c124b3621a2aa57ea2c3efe035eff4560f33ddebb7adab81fce69a0c8c2edc16520dda83d59a23be867963ac65f2cc710bbcfb96ee103deb771d105fd85 , private_dQ = 0x04cae8aa0d9faa165c87b682ec140b8ed3b50b24594b7a3b2c220b3669bb819f984f55310a1ae7823651d4a02e99447972595139363434e5e30a7e7d241551e1b9 , private_qinv = 0x07d3e47bf686600b11ac283ce88dbb3f6051e8efd04680e44c171ef531b80b2b7c39fc766320e2cf15d8d99820e96ff30dc69691839c4b40d7b06e45307dc91f3f } vectorsKey8 = [ -- Example 8.1 VectorPSS { message = "\x81\x33\x2f\x4b\xe6\x29\x48\x41\x5e\xa1\xd8\x99\x79\x2e\xea\xcf\x6c\x6e\x1d\xb1\xda\x8b\xe1\x3b\x5c\xea\x41\xdb\x2f\xed\x46\x70\x92\xe1\xff\x39\x89\x14\xc7\x14\x25\x97\x75\xf5\x95\xf8\x54\x7f\x73\x56\x92\xa5\x75\xe6\x92\x3a\xf7\x8f\x22\xc6\x99\x7d\xdb\x90\xfb\x6f\x72\xd7\xbb\x0d\xd5\x74\x4a\x31\xde\xcd\x3d\xc3\x68\x58\x49\x83\x6e\xd3\x4a\xec\x59\x63\x04\xad\x11\x84\x3c\x4f\x88\x48\x9f\x20\x97\x35\xf5\xfb\x7f\xda\xf7\xce\xc8\xad\xdc\x58\x18\x16\x8f\x88\x0a\xcb\xf4\x90\xd5\x10\x05\xb7\xa8\xe8\x4e\x43\xe5\x42\x87\x97\x75\x71\xdd\x99\xee\xa4\xb1\x61\xeb\x2d\xf1\xf5\x10\x8f\x12\xa4\x14\x2a\x83\x32\x2e\xdb\x05\xa7\x54\x87\xa3\x43\x5c\x9a\x78\xce\x53\xed\x93\xbc\x55\x08\x57\xd7\xa9\xfb" , salt = "\x1d\x65\x49\x1d\x79\xc8\x64\xb3\x73\x00\x9b\xe6\xf6\xf2\x46\x7b\xac\x4c\x78\xfa" , signature = "\x02\x62\xac\x25\x4b\xfa\x77\xf3\xc1\xac\xa2\x2c\x51\x79\xf8\xf0\x40\x42\x2b\x3c\x5b\xaf\xd4\x0a\x8f\x21\xcf\x0f\xa5\xa6\x67\xcc\xd5\x99\x3d\x42\xdb\xaf\xb4\x09\xc5\x20\xe2\x5f\xce\x2b\x1e\xe1\xe7\x16\x57\x7f\x1e\xfa\x17\xf3\xda\x28\x05\x2f\x40\xf0\x41\x9b\x23\x10\x6d\x78\x45\xaa\xf0\x11\x25\xb6\x98\xe7\xa4\xdf\xe9\x2d\x39\x67\xbb\x00\xc4\xd0\xd3\x5b\xa3\x55\x2a\xb9\xa8\xb3\xee\xf0\x7c\x7f\xec\xdb\xc5\x42\x4a\xc4\xdb\x1e\x20\xcb\x37\xd0\xb2\x74\x47\x69\x94\x0e\xa9\x07\xe1\x7f\xbb\xca\x67\x3b\x20\x52\x23\x80\xc5" } -- Example 8.2 , VectorPSS { message = "\xe2\xf9\x6e\xaf\x0e\x05\xe7\xba\x32\x6e\xcc\xa0\xba\x7f\xd2\xf7\xc0\x23\x56\xf3\xce\xde\x9d\x0f\xaa\xbf\x4f\xcc\x8e\x60\xa9\x73\xe5\x59\x5f\xd9\xea\x08" , salt = "\x43\x5c\x09\x8a\xa9\x90\x9e\xb2\x37\x7f\x12\x48\xb0\x91\xb6\x89\x87\xff\x18\x38" , signature = "\x27\x07\xb9\xad\x51\x15\xc5\x8c\x94\xe9\x32\xe8\xec\x0a\x28\x0f\x56\x33\x9e\x44\xa1\xb5\x8d\x4d\xdc\xff\x2f\x31\x2e\x5f\x34\xdc\xfe\x39\xe8\x9c\x6a\x94\xdc\xee\x86\xdb\xbd\xae\x5b\x79\xba\x4e\x08\x19\xa9\xe7\xbf\xd9\xd9\x82\xe7\xee\x6c\x86\xee\x68\x39\x6e\x8b\x3a\x14\xc9\xc8\xf3\x4b\x17\x8e\xb7\x41\xf9\xd3\xf1\x21\x10\x9b\xf5\xc8\x17\x2f\xad\xa2\xe7\x68\xf9\xea\x14\x33\x03\x2c\x00\x4a\x8a\xa0\x7e\xb9\x90\x00\x0a\x48\xdc\x94\xc8\xba\xc8\xaa\xbe\x2b\x09\xb1\xaa\x46\xc0\xa2\xaa\x0e\x12\xf6\x3f\xbb\xa7\x75\xba\x7e" } -- Example 8.3 , VectorPSS { message = "\xe3\x5c\x6e\xd9\x8f\x64\xa6\xd5\xa6\x48\xfc\xab\x8a\xdb\x16\x33\x1d\xb3\x2e\x5d\x15\xc7\x4a\x40\xed\xf9\x4c\x3d\xc4\xa4\xde\x79\x2d\x19\x08\x89\xf2\x0f\x1e\x24\xed\x12\x05\x4a\x6b\x28\x79\x8f\xcb\x42\xd1\xc5\x48\x76\x9b\x73\x4c\x96\x37\x31\x42\x09\x2a\xed\x27\x76\x03\xf4\x73\x8d\xf4\xdc\x14\x46\x58\x6d\x0e\xc6\x4d\xa4\xfb\x60\x53\x6d\xb2\xae\x17\xfc\x7e\x3c\x04\xbb\xfb\xbb\xd9\x07\xbf\x11\x7c\x08\x63\x6f\xa1\x6f\x95\xf5\x1a\x62\x16\x93\x4d\x3e\x34\xf8\x50\x30\xf1\x7b\xbb\xc5\xba\x69\x14\x40\x58\xaf\xf0\x81\xe0\xb1\x9c\xf0\x3c\x17\x19\x5c\x5e\x88\x8b\xa5\x8f\x6f\xe0\xa0\x2e\x5c\x3b\xda\x97\x19\xa7" , salt = "\xc6\xeb\xbe\x76\xdf\x0c\x4a\xea\x32\xc4\x74\x17\x5b\x2f\x13\x68\x62\xd0\x45\x29" , signature = "\x2a\xd2\x05\x09\xd7\x8c\xf2\x6d\x1b\x6c\x40\x61\x46\x08\x6e\x4b\x0c\x91\xa9\x1c\x2b\xd1\x64\xc8\x7b\x96\x6b\x8f\xaa\x42\xaa\x0c\xa4\x46\x02\x23\x23\xba\x4b\x1a\x1b\x89\x70\x6d\x7f\x4c\x3b\xe5\x7d\x7b\x69\x70\x2d\x16\x8a\xb5\x95\x5e\xe2\x90\x35\x6b\x8c\x4a\x29\xed\x46\x7d\x54\x7e\xc2\x3c\xba\xdf\x28\x6c\xcb\x58\x63\xc6\x67\x9d\xa4\x67\xfc\x93\x24\xa1\x51\xc7\xec\x55\xaa\xc6\xdb\x40\x84\xf8\x27\x26\x82\x5c\xfe\x1a\xa4\x21\xbc\x64\x04\x9f\xb4\x2f\x23\x14\x8f\x9c\x25\xb2\xdc\x30\x04\x37\xc3\x8d\x42\x8a\xa7\x5f\x96" } -- Example 8.4 , VectorPSS { message = "\xdb\xc5\xf7\x50\xa7\xa1\x4b\xe2\xb9\x3e\x83\x8d\x18\xd1\x4a\x86\x95\xe5\x2e\x8a\xdd\x9c\x0a\xc7\x33\xb8\xf5\x6d\x27\x47\xe5\x29\xa0\xcc\xa5\x32\xdd\x49\xb9\x02\xae\xfe\xd5\x14\x44\x7f\x9e\x81\xd1\x61\x95\xc2\x85\x38\x68\xcb\x9b\x30\xf7\xd0\xd4\x95\xc6\x9d\x01\xb5\xc5\xd5\x0b\x27\x04\x5d\xb3\x86\x6c\x23\x24\xa4\x4a\x11\x0b\x17\x17\x74\x6d\xe4\x57\xd1\xc8\xc4\x5c\x3c\xd2\xa9\x29\x70\xc3\xd5\x96\x32\x05\x5d\x4c\x98\xa4\x1d\x6e\x99\xe2\xa3\xdd\xd5\xf7\xf9\x97\x9a\xb3\xcd\x18\xf3\x75\x05\xd2\x51\x41\xde\x2a\x1b\xff\x17\xb3\xa7\xdc\xe9\x41\x9e\xcc\x38\x5c\xf1\x1d\x72\x84\x0f\x19\x95\x3f\xd0\x50\x92\x51\xf6\xca\xfd\xe2\x89\x3d\x0e\x75\xc7\x81\xba\x7a\x50\x12\xca\x40\x1a\x4f\xa9\x9e\x04\xb3\xc3\x24\x9f\x92\x6d\x5a\xfe\x82\xcc\x87\xda\xb2\x2c\x3c\x1b\x10\x5d\xe4\x8e\x34\xac\xe9\xc9\x12\x4e\x59\x59\x7a\xc7\xeb\xf8" , salt = "\x02\x1f\xdc\xc6\xeb\xb5\xe1\x9b\x1c\xb1\x6e\x9c\x67\xf2\x76\x81\x65\x7f\xe2\x0a" , signature = "\x1e\x24\xe6\xe5\x86\x28\xe5\x17\x50\x44\xa9\xeb\x6d\x83\x7d\x48\xaf\x12\x60\xb0\x52\x0e\x87\x32\x7d\xe7\x89\x7e\xe4\xd5\xb9\xf0\xdf\x0b\xe3\xe0\x9e\xd4\xde\xa8\xc1\x45\x4f\xf3\x42\x3b\xb0\x8e\x17\x93\x24\x5a\x9d\xf8\xbf\x6a\xb3\x96\x8c\x8e\xdd\xc3\xb5\x32\x85\x71\xc7\x7f\x09\x1c\xc5\x78\x57\x69\x12\xdf\xeb\xd1\x64\xb9\xde\x54\x54\xfe\x0b\xe1\xc1\xf6\x38\x5b\x32\x83\x60\xce\x67\xec\x7a\x05\xf6\xe3\x0e\xb4\x5c\x17\xc4\x8a\xc7\x00\x41\xd2\xca\xb6\x7f\x0a\x2a\xe7\xaa\xfd\xcc\x8d\x24\x5e\xa3\x44\x2a\x63\x00\xcc\xc7" } -- Example 8.5 , VectorPSS { message = "\x04\xdc\x25\x1b\xe7\x2e\x88\xe5\x72\x34\x85\xb6\x38\x3a\x63\x7e\x2f\xef\xe0\x76\x60\xc5\x19\xa5\x60\xb8\xbc\x18\xbd\xed\xb8\x6e\xae\x23\x64\xea\x53\xba\x9d\xca\x6e\xb3\xd2\xe7\xd6\xb8\x06\xaf\x42\xb3\xe8\x7f\x29\x1b\x4a\x88\x81\xd5\xbf\x57\x2c\xc9\xa8\x5e\x19\xc8\x6a\xcb\x28\xf0\x98\xf9\xda\x03\x83\xc5\x66\xd3\xc0\xf5\x8c\xfd\x8f\x39\x5d\xcf\x60\x2e\x5c\xd4\x0e\x8c\x71\x83\xf7\x14\x99\x6e\x22\x97\xef" , salt = "\xc5\x58\xd7\x16\x7c\xbb\x45\x08\xad\xa0\x42\x97\x1e\x71\xb1\x37\x7e\xea\x42\x69" , signature = "\x33\x34\x1b\xa3\x57\x6a\x13\x0a\x50\xe2\xa5\xcf\x86\x79\x22\x43\x88\xd5\x69\x3f\x5a\xcc\xc2\x35\xac\x95\xad\xd6\x8e\x5e\xb1\xee\xc3\x16\x66\xd0\xca\x7a\x1c\xda\x6f\x70\xa1\xaa\x76\x2c\x05\x75\x2a\x51\x95\x0c\xdb\x8a\xf3\xc5\x37\x9f\x18\xcf\xe6\xb5\xbc\x55\xa4\x64\x82\x26\xa1\x5e\x91\x2e\xf1\x9a\xd7\x7a\xde\xea\x91\x1d\x67\xcf\xef\xd6\x9b\xa4\x3f\xa4\x11\x91\x35\xff\x64\x21\x17\xba\x98\x5a\x7e\x01\x00\x32\x5e\x95\x19\xf1\xca\x6a\x92\x16\xbd\xa0\x55\xb5\x78\x50\x15\x29\x11\x25\xe9\x0d\xcd\x07\xa2\xca\x96\x73\xee" } -- Example 8.6 , VectorPSS { message = "\x0e\xa3\x7d\xf9\xa6\xfe\xa4\xa8\xb6\x10\x37\x3c\x24\xcf\x39\x0c\x20\xfa\x6e\x21\x35\xc4\x00\xc8\xa3\x4f\x5c\x18\x3a\x7e\x8e\xa4\xc9\xae\x09\x0e\xd3\x17\x59\xf4\x2d\xc7\x77\x19\xcc\xa4\x00\xec\xdc\xc5\x17\xac\xfc\x7a\xc6\x90\x26\x75\xb2\xef\x30\xc5\x09\x66\x5f\x33\x21\x48\x2f\xc6\x9a\x9f\xb5\x70\xd1\x5e\x01\xc8\x45\xd0\xd8\xe5\x0d\x2a\x24\xcb\xf1\xcf\x0e\x71\x49\x75\xa5\xdb\x7b\x18\xd9\xe9\xe9\xcb\x91\xb5\xcb\x16\x86\x90\x60\xed\x18\xb7\xb5\x62\x45\x50\x3f\x0c\xaf\x90\x35\x2b\x8d\xe8\x1c\xb5\xa1\xd9\xc6\x33\x60\x92\xf0\xcd" , salt = "\x76\xfd\x4e\x64\xfd\xc9\x8e\xb9\x27\xa0\x40\x3e\x35\xa0\x84\xe7\x6b\xa9\xf9\x2a" , signature = "\x1e\xd1\xd8\x48\xfb\x1e\xdb\x44\x12\x9b\xd9\xb3\x54\x79\x5a\xf9\x7a\x06\x9a\x7a\x00\xd0\x15\x10\x48\x59\x3e\x0c\x72\xc3\x51\x7f\xf9\xff\x2a\x41\xd0\xcb\x5a\x0a\xc8\x60\xd7\x36\xa1\x99\x70\x4f\x7c\xb6\xa5\x39\x86\xa8\x8b\xbd\x8a\xbc\xc0\x07\x6a\x2c\xe8\x47\x88\x00\x31\x52\x5d\x44\x9d\xa2\xac\x78\x35\x63\x74\xc5\x36\xe3\x43\xfa\xa7\xcb\xa4\x2a\x5a\xaa\x65\x06\x08\x77\x91\xc0\x6a\x8e\x98\x93\x35\xae\xd1\x9b\xfa\xb2\xd5\xe6\x7e\x27\xfb\x0c\x28\x75\xaf\x89\x6c\x21\xb6\xe8\xe7\x30\x9d\x04\xe4\xf6\x72\x7e\x69\x46\x3e" } ] 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) , testGroup "signature key 1025" $ map (doSignTest rsaKey2) (zip [katZero..] vectorsKey2) , testGroup "verify key 1025" $ map (doVerifyTest rsaKey2) (zip [katZero..] vectorsKey2) , testGroup "signature key 1026" $ map (doSignTest rsaKey3) (zip [katZero..] vectorsKey3) , testGroup "verify key 1026" $ map (doVerifyTest rsaKey3) (zip [katZero..] vectorsKey3) , testGroup "signature key 1031" $ map (doSignTest rsaKey8) (zip [katZero..] vectorsKey8) , testGroup "verify key 1031" $ map (doVerifyTest rsaKey8) (zip [katZero..] vectorsKey8) ] cryptonite-0.26/tests/KAT_PubKey/P256.hs0000644000000000000000000001447013470442731016072 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 -- Cover the full range up to 2^256-1 except 0 and curveN. To test edge -- cases with arithmetic functions, some values close to 0, curveN and -- 2^256 are given higher frequency. arbitrary = P256Scalar <$> oneof [ choose (1, w) , choose (w + 1, curveN - w - 1) , choose (curveN - w, curveN - 1) , choose (curveN + 1, curveN + w) , choose (curveN + w + 1, high - w - 1) , choose (high - w, high - 1) ] where high = 2^(256 :: Int) w = 100 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 i2ospScalar :: Integer -> Bytes i2ospScalar i = case i2ospOf 32 i of Nothing -> error "invalid size of P256 scalar" Just b -> b unP256Scalar :: P256Scalar -> P256.Scalar unP256Scalar (P256Scalar r) = let rBytes = i2ospScalar r in case P256.scalarFromBinary rBytes of CryptoFailed err -> error ("cannot convert scalar: " ++ show err) CryptoPassed scalar -> scalar unP256 :: P256Scalar -> Integer unP256 (P256Scalar r) = r 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 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 `mod` curveN v' = P256.scalarAdd (unP256Scalar r) P256.scalarZero in v `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 "sub0" $ \r -> let v = unP256 r `mod` curveN v' = P256.scalarSub (unP256Scalar r) P256.scalarZero in v `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.unsafePointFromBinary 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 , testProperty "point-negate" $ propertyPointNegate ] ] 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 (unP256 r1 + unP256 r2) `mod` curveN /= 0 ==> propertyHold [ eqTest "p256" pR (P256.pointAdd p1 p2) , eqTest "ecc" peR (pointP256ToECC pR) ] propertyPointNegate r = let p = P256.toPoint (unP256Scalar r) pe = ECC.pointMul curve (unP256 r) curveGen pR = P256.pointNegate p in ECC.pointNegate curve pe `propertyEq` (pointP256ToECC pR) cryptonite-0.26/tests/KAT_PubKey/RSA.hs0000644000000000000000000001573713414232447016071 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.RSA (rsaTests) where import qualified Crypto.PubKey.RSA as RSA import qualified Crypto.PubKey.RSA.PKCS15 as RSA import Crypto.Hash import Imports import Data.Either (isRight) data VectorRSA = VectorRSA { size :: Int , msg :: ByteString , n :: Integer , e :: Integer , d :: Integer , p :: Integer , q :: Integer , dP :: Integer , dQ :: Integer , qinv :: Integer , sig :: Either RSA.Error ByteString } vectorsSHA1 = [ VectorRSA { size = 2048 `div` 8 , msg = "The quick brown fox jumps over the lazy dog" , n = 0x00c896c245fcca81775346c5f4f958229cab1aee08196dab4ee5959018b856aab93e4486f37a32da1a6804403c88473ecf9f1b9266fc682400d45329b6ec195710c98d9ba728bc09d767e7e9d9b8b102c3b7e7529b87f649a2a5ebe165da21863ec7842de600a834a8be2227bc989145b52f84ba685d45484a3d530745598a5d8a9e7551b3278bf139a770929f776aed5d43559205fe937df93eeb8ff3fb3f2ce22d4b8a5c17aeafd19758ac5e6251df09ef6a2858e8558a7f476dde4efe859ff2fcb97767614563033fd1d2d300196b1abf256f7badb16c17def3804946d1bf9cd51760176b41bbd506b44ff2bfe5bcd5052180da3cfbbc6cd6f662c06a8baed9 , e = 0x10001 , d = 0x58aa533bae8f310536d95cdd796e5cf655a7f4b9bdcbbd62859743f7b95c0de10e462a44ebaa18c07d640ba4f6344fee648d427ca56bbf2662b45407187be70173a655bc6104257182eb7f720ef2a79f2de6619c804ffca299a7179df6fac4a57179daf4052c550295f0f111ab7ae38e406ff219f9c88b38cdbcaac51bdc4e961361b87e100d168fc08b298626a806b3bfeaa9579f400bbe6e3e6e4ae9b27446e1c5ce8c10c848b9ad7b6ed3a6b3871ad6a1a88af24e581da054845c197e8bae1582858410087c1180c4f0cc61689abfd0f61b8031910f3b3779e11a7fbe823d9a704c63c313f78c994975de834ee9ead5faf6c18b3e4248c51ba307776bf845 , p = 0x00f85bfcfe55af59445f21f67ab1d8617d1f84360556eeb660d5c466f29e4d2228f9cc3fde4c594ea97069a19c666b68b6d905b65738ae63de6c11f9181ee9262313e5165591651bb3abec192abbc8c3694550bcffa451a2e2d1976bf3ecbc4480354f8d8646133298156aaa626b8807c5295850f93686400835466b6a5ccec61b , q = 0x00cec28b22b1d37c6c60d25e9747cb1bebd1270f0306db56ed8533f392d6a0cfe6b3dde13789758cf89febac214ba96667e46599f89ca210dced550ca6092a854ff95dff80ea48ff1a83455f4bb93f2ececa782da03b85a789239e8be5264130628724ceab57c8f76e4c7e822bf4fbf334c7d32610bec65047433e0e3b636afe1b , dP = 0x52fe0a50c339514f33ab19be6e67ac4c2f97f2a55e236ef674f8a89e329ffbe64d731f749d76ca7e7c7e0fef3f9a6ce78d260784a600408736fdda8b60e8f0419088612a3ee7d695f7c171b78200d8abf8e9bdfe7f5e785beb45fa610c9eed151abb76c383ef2e5cfbeb24fcb68a426e741e7b108c53d859e5d39e5970a1f839 , dQ = 0x39ef91853b47038a6ae707d2642fa9b73e782f60adbf307085eeb4c5e496532b56234a4481a40ac870275da846c74506bf9d28b3dd501c618baf5548013185018fe2a301c0a48bb726297e367dc6129ba7685d8094ad32f0dea64295074f24fbb6dabd7e8daea686a5b09d512be89d91a09cae01eb332eb389480e3cddf2d119 , qinv = 0x09ce1fa29008ef4b9798e5b8ec213dbdfec4fab4403ebf4b8786ad401ef33bc880c40a990b0826f72415192a206a504b27d2ba45ca555706200ea8e7a9b42d4077e9e6e0d80d4144966c53a36d23d30d987322dcc0013efe8df3b6b5914a2ceefc22cc5de6d569731794e9894f18f11d36a79558dc4c3ae5db1ce9bd05e7bf2e , sig = Right "\x56\x66\x99\x0f\xd4\xea\x2b\xe0\x6d\x46\x3b\x10\x99\x5b\x06\x32\x5e\xec\x29\xfe\xa4\x63\x4d\x54\xf6\x31\x74\x5d\x01\x5a\x67\x09\x2e\xa7\x02\x8a\x48\x00\x3c\x0d\xef\x04\xe7\x52\x46\xe0\xfa\xb1\x42\x26\x89\xe7\xec\x25\x44\x76\xa0\x86\x33\xb0\xbe\x22\x17\x88\x9b\x18\x4d\x3e\xc2\x9b\xd4\x61\x2b\x9e\xde\x08\x56\xf8\xd5\xee\xb8\x38\xf4\x3d\xda\x9a\xbb\x34\x58\x87\x71\x1d\x1a\x7e\xc7\x3d\x46\x39\x01\x79\x29\x8b\xa4\xcd\xce\xd7\xab\xcb\x2e\x94\x5c\xfd\x54\xcc\xef\x80\x31\xfc\x5e\x8f\xc2\x4d\x76\x1e\x4c\xbc\x50\x7a\x9b\x08\xae\x85\xeb\x6a\xe0\x80\xdc\xff\x60\x13\xb0\x31\x94\x14\x9d\x8f\x9f\x48\x38\xcf\x4c\x82\x9d\x3b\x68\xc6\xe4\xe9\x5d\x94\x74\xa2\xac\x1f\xb9\x84\x41\x86\x11\xeb\x2c\x50\x64\xd7\x00\xe0\x85\x21\x5a\xd7\xae\x9b\x4c\x8e\x6a\x92\x97\xac\xcc\xb8\x38\x4f\x41\xb9\x3d\xa9\xfe\x69\x8b\x04\x81\xad\xfb\x0f\x49\x74\xfe\x26\x9c\x86\x0c\xf3\xd1\x8e\xa1\xb5\xaf\xef\x85\x3d\xfe\xd0\x7c\xcf\x18\xe4\x0f\x14\x99\xea\x93\x61\x79\x16\xbf\x38\xac\xa2\xa2\xac\xac\x2d\xae\x21\x85\x71\x94\xda\x5d\xa1\x82\xa8\x76\x82\xe5\x2f" } , VectorRSA { size = 360 `div` 8 , msg = "The quick brown fox jumps over the lazy dog" , n = 0x00bc2d7481c83c8be55da4caeaf1a30dbf9a1226ba7443c0a66213180d3eb8e29c3162401b7be067dff8f571a8eb , e = 0x10001 , d = 0x726fb62d82c707507a2d5055a6934136270d28ce350c3a36d89066e26fb54f5b33da0bc9a05c2084f2b39be4e1 , p = 0x0e3ff89e1f95a461c9f5ee480fd7b13529a225f3ee07fb , q = 0x0d349ebc89329b493c03451ad20155de9775df55c55fd1 , dP = 0x00943adef9fb93a561967bab33f198c2c7414e777df997 , dQ = 0x078de99ceb5392f7f327dfb97717a27ae2e4606dddaa71 , qinv = 0x0c54d59eaa029844fb3fe33a180161590b1cb103cc668e , sig = Left RSA.SignatureTooLong } , VectorRSA { size = 368 `div` 8 , msg = "The quick brown fox jumps over the lazy dog" , n = 0x009cff2fd20246e390d6860b48a3926e83086d1386f7147e9f195623cf8f18546ceb20d428b77e0748864c8f611cb7 , e = 0x10001 , d = 0x0097706cbf6624dd448c3a36ce35c27d49762a4948ca33804178d2ff826f8d336aaed622801c8d76d442be371da841 , p = 0x00d12519f81441069ab1a86c38e0065e9578a46e655d5a17 , q = 0x00c02b485ac3ee241d57b6b282f830d7d5bf6f4de75c1661 , dP = 0x00a1af4611444f34f4d88d7504cf23fd711e70382c42ec07 , dQ = 0x04226a4219a90bf9dda33e9ff6bb0649c0fea20c723cc1 , qinv = 0x5dd87bf3c1e295dcc8602859a7cd74f05a2fe91a9d5877 , sig = Right "\x51\xe4\xdd\x98\xee\xd5\x06\xef\x7a\xa5\x3c\xaf\x29\x33\xa4\x91\xfa\x8b\xb8\x09\xcf\x3e\xa1\x64\x92\x71\xad\x7b\x3a\x83\xb2\xa0\x77\x94\x4e\x59\xdf\x69\x58\x2e\xc8\x8d\xa0\x70\xfe\x7d" } ] vectorToPrivate :: VectorRSA -> RSA.PrivateKey vectorToPrivate vector = RSA.PrivateKey { RSA.private_pub = vectorToPublic vector , RSA.private_d = d vector , RSA.private_p = p vector , RSA.private_q = q vector , RSA.private_dP = dP vector , RSA.private_dQ = dQ vector , RSA.private_qinv = qinv vector } vectorToPublic :: VectorRSA -> RSA.PublicKey vectorToPublic vector = RSA.PublicKey { RSA.public_size = size vector , RSA.public_n = n vector , RSA.public_e = e vector } vectorHasSignature :: VectorRSA -> Bool vectorHasSignature = isRight . sig doSignatureTest (i, vector) = testCase (show i) (expected @=? actual) where expected = sig vector actual = RSA.sign Nothing (Just SHA1) (vectorToPrivate vector) (msg vector) doVerifyTest (i, vector) = testCase (show i) (True @=? actual) where actual = RSA.verify (Just SHA1) (vectorToPublic vector) (msg vector) bs Right bs = sig vector rsaTests = testGroup "RSA" [ testGroup "SHA1" [ testGroup "signature" $ map doSignatureTest (zip [katZero..] vectorsSHA1) , testGroup "verify" $ map doVerifyTest $ filter (vectorHasSignature . snd) (zip [katZero..] vectorsSHA1) ] ] cryptonite-0.26/tests/KAT_PubKey/Rabin.hs0000644000000000000000000002365613414232447016476 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module KAT_PubKey.Rabin (rabinTests) where import qualified Data.ByteString as B import Crypto.Hash import Crypto.Number.Serialize (os2ip) import qualified Crypto.PubKey.Rabin.Basic as BRabin import qualified Crypto.PubKey.Rabin.Modified as MRabin import qualified Crypto.PubKey.Rabin.OAEP as OAEP import qualified Crypto.PubKey.Rabin.RW as RW import Imports basicRabinKey = BRabin.PrivateKey { BRabin.private_pub = BRabin.PublicKey { BRabin.public_n = 0xc9c4b0df9db989d93df4137fc2de2a9cee2610523f7a450ecbbf252babe98fba2f8e389c3e420c081e18f584c5746ca43f77f6af1fc79161f8bf8fbcb9564779986ecbe656dd16740cb8e399c33ff1dcc679e73c9c98a58c65a8673b7de57290a2d3191cb27e29d627f7ec6e874b1406051ffe9181e4d90d1b487b100ad30685 , BRabin.public_size = 128 } , BRabin.private_p = 0xe071f231ab5912285a1f8db199795f5efdea4c32f646a3436eaec091ba853a3092216f26b539bbac1fe2ab2e4fbb20aad272a434a1e909bf6d3028aecae2a7b7 , BRabin.private_q = 0xe6229470dc7da58bfcd962f1b3ddcf52304efbfb91d31c8ed84dbae2380c1ad2e338a523b4250863a689b3f262f949bd7a9f1a603c36634bb932dd71bf5daba3 , BRabin.private_a = 0x65956653f711a63b776ce45862d4cd78f1ad7b1f8ed118bb8b5ea5fffd59762da5dc7c5298e236a8e45d5c93477cbc51f214b1cd1a4980eda859c1cb05e55666 , BRabin.private_b = -0x63126dd9c5d6b5215f62012885570e1306b6a47ec1c46553f3b13ceae869149d14544438dbb976800cd62fbb52266f9a6405bc91f192a462c974bc8a6f832e03 } modifiedRabinKey = MRabin.PrivateKey { MRabin.private_pub = MRabin.PublicKey { MRabin.public_n = 0x9461a6e7c55cb610f20fd9af5d642404a63332a8d7c4fe7aa559cbcaec691e7216eed5d9322cb6a8619c220a0241b44e0d0a7cefda01fb84e59722b4e842ab5e190d214424bbdfed6d523426fc57a28045dfbb6e8159123077c542c0278ee2daf2d8993e286bf709a10a948da6b13008441581a22233f0ad3d5ebc5858ff7be5 , MRabin.public_size = 128 } , MRabin.private_p = 0xc401e0ddbe565a8797292389bebb561c35eb019116ba25cc6c865a8d3d7bc599626ddf0bc4f575c22f89144fe99fc3300dd497ec2b7acc0221e729a61756b3f3 , MRabin.private_q = 0xc1cc0e35f23f5086691a18c755881e3fe6937581948b109f47605b45d055e7b352e19ff729dfb33fbecb1d28b115e590449e5e4e228ab1876d889d3d41d87ec7 , MRabin.private_d = 0x128c34dcf8ab96c21e41fb35ebac848094c666551af89fcf54ab39795d8d23ce42dddabb264596d50c33844140483689c1a14f9dfb403f709cb2e4569d08556b9267e6460e84c69beda1defabd0285c4852c288b7ac27b78987bd19da337a6b1c7b123476732d9c0f656cc62a17f70e8fe34516cfa85ce6475bddeae9ffa0926 } rwKey = RW.PrivateKey { RW.private_pub = RW.PublicKey { RW.public_n = 0x992db4c84564c68d4ee2fe0903d938b41e83bcac48dfe8f2219ccee2ccbdefda4cbeea9f1c98a515c5f39a458f5ea11bca97102aaa3d9ac69e000093024e7b968359287cdf57bdacff5df1893df3539c7e358f037d49b5c6ae7110ab8117220c73b6265987039c2c97078fccacdd3f5a560aff5076fdc3958c532db28ab9a855 , RW.public_size = 128 } , RW.private_p = 0xc144dd739c45397d61868ca944a9729a7ad34cf90466c8f5c98a88f5ab5e3288bcfd31d4af1d441d23a756a60abd4cf05c3e0b0053eb150166a327ae31e9347b , RW.private_q = 0xcae5a381f25a27ae2c359068753118fc384471cd6027e88b8b910306fb940781261089259a3c569546677aebd268704c767a071dbd4f50cb9f15fe448788856f , RW.private_d = 0x1325b69908ac98d1a9dc5fc1207b271683d07795891bfd1e443399dc5997bdfb4997dd53e39314a2b8be7348b1ebd4237952e2055547b358d3c000126049cf729ee5d4f0ea170b902e343a8ef0831900b963ba07a3176088ab2ab095db449d0052150d6be7b5402f459f17c759f6f043b06a5da64cb86bb910d340f7fa28fdce } data EncryptionVector = EncryptionVector { seed :: ByteString , plainText :: ByteString , cipherText :: ByteString } data SignatureVector = SignatureVector { message :: ByteString , padding :: ByteString , signature :: Integer } basicRabinEncryptionVectors = [ EncryptionVector { plainText = "\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 = "\xaf\xc7\x03\xe3\x9d\x2f\x81\xc6\x3a\x80\x2a\xd1\x44\x26\x3f\x17\x0c\x0a\xe6\x48\x68\x98\x23\x14\x8f\x95\xd2\xce\xbb\xe7\x3f\x49\x34\x76\x1d\x99\x30\x7b\xeb\x84\xe5\x2a\x10\xd2\x1e\x11\x7e\x65\xe8\x88\x24\xc1\x12\xeb\x19\x0d\x97\xcd\x12\x25\x6b\x1f\x9b\x0c\x40\x40\xa3\x47\x00\xb7\x11\xf8\x50\x08\x51\x79\xe8\x1b\xd1\x77\xe0\x99\xa7\xe1\x5c\x63\xda\x29\xc7\xde\x28\x5d\x60\xed\x8e\xb2\x12\xd4\xfe\xb8\x1a\x5d\x17\x65\x80\x62\x6e\x65\x5c\x37\x07\x1c\xfa\xff\xe6\x21\xa5\x9f\xcd\x6a\x6a\xce\xa6\x96\xb2\xc5\x08\xe6" } ] basicRabinSignatureVectors = [ SignatureVector { 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" , padding = "\xe9\x87\x17\x15\xa2\xe4\x30\x15" , signature = 0xac95807bdd03ca975690151d39d23d75e5db2731c4ba30b83c3f3ea74709e4d4e340d7dab952356a76c9b8705b214e28d59f5bdc7c7fdff4e104569e30359b5c65c2dcd5b94db58505cd8b188267121700beebd7edbee492e374514646471b5c3fa252a2580dc7343f455683815d6d7c590dd3bcaa7df41d8b08197ccb183408 } ] modifiedRabinSignatureVectors = [ SignatureVector { 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" , padding = B.empty -- not used , signature = 0x278c7c269119218ab7f501ea53a97ab15a3a5a263c6daed8980abec78291e9729e0e3457731cdea8ec31a7566e93d10fc9b2615fe3e54f4533a5506ac24a3bd286e270324e538066f0ddf503f9b5e0c18e18379659834906ebd99c0d31588c66e70fc653bc8865b9239999cbd35704917d8647d1199286c533233e3e03582dd } ] rwEncryptionVectors = [ EncryptionVector { plainText = "\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 = "\x40\xc2\xe3\x36\xac\x46\x72\x8a\xaf\x33\x75\xe1\x27\xd0\x38\x40\xe2\x24\x4e\x20\xa7\x5d\x85\xd3\x74\x81\x21\xfd\xc9\x40\x90\x80\x8c\xed\x2d\xd3\x5b\xc4\xb7\xc9\x7c\x80\xa5\x2f\x63\x86\x34\x4e\x8c\x92\x07\x86\x9e\xda\xfd\xf8\x11\x83\x8a\x5a\x23\xc1\xe6\x77\x37\x5d\xf9\x5c\x60\xd1\x6d\xfd\x0c\x54\xd1\x00\xe9\xab\x97\x6d\x8e\x83\x8b\x6e\x1a\x38\x73\x43\xe2\x24\xc2\xe2\x4e\x74\x3f\xe4\x4d\xdd\x27\xed\xc7\x72\x88\xd3\x0f\x93\xb3\xdb\xa2\xb7\xaf\x6d\xe9\xab\x76\x53\x63\xf9\x62\xd7\x52\x44\x61\x60\x5d\x2e\x9b\xf7" } ] rwSignatureVectors = [ SignatureVector { 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" , padding = B.empty -- not used , signature = 0x1e57b554a8e83aacd9d4067f9535991e7db47803250cded5cc8af5458a6bb11fea852139e0afe143f9339dd94a518e354e702134d1ae222460127829d92e8bf6441336f5ae7044ec7b6c3ad8b9aeeb1ea02a49798e020cb5b558120bbb51f060eb1608ba68f90cac7edb1051c177d3bdbb99d1ad92e8d75d6f72f1d06f1d25be } ] doBasicRabinEncryptTest key (i, vector) = testCase (show i) (Right (cipherText vector) @=? actual) where actual = BRabin.encryptWithSeed (seed vector) (OAEP.defaultOAEPParams SHA1) key (plainText vector) doBasicRabinDecryptTest key (i, vector) = testCase (show i) (Just (plainText vector) @=? actual) where actual = BRabin.decrypt (OAEP.defaultOAEPParams SHA1) key (cipherText vector) doBasicRabinSignTest key (i, vector) = testCase (show i) (Right (BRabin.Signature ((os2ip $ padding vector), (signature vector))) @=? actual) where actual = BRabin.signWith (padding vector) key SHA1 (message vector) doBasicRabinVerifyTest key (i, vector) = testCase (show i) (True @=? actual) where actual = BRabin.verify key SHA1 (message vector) (BRabin.Signature ((os2ip $ padding vector), (signature vector))) doModifiedRabinSignTest key (i, vector) = testCase (show i) (Right (signature vector) @=? actual) where actual = MRabin.sign key SHA1 (message vector) doModifiedRabinVerifyTest key (i, vector) = testCase (show i) (True @=? actual) where actual = MRabin.verify key SHA1 (message vector) (signature vector) doRwEncryptTest key (i, vector) = testCase (show i) (Right (cipherText vector) @=? actual) where actual = RW.encryptWithSeed (seed vector) (OAEP.defaultOAEPParams SHA1) key (plainText vector) doRwDecryptTest key (i, vector) = testCase (show i) (Just (plainText vector) @=? actual) where actual = RW.decrypt (OAEP.defaultOAEPParams SHA1) key (cipherText vector) doRwSignTest key (i, vector) = testCase (show i) (Right (signature vector) @=? actual) where actual = RW.sign key SHA1 (message vector) doRwVerifyTest key (i, vector) = testCase (show i) (True @=? actual) where actual = RW.verify key SHA1 (message vector) (signature vector) rabinTests = testGroup "Rabin" [ testGroup "Basic" [ testGroup "encrypt" $ map (doBasicRabinEncryptTest $ BRabin.private_pub basicRabinKey) (zip [katZero..] basicRabinEncryptionVectors) , testGroup "decrypt" $ map (doBasicRabinDecryptTest $ basicRabinKey) (zip [katZero..] basicRabinEncryptionVectors) , testGroup "sign" $ map (doBasicRabinSignTest $ basicRabinKey) (zip [katZero..] basicRabinSignatureVectors) , testGroup "verify" $ map (doBasicRabinVerifyTest $ BRabin.private_pub basicRabinKey) (zip [katZero..] basicRabinSignatureVectors) ] , testGroup "Modified" [ testGroup "sign" $ map (doModifiedRabinSignTest $ modifiedRabinKey) (zip [katZero..] modifiedRabinSignatureVectors) , testGroup "verify" $ map (doModifiedRabinVerifyTest $ MRabin.private_pub modifiedRabinKey) (zip [katZero..] modifiedRabinSignatureVectors) ] , testGroup "RW" [ testGroup "encrypt" $ map (doRwEncryptTest $ RW.private_pub rwKey) (zip [katZero..] rwEncryptionVectors) , testGroup "decrypt" $ map (doRwDecryptTest $ rwKey) (zip [katZero..] rwEncryptionVectors) , testGroup "sign" $ map (doRwSignTest $ rwKey) (zip [katZero..] rwSignatureVectors) , testGroup "verify" $ map (doRwVerifyTest $ RW.private_pub rwKey) (zip [katZero..] rwSignatureVectors) ] ] cryptonite-0.26/tests/KAT_PubKey.hs0000644000000000000000000000310213414232447015423 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 KAT_PubKey.RSA import KAT_PubKey.Rabin 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) , rsaTests , pssTests , oaepTests , dsaTests , eccTests , ecdsaTests , P256.tests , rabinTests ] --newKats = [ eccKatTests ] cryptonite-0.26/tests/KAT_RC4.hs0000644000000000000000000000155713414232447014630 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.26/tests/KAT_Scrypt.hs0000644000000000000000000000355013414232447015517 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.26/tests/KAT_TripleDES.hs0000644000000000000000000000047113414232447016025 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.26/tests/KAT_Twofish.hs0000644000000000000000000000554313414232447015662 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.26/tests/ChaChaPoly1305.hs0000644000000000000000000001015513414232447016017 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.26/tests/Number.hs0000644000000000000000000001675713470442731015002 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Number (tests) where import Imports import Data.ByteArray (Bytes) import qualified Data.ByteArray as B import Crypto.Number.Basic import Crypto.Number.Generate import qualified Crypto.Number.Serialize as BE import qualified Crypto.Number.Serialize.LE as LE 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 "as-power-of-2-and-odd" $ \n -> let (e, a1) = asPowerOf2AndOdd n in n == (2^e)*a1 , testProperty "marshalling-be" $ \qaInt -> getQAInteger qaInt == BE.os2ip (BE.i2osp (getQAInteger qaInt) :: Bytes) , testProperty "marshalling-le" $ \qaInt -> getQAInteger qaInt == LE.os2ip (LE.i2osp (getQAInteger qaInt) :: Bytes) , testProperty "be-rev-le" $ \qaInt -> getQAInteger qaInt == LE.os2ip (B.reverse (BE.i2osp (getQAInteger qaInt) :: Bytes)) , testProperty "be-rev-le-40" $ \qaInt -> getQAInteger qaInt == LE.os2ip (B.reverse (BE.i2ospOf_ 40 (getQAInteger qaInt) :: Bytes)) , testProperty "le-rev-be" $ \qaInt -> getQAInteger qaInt == BE.os2ip (B.reverse (LE.i2osp (getQAInteger qaInt) :: Bytes)) , testProperty "le-rev-be-40" $ \qaInt -> getQAInteger qaInt == BE.os2ip (B.reverse (LE.i2ospOf_ 40 (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 @=? BE.i2ospOf_ sz n) toSerializationKatInteger (i, (_, n, ba)) = testCase (show i) (n @=? BE.os2ip ba) cryptonite-0.26/tests/Number/F2m.hs0000644000000000000000000000601113414232447015403 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.26/tests/Padding.hs0000644000000000000000000000247713470442731015112 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} module Padding (tests) where import qualified Data.ByteString as B import Imports 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.26/tests/Poly1305.hs0000644000000000000000000000260213414232447014765 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.26/tests/Salsa.hs0000644000000000000000000001431513414232447014600 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.26/tests/Utils.hs0000644000000000000000000001110613470442731014631 0ustar0000000000000000{-# LANGUAGE ExistentialQuantification #-} module Utils where import Control.Applicative 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` vectorOf 16 (choose (0,14)) newtype ChunkingLen0_127 = ChunkingLen0_127 [Int] deriving (Show,Eq) instance Arbitrary ChunkingLen0_127 where arbitrary = ChunkingLen0_127 `fmap` vectorOf 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 <$> arbitraryBSof 0 32 -- [ 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 = fmap B.pack . vector arbitraryBSof :: Int -> Int -> Gen ByteString arbitraryBSof minSize maxSize = choose (minSize, maxSize) >>= arbitraryBS 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.26/tests/XSalsa.hs0000644000000000000000000005467513414232447014745 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.26/benchs/Bench.hs0000644000000000000000000003737613470442731014671 0ustar0000000000000000{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts #-} module Main where import Gauge.Main import Crypto.Cipher.AES import Crypto.Cipher.Blowfish import Crypto.Cipher.CAST5 import qualified Crypto.Cipher.ChaChaPoly1305 as CP import Crypto.Cipher.DES import Crypto.Cipher.Twofish import Crypto.Cipher.Types import Crypto.ECC import Crypto.Error import Crypto.Hash import qualified Crypto.KDF.BCrypt as BCrypt import qualified Crypto.KDF.PBKDF2 as PBKDF2 import Crypto.Number.Basic (numBits) import Crypto.Number.Generate import qualified Crypto.PubKey.DH as DH import qualified Crypto.PubKey.ECC.Types as ECC import qualified Crypto.PubKey.ECC.Prim as ECC import Crypto.Random import Control.DeepSeq (NFData) import Data.ByteArray (ByteArray, Bytes) import qualified Data.ByteString as B import Number.F2m data HashAlg = forall alg . HashAlgorithm alg => HashAlg alg benchHash = [ env oneKB $ \b -> bgroup "1KB" $ map (doHashBench b) hashAlgs , env oneMB $ \b -> bgroup "1MB" $ map (doHashBench b) hashAlgs ] where doHashBench b (name, HashAlg alg) = bench name $ nf (hashWith alg) b oneKB :: IO Bytes oneKB = getRandomBytes 1024 oneMB :: IO Bytes oneMB = getRandomBytes $ 1024 * 1024 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 benchBCrypt = [ bench "cryptonite-BCrypt-4" $ nf bcrypt 4 , bench "cryptonite-BCrypt-5" $ nf bcrypt 5 , bench "cryptonite-BCrypt-7" $ nf bcrypt 7 , bench "cryptonite-BCrypt-11" $ nf bcrypt 11 ] where bcrypt :: Int -> B.ByteString bcrypt cost = BCrypt.bcrypt cost mysalt mypass mypass, mysalt :: B.ByteString mypass = "password" mysalt = "saltsaltsaltsalt" 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 "Twofish128-input=1024" $ nf (run (undefined :: Twofish128) cipherInit key16) input1024 , bench "CAST5-128-input=1024" $ nf (run (undefined :: CAST5) 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 "Twofish128-input=1024" $ nf (run (undefined :: Twofish128) cipherInit key16 iv16) input1024 , bench "CAST5-128-input=1024" $ nf (run (undefined :: CAST5) 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 (cp key32) (input64, input1024) , bench "AES-GCM" $ nf (gcm key32) (input64, input1024) , bench "AES-CCM" $ nf (ccm key32) (input64, input1024) ] where cp 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 (outtag, out) gcm k (ini, plain) = let ctx = throwCryptoError (cipherInit k) :: AES256 state = throwCryptoError $ aeadInit AEAD_GCM ctx nonce12 in aeadSimpleEncrypt state ini plain 16 ccm k (ini, plain) = let ctx = throwCryptoError (cipherInit k) :: AES256 mode = AEAD_CCM 1024 CCM_M16 CCM_L3 state = throwCryptoError $ aeadInit mode ctx nonce12 in aeadSimpleEncrypt state ini plain 16 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 benchFFDH = map doFFDHBench primes where doFFDHBench (e, p) = let bits = numBits p params = DH.Params { DH.params_p = p, DH.params_g = 2, DH.params_bits = bits } in env (generate e params) $ bench (show bits) . nf (run params) generate e params = do aPriv <- DH.PrivateNumber `fmap` generatePriv e bPriv <- DH.PrivateNumber `fmap` generatePriv e return (aPriv, DH.calculatePublic params bPriv) generatePriv e = generateParams e (Just SetHighest) False run params (priv, pub) = DH.getShared params priv pub -- RFC 7919: prime p with minimal size of exponent primes = [ (225, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B423861285C97FFFFFFFFFFFFFFFF) , (275, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B66C62E37FFFFFFFFFFFFFFFF) , (325, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E655F6AFFFFFFFFFFFFFFFF) , (375, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CD0E40E65FFFFFFFFFFFFFFFF) , (400, 0xFFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617AD3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797ABC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F619172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005C58EF1837D1683B2C6F34A26C1B2EFFA886B4238611FCFDCDE355B3B6519035BBC34F4DEF99C023861B46FC9D6E6C9077AD91D2691F7F7EE598CB0FAC186D91CAEFE130985139270B4130C93BC437944F4FD4452E2D74DD364F2E21E71F54BFF5CAE82AB9C9DF69EE86D2BC522363A0DABC521979B0DEADA1DBF9A42D5C4484E0ABCD06BFA53DDEF3C1B20EE3FD59D7C25E41D2B669E1EF16E6F52C3164DF4FB7930E9E4E58857B6AC7D5F42D69F6D187763CF1D5503400487F55BA57E31CC7A7135C886EFB4318AED6A1E012D9E6832A907600A918130C46DC778F971AD0038092999A333CB8B7A1A1DB93D7140003C2A4ECEA9F98D0ACC0A8291CDCEC97DCF8EC9B55A7F88A46B4DB5A851F44182E1C68A007E5E0DD9020BFD64B645036C7A4E677D2C38532A3A23BA4442CAF53EA63BB454329B7624C8917BDD64B1C0FD4CB38E8C334C701C3ACDAD0657FCCFEC719B1F5C3E4E46041F388147FB4CFDB477A52471F7A9A96910B855322EDB6340D8A00EF092350511E30ABEC1FFF9E3A26E7FB29F8C183023C3587E38DA0077D9B4763E4E4B94B2BBC194C6651E77CAF992EEAAC0232A281BF6B3A739C1226116820AE8DB5847A67CBEF9C9091B462D538CD72B03746AE77F5E62292C311562A846505DC82DB854338AE49F5235C95B91178CCF2DD5CACEF403EC9D1810C6272B045B3B71F9DC6B80D63FDD4A8E9ADB1E6962A69526D43161C1A41D570D7938DAD4A40E329CCFF46AAA36AD004CF600C8381E425A31D951AE64FDB23FCEC9509D43687FEB69EDD1CC5E0B8CC3BDF64B10EF86B63142A3AB8829555B2F747C932665CB2C0F1CC01BD70229388839D2AF05E454504AC78B7582822846C0BA35C35F5C59160CC046FD8251541FC68C9C86B022BB7099876A460E7451A8A93109703FEE1C217E6C3826E52C51AA691E0E423CFC99E9E31650C1217B624816CDAD9A95F9D5B8019488D9C0A0A1FE3075A577E23183F81D4A3F2FA4571EFC8CE0BA8A4FE8B6855DFE72B0A66EDED2FBABFBE58A30FAFABE1C5D71A87E2F741EF8C1FE86FEA6BBFDE530677F0D97D11D49F7A8443D0822E506A9F4614E011E2A94838FF88CD68C8BB7C5C6424CFFFFFFFFFFFFFFFF) ] data CurveDH = forall c . (EllipticCurveDH c, NFData (Scalar c), NFData (Point c)) => CurveDH c benchECDH = map doECDHBench curves where doECDHBench (name, CurveDH c) = let proxy = Just c -- using Maybe as Proxy in env (generate proxy) $ bench name . nf (run proxy) generate proxy = do KeyPair _ aScalar <- curveGenerateKeyPair proxy KeyPair bPoint _ <- curveGenerateKeyPair proxy return (aScalar, bPoint) run proxy (s, p) = throwCryptoError (ecdh proxy s p) curves = [ ("P256R1", CurveDH Curve_P256R1) , ("P384R1", CurveDH Curve_P384R1) , ("P521R1", CurveDH Curve_P521R1) , ("X25519", CurveDH Curve_X25519) , ("X448", CurveDH Curve_X448) ] main = defaultMain [ bgroup "hash" benchHash , bgroup "block-cipher" benchBlockCipher , bgroup "AE" benchAE , bgroup "pbkdf2" benchPBKDF2 , bgroup "bcrypt" benchBCrypt , bgroup "ECC" benchECC , bgroup "DH" [ bgroup "FFDH" benchFFDH , bgroup "ECDH" benchECDH ] , bgroup "F2m" benchF2m ] cryptonite-0.26/benchs/Number/F2m.hs0000644000000000000000000000236313414232447015511 0ustar0000000000000000{-# LANGUAGE PackageImports #-} module Number.F2m (benchF2m) where import Gauge.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.26/README.md0000644000000000000000000000717613414232447013325 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) Stability --------- Cryptonite APIs are stable, and we only strive to add, not change or remove. Note that because the API exposed is wide and also expose internals things (for power users and flexibility), certains APIs can be revised in extreme cases where we can't just add. Versioning ---------- Next version of `0.x` is `0.(x+1)`. There's no exceptions, or API related meaning behind the numbers. Each versions of stackage (going back 3 stable LTS) has a cryptonite version that we maintain with security fixes when necessary and are versioned with the following `0.x.y` scheme. 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 ------- See [Haskell packages guidelines](https://github.com/vincenthz/haskell-pkg-guidelines/blob/master/README.md#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) * [Ed448-Goldilocks](http://ed448goldilocks.sourceforge.net/) * [EdDSA-test-vectors](http://www.ietf.org/rfc/rfc8032.txt) * [AFIS](http://clemens.endorphin.org/cryptography) cryptonite-0.26/CHANGELOG.md0000644000000000000000000001714213470460012013642 0ustar0000000000000000## 0.26 * Add Rabin cryptosystem (and variants) * Add bcrypt_pbkdf key derivation function * Optimize Blowfish implementation * Add KMAC (Keccak Message Authentication Code) * Add ECDSA sign/verify digest APIs * Hash algorithms with runtime output length * Update blake2 to latest upstream version * RSA-PSS with arbitrary key size * SHAKE with output length not divisible by 8 * Add Read and Data instances for Digest type * Improve P256 scalar primitives * Fix hash truncation bug in DSA * Fix cost parsing for bcrypt * Fix ECC failures on arm64 * Correction to PKCS#1 v1.5 padding * Use powModSecInteger when available * Drop GHC 7.8 and GHC 7.10 support, refer to pkg-guidelines * Optimise GCM mode * Add little endian serialization of integer ## 0.25 * Improve digest binary conversion efficiency * AES CCM support * Add MonadFailure instance for CryptoFailable * Various misc improvements on documentation * Edwards25519 lowlevel arithmetic support * P256 add point negation * Improvement in ECC (benchmark, better normalization) * Blake2 improvements to context size * Use gauge instead of criterion * Use haskell-ci for CI scripts * Improve Digest memory representation to be 2 less Ints and one less boxing moving from `UArray` to `Block` ## 0.24 * Ed25519: generateSecret & Documentation updates * Repair tutorial * RSA: Allow signing digest directly * IV add: fix overflow behavior * P256: validate point when decoding * Compilation fix with deepseq disabled * Improve Curve448 and use decaf for Ed448 * Compilation flag blake2 sse merged in sse support * Process unaligned data better in hashes and AES, on architecture needing alignment * Drop support for ghc 7.6 * Add ability to create random generator Seed from binary data and loosen constraint on ChaChaDRG seed from ByteArray to ByteArrayAccess. * Add 3 associated types with the HashAlgorithm class, to get access to the constant for BlockSize, DigestSize and ContextSize at the type level. the related function that this replaced will be deprecated in later release, and eventually removed. API CHANGES: * Improve ECDH safety to return failure for bad inputs (e.g. public point in small order subgroup). To go back to previous behavior you can replace `ecdh` by `ecdhRaw`. It's recommended to use `ecdh` and handle the error appropriately. * Users defining their own HashAlgorithm needs to define the HashBlockSize, HashDigest, HashInternalContextSize associated types ## 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.26/LICENSE0000644000000000000000000000273013414232447013042 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.26/Setup.hs0000644000000000000000000000005613414232447013470 0ustar0000000000000000import Distribution.Simple main = defaultMain cryptonite-0.26/cryptonite.cabal0000644000000000000000000004171013470726546015234 0ustar0000000000000000Name: cryptonite version: 0.26 Synopsis: Cryptography Primitives sink Description: A repository of cryptographic primitives. . * Symmetric ciphers: AES, DES, 3DES, CAST5, Blowfish, Twofish, Camellia, RC4, Salsa, XSalsa, ChaCha. . * Hash: SHA1, SHA2, SHA3, SHAKE, MD2, MD4, MD5, Keccak, Skein, Ripemd, Tiger, Whirlpool, Blake2 . * MAC: HMAC, KMAC, Poly1305 . * Asymmetric crypto: DSA, RSA, DH, ECDH, ECDSA, ECC, Curve25519, Curve448, Ed25519, Ed448 . * Key Derivation Function: PBKDF2, Scrypt, HKDF, Argon2, BCrypt, BCryptPBKDF . * 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 tested-with: GHC==8.6.5, GHC==8.4.4, GHC==8.2.2, GHC==8.0.2 extra-doc-files: README.md CHANGELOG.md extra-source-files: cbits/*.h cbits/aes/*.h cbits/ed25519/*.h cbits/decaf/include/*.h cbits/decaf/include/decaf/*.h cbits/decaf/include/arch_32/*.h cbits/decaf/include/arch_ref64/*.h cbits/decaf/p448/arch_32/*.h cbits/decaf/p448/arch_ref64/*.h cbits/decaf/p448/*.h cbits/decaf/ed448goldilocks/decaf_tables.c cbits/decaf/ed448goldilocks/decaf.c 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 of (BLAKE2, ARGON2) 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.CAST5 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.ECC.Edwards25519 Crypto.Error Crypto.MAC.CMAC Crypto.MAC.Poly1305 Crypto.MAC.HMAC Crypto.MAC.KMAC Crypto.Number.Basic Crypto.Number.F2m Crypto.Number.Generate Crypto.Number.ModArithmetic Crypto.Number.Nat Crypto.Number.Prime Crypto.Number.Serialize Crypto.Number.Serialize.LE Crypto.Number.Serialize.Internal Crypto.Number.Serialize.Internal.LE Crypto.KDF.Argon2 Crypto.KDF.PBKDF2 Crypto.KDF.Scrypt Crypto.KDF.BCrypt Crypto.KDF.BCryptPBKDF 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.PubKey.Rabin.OAEP Crypto.PubKey.Rabin.Basic Crypto.PubKey.Rabin.Modified Crypto.PubKey.Rabin.RW Crypto.PubKey.Rabin.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.CAST5.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.Blake2 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.SHAKE 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.ByteArray Crypto.Internal.Compat Crypto.Internal.CompatPrim Crypto.Internal.DeepSeq Crypto.Internal.Imports Crypto.Internal.Nat Crypto.Internal.Words Crypto.Internal.WordArray if impl(ghc < 8.0) Buildable: False else Build-depends: base Build-depends: bytestring , memory >= 0.14.18 , basement >= 0.0.6 , ghc-prim ghc-options: -Wall -fwarn-tabs -optc-O3 if os(linux) extra-libraries: pthread 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/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 , cbits/ed25519/ed25519.c include-dirs: cbits , cbits/ed25519 , cbits/decaf/include , cbits/decaf/p448 if arch(x86_64) || arch(aarch64) C-sources: cbits/decaf/p448/arch_ref64/f_impl.c , cbits/decaf/p448/f_generic.c , cbits/decaf/p448/f_arithmetic.c , cbits/decaf/utils.c , cbits/decaf/ed448goldilocks/scalar.c , cbits/decaf/ed448goldilocks/decaf_all.c , cbits/decaf/ed448goldilocks/eddsa.c include-dirs: cbits/decaf/include/arch_ref64 , cbits/decaf/p448/arch_ref64 else C-sources: cbits/decaf/p448/arch_32/f_impl.c , cbits/decaf/p448/f_generic.c , cbits/decaf/p448/f_arithmetic.c , cbits/decaf/utils.c , cbits/decaf/ed448goldilocks/scalar.c , cbits/decaf/ed448goldilocks/decaf_all.c , cbits/decaf/ed448goldilocks/eddsa.c include-dirs: cbits/decaf/include/arch_32 , cbits/decaf/p448/arch_32 if arch(x86_64) || arch(aarch64) 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_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 BCryptPBKDF ECC ECC.Edwards25519 Hash Imports KAT_AES.KATCBC KAT_AES.KATECB KAT_AES.KATGCM KAT_AES.KATCCM KAT_AES.KATOCB3 KAT_AES.KATXTS KAT_AES KAT_AFIS KAT_Argon2 KAT_Blowfish KAT_CAST5 KAT_Camellia KAT_Curve25519 KAT_Curve448 KAT_DES KAT_Ed25519 KAT_Ed448 KAT_CMAC KAT_HKDF KAT_HMAC KAT_KMAC 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.RSA KAT_PubKey.Rabin KAT_PubKey KAT_RC4 KAT_Scrypt KAT_TripleDES KAT_Twofish ChaChaPoly1305 Number Number.F2m Padding Poly1305 Salsa Utils XSalsa Build-Depends: base >= 0 && < 10 , bytestring , memory , tasty , tasty-quickcheck , tasty-hunit , tasty-kat , cryptonite ghc-options: -Wall -fno-warn-orphans -fno-warn-missing-signatures -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 , bytestring , deepseq , memory , gauge , random , cryptonite ghc-options: -Wall -fno-warn-missing-signatures default-language: Haskell2010 cryptonite-0.26/cbits/cryptonite_pbkdf2.h0000644000000000000000000000211413414232447016736 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.26/cbits/cryptonite_blake2sp.h0000644000000000000000000000056113414232447017275 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.26/cbits/cryptonite_whirlpool.h0000644000000000000000000000206413414232447017611 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.26/cbits/cryptonite_sha512.h0000644000000000000000000000464113414232447016600 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.26/cbits/cryptonite_md5.h0000644000000000000000000000331413414232447016256 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.26/cbits/cryptonite_sha3.h0000644000000000000000000000553213470442731016434 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_finalize_cshake(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.26/cbits/cryptonite_blake2s.h0000644000000000000000000000054713414232447017121 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.26/cbits/cryptonite_sha256.h0000644000000000000000000000413113414232447016577 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.26/cbits/cryptonite_poly1305.h0000644000000000000000000000410113414232447017060 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.26/cbits/cryptonite_md2.h0000644000000000000000000000334213414232447016254 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.26/cbits/cryptonite_blake2b.h0000644000000000000000000000054713414232447017100 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.26/cbits/cryptonite_chacha.h0000644000000000000000000000454113414232447017003 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.26/cbits/cryptonite_salsa.h0000644000000000000000000000465113414232447016701 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.26/cbits/cryptonite_sha1.h0000644000000000000000000000340413414232447016425 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.26/cbits/cryptonite_align.h0000644000000000000000000000524013414232447016663 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.26/cbits/cryptonite_bitfn.h0000644000000000000000000001570113414232447016676 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.26/cbits/cryptonite_blake2bp.h0000644000000000000000000000056113414232447017254 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.26/cbits/cryptonite_ripemd.h0000644000000000000000000000341413414232447017052 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.26/cbits/cryptonite_skein256.h0000644000000000000000000000345213414232447017142 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.26/cbits/cryptonite_curve25519.h0000644000000000000000000000023713414232447017324 0ustar0000000000000000#ifndef CRYPTONITE_CURVE25519_H #define CRYPTONITE_CURVE25519_H int cryptonite_curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint); #endif cryptonite-0.26/cbits/cryptonite_md4.h0000644000000000000000000000331413414232447016255 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.26/cbits/cryptonite_aes.h0000644000000000000000000001211313414232447016336 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; /* size = 4*16+4*4= 80 */ typedef struct { aes_block xi; aes_block header_cbcmac; aes_block b0; aes_block nonce; uint32_t length_aad; uint32_t length_input; uint32_t length_M; uint32_t length_L; } aes_ccm; 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); void cryptonite_aes_ccm_init(aes_ccm *ccm, aes_key *key, uint8_t *nonce, uint32_t len, uint32_t msg_size, int m, int l); void cryptonite_aes_ccm_aad(aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_ccm_encrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_ccm_decrypt(uint8_t *output, aes_ccm *ccm, aes_key *key, uint8_t *input, uint32_t length); void cryptonite_aes_ccm_finish(uint8_t *tag, aes_ccm *ccm, aes_key *key); #endif cryptonite-0.26/cbits/cryptonite_skein512.h0000644000000000000000000000345213414232447017135 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.26/cbits/cryptonite_cpu.h0000644000000000000000000000350013414232447016355 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.26/cbits/cryptonite_tiger.h0000644000000000000000000000334613414232447016710 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.26/cbits/cryptonite_rc4.h0000644000000000000000000000046013414232447016260 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.26/cbits/cryptonite_xsalsa.h0000644000000000000000000000344613414232447017072 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.26/cbits/cryptonite_skein.h0000644000000000000000000000353213414232447016704 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.26/cbits/aes/generic.h0000644000000000000000000000352213414232447015476 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.26/cbits/aes/block128.h0000644000000000000000000000745413414232447015417 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 #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, const uint8_t *src, uint32_t len) { int i; for (i = 0; i < len; i++) block->b[i] = src[i]; } static inline void block128_copy_aligned(block128 *d, const block128 *s) { d->q[0] = s->q[0]; d->q[1] = s->q[1]; } static inline void block128_copy(block128 *d, const block128 *s) { if (need_alignment(d, 8) || need_alignment(s, 8)) { block128_copy_bytes(d, (const uint8_t *) s, 16); } else { block128_copy_aligned(d, s); } } static inline void block128_zero(block128 *d) { d->q[0] = 0; d->q[1] = 0; } static inline void block128_xor_bytes(block128 *block, const uint8_t *src, uint32_t len) { int i; for (i = 0; i < len; i++) block->b[i] ^= src[i]; } static inline void block128_xor_aligned(block128 *d, const block128 *s) { d->q[0] ^= s->q[0]; d->q[1] ^= s->q[1]; } static inline void block128_xor(block128 *d, const block128 *s) { if (need_alignment(d, 8) || need_alignment(s, 8)) { block128_xor_bytes(d, (const uint8_t *) s, 16); } else { block128_xor_aligned(d, s); } } static inline void block128_vxor_bytes(block128 *block, const uint8_t *src1, const uint8_t *src2, uint32_t len) { int i; for (i = 0; i < len; i++) block->b[i] = src1[i] ^ src2[i]; } static inline void block128_vxor_aligned(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_vxor(block128 *d, const block128 *s1, const block128 *s2) { if (need_alignment(d, 8) || need_alignment(s1, 8) || need_alignment(s2, 8)) { block128_vxor_bytes(d, (const uint8_t *) s1, (const uint8_t *) s2, 16); } else { block128_vxor_aligned(d, s1, s2); } } 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.26/cbits/aes/gf.h0000644000000000000000000000340113470442731014453 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_aes_generic_gf_mul(block128 *a, block128 *b); void cryptonite_aes_generic_gf_mulx(block128 *a); #endif cryptonite-0.26/cbits/aes/x86ni.h0000644000000000000000000001007713470442731015042 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); #ifdef WITH_PCLMUL void cryptonite_aesni_init_pclmul(); void cryptonite_aesni_gf_mul(block128 *a, block128 *b); #endif #endif #endif #endif cryptonite-0.26/cbits/ed25519/ed25519-donna-64bit-x86-32bit.h0000644000000000000000000003763113414232447020705 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.26/cbits/ed25519/ed25519-donna-portable-identify.h0000644000000000000000000000553613414232447022031 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.26/cbits/ed25519/ed25519-randombytes.h0000644000000000000000000000012013414232447017622 0ustar0000000000000000void ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) { exit(1); } cryptonite-0.26/cbits/ed25519/modm-donna-64bit.h0000644000000000000000000003205213414232447017267 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.26/cbits/ed25519/ed25519-donna-basepoint-table.h0000644000000000000000000036222013414232447021455 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.26/cbits/ed25519/modm-donna-32bit.h0000644000000000000000000005121613414232447017265 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.26/cbits/ed25519/ed25519-donna.h0000644000000000000000000000531213414232447016402 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.26/cbits/ed25519/ed25519-donna-64bit-tables.h0000644000000000000000000002421413414232447020602 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.26/cbits/ed25519/ed25519-donna-64bit-x86.h0000644000000000000000000003124213414232447017754 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.26/cbits/ed25519/ed25519-hash.h0000644000000000000000000000125113414232447016224 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.26/cbits/ed25519/curve25519-donna-32bit.h0000644000000000000000000005412613414232447020066 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.26/cbits/ed25519/ed25519-donna-32bit-sse2.h0000644000000000000000000004432013414232447020177 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.26/cbits/ed25519/curve25519-donna-64bit.h0000644000000000000000000003502513414232447020070 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.26/cbits/ed25519/ed25519-donna-impl-base.h0000644000000000000000000002426413414232447020260 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); } // diverges from the original source code and resolves bug explained // in if (i == 0) { ge25519_p1p1_to_full(r, &t); } else { 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.26/cbits/ed25519/ed25519-donna-portable.h0000644000000000000000000001127513414232447020215 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.26/cbits/ed25519/ed25519-donna-32bit-tables.h0000644000000000000000000002734213414232447020602 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.26/cbits/ed25519/ed25519-cryptonite-exts.h0000644000000000000000000001543013414232447020466 0ustar0000000000000000/* Public domain by Olivier Chéron Arithmetic extensions to Ed25519-donna */ /* Scalar functions */ void ED25519_FN(ed25519_scalar_encode) (unsigned char out[32], const bignum256modm in) { contract256_modm(out, in); } void ED25519_FN(ed25519_scalar_decode_long) (bignum256modm out, const unsigned char *in, size_t len) { expand256_modm(out, in, len); } int ED25519_FN(ed25519_scalar_eq) (const bignum256modm a, const bignum256modm b) { bignum256modm_element_t e = 0; for (int i = 0; i < bignum256modm_limb_size; i++) { e |= a[i] ^ b[i]; } return (int) (1 & ((e - 1) >> bignum256modm_bits_per_limb)); } void ED25519_FN(ed25519_scalar_add) (bignum256modm r, const bignum256modm x, const bignum256modm y) { add256_modm(r, x, y); } void ED25519_FN(ed25519_scalar_mul) (bignum256modm r, const bignum256modm x, const bignum256modm y) { mul256_modm(r, x, y); } /* Point functions */ void ED25519_FN(ed25519_point_encode) (unsigned char r[32], const ge25519 *p) { ge25519_pack(r, p); } int ED25519_FN(ed25519_point_decode_vartime) (ge25519 *r, const unsigned char p[32]) { unsigned char p_neg[32]; // invert parity bit of X coordinate so the point is negated twice // (once here, once in ge25519_unpack_negative_vartime) for (int i = 0; i < 31; i++) { p_neg[i] = p[i]; } p_neg[31] = p[31] ^ 0x80; return ge25519_unpack_negative_vartime(r, p_neg); } int ED25519_FN(ed25519_point_eq) (const ge25519 *p, const ge25519 *q) { bignum25519 a, b; unsigned char contract_a[32], contract_b[32]; int eq; // pX * qZ = qX * pZ curve25519_mul(a, p->x, q->z); curve25519_contract(contract_a, a); curve25519_mul(b, q->x, p->z); curve25519_contract(contract_b, b); eq = ed25519_verify(contract_a, contract_b, 32); // pY * qZ = qY * pZ curve25519_mul(a, p->y, q->z); curve25519_contract(contract_a, a); curve25519_mul(b, q->y, p->z); curve25519_contract(contract_b, b); eq &= ed25519_verify(contract_a, contract_b, 32); return eq; } static int ED25519_FN(ed25519_point_is_identity) (const ge25519 *p) { static const unsigned char zero[32] = {0}; unsigned char check[32]; bignum25519 d; int eq; // pX = 0 curve25519_contract(check, p->x); eq = ed25519_verify(check, zero, 32); // pY - pZ = 0 curve25519_sub_reduce(d, p->y, p->z); curve25519_contract(check, d); eq &= ed25519_verify(check, zero, 32); return eq; } void ED25519_FN(ed25519_point_negate) (ge25519 *r, const ge25519 *p) { curve25519_neg(r->x, p->x); curve25519_copy(r->y, p->y); curve25519_copy(r->z, p->z); curve25519_neg(r->t, p->t); } void ED25519_FN(ed25519_point_add) (ge25519 *r, const ge25519 *p, const ge25519 *q) { ge25519_add(r, p, q); } void ED25519_FN(ed25519_point_double) (ge25519 *r, const ge25519 *p) { ge25519_double(r, p); } void ED25519_FN(ed25519_point_mul_by_cofactor) (ge25519 *r, const ge25519 *p) { ge25519_double_partial(r, p); ge25519_double_partial(r, r); ge25519_double(r, r); } void ED25519_FN(ed25519_point_base_scalarmul) (ge25519 *r, const bignum256modm s) { ge25519_scalarmult_base_niels(r, ge25519_niels_base_multiples, s); } #if defined(ED25519_64BIT) typedef uint64_t ed25519_move_cond_word; #else typedef uint32_t ed25519_move_cond_word; #endif /* out = (flag) ? in : out */ DONNA_INLINE static void ed25519_move_cond_pniels(ge25519_pniels *out, const ge25519_pniels *in, uint32_t flag) { const int word_count = sizeof(ge25519_pniels) / sizeof(ed25519_move_cond_word); const ed25519_move_cond_word nb = (ed25519_move_cond_word) flag - 1, b = ~nb; ed25519_move_cond_word *outw = (ed25519_move_cond_word *) out; const ed25519_move_cond_word *inw = (const ed25519_move_cond_word *) in; // ge25519_pniels has 4 coordinates, so word_count is divisible by 4 for (int i = 0; i < word_count; i += 4) { outw[i + 0] = (outw[i + 0] & nb) | (inw[i + 0] & b); outw[i + 1] = (outw[i + 1] & nb) | (inw[i + 1] & b); outw[i + 2] = (outw[i + 2] & nb) | (inw[i + 2] & b); outw[i + 3] = (outw[i + 3] & nb) | (inw[i + 3] & b); } } static void ed25519_point_scalarmul_w_choose_pniels(ge25519_pniels *t, const ge25519_pniels table[15], uint32_t pos) { // initialize t to identity, i.e. (1, 1, 1, 0) memset(t, 0, sizeof(ge25519_pniels)); t->ysubx[0] = 1; t->xaddy[0] = 1; t->z[0] = 1; // move one entry from table matching requested position, // scanning all table to avoid cache-timing attack // // when pos == 0, no entry matches and this returns // identity as expected for (uint32_t i = 1; i < 16; i++) { uint32_t flag = ((i ^ pos) - 1) >> 31; ed25519_move_cond_pniels(t, table + i - 1, flag); } } void ED25519_FN(ed25519_point_scalarmul) (ge25519 *r, const ge25519 *p, const bignum256modm s) { ge25519_pniels mult[15]; ge25519_pniels pn; ge25519_p1p1 t; unsigned char ss[32]; // transform scalar as little-endian number contract256_modm(ss, s); // initialize r to identity, i.e. ge25519 (0, 1, 1, 0) memset(r, 0, sizeof(ge25519)); r->y[0] = 1; r->z[0] = 1; // precompute multiples of P: 1.P, 2.P, ..., 15.P ge25519_full_to_pniels(&mult[0], p); for (int i = 1; i < 15; i++) { ge25519_pnielsadd(&mult[i], p, &mult[i-1]); } // 4-bit fixed window, still 256 doublings but 64 additions for (int i = 31; i >= 0; i--) { // higher bits in ss[i] ed25519_point_scalarmul_w_choose_pniels(&pn, mult, ss[i] >> 4); ge25519_pnielsadd_p1p1(&t, r, &pn, 0); ge25519_p1p1_to_partial(r, &t); ge25519_double_partial(r, r); ge25519_double_partial(r, r); ge25519_double_partial(r, r); ge25519_double(r, r); // lower bits in ss[i] ed25519_point_scalarmul_w_choose_pniels(&pn, mult, ss[i] & 0x0F); ge25519_pnielsadd_p1p1(&t, r, &pn, 0); if (i > 0) { ge25519_p1p1_to_partial(r, &t); ge25519_double_partial(r, r); ge25519_double_partial(r, r); ge25519_double_partial(r, r); ge25519_double(r, r); } else { ge25519_p1p1_to_full(r, &t); } } } void ED25519_FN(ed25519_base_double_scalarmul_vartime) (ge25519 *r, const bignum256modm s1, const ge25519 *p2, const bignum256modm s2) { // computes [s1]basepoint + [s2]p2 ge25519_double_scalarmult_vartime(r, p2, s2, s1); } int ED25519_FN(ed25519_point_has_prime_order) (const ge25519 *p) { static const bignum256modm sc_zero = {0}; ge25519 q; // computes Q = m.P, vartime allowed because m is not secret ED25519_FN(ed25519_base_double_scalarmul_vartime) (&q, sc_zero, p, modm_m); return ED25519_FN(ed25519_point_is_identity) (&q); } cryptonite-0.26/cbits/ed25519/curve25519-donna-helpers.h0000644000000000000000000000450613414232447020602 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.26/cbits/ed25519/ed25519.h0000644000000000000000000000176213414232447015312 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.26/cbits/ed25519/ed25519-donna-batchverify.h0000644000000000000000000001673413414232447020720 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.26/cbits/decaf/include/field.h0000644000000000000000000000555713414232447017074 0ustar0000000000000000/** * @file field.h * @brief Generic gf header. * @copyright * Copyright (c) 2014 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * @author Mike Hamburg */ #ifndef __GF_H__ #define __GF_H__ #include "constant_time.h" #include "f_field.h" #include /** Square x, n times. */ static CRYPTONITE_DECAF_INLINE void cryptonite_gf_sqrn ( cryptonite_gf_s *__restrict__ y, const gf x, int n ) { gf tmp; assert(n>0); if (n&1) { cryptonite_gf_sqr(y,x); n--; } else { cryptonite_gf_sqr(tmp,x); cryptonite_gf_sqr(y,tmp); n-=2; } for (; n; n-=2) { cryptonite_gf_sqr(tmp,y); cryptonite_gf_sqr(y,tmp); } } #define cryptonite_gf_add_nr cryptonite_gf_add_RAW /** Subtract mod p. Bias by 2 and don't reduce */ static inline void cryptonite_gf_sub_nr ( gf c, const gf a, const gf b ) { cryptonite_gf_sub_RAW(c,a,b); cryptonite_gf_bias(c, 2); if (GF_HEADROOM < 3) cryptonite_gf_weak_reduce(c); } /** Subtract mod p. Bias by amt but don't reduce. */ static inline void cryptonite_gf_subx_nr ( gf c, const gf a, const gf b, int amt ) { cryptonite_gf_sub_RAW(c,a,b); cryptonite_gf_bias(c, amt); if (GF_HEADROOM < amt+1) cryptonite_gf_weak_reduce(c); } /** Mul by signed int. Not constant-time WRT the sign of that int. */ static inline void cryptonite_gf_mulw(gf c, const gf a, int32_t w) { if (w>0) { cryptonite_gf_mulw_unsigned(c, a, w); } else { cryptonite_gf_mulw_unsigned(c, a, -w); cryptonite_gf_sub(c,ZERO,c); } } /** Constant time, x = is_z ? z : y */ static inline void cryptonite_gf_cond_sel(gf x, const gf y, const gf z, mask_t is_z) { constant_time_select(x,y,z,sizeof(gf),is_z,0); } /** Constant time, if (neg) x=-x; */ static inline void cryptonite_gf_cond_neg(gf x, mask_t neg) { gf y; cryptonite_gf_sub(y,ZERO,x); cryptonite_gf_cond_sel(x,x,y,neg); } /** Constant time, if (swap) (x,y) = (y,x); */ static inline void cryptonite_gf_cond_swap(gf x, cryptonite_gf_s *__restrict__ y, mask_t swap) { constant_time_cond_swap(x,y,sizeof(cryptonite_gf_s),swap); } static CRYPTONITE_DECAF_INLINE void cryptonite_gf_mul_qnr(cryptonite_gf_s *__restrict__ out, const gf x) { #if P_MOD_8 == 5 /* r = QNR * r0^2 */ cryptonite_gf_mul(out,x,SQRT_MINUS_ONE); #elif P_MOD_8 == 3 || P_MOD_8 == 7 cryptonite_gf_sub(out,ZERO,x); #else #error "Only supporting p=3,5,7 mod 8" #endif } static CRYPTONITE_DECAF_INLINE void cryptonite_gf_div_qnr(cryptonite_gf_s *__restrict__ out, const gf x) { #if P_MOD_8 == 5 /* r = QNR * r0^2 */ cryptonite_gf_mul(out,x,SQRT_MINUS_ONE); cryptonite_gf_sub(out,ZERO,out); #elif P_MOD_8 == 3 || P_MOD_8 == 7 cryptonite_gf_sub(out,ZERO,x); #else #error "Only supporting p=3,5,7 mod 8" #endif } #endif // __GF_H__ cryptonite-0.26/cbits/decaf/include/decaf.h0000644000000000000000000000211213414232447017033 0ustar0000000000000000/** * @file decaf.h * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * Master header for Decaf library. * * The Decaf library implements cryptographic operations on a elliptic curve * groups of prime order p. It accomplishes this by using a twisted Edwards * curve (isogenous to Ed448-Goldilocks or Ed25519) and wiping out the cofactor. * * The formulas are all complete and have no special cases. However, some * functions can fail. For example, decoding functions can fail because not * every string is the encoding of a valid group element. * * The formulas contain no data-dependent branches, timing or memory accesses, * except for cryptonite_decaf_XXX_base_double_scalarmul_non_secret. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #ifndef __CRYPTONITE_DECAF_H__ #define __CRYPTONITE_DECAF_H__ 1 #include #include #endif /* __CRYPTONITE_DECAF_H__ */ cryptonite-0.26/cbits/decaf/include/constant_time.h0000644000000000000000000003021313414232447020643 0ustar0000000000000000/** * @file constant_time.h * @copyright * Copyright (c) 2014 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * @author Mike Hamburg * * @brief Constant-time routines. */ #ifndef __CONSTANT_TIME_H__ #define __CONSTANT_TIME_H__ 1 #include "word.h" #include /* * Constant-time operations on hopefully-compile-time-sized memory * regions. Needed for flexibility / demagication: not all fields * have sizes which are multiples of the vector width, necessitating * a change from the Ed448 versions. * * These routines would be much simpler to define at the byte level, * but if not vectorized they would be a significant fraction of the * runtime. Eg on NEON-less ARM, constant_time_lookup is like 15% of * signing time, vs 6% on Haswell with its fancy AVX2 vectors. * * If the compiler could do a good job of autovectorizing the code, * we could just leave it with the byte definition. But that's unlikely * on most deployed compilers, especially if you consider that pcmpeq[size] * is much faster than moving a scalar to the vector unit (which is what * a naive autovectorizer will do with constant_time_lookup on Intel). * * Instead, we're putting our trust in the loop unroller and unswitcher. */ /** * Unaligned big (vector?) register. */ typedef struct { big_register_t unaligned; } __attribute__((packed)) unaligned_br_t; /** * Unaligned word register, for architectures where that matters. */ typedef struct { word_t unaligned; } __attribute__((packed)) unaligned_word_t; /** * @brief Constant-time conditional swap. * * If doswap, then swap elem_bytes between *a and *b. * * *a and *b must not alias. Also, they must be at least as aligned * as their sizes, if the CPU cares about that sort of thing. */ static __inline__ void __attribute__((unused,always_inline)) constant_time_cond_swap ( void *__restrict__ a_, void *__restrict__ b_, word_t elem_bytes, mask_t doswap ) { word_t k; unsigned char *a = (unsigned char *)a_; unsigned char *b = (unsigned char *)b_; big_register_t br_mask = br_set_to_mask(doswap); for (k=0; k<=elem_bytes-sizeof(big_register_t); k+=sizeof(big_register_t)) { if (elem_bytes % sizeof(big_register_t)) { /* unaligned */ big_register_t xor = ((unaligned_br_t*)(&a[k]))->unaligned ^ ((unaligned_br_t*)(&b[k]))->unaligned; xor &= br_mask; ((unaligned_br_t*)(&a[k]))->unaligned ^= xor; ((unaligned_br_t*)(&b[k]))->unaligned ^= xor; } else { /* aligned */ big_register_t xor = *((big_register_t*)(&a[k])) ^ *((big_register_t*)(&b[k])); xor &= br_mask; *((big_register_t*)(&a[k])) ^= xor; *((big_register_t*)(&b[k])) ^= xor; } } if (elem_bytes % sizeof(big_register_t) >= sizeof(word_t)) { for (; k<=elem_bytes-sizeof(word_t); k+=sizeof(word_t)) { if (elem_bytes % sizeof(word_t)) { /* unaligned */ word_t xor = ((unaligned_word_t*)(&a[k]))->unaligned ^ ((unaligned_word_t*)(&b[k]))->unaligned; xor &= doswap; ((unaligned_word_t*)(&a[k]))->unaligned ^= xor; ((unaligned_word_t*)(&b[k]))->unaligned ^= xor; } else { /* aligned */ word_t xor = *((word_t*)(&a[k])) ^ *((word_t*)(&b[k])); xor &= doswap; *((word_t*)(&a[k])) ^= xor; *((word_t*)(&b[k])) ^= xor; } } } if (elem_bytes % sizeof(word_t)) { for (; kunaligned |= br_mask & ((const unaligned_br_t*)(&table[k+j*elem_bytes]))->unaligned; } else { /* aligned */ *(big_register_t *)(out+k) |= br_mask & *(const big_register_t*)(&table[k+j*elem_bytes]); } } word_t mask = word_is_zero(idx^j); if (elem_bytes % sizeof(big_register_t) >= sizeof(word_t)) { for (; k<=elem_bytes-sizeof(word_t); k+=sizeof(word_t)) { if (elem_bytes % sizeof(word_t)) { /* input unaligned, output aligned */ *(word_t *)(out+k) |= mask & ((const unaligned_word_t*)(&table[k+j*elem_bytes]))->unaligned; } else { /* aligned */ *(word_t *)(out+k) |= mask & *(const word_t*)(&table[k+j*elem_bytes]); } } } if (elem_bytes % sizeof(word_t)) { for (; kunaligned = ( ((unaligned_br_t*)(&table[k+j*elem_bytes]))->unaligned & ~br_mask ) | ( ((const unaligned_br_t *)(in+k))->unaligned & br_mask ); } else { /* aligned */ *(big_register_t*)(&table[k+j*elem_bytes]) = ( *(big_register_t*)(&table[k+j*elem_bytes]) & ~br_mask ) | ( *(const big_register_t *)(in+k) & br_mask ); } } word_t mask = word_is_zero(idx^j); if (elem_bytes % sizeof(big_register_t) >= sizeof(word_t)) { for (; k<=elem_bytes-sizeof(word_t); k+=sizeof(word_t)) { if (elem_bytes % sizeof(word_t)) { /* output unaligned, input aligned */ ((unaligned_word_t*)(&table[k+j*elem_bytes]))->unaligned = ( ((unaligned_word_t*)(&table[k+j*elem_bytes]))->unaligned & ~mask ) | ( *(const word_t *)(in+k) & mask ); } else { /* aligned */ *(word_t*)(&table[k+j*elem_bytes]) = ( *(word_t*)(&table[k+j*elem_bytes]) & ~mask ) | ( *(const word_t *)(in+k) & mask ); } } } if (elem_bytes % sizeof(word_t)) { for (; kunaligned = br_mask & ((const unaligned_br_t*)(&b[k]))->unaligned; } else { /* aligned */ *(big_register_t *)(a+k) = br_mask & *(const big_register_t*)(&b[k]); } } if (elem_bytes % sizeof(big_register_t) >= sizeof(word_t)) { for (; k<=elem_bytes-sizeof(word_t); k+=sizeof(word_t)) { if (elem_bytes % sizeof(word_t)) { /* unaligned */ ((unaligned_word_t*)(&a[k]))->unaligned = mask & ((const unaligned_word_t*)(&b[k]))->unaligned; } else { /* aligned */ *(word_t *)(a+k) = mask & *(const word_t*)(&b[k]); } } } if (elem_bytes % sizeof(word_t)) { for (; kunaligned = ( br_mask & ((const unaligned_br_t*)(&bTrue [k]))->unaligned) | (~br_mask & ((const unaligned_br_t*)(&bFalse[k]))->unaligned); } else { /* aligned */ *(big_register_t *)(a+k) = ( br_mask & *(const big_register_t*)(&bTrue [k])) | (~br_mask & *(const big_register_t*)(&bFalse[k])); } } if (elem_bytes % sizeof(big_register_t) >= sizeof(word_t)) { for (; k<=elem_bytes-sizeof(word_t); k+=sizeof(word_t)) { if (alignment_bytes % sizeof(word_t)) { /* unaligned */ ((unaligned_word_t*)(&a[k]))->unaligned = ( mask & ((const unaligned_word_t*)(&bTrue [k]))->unaligned) | (~mask & ((const unaligned_word_t*)(&bFalse[k]))->unaligned); } else { /* aligned */ *(word_t *)(a+k) = ( mask & *(const word_t*)(&bTrue [k])) | (~mask & *(const word_t*)(&bFalse[k])); } } } if (elem_bytes % sizeof(word_t)) { for (; k #if defined(__sun) && defined(__SVR4) extern int posix_memalign(void **, size_t, size_t); #endif #include #include #include "arch_intrinsics.h" #include #ifndef _BSD_SOURCE #define _BSD_SOURCE 1 #endif #ifndef _DEFAULT_SOURCE #define _DEFAULT_SOURCE 1 #endif #include "portable_endian.h" #include #include #include #if defined(__ARM_NEON__) #include #elif defined(__SSE2__) #if !defined(__GNUC__) || __clang__ || __GNUC__ >= 5 || (__GNUC__==4 && __GNUC_MINOR__ >= 4) #include #else #include #endif #endif #if (ARCH_WORD_BITS == 64) typedef uint64_t word_t, mask_t; typedef __uint128_t dword_t; typedef int32_t hsword_t; typedef int64_t sword_t; typedef __int128_t dsword_t; #elif (ARCH_WORD_BITS == 32) typedef uint32_t word_t, mask_t; typedef uint64_t dword_t; typedef int16_t hsword_t; typedef int32_t sword_t; typedef int64_t dsword_t; #else #error "For now, libdecaf only supports 32- and 64-bit architectures." #endif /* Scalar limbs are keyed off of the API word size instead of the arch word size. */ #if CRYPTONITE_DECAF_WORD_BITS == 64 #define SC_LIMB(x) (x##ull) #elif CRYPTONITE_DECAF_WORD_BITS == 32 #define SC_LIMB(x) ((uint32_t)x##ull),(x##ull>>32) #else #error "For now, libdecaf only supports 32- and 64-bit architectures." #endif #ifdef __ARM_NEON__ typedef uint32x4_t vecmask_t; #elif __clang__ typedef uint64_t uint64x2_t __attribute__((ext_vector_type(2))); typedef int64_t int64x2_t __attribute__((ext_vector_type(2))); typedef uint64_t uint64x4_t __attribute__((ext_vector_type(4))); typedef int64_t int64x4_t __attribute__((ext_vector_type(4))); typedef uint32_t uint32x4_t __attribute__((ext_vector_type(4))); typedef int32_t int32x4_t __attribute__((ext_vector_type(4))); typedef uint32_t uint32x2_t __attribute__((ext_vector_type(2))); typedef int32_t int32x2_t __attribute__((ext_vector_type(2))); typedef uint32_t uint32x8_t __attribute__((ext_vector_type(8))); typedef int32_t int32x8_t __attribute__((ext_vector_type(8))); typedef word_t vecmask_t __attribute__((ext_vector_type(4))); #else /* GCC, hopefully? */ typedef uint64_t uint64x2_t __attribute__((vector_size(16))); typedef int64_t int64x2_t __attribute__((vector_size(16))); typedef uint64_t uint64x4_t __attribute__((vector_size(32))); typedef int64_t int64x4_t __attribute__((vector_size(32))); typedef uint32_t uint32x4_t __attribute__((vector_size(16))); typedef int32_t int32x4_t __attribute__((vector_size(16))); typedef uint32_t uint32x2_t __attribute__((vector_size(8))); typedef int32_t int32x2_t __attribute__((vector_size(8))); typedef uint32_t uint32x8_t __attribute__((vector_size(32))); typedef int32_t int32x8_t __attribute__((vector_size(32))); typedef word_t vecmask_t __attribute__((vector_size(32))); #endif #if __AVX2__ #define VECTOR_ALIGNED __attribute__((aligned(32))) typedef uint32x8_t big_register_t; typedef uint64x4_t uint64xn_t; typedef uint32x8_t uint32xn_t; static CRYPTONITE_DECAF_INLINE big_register_t br_set_to_mask(mask_t x) { uint32_t y = (uint32_t)x; big_register_t ret = {y,y,y,y,y,y,y,y}; return ret; } #elif __SSE2__ #define VECTOR_ALIGNED __attribute__((aligned(16))) typedef uint32x4_t big_register_t; typedef uint64x2_t uint64xn_t; typedef uint32x4_t uint32xn_t; static CRYPTONITE_DECAF_INLINE big_register_t br_set_to_mask(mask_t x) { uint32_t y = x; big_register_t ret = {y,y,y,y}; return ret; } #elif __ARM_NEON__ #define VECTOR_ALIGNED __attribute__((aligned(16))) typedef uint32x4_t big_register_t; typedef uint64x2_t uint64xn_t; typedef uint32x4_t uint32xn_t; static CRYPTONITE_DECAF_INLINE big_register_t br_set_to_mask(mask_t x) { return vdupq_n_u32(x); } #elif _WIN64 || __amd64__ || __X86_64__ || __aarch64__ #define VECTOR_ALIGNED __attribute__((aligned(8))) typedef uint64_t big_register_t, uint64xn_t; typedef uint32_t uint32xn_t; static CRYPTONITE_DECAF_INLINE big_register_t br_set_to_mask(mask_t x) { return (big_register_t)x; } #else #define VECTOR_ALIGNED __attribute__((aligned(4))) typedef uint64_t uint64xn_t; typedef uint32_t uint32xn_t; typedef uint32_t big_register_t; static CRYPTONITE_DECAF_INLINE big_register_t br_set_to_mask(mask_t x) { return (big_register_t)x; } #endif typedef struct { uint64xn_t unaligned; } __attribute__((packed)) unaligned_uint64xn_t; typedef struct { uint32xn_t unaligned; } __attribute__((packed)) unaligned_uint32xn_t; #if __AVX2__ static CRYPTONITE_DECAF_INLINE big_register_t br_is_zero(big_register_t x) { return (big_register_t)(x == br_set_to_mask(0)); } #elif __SSE2__ static CRYPTONITE_DECAF_INLINE big_register_t br_is_zero(big_register_t x) { return (big_register_t)_mm_cmpeq_epi32((__m128i)x, _mm_setzero_si128()); //return (big_register_t)(x == br_set_to_mask(0)); } #elif __ARM_NEON__ static CRYPTONITE_DECAF_INLINE big_register_t br_is_zero(big_register_t x) { return vceqq_u32(x,x^x); } #else #define br_is_zero word_is_zero #endif /** * Really call memset, in a way that prevents the compiler from optimizing it out. * @param p The object to zeroize. * @param c The char to set it to (probably zero). * @param s The size of the object. */ #if defined(__DARWIN_C_LEVEL) || defined(__STDC_LIB_EXT1__) #define HAS_MEMSET_S #endif #if !defined(__STDC_WANT_LIB_EXT1__) || __STDC_WANT_LIB_EXT1__ != 1 #define NEED_MEMSET_S_EXTERN #endif #ifdef HAS_MEMSET_S #ifdef NEED_MEMSET_S_EXTERN extern int memset_s(void *, size_t, int, size_t); #endif static CRYPTONITE_DECAF_INLINE void really_memset(void *p, char c, size_t s) { memset_s(p, s, c, s); } #else /* PERF: use words? */ static CRYPTONITE_DECAF_INLINE void really_memset(void *p, char c, size_t s) { volatile char *pv = (volatile char *)p; size_t i; for (i=0; i 305 #define UNROLL _Pragma("clang loop unroll(full)") #endif #endif #ifndef UNROLL #define UNROLL #endif /* The plan on booleans: * * The external interface uses cryptonite_decaf_bool_t, but this might be a different * size than our particular arch's word_t (and thus mask_t). Also, the caller * isn't guaranteed to pass it as nonzero. So bool_to_mask converts word sizes * and checks nonzero. * * On the flip side, mask_t is always -1 or 0, but it might be a different size * than cryptonite_decaf_bool_t. * * On the third hand, we have success vs boolean types, but that's handled in * common.h: it converts between cryptonite_decaf_bool_t and cryptonite_decaf_error_t. */ static CRYPTONITE_DECAF_INLINE cryptonite_decaf_bool_t mask_to_bool (mask_t m) { return (cryptonite_decaf_sword_t)(sword_t)m; } static CRYPTONITE_DECAF_INLINE mask_t bool_to_mask (cryptonite_decaf_bool_t m) { /* On most arches this will be optimized to a simple cast. */ mask_t ret = 0; unsigned int limit = sizeof(cryptonite_decaf_bool_t)/sizeof(mask_t); if (limit < 1) limit = 1; for (unsigned int i=0; i> (i*8*sizeof(word_t))); } return ret; } static CRYPTONITE_DECAF_INLINE void ignore_result ( cryptonite_decaf_bool_t boo ) { (void)boo; } #endif /* __WORD_H__ */ cryptonite-0.26/cbits/decaf/include/decaf/sha512.h0000644000000000000000000000003513414232447020040 0ustar0000000000000000/* Not needed if 448-only */ cryptonite-0.26/cbits/decaf/include/decaf/common.h0000644000000000000000000001140013414232447020323 0ustar0000000000000000/** * @file decaf/common.h * @author Mike Hamburg * * @copyright * Copyright (c) 2015 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @brief Common utility headers for Decaf library. */ #ifndef __CRYPTONITE_DECAF_COMMON_H__ #define __CRYPTONITE_DECAF_COMMON_H__ 1 #include #include #ifdef __cplusplus extern "C" { #endif /* Goldilocks' build flags default to hidden and stripping executables. */ /** @cond internal */ #if defined(DOXYGEN) && !defined(__attribute__) #define __attribute__((x)) #endif #define CRYPTONITE_DECAF_API_VIS __attribute__((visibility("default"))) #define CRYPTONITE_DECAF_NOINLINE __attribute__((noinline)) #define CRYPTONITE_DECAF_WARN_UNUSED __attribute__((warn_unused_result)) #define CRYPTONITE_DECAF_NONNULL __attribute__((nonnull)) #define CRYPTONITE_DECAF_INLINE inline __attribute__((always_inline,unused)) // Cribbed from libnotmuch #if defined (__clang_major__) && __clang_major__ >= 3 \ || defined (__GNUC__) && __GNUC__ >= 5 \ || defined (__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ >= 5 #define CRYPTONITE_DECAF_DEPRECATED(msg) __attribute__ ((deprecated(msg))) #else #define CRYPTONITE_DECAF_DEPRECATED(msg) __attribute__ ((deprecated)) #endif /** @endcond */ /* Internal word types. * * Somewhat tricky. This could be decided separately per platform. However, * the structs do need to be all the same size and alignment on a given * platform to support dynamic linking, since even if you header was built * with eg arch_neon, you might end up linking a library built with arch_arm32. */ #ifndef CRYPTONITE_DECAF_WORD_BITS #if (defined(__ILP64__) || defined(__amd64__) || defined(__x86_64__) || (((__UINT_FAST32_MAX__)>>30)>>30)) #define CRYPTONITE_DECAF_WORD_BITS 64 /**< The number of bits in a word */ #else #define CRYPTONITE_DECAF_WORD_BITS 32 /**< The number of bits in a word */ #endif #endif #if CRYPTONITE_DECAF_WORD_BITS == 64 typedef uint64_t cryptonite_decaf_word_t; /**< Word size for internal computations */ typedef int64_t cryptonite_decaf_sword_t; /**< Signed word size for internal computations */ typedef uint64_t cryptonite_decaf_bool_t; /**< "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */ typedef __uint128_t cryptonite_decaf_dword_t; /**< Double-word size for internal computations */ typedef __int128_t cryptonite_decaf_dsword_t; /**< Signed double-word size for internal computations */ #elif CRYPTONITE_DECAF_WORD_BITS == 32 /**< The number of bits in a word */ typedef uint32_t cryptonite_decaf_word_t; /**< Word size for internal computations */ typedef int32_t cryptonite_decaf_sword_t; /**< Signed word size for internal computations */ typedef uint32_t cryptonite_decaf_bool_t; /**< "Boolean" type, will be set to all-zero or all-one (i.e. -1u) */ typedef uint64_t cryptonite_decaf_dword_t; /**< Double-word size for internal computations */ typedef int64_t cryptonite_decaf_dsword_t; /**< Signed double-word size for internal computations */ #else #error "Only supporting CRYPTONITE_DECAF_WORD_BITS = 32 or 64 for now" #endif /** CRYPTONITE_DECAF_TRUE = -1 so that CRYPTONITE_DECAF_TRUE & x = x */ static const cryptonite_decaf_bool_t CRYPTONITE_DECAF_TRUE = -(cryptonite_decaf_bool_t)1; /** CRYPTONITE_DECAF_FALSE = 0 so that CRYPTONITE_DECAF_FALSE & x = 0 */ static const cryptonite_decaf_bool_t CRYPTONITE_DECAF_FALSE = 0; /** Another boolean type used to indicate success or failure. */ typedef enum { CRYPTONITE_DECAF_SUCCESS = -1, /**< The operation succeeded. */ CRYPTONITE_DECAF_FAILURE = 0 /**< The operation failed. */ } cryptonite_decaf_error_t; /** Return success if x is true */ static CRYPTONITE_DECAF_INLINE cryptonite_decaf_error_t cryptonite_decaf_succeed_if(cryptonite_decaf_bool_t x) { return (cryptonite_decaf_error_t)x; } /** Return CRYPTONITE_DECAF_TRUE iff x == CRYPTONITE_DECAF_SUCCESS */ static CRYPTONITE_DECAF_INLINE cryptonite_decaf_bool_t cryptonite_decaf_successful(cryptonite_decaf_error_t e) { cryptonite_decaf_dword_t w = ((cryptonite_decaf_word_t)e) ^ ((cryptonite_decaf_word_t)CRYPTONITE_DECAF_SUCCESS); return (w-1)>>CRYPTONITE_DECAF_WORD_BITS; } /** Overwrite data with zeros. Uses memset_s if available. */ void cryptonite_decaf_bzero ( void *data, size_t size ) CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_API_VIS; /** Compare two buffers, returning CRYPTONITE_DECAF_TRUE if they are equal. */ cryptonite_decaf_bool_t cryptonite_decaf_memeq ( const void *data1, const void *data2, size_t size ) CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_API_VIS; #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __CRYPTONITE_DECAF_COMMON_H__ */ cryptonite-0.26/cbits/decaf/include/decaf/point_448.h0000644000000000000000000006423413414232447020600 0ustar0000000000000000/** * @file decaf/point_448.h * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @brief A group of prime order p, based on Ed448-Goldilocks. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #ifndef __CRYPTONITE_DECAF_POINT_448_H__ #define __CRYPTONITE_DECAF_POINT_448_H__ 1 #include #ifdef __cplusplus extern "C" { #endif /** @cond internal */ #define CRYPTONITE_DECAF_448_SCALAR_LIMBS ((446-1)/CRYPTONITE_DECAF_WORD_BITS+1) /** @endcond */ /** The number of bits in a scalar */ #define CRYPTONITE_DECAF_448_SCALAR_BITS 446 /** @cond internal */ #ifndef __CRYPTONITE_DECAF_448_GF_DEFINED__ #define __CRYPTONITE_DECAF_448_GF_DEFINED__ 1 /** @brief Galois field element internal structure */ typedef struct cryptonite_gf_448_s { cryptonite_decaf_word_t limb[512/CRYPTONITE_DECAF_WORD_BITS]; } __attribute__((aligned(16))) cryptonite_gf_448_s, cryptonite_gf_448_t[1]; #endif /* __CRYPTONITE_DECAF_448_GF_DEFINED__ */ /** @endcond */ /** Number of bytes in a serialized point. */ #define CRYPTONITE_DECAF_448_SER_BYTES 56 /** Number of bytes in an elligated point. For now set the same as SER_BYTES * but could be different for other curves. */ #define CRYPTONITE_DECAF_448_HASH_BYTES 56 /** Number of bytes in a serialized scalar. */ #define CRYPTONITE_DECAF_448_SCALAR_BYTES 56 /** Number of bits in the "which" field of an elligator inverse */ #define CRYPTONITE_DECAF_448_INVERT_ELLIGATOR_WHICH_BITS 3 /** Number of bytes in an x448 public key */ #define CRYPTONITE_DECAF_X448_PUBLIC_BYTES 56 /** Number of bytes in an x448 private key */ #define CRYPTONITE_DECAF_X448_PRIVATE_BYTES 56 /** Twisted Edwards extended homogeneous coordinates */ typedef struct cryptonite_decaf_448_point_s { /** @cond internal */ cryptonite_gf_448_t x,y,z,t; /** @endcond */ } cryptonite_decaf_448_point_t[1]; /** Precomputed table based on a point. Can be trivial implementation. */ struct cryptonite_decaf_448_precomputed_s; /** Precomputed table based on a point. Can be trivial implementation. */ typedef struct cryptonite_decaf_448_precomputed_s cryptonite_decaf_448_precomputed_s; /** Size and alignment of precomputed point tables. */ extern const size_t cryptonite_decaf_448_sizeof_precomputed_s CRYPTONITE_DECAF_API_VIS, cryptonite_decaf_448_alignof_precomputed_s CRYPTONITE_DECAF_API_VIS; /** Scalar is stored packed, because we don't need the speed. */ typedef struct cryptonite_decaf_448_scalar_s { /** @cond internal */ cryptonite_decaf_word_t limb[CRYPTONITE_DECAF_448_SCALAR_LIMBS]; /** @endcond */ } cryptonite_decaf_448_scalar_t[1]; /** A scalar equal to 1. */ extern const cryptonite_decaf_448_scalar_t cryptonite_decaf_448_scalar_one CRYPTONITE_DECAF_API_VIS; /** A scalar equal to 0. */ extern const cryptonite_decaf_448_scalar_t cryptonite_decaf_448_scalar_zero CRYPTONITE_DECAF_API_VIS; /** The identity point on the curve. */ extern const cryptonite_decaf_448_point_t cryptonite_decaf_448_point_identity CRYPTONITE_DECAF_API_VIS; /** An arbitrarily chosen base point on the curve. */ extern const cryptonite_decaf_448_point_t cryptonite_decaf_448_point_base CRYPTONITE_DECAF_API_VIS; /** Precomputed table for the base point on the curve. */ extern const struct cryptonite_decaf_448_precomputed_s *cryptonite_decaf_448_precomputed_base CRYPTONITE_DECAF_API_VIS; /** * @brief Read a scalar from wire format or from bytes. * * @param [in] ser Serialized form of a scalar. * @param [out] out Deserialized form. * * @retval CRYPTONITE_DECAF_SUCCESS The scalar was correctly encoded. * @retval CRYPTONITE_DECAF_FAILURE The scalar was greater than the modulus, * and has been reduced modulo that modulus. */ cryptonite_decaf_error_t cryptonite_decaf_448_scalar_decode ( cryptonite_decaf_448_scalar_t out, const unsigned char ser[CRYPTONITE_DECAF_448_SCALAR_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Read a scalar from wire format or from bytes. Reduces mod * scalar prime. * * @param [in] ser Serialized form of a scalar. * @param [in] ser_len Length of serialized form. * @param [out] out Deserialized form. */ void cryptonite_decaf_448_scalar_decode_long ( cryptonite_decaf_448_scalar_t out, const unsigned char *ser, size_t ser_len ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Serialize a scalar to wire format. * * @param [out] ser Serialized form of a scalar. * @param [in] s Deserialized scalar. */ void cryptonite_decaf_448_scalar_encode ( unsigned char ser[CRYPTONITE_DECAF_448_SCALAR_BYTES], const cryptonite_decaf_448_scalar_t s ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE CRYPTONITE_DECAF_NOINLINE; /** * @brief Add two scalars. The scalars may use the same memory. * @param [in] a One scalar. * @param [in] b Another scalar. * @param [out] out a+b. */ void cryptonite_decaf_448_scalar_add ( cryptonite_decaf_448_scalar_t out, const cryptonite_decaf_448_scalar_t a, const cryptonite_decaf_448_scalar_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Compare two scalars. * @param [in] a One scalar. * @param [in] b Another scalar. * @retval CRYPTONITE_DECAF_TRUE The scalars are equal. * @retval CRYPTONITE_DECAF_FALSE The scalars are not equal. */ cryptonite_decaf_bool_t cryptonite_decaf_448_scalar_eq ( const cryptonite_decaf_448_scalar_t a, const cryptonite_decaf_448_scalar_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Subtract two scalars. The scalars may use the same memory. * @param [in] a One scalar. * @param [in] b Another scalar. * @param [out] out a-b. */ void cryptonite_decaf_448_scalar_sub ( cryptonite_decaf_448_scalar_t out, const cryptonite_decaf_448_scalar_t a, const cryptonite_decaf_448_scalar_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Multiply two scalars. The scalars may use the same memory. * @param [in] a One scalar. * @param [in] b Another scalar. * @param [out] out a*b. */ void cryptonite_decaf_448_scalar_mul ( cryptonite_decaf_448_scalar_t out, const cryptonite_decaf_448_scalar_t a, const cryptonite_decaf_448_scalar_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Halve a scalar. The scalars may use the same memory. * @param [in] a A scalar. * @param [out] out a/2. */ void cryptonite_decaf_448_scalar_halve ( cryptonite_decaf_448_scalar_t out, const cryptonite_decaf_448_scalar_t a ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Invert a scalar. When passed zero, return 0. The input and output may alias. * @param [in] a A scalar. * @param [out] out 1/a. * @return CRYPTONITE_DECAF_SUCCESS The input is nonzero. */ cryptonite_decaf_error_t cryptonite_decaf_448_scalar_invert ( cryptonite_decaf_448_scalar_t out, const cryptonite_decaf_448_scalar_t a ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Copy a scalar. The scalars may use the same memory, in which * case this function does nothing. * @param [in] a A scalar. * @param [out] out Will become a copy of a. */ static inline void CRYPTONITE_DECAF_NONNULL cryptonite_decaf_448_scalar_copy ( cryptonite_decaf_448_scalar_t out, const cryptonite_decaf_448_scalar_t a ) { *out = *a; } /** * @brief Set a scalar to an unsigned 64-bit integer. * @param [in] a An integer. * @param [out] out Will become equal to a. */ void cryptonite_decaf_448_scalar_set_unsigned ( cryptonite_decaf_448_scalar_t out, uint64_t a ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL; /** * @brief Encode a point as a sequence of bytes. * * @param [out] ser The byte representation of the point. * @param [in] pt The point to encode. */ void cryptonite_decaf_448_point_encode ( uint8_t ser[CRYPTONITE_DECAF_448_SER_BYTES], const cryptonite_decaf_448_point_t pt ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Decode a point from a sequence of bytes. * * Every point has a unique encoding, so not every * sequence of bytes is a valid encoding. If an invalid * encoding is given, the output is undefined. * * @param [out] pt The decoded point. * @param [in] ser The serialized version of the point. * @param [in] allow_identity CRYPTONITE_DECAF_TRUE if the identity is a legal input. * @retval CRYPTONITE_DECAF_SUCCESS The decoding succeeded. * @retval CRYPTONITE_DECAF_FAILURE The decoding didn't succeed, because * ser does not represent a point. */ cryptonite_decaf_error_t cryptonite_decaf_448_point_decode ( cryptonite_decaf_448_point_t pt, const uint8_t ser[CRYPTONITE_DECAF_448_SER_BYTES], cryptonite_decaf_bool_t allow_identity ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Copy a point. The input and output may alias, * in which case this function does nothing. * * @param [out] a A copy of the point. * @param [in] b Any point. */ static inline void CRYPTONITE_DECAF_NONNULL cryptonite_decaf_448_point_copy ( cryptonite_decaf_448_point_t a, const cryptonite_decaf_448_point_t b ) { *a=*b; } /** * @brief Test whether two points are equal. If yes, return * CRYPTONITE_DECAF_TRUE, else return CRYPTONITE_DECAF_FALSE. * * @param [in] a A point. * @param [in] b Another point. * @retval CRYPTONITE_DECAF_TRUE The points are equal. * @retval CRYPTONITE_DECAF_FALSE The points are not equal. */ cryptonite_decaf_bool_t cryptonite_decaf_448_point_eq ( const cryptonite_decaf_448_point_t a, const cryptonite_decaf_448_point_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Add two points to produce a third point. The * input points and output point can be pointers to the same * memory. * * @param [out] sum The sum a+b. * @param [in] a An addend. * @param [in] b An addend. */ void cryptonite_decaf_448_point_add ( cryptonite_decaf_448_point_t sum, const cryptonite_decaf_448_point_t a, const cryptonite_decaf_448_point_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL; /** * @brief Double a point. Equivalent to * cryptonite_decaf_448_point_add(two_a,a,a), but potentially faster. * * @param [out] two_a The sum a+a. * @param [in] a A point. */ void cryptonite_decaf_448_point_double ( cryptonite_decaf_448_point_t two_a, const cryptonite_decaf_448_point_t a ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL; /** * @brief Subtract two points to produce a third point. The * input points and output point can be pointers to the same * memory. * * @param [out] diff The difference a-b. * @param [in] a The minuend. * @param [in] b The subtrahend. */ void cryptonite_decaf_448_point_sub ( cryptonite_decaf_448_point_t diff, const cryptonite_decaf_448_point_t a, const cryptonite_decaf_448_point_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL; /** * @brief Negate a point to produce another point. The input * and output points can use the same memory. * * @param [out] nega The negated input point * @param [in] a The input point. */ void cryptonite_decaf_448_point_negate ( cryptonite_decaf_448_point_t nega, const cryptonite_decaf_448_point_t a ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL; /** * @brief Multiply a base point by a scalar: scaled = scalar*base. * * @param [out] scaled The scaled point base*scalar * @param [in] base The point to be scaled. * @param [in] scalar The scalar to multiply by. */ void cryptonite_decaf_448_point_scalarmul ( cryptonite_decaf_448_point_t scaled, const cryptonite_decaf_448_point_t base, const cryptonite_decaf_448_scalar_t scalar ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Multiply a base point by a scalar: scaled = scalar*base. * This function operates directly on serialized forms. * * @warning This function is experimental. It may not be supported * long-term. * * @param [out] scaled The scaled point base*scalar * @param [in] base The point to be scaled. * @param [in] scalar The scalar to multiply by. * @param [in] allow_identity Allow the input to be the identity. * @param [in] short_circuit Allow a fast return if the input is illegal. * * @retval CRYPTONITE_DECAF_SUCCESS The scalarmul succeeded. * @retval CRYPTONITE_DECAF_FAILURE The scalarmul didn't succeed, because * base does not represent a point. */ cryptonite_decaf_error_t cryptonite_decaf_448_direct_scalarmul ( uint8_t scaled[CRYPTONITE_DECAF_448_SER_BYTES], const uint8_t base[CRYPTONITE_DECAF_448_SER_BYTES], const cryptonite_decaf_448_scalar_t scalar, cryptonite_decaf_bool_t allow_identity, cryptonite_decaf_bool_t short_circuit ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NOINLINE; /** * @brief RFC 7748 Diffie-Hellman scalarmul. This function uses a different * (non-Decaf) encoding. * * @param [out] scaled The scaled point base*scalar * @param [in] base The point to be scaled. * @param [in] scalar The scalar to multiply by. * * @retval CRYPTONITE_DECAF_SUCCESS The scalarmul succeeded. * @retval CRYPTONITE_DECAF_FAILURE The scalarmul didn't succeed, because the base * point is in a small subgroup. */ cryptonite_decaf_error_t cryptonite_decaf_x448 ( uint8_t out[CRYPTONITE_DECAF_X448_PUBLIC_BYTES], const uint8_t base[CRYPTONITE_DECAF_X448_PUBLIC_BYTES], const uint8_t scalar[CRYPTONITE_DECAF_X448_PRIVATE_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NOINLINE; /** The base point for X448 Diffie-Hellman */ extern const uint8_t cryptonite_decaf_x448_base_point[CRYPTONITE_DECAF_X448_PUBLIC_BYTES] CRYPTONITE_DECAF_API_VIS; /** * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses * a different (non-Decaf) encoding. * * @deprecated Renamed to cryptonite_decaf_x448_derive_public_key. * I have no particular timeline for removing this name. * * @param [out] scaled The scaled point base*scalar * @param [in] scalar The scalar to multiply by. */ void cryptonite_decaf_x448_generate_key ( uint8_t out[CRYPTONITE_DECAF_X448_PUBLIC_BYTES], const uint8_t scalar[CRYPTONITE_DECAF_X448_PRIVATE_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE CRYPTONITE_DECAF_DEPRECATED("Renamed to cryptonite_decaf_x448_derive_public_key"); /** * @brief RFC 7748 Diffie-Hellman base point scalarmul. This function uses * a different (non-Decaf) encoding. * * Does exactly the same thing as cryptonite_decaf_x448_generate_key, * but has a better name. * * @param [out] scaled The scaled point base*scalar * @param [in] scalar The scalar to multiply by. */ void cryptonite_decaf_x448_derive_public_key ( uint8_t out[CRYPTONITE_DECAF_X448_PUBLIC_BYTES], const uint8_t scalar[CRYPTONITE_DECAF_X448_PRIVATE_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /* FUTURE: uint8_t cryptonite_decaf_448_encode_like_curve448) */ /** * @brief Precompute a table for fast scalar multiplication. * Some implementations do not include precomputed points; for * those implementations, this implementation simply copies the * point. * * @param [out] a A precomputed table of multiples of the point. * @param [in] b Any point. */ void cryptonite_decaf_448_precompute ( cryptonite_decaf_448_precomputed_s *a, const cryptonite_decaf_448_point_t b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Multiply a precomputed base point by a scalar: * scaled = scalar*base. * Some implementations do not include precomputed points; for * those implementations, this function is the same as * cryptonite_decaf_448_point_scalarmul * * @param [out] scaled The scaled point base*scalar * @param [in] base The point to be scaled. * @param [in] scalar The scalar to multiply by. */ void cryptonite_decaf_448_precomputed_scalarmul ( cryptonite_decaf_448_point_t scaled, const cryptonite_decaf_448_precomputed_s *base, const cryptonite_decaf_448_scalar_t scalar ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Multiply two base points by two scalars: * scaled = scalar1*base1 + scalar2*base2. * * Equivalent to two calls to cryptonite_decaf_448_point_scalarmul, but may be * faster. * * @param [out] combo The linear combination scalar1*base1 + scalar2*base2. * @param [in] base1 A first point to be scaled. * @param [in] scalar1 A first scalar to multiply by. * @param [in] base2 A second point to be scaled. * @param [in] scalar2 A second scalar to multiply by. */ void cryptonite_decaf_448_point_double_scalarmul ( cryptonite_decaf_448_point_t combo, const cryptonite_decaf_448_point_t base1, const cryptonite_decaf_448_scalar_t scalar1, const cryptonite_decaf_448_point_t base2, const cryptonite_decaf_448_scalar_t scalar2 ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * Multiply one base point by two scalars: * * a1 = scalar1 * base * a2 = scalar2 * base * * Equivalent to two calls to cryptonite_decaf_448_point_scalarmul, but may be * faster. * * @param [out] a1 The first multiple. It may be the same as the input point. * @param [out] a2 The second multiple. It may be the same as the input point. * @param [in] base1 A point to be scaled. * @param [in] scalar1 A first scalar to multiply by. * @param [in] scalar2 A second scalar to multiply by. */ void cryptonite_decaf_448_point_dual_scalarmul ( cryptonite_decaf_448_point_t a1, cryptonite_decaf_448_point_t a2, const cryptonite_decaf_448_point_t base1, const cryptonite_decaf_448_scalar_t scalar1, const cryptonite_decaf_448_scalar_t scalar2 ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Multiply two base points by two scalars: * scaled = scalar1*cryptonite_decaf_448_point_base + scalar2*base2. * * Otherwise equivalent to cryptonite_decaf_448_point_double_scalarmul, but may be * faster at the expense of being variable time. * * @param [out] combo The linear combination scalar1*base + scalar2*base2. * @param [in] scalar1 A first scalar to multiply by. * @param [in] base2 A second point to be scaled. * @param [in] scalar2 A second scalar to multiply by. * * @warning: This function takes variable time, and may leak the scalars * used. It is designed for signature verification. */ void cryptonite_decaf_448_base_double_scalarmul_non_secret ( cryptonite_decaf_448_point_t combo, const cryptonite_decaf_448_scalar_t scalar1, const cryptonite_decaf_448_point_t base2, const cryptonite_decaf_448_scalar_t scalar2 ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Constant-time decision between two points. If pick_b * is zero, out = a; else out = b. * * @param [out] out The output. It may be the same as either input. * @param [in] a Any point. * @param [in] b Any point. * @param [in] pick_b If nonzero, choose point b. */ void cryptonite_decaf_448_point_cond_sel ( cryptonite_decaf_448_point_t out, const cryptonite_decaf_448_point_t a, const cryptonite_decaf_448_point_t b, cryptonite_decaf_word_t pick_b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Constant-time decision between two scalars. If pick_b * is zero, out = a; else out = b. * * @param [out] out The output. It may be the same as either input. * @param [in] a Any scalar. * @param [in] b Any scalar. * @param [in] pick_b If nonzero, choose scalar b. */ void cryptonite_decaf_448_scalar_cond_sel ( cryptonite_decaf_448_scalar_t out, const cryptonite_decaf_448_scalar_t a, const cryptonite_decaf_448_scalar_t b, cryptonite_decaf_word_t pick_b ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Test that a point is valid, for debugging purposes. * * @param [in] to_test The point to test. * @retval CRYPTONITE_DECAF_TRUE The point is valid. * @retval CRYPTONITE_DECAF_FALSE The point is invalid. */ cryptonite_decaf_bool_t cryptonite_decaf_448_point_valid ( const cryptonite_decaf_448_point_t to_test ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_WARN_UNUSED CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Torque a point, for debugging purposes. The output * will be equal to the input. * * @param [out] q The point to torque. * @param [in] p The point to torque. */ void cryptonite_decaf_448_point_debugging_torque ( cryptonite_decaf_448_point_t q, const cryptonite_decaf_448_point_t p ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Projectively scale a point, for debugging purposes. * The output will be equal to the input, and will be valid * even if the factor is zero. * * @param [out] q The point to scale. * @param [in] p The point to scale. * @param [in] factor Serialized GF factor to scale. */ void cryptonite_decaf_448_point_debugging_pscale ( cryptonite_decaf_448_point_t q, const cryptonite_decaf_448_point_t p, const unsigned char factor[CRYPTONITE_DECAF_448_SER_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Almost-Elligator-like hash to curve. * * Call this function with the output of a hash to make a hash to the curve. * * This function runs Elligator2 on the cryptonite_decaf_448 Jacobi quartic model. It then * uses the isogeny to put the result in twisted Edwards form. As a result, * it is safe (cannot produce points of order 4), and would be compatible with * hypothetical other implementations of Decaf using a Montgomery or untwisted * Edwards model. * * Unlike Elligator, this function may be up to 4:1 on [0,(p-1)/2]: * A factor of 2 due to the isogeny. * A factor of 2 because we quotient out the 2-torsion. * * This makes it about 8:1 overall, or 16:1 overall on curves with cofactor 8. * * Negating the input (mod q) results in the same point. Inverting the input * (mod q) results in the negative point. This is the same as Elligator. * * This function isn't quite indifferentiable from a random oracle. * However, it is suitable for many protocols, including SPEKE and SPAKE2 EE. * Furthermore, calling it twice with independent seeds and adding the results * is indifferentiable from a random oracle. * * @param [in] hashed_data Output of some hash function. * @param [out] pt The data hashed to the curve. */ void cryptonite_decaf_448_point_from_hash_nonuniform ( cryptonite_decaf_448_point_t pt, const unsigned char hashed_data[CRYPTONITE_DECAF_448_HASH_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Indifferentiable hash function encoding to curve. * * Equivalent to calling cryptonite_decaf_448_point_from_hash_nonuniform twice and adding. * * @param [in] hashed_data Output of some hash function. * @param [out] pt The data hashed to the curve. */ void cryptonite_decaf_448_point_from_hash_uniform ( cryptonite_decaf_448_point_t pt, const unsigned char hashed_data[2*CRYPTONITE_DECAF_448_HASH_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief Inverse of elligator-like hash to curve. * * This function writes to the buffer, to make it so that * cryptonite_decaf_448_point_from_hash_nonuniform(buffer) = pt if * possible. Since there may be multiple preimages, the * "which" parameter chooses between them. To ensure uniform * inverse sampling, this function succeeds or fails * independently for different "which" values. * * @param [out] recovered_hash Encoded data. * @param [in] pt The point to encode. * @param [in] which A value determining which inverse point * to return. * * @retval CRYPTONITE_DECAF_SUCCESS The inverse succeeded. * @retval CRYPTONITE_DECAF_FAILURE The inverse failed. */ cryptonite_decaf_error_t cryptonite_decaf_448_invert_elligator_nonuniform ( unsigned char recovered_hash[CRYPTONITE_DECAF_448_HASH_BYTES], const cryptonite_decaf_448_point_t pt, uint32_t which ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE CRYPTONITE_DECAF_WARN_UNUSED; /** * @brief Inverse of elligator-like hash to curve. * * This function writes to the buffer, to make it so that * cryptonite_decaf_448_point_from_hash_uniform(buffer) = pt if * possible. Since there may be multiple preimages, the * "which" parameter chooses between them. To ensure uniform * inverse sampling, this function succeeds or fails * independently for different "which" values. * * @param [out] recovered_hash Encoded data. * @param [in] pt The point to encode. * @param [in] which A value determining which inverse point * to return. * * @retval CRYPTONITE_DECAF_SUCCESS The inverse succeeded. * @retval CRYPTONITE_DECAF_FAILURE The inverse failed. */ cryptonite_decaf_error_t cryptonite_decaf_448_invert_elligator_uniform ( unsigned char recovered_hash[2*CRYPTONITE_DECAF_448_HASH_BYTES], const cryptonite_decaf_448_point_t pt, uint32_t which ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE CRYPTONITE_DECAF_WARN_UNUSED; /** * @brief Overwrite scalar with zeros. */ void cryptonite_decaf_448_scalar_destroy ( cryptonite_decaf_448_scalar_t scalar ) CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_API_VIS; /** * @brief Overwrite point with zeros. */ void cryptonite_decaf_448_point_destroy ( cryptonite_decaf_448_point_t point ) CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_API_VIS; /** * @brief Overwrite precomputed table with zeros. */ void cryptonite_decaf_448_precomputed_destroy ( cryptonite_decaf_448_precomputed_s *pre ) CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_API_VIS; #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __CRYPTONITE_DECAF_POINT_448_H__ */ cryptonite-0.26/cbits/decaf/include/decaf/shake.h0000644000000000000000000000700313414232447020132 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 CRYPTONITE_DECAF_SHAKE_H #define CRYPTONITE_DECAF_SHAKE_H #include "cryptonite_sha3.h" #include #define CHUNK_SIZE_32 0x80000000 typedef struct sha3_shake256_ctx { struct sha3_ctx sc[1]; uint8_t filler[136]; // 200 - 2*(256/8) } cryptonite_decaf_shake256_ctx_t[1]; static inline void cryptonite_decaf_shake256_init(cryptonite_decaf_shake256_ctx_t ctx) { cryptonite_sha3_init(ctx -> sc, 256); } static inline void cryptonite_decaf_shake256_update(cryptonite_decaf_shake256_ctx_t ctx, const uint8_t *in, size_t inlen) { #if __SIZE_MAX__ > UINT32_MAX // split data over 4 GB in 2-GB chunks while (inlen > UINT32_MAX) { cryptonite_sha3_update(ctx -> sc, in, CHUNK_SIZE_32); inlen -= CHUNK_SIZE_32; in += CHUNK_SIZE_32; } #endif cryptonite_sha3_update(ctx -> sc, in, (uint32_t) inlen); } static inline void cryptonite_decaf_shake256_output(cryptonite_decaf_shake256_ctx_t ctx, uint8_t *out, size_t outlen) { #if __SIZE_MAX__ > UINT32_MAX // split data over 4 GB in 2-GB chunks while (outlen > UINT32_MAX) { cryptonite_sha3_output(ctx -> sc, out, CHUNK_SIZE_32); outlen -= CHUNK_SIZE_32; out += CHUNK_SIZE_32; } #endif cryptonite_sha3_output(ctx -> sc, out, (uint32_t) outlen); } static inline void cryptonite_decaf_shake256_final(cryptonite_decaf_shake256_ctx_t ctx, uint8_t *out, size_t outlen) { cryptonite_sha3_finalize_shake(ctx -> sc); cryptonite_decaf_shake256_output(ctx, out, outlen); cryptonite_decaf_shake256_init(ctx); } static inline void cryptonite_decaf_shake256_destroy(cryptonite_decaf_shake256_ctx_t ctx) { cryptonite_decaf_bzero(ctx, sizeof(*ctx)); } static inline void cryptonite_decaf_shake256_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { cryptonite_decaf_shake256_ctx_t ctx; cryptonite_decaf_shake256_init(ctx); cryptonite_decaf_shake256_update(ctx, in, inlen); cryptonite_sha3_finalize_shake(ctx -> sc); cryptonite_decaf_shake256_output(ctx, out, outlen); cryptonite_decaf_shake256_destroy(ctx); } #endif cryptonite-0.26/cbits/decaf/include/decaf/ed448.h0000644000000000000000000002215513414232447017674 0ustar0000000000000000/** * @file decaf/ed448.h * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @brief A group of prime order p, based on Ed448-Goldilocks. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #ifndef __CRYPTONITE_DECAF_ED448_H__ #define __CRYPTONITE_DECAF_ED448_H__ 1 #include #include #include #ifdef __cplusplus extern "C" { #endif /** Number of bytes in an EdDSA public key. */ #define CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES 57 /** Number of bytes in an EdDSA private key. */ #define CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES /** Number of bytes in an EdDSA private key. */ #define CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES (CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES + CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES) /** Does EdDSA support non-contextual signatures? */ #define CRYPTONITE_DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS 0 /** Prehash context renaming macros. */ #define cryptonite_decaf_ed448_prehash_ctx_s cryptonite_decaf_shake256_ctx_s #define cryptonite_decaf_ed448_prehash_ctx_t cryptonite_decaf_shake256_ctx_t #define cryptonite_decaf_ed448_prehash_update cryptonite_decaf_shake256_update #define cryptonite_decaf_ed448_prehash_destroy cryptonite_decaf_shake256_destroy /** * @brief EdDSA key generation. This function uses a different (non-Decaf) * encoding. * * @param [out] pubkey The public key. * @param [in] privkey The private key. */ void cryptonite_decaf_ed448_derive_public_key ( uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const uint8_t privkey[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA signing. * * @param [out] signature The signature. * @param [in] privkey The private key. * @param [in] pubkey The public key. * @param [in] message The message to sign. * @param [in] message_len The length of the message. * @param [in] prehashed Nonzero if the message is actually the hash of something you want to sign. * @param [in] context A "context" for this signature of up to 255 bytes. * @param [in] context_len Length of the context. * * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is * safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives * you no seat belt. */ void cryptonite_decaf_ed448_sign ( uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, uint8_t context_len ) CRYPTONITE_DECAF_API_VIS __attribute__((nonnull(1,2,3))) CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA signing with prehash. * * @param [out] signature The signature. * @param [in] privkey The private key. * @param [in] pubkey The public key. * @param [in] hash The hash of the message. This object will not be modified by the call. * @param [in] context A "context" for this signature of up to 255 bytes. Must be the same as what was used for the prehash. * @param [in] context_len Length of the context. * * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is * safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives * you no seat belt. */ void cryptonite_decaf_ed448_sign_prehash ( uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t privkey[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const cryptonite_decaf_ed448_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len ) CRYPTONITE_DECAF_API_VIS __attribute__((nonnull(1,2,3,4))) CRYPTONITE_DECAF_NOINLINE; /** * @brief Prehash initialization, with contexts if supported. * * @param [out] hash The hash object to be initialized. */ void cryptonite_decaf_ed448_prehash_init ( cryptonite_decaf_ed448_prehash_ctx_t hash ) CRYPTONITE_DECAF_API_VIS __attribute__((nonnull(1))) CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA signature verification. * * Uses the standard (i.e. less-strict) verification formula. * * @param [in] signature The signature. * @param [in] pubkey The public key. * @param [in] message The message to verify. * @param [in] message_len The length of the message. * @param [in] prehashed Nonzero if the message is actually the hash of something you want to verify. * @param [in] context A "context" for this signature of up to 255 bytes. * @param [in] context_len Length of the context. * * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is * safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives * you no seat belt. */ cryptonite_decaf_error_t cryptonite_decaf_ed448_verify ( const uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const uint8_t *message, size_t message_len, uint8_t prehashed, const uint8_t *context, uint8_t context_len ) CRYPTONITE_DECAF_API_VIS __attribute__((nonnull(1,2))) CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA signature verification. * * Uses the standard (i.e. less-strict) verification formula. * * @param [in] signature The signature. * @param [in] pubkey The public key. * @param [in] hash The hash of the message. This object will not be modified by the call. * @param [in] context A "context" for this signature of up to 255 bytes. Must be the same as what was used for the prehash. * @param [in] context_len Length of the context. * * @warning For Ed25519, it is unsafe to use the same key for both prehashed and non-prehashed * messages, at least without some very careful protocol-level disambiguation. For Ed448 it is * safe. The C++ wrapper is designed to make it harder to screw this up, but this C code gives * you no seat belt. */ cryptonite_decaf_error_t cryptonite_decaf_ed448_verify_prehash ( const uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES], const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const cryptonite_decaf_ed448_prehash_ctx_t hash, const uint8_t *context, uint8_t context_len ) CRYPTONITE_DECAF_API_VIS __attribute__((nonnull(1,2))) CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA point encoding. Used internally, exposed externally. * Multiplies the point by the current cofactor first. * * @param [out] enc The encoded point. * @param [in] p The point. */ void cryptonite_decaf_448_point_mul_by_cofactor_and_encode_like_eddsa ( uint8_t enc[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const cryptonite_decaf_448_point_t p ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA point decoding. Remember that while points on the * EdDSA curves have cofactor information, Decaf ignores (quotients * out) all cofactor information. * * @param [out] enc The encoded point. * @param [in] p The point. */ cryptonite_decaf_error_t cryptonite_decaf_448_point_decode_like_eddsa_and_ignore_cofactor ( cryptonite_decaf_448_point_t p, const uint8_t enc[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA to ECDH public key conversion * Deserialize the point to get y on Edwards curve, * Convert it to u coordinate on Montgomery curve. * * @warning This function does not check that the public key being converted * is a valid EdDSA public key (FUTURE?) * * @param[out] x The ECDH public key as in RFC7748(point on Montgomery curve) * @param[in] ed The EdDSA public key(point on Edwards curve) */ void cryptonite_decaf_ed448_convert_public_key_to_x448 ( uint8_t x[CRYPTONITE_DECAF_X448_PUBLIC_BYTES], const uint8_t ed[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; /** * @brief EdDSA to ECDH private key conversion * Using the appropriate hash function, hash the EdDSA private key * and keep only the lower bytes to get the ECDH private key * * @param[out] x The ECDH private key as in RFC7748 * @param[in] ed The EdDSA private key */ void cryptonite_decaf_ed448_convert_private_key_to_x448 ( uint8_t x[CRYPTONITE_DECAF_X448_PRIVATE_BYTES], const uint8_t ed[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES] ) CRYPTONITE_DECAF_API_VIS CRYPTONITE_DECAF_NONNULL CRYPTONITE_DECAF_NOINLINE; #ifdef __cplusplus } /* extern "C" */ #endif #endif /* __CRYPTONITE_DECAF_ED448_H__ */ cryptonite-0.26/cbits/decaf/include/decaf/point_255.h0000644000000000000000000000003513414232447020561 0ustar0000000000000000/* Not needed if 448-only */ cryptonite-0.26/cbits/decaf/include/arch_32/arch_intrinsics.h0000644000000000000000000000115713414232447022404 0ustar0000000000000000/* Copyright (c) 2016 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ #ifndef __ARCH_ARCH_32_ARCH_INTRINSICS_H__ #define __ARCH_ARCH_32_ARCH_INTRINSICS_H__ #define ARCH_WORD_BITS 32 static __inline__ __attribute((always_inline,unused)) uint32_t word_is_zero(uint32_t a) { /* let's hope the compiler isn't clever enough to optimize this. */ return (((uint64_t)a)-1)>>32; } static __inline__ __attribute((always_inline,unused)) uint64_t widemul(uint32_t a, uint32_t b) { return ((uint64_t)a) * b; } #endif /* __ARCH_ARM_32_ARCH_INTRINSICS_H__ */ cryptonite-0.26/cbits/decaf/include/arch_ref64/arch_intrinsics.h0000644000000000000000000000116213414232447023102 0ustar0000000000000000/* Copyright (c) 2016 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ #ifndef __ARCH_REF64_ARCH_INTRINSICS_H__ #define __ARCH_REF64_ARCH_INTRINSICS_H__ #define ARCH_WORD_BITS 64 static __inline__ __attribute((always_inline,unused)) uint64_t word_is_zero(uint64_t a) { /* let's hope the compiler isn't clever enough to optimize this. */ return (((__uint128_t)a)-1)>>64; } static __inline__ __attribute((always_inline,unused)) __uint128_t widemul(uint64_t a, uint64_t b) { return ((__uint128_t)a) * b; } #endif /* ARCH_REF64_ARCH_INTRINSICS_H__ */ cryptonite-0.26/cbits/decaf/p448/arch_32/f_impl.h0000644000000000000000000000240413414232447017540 0ustar0000000000000000/* Copyright (c) 2014-2016 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ #define GF_HEADROOM 2 #define LIMB(x) (x##ull)&((1ull<<28)-1), (x##ull)>>28 #define FIELD_LITERAL(a,b,c,d,e,f,g,h) \ {{LIMB(a),LIMB(b),LIMB(c),LIMB(d),LIMB(e),LIMB(f),LIMB(g),LIMB(h)}} #define LIMB_PLACE_VALUE(i) 28 void cryptonite_gf_add_RAW (gf out, const gf a, const gf b) { for (unsigned int i=0; ilimb[0]); i++) { out->limb[i] = a->limb[i] + b->limb[i]; } } void cryptonite_gf_sub_RAW (gf out, const gf a, const gf b) { for (unsigned int i=0; ilimb[0]); i++) { out->limb[i] = a->limb[i] - b->limb[i]; } } void cryptonite_gf_bias (gf a, int amt) { uint32_t co1 = ((1ull<<28)-1)*amt, co2 = co1-amt; for (unsigned int i=0; ilimb[0]); i++) { a->limb[i] += (i==sizeof(*a)/sizeof(a->limb[0])/2) ? co2 : co1; } } void cryptonite_gf_weak_reduce (gf a) { uint32_t mask = (1ull<<28) - 1; uint32_t tmp = a->limb[15] >> 28; a->limb[8] += tmp; for (unsigned int i=15; i>0; i--) { a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>28); } a->limb[0] = (a->limb[0] & mask) + tmp; } cryptonite-0.26/cbits/decaf/p448/arch_ref64/f_impl.h0000644000000000000000000000213713414232447020245 0ustar0000000000000000/* Copyright (c) 2014-2016 Cryptography Research, Inc. * Released under the MIT License. See LICENSE.txt for license information. */ #define GF_HEADROOM 9999 /* Everything is reduced anyway */ #define FIELD_LITERAL(a,b,c,d,e,f,g,h) {{a,b,c,d,e,f,g,h}} #define LIMB_PLACE_VALUE(i) 56 void cryptonite_gf_add_RAW (gf out, const gf a, const gf b) { for (unsigned int i=0; i<8; i++) { out->limb[i] = a->limb[i] + b->limb[i]; } cryptonite_gf_weak_reduce(out); } void cryptonite_gf_sub_RAW (gf out, const gf a, const gf b) { uint64_t co1 = ((1ull<<56)-1)*2, co2 = co1-2; for (unsigned int i=0; i<8; i++) { out->limb[i] = a->limb[i] - b->limb[i] + ((i==4) ? co2 : co1); } cryptonite_gf_weak_reduce(out); } void cryptonite_gf_bias (gf a, int amt) { (void) a; (void) amt; } void cryptonite_gf_weak_reduce (gf a) { uint64_t mask = (1ull<<56) - 1; uint64_t tmp = a->limb[7] >> 56; a->limb[4] += tmp; for (unsigned int i=7; i>0; i--) { a->limb[i] = (a->limb[i] & mask) + (a->limb[i-1]>>56); } a->limb[0] = (a->limb[0] & mask) + tmp; } cryptonite-0.26/cbits/decaf/p448/f_field.h0000644000000000000000000000760613414232447016452 0ustar0000000000000000/** * @file p448/f_field.h * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @brief Field-specific code for 2^448 - 2^224 - 1. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #ifndef __P448_F_FIELD_H__ #define __P448_F_FIELD_H__ 1 #include "constant_time.h" #include #include #include "word.h" #define __CRYPTONITE_DECAF_448_GF_DEFINED__ 1 #define NLIMBS (64/sizeof(word_t)) #define X_SER_BYTES 56 #define SER_BYTES 56 typedef struct cryptonite_gf_448_s { word_t limb[NLIMBS]; } __attribute__((aligned(16))) cryptonite_gf_448_s, cryptonite_gf_448_t[1]; #define GF_LIT_LIMB_BITS 56 #define GF_BITS 448 #define ZERO cryptonite_gf_448_ZERO #define ONE cryptonite_gf_448_ONE #define MODULUS cryptonite_gf_448_MODULUS #define gf cryptonite_gf_448_t #define cryptonite_gf_s cryptonite_gf_448_s #define cryptonite_gf_eq cryptonite_gf_448_eq #define cryptonite_gf_hibit cryptonite_gf_448_hibit #define cryptonite_gf_copy cryptonite_gf_448_copy #define cryptonite_gf_add cryptonite_gf_448_add #define cryptonite_gf_sub cryptonite_gf_448_sub #define cryptonite_gf_add_RAW cryptonite_gf_448_add_RAW #define cryptonite_gf_sub_RAW cryptonite_gf_448_sub_RAW #define cryptonite_gf_bias cryptonite_gf_448_bias #define cryptonite_gf_weak_reduce cryptonite_gf_448_weak_reduce #define cryptonite_gf_strong_reduce cryptonite_gf_448_strong_reduce #define cryptonite_gf_mul cryptonite_gf_448_mul #define cryptonite_gf_sqr cryptonite_gf_448_sqr #define cryptonite_gf_mulw_unsigned cryptonite_gf_448_mulw_unsigned #define cryptonite_gf_isr cryptonite_gf_448_isr #define cryptonite_gf_serialize cryptonite_gf_448_serialize #define cryptonite_gf_deserialize cryptonite_gf_448_deserialize /* RFC 7748 support */ #define X_PUBLIC_BYTES X_SER_BYTES #define X_PRIVATE_BYTES X_PUBLIC_BYTES #define X_PRIVATE_BITS 448 #define SQRT_MINUS_ONE P448_SQRT_MINUS_ONE /* might not be defined */ #define INLINE_UNUSED __inline__ __attribute__((unused,always_inline)) #ifdef __cplusplus extern "C" { #endif /* Defined below in f_impl.h */ static INLINE_UNUSED void cryptonite_gf_copy (gf out, const gf a) { *out = *a; } static INLINE_UNUSED void cryptonite_gf_add_RAW (gf out, const gf a, const gf b); static INLINE_UNUSED void cryptonite_gf_sub_RAW (gf out, const gf a, const gf b); static INLINE_UNUSED void cryptonite_gf_bias (gf inout, int amount); static INLINE_UNUSED void cryptonite_gf_weak_reduce (gf inout); void cryptonite_gf_strong_reduce (gf inout); void cryptonite_gf_add (gf out, const gf a, const gf b); void cryptonite_gf_sub (gf out, const gf a, const gf b); void cryptonite_gf_mul (cryptonite_gf_s *__restrict__ out, const gf a, const gf b); void cryptonite_gf_mulw_unsigned (cryptonite_gf_s *__restrict__ out, const gf a, uint32_t b); void cryptonite_gf_sqr (cryptonite_gf_s *__restrict__ out, const gf a); mask_t cryptonite_gf_isr(gf a, const gf x); /** a^2 x = 1, QNR, or 0 if x=0. Return true if successful */ mask_t cryptonite_gf_eq (const gf x, const gf y); mask_t cryptonite_gf_hibit (const gf x); void cryptonite_gf_serialize (uint8_t *serial, const gf x,int with_highbit); mask_t cryptonite_gf_deserialize (gf x, const uint8_t serial[SER_BYTES],int with_highbit); #ifdef __cplusplus } /* extern "C" */ #endif #include "f_impl.h" /* Bring in the inline implementations */ #define P_MOD_8 7 #if P_MOD_8 == 5 extern const gf SQRT_MINUS_ONE; #endif #ifndef LIMBPERM #define LIMBPERM(i) (i) #endif #define LIMB_MASK(i) (((1ull)< #define API_NS(_id) cryptonite_decaf_448_##_id const API_NS(point_t) API_NS(point_base) = {{ {FIELD_LITERAL(0x00fffffffffffffe,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff,0x0000000000000003,0x0000000000000000,0x0000000000000000,0x0000000000000000)}, {FIELD_LITERAL(0x0081e6d37f752992,0x003078ead1c28721,0x00135cfd2394666c,0x0041149c50506061,0x0031d30e4f5490b3,0x00902014990dc141,0x0052341b04c1e328,0x0014237853c10a1b)}, {FIELD_LITERAL(0x00fffffffffffffb,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff,0x00fffffffffffffe,0x00ffffffffffffff,0x00ffffffffffffff,0x00ffffffffffffff)}, {FIELD_LITERAL(0x008f205b70660415,0x00881c60cfd3824f,0x00377a638d08500d,0x008c66d5d4672615,0x00e52fa558e08e13,0x0087770ae1b6983d,0x004388f55a0aa7ff,0x00b4d9a785cf1a91)} }}; const gf API_NS(precomputed_base_as_fe)[240] VECTOR_ALIGNED = { {FIELD_LITERAL(0x00e614a9f7278dc5,0x002e454ad04c5124,0x00d8f58cee1436f3,0x00c83ed46e4180ec,0x00a41e93274a38fa,0x00c1e7e53257771e,0x0043e0ff03c0392f,0x002c7c6405ce61df)}, {FIELD_LITERAL(0x0033c4f9dc990b33,0x00c291cb1ceb55c3,0x002ae3f58ade88b2,0x006b1f9f11395474,0x002ded6e4b27ff7c,0x0041012ed4aa10e1,0x003c22d20a36bae7,0x001f584eed472b19)}, {FIELD_LITERAL(0x00c3514779ee6f60,0x001574c873b20c2b,0x004cd6a46a5a5e65,0x0059a068aeb4204a,0x004c610458bc354d,0x00e94567479d02d2,0x00feaf77ed118e28,0x00f58a8bf115eeb5)}, {FIELD_LITERAL(0x0046110878fcb20f,0x00df43db21cc6f32,0x00ffdde9f4516644,0x00519917791686b9,0x00b72b441fd34473,0x008d45684cb1c72b,0x0015181370fc17a5,0x00a456d1307f74d3)}, {FIELD_LITERAL(0x001430f149b607dc,0x00e992ccd16715fc,0x00a62209b0a32a09,0x00b889cedc26b8e4,0x0059bf9a3ac109cf,0x006871bb3b7feac2,0x00f4a4d5fd9a0e6b,0x00b95db460cd69a5)}, {FIELD_LITERAL(0x0036304418bda702,0x007bc56861561558,0x00f344bc8e30416f,0x00a64537080f59d7,0x00b4c20077d00ace,0x00ee79620b26f8cc,0x00a6a558e0b5403d,0x008f1d2c766f3d19)}, {FIELD_LITERAL(0x00ef21c0297d3112,0x0073f89bd27c35b1,0x00ec44f9b1ff5e33,0x006bee51d878f1ee,0x001571a4b2aceddb,0x00cd0182d55131d1,0x0026761dbc1844be,0x00f01865af716474)}, {FIELD_LITERAL(0x0021dfef3f5fe8cc,0x0038c659ed1dbd68,0x0058ded9bcebe283,0x00077bbb094983ee,0x00b7b484e913d70c,0x0063e477a9506397,0x0000b996a6e01629,0x00ab68b41f75cd37)}, {FIELD_LITERAL(0x00a1fbd946403a4e,0x00be5a4e2d611b05,0x00ea4f210888bc6e,0x0043e9b0e0ae50fe,0x002abc4f6bd86845,0x00c3ed649c67f663,0x00d4eeb391a520e7,0x004b19cf1bfe7584)}, {FIELD_LITERAL(0x0099a75e6f22999e,0x001f16454c79f659,0x00d776a37fddc812,0x0095fdd63b6b0a78,0x00d232169366e947,0x002ea77dd21e9de7,0x00e8c46e85f97a90,0x00358758651f8cd9)}, {FIELD_LITERAL(0x002b6f5036a07bdf,0x004f6940af3e2646,0x00866028f8986799,0x00838b26ccb50415,0x0010557417f00b11,0x008a3b6bc447e96b,0x003de3d035e9e0c9,0x00188fca2b6d4011)}, {FIELD_LITERAL(0x001ca4038635312b,0x0078dc75c1e01c44,0x004340f00b3100a4,0x005e63e36bf6646e,0x008e1efd4b624688,0x00a61c2ffb1525e1,0x0072587505a75b81,0x00a8637140d96e78)}, {FIELD_LITERAL(0x004a7c41ffac8a41,0x005bf37075b1c20b,0x00c053b570a42408,0x002bb7e278d328e7,0x00b2378b63245100,0x003318bf2a1a368a,0x00f4e3e0bdbe02de,0x0058921e4b1e32f8)}, {FIELD_LITERAL(0x005e93d6fa1118a0,0x0062b43515d381e2,0x002c42864052e620,0x00af258bae6ccbd3,0x00954247094d654d,0x005db01f5b010810,0x009c8cf25efa8204,0x005f73ced3714ef7)}, {FIELD_LITERAL(0x0085f89aff2cf49d,0x00f591ee8480f6f0,0x00378ed518114265,0x00f04293e2a09008,0x00c58688db9140ed,0x00e9912696399ff1,0x0055bd1b96367413,0x0023a70cf830f999)}, {FIELD_LITERAL(0x001c83772944584e,0x00c1ba881e472bcc,0x00af2715a0aef13f,0x00bd0360d25610a6,0x00c42f8b3eebebde,0x00a9e474849788b1,0x00dcd1a1a2efec5c,0x009480d34c2818c0)}, {FIELD_LITERAL(0x00b4b6e09a565d74,0x0095efcf6175aa48,0x00498defe7ae7810,0x00309b684ed26470,0x007a8873a91d4e44,0x00ea4b3f857eb27a,0x00979b8619d25a9e,0x00721a2770eeb6e9)}, {FIELD_LITERAL(0x00b422f0f4be195f,0x00e88cfa83bfa2db,0x009fd60666ea4268,0x0095a458f5e801d0,0x00b9eee6882081f6,0x00b27edb37604948,0x00a7f67c4d44d8db,0x00df840ccf290c01)}, {FIELD_LITERAL(0x00c9fed0d47c9103,0x00ba73ed9294a043,0x005cbbc928e652e1,0x0068419e98ee8215,0x00f63de63786300b,0x009aa9bb6c19f8aa,0x0066c536b573213f,0x00d2b77a5b2f2450)}, {FIELD_LITERAL(0x00810236c68d5b74,0x00d0a1af1872a011,0x007f23ee29e3801a,0x009a55a678f8dba4,0x0065445dcff9be40,0x00f3978789a9abc5,0x00001f010d23f5e8,0x00ff80042934b0c5)}, {FIELD_LITERAL(0x00a6749f4b3f9745,0x003ab85f4180e502,0x006a7de9b530ed50,0x0050b5353b0441bf,0x00a093583ac6ede4,0x00c4918ad1406299,0x000f75cf2a353a2b,0x001c6644a0683a56)}, {FIELD_LITERAL(0x00e8694156c09bfe,0x00f6f3a5bd17ad96,0x0098dbed45edad12,0x00edfe2b84921821,0x0097884330199b67,0x004aab02685b3e9e,0x0068ac0bd2453c30,0x00167c1c1c87d8f5)}, {FIELD_LITERAL(0x008bba5fbf63f599,0x0059a3c960c7d63f,0x00ce2db75b08b7d9,0x0097e80cb2104171,0x009b68be26a140d0,0x002b9b9954e94c68,0x00023ca8fc411beb,0x00cbc4bcccbada07)}, {FIELD_LITERAL(0x0053c100e77b678d,0x000f115c400fa96f,0x005928d3de22afa2,0x00e47cd9bdbdbe96,0x00597ecfe84abf19,0x0058bb428e4c7a32,0x00dd582f76ecf584,0x00b1211365eccb79)}, {FIELD_LITERAL(0x00dbfb9a00a58e68,0x004468189350d82f,0x00b4b12407ee92c6,0x00e27a7908f73455,0x00f071170071b5ae,0x00221a5e6ba229dd,0x001903e3f6a81f83,0x00be36325402775f)}, {FIELD_LITERAL(0x004d298d6e691756,0x00775644dfce310b,0x00a861887823ea98,0x00cf0b6014fa6e6f,0x005f4e296380826f,0x00bf423392627f90,0x002893bfc8122f6a,0x00440dbc89bea228)}, {FIELD_LITERAL(0x00acbb4f40a4ab73,0x00d6a82f48fa3366,0x000a7958fc6faac2,0x008a4cdd60a7c33c,0x005e5587dd8b6f1a,0x00e40f63086a88e8,0x0030940cbbcda0ad,0x009a42e3dc35c130)}, {FIELD_LITERAL(0x00d37716cad825f1,0x00883870cba9552a,0x008ef785f5c762e3,0x006cb253e0469242,0x007b8f17fee9d967,0x00a43de6932b52b6,0x001aca9fe2af783c,0x008967778ff0b680)}, {FIELD_LITERAL(0x006400c4cdc6c9c3,0x001e8c978691083f,0x00ad74f01f68e0c5,0x00f7feb0372b5f6a,0x002f60d175ade13a,0x0098ec54a221a678,0x00fcfea8a71f244e,0x00dea6660e45ded2)}, {FIELD_LITERAL(0x002585b4aa8d6752,0x00e62da7615a2089,0x0010c1c741f39b68,0x00569bb1eced9f65,0x00ba6d09e4daa724,0x007d3e20aef281b9,0x00bd7f65aca3ffdc,0x00dea434a50288a8)}, {FIELD_LITERAL(0x007ba92a2489170f,0x00cd356354d31e9c,0x00a60d47406e5430,0x009c3d5fde8ed877,0x00079eaa50dd08d1,0x0024674d593ffa5f,0x005391be9596c53b,0x00856ca8d50acdd9)}, {FIELD_LITERAL(0x00d4620aa5e5bdec,0x002303c4b9b5d941,0x003b061f857ebb2a,0x00371f9e856d49fd,0x0071c36c5335051e,0x0040e4346a4d359f,0x00b31dbd959ec40c,0x00d99353a71bf6de)}, {FIELD_LITERAL(0x0078898adf0f21dd,0x006e09bfedd8604a,0x00efaf0e0f9bb666,0x00b0f685db8852c3,0x0094c86ec566b841,0x00e5c2879ba50dbe,0x00a87cd444cff758,0x00d3e26fd47f23df)}, {FIELD_LITERAL(0x00b82c07fb1854f8,0x0057f654a06fad9f,0x004c00383250cf92,0x008b91713d291af6,0x002f2521777859b9,0x00533111421f22c8,0x00643da86fab9794,0x00dc7fb0680e3d40)}, {FIELD_LITERAL(0x00e59ffd40e87788,0x006431e9755a50af,0x00a03ce700fb580a,0x00ad7e70aa3c9b9e,0x0078970a2b4db503,0x00c800451849637a,0x00e7e6a5b49e123f,0x00e1ed15f77bcb4d)}, {FIELD_LITERAL(0x00bc1d1d1af47f28,0x00ebc5501bbd81f0,0x00aa6b5513547aa4,0x0074ed33551343fe,0x00d2114f6ef7d43b,0x006335b41d518aeb,0x00ebd46919692fb8,0x0052d5d4e3fada95)}, {FIELD_LITERAL(0x00ebfc9f489799a4,0x00497535b6980688,0x00fef76499e6a51b,0x00018eedde7a18da,0x00f435d9e72b69c7,0x005ab0faa8281675,0x003232d06e290be8,0x005473ec8be0286c)}, {FIELD_LITERAL(0x00c6eb0d0ebb4874,0x00856a2274119097,0x00380bc7b29e3719,0x00b1ae149f0e424d,0x0009b41855b9de26,0x0098684013d0f53f,0x0082e8554c38a6ff,0x00e76c18c353743a)}, {FIELD_LITERAL(0x008da1194e1ab61f,0x008edb5f89688805,0x00f4970252f851bd,0x007a46f632b6ad20,0x006d2d1c37e9f90a,0x0060dd09353f665f,0x000a625a80d86657,0x000f93f6fedd0888)}, {FIELD_LITERAL(0x003b019b31992fb4,0x004f6a2ad1f64c28,0x008a744134e5c571,0x000ca33172f9af3f,0x00d478755a67bb8b,0x009d1f5c48abb223,0x004da4d6f12ee901,0x0084f09541f4140d)}, {FIELD_LITERAL(0x0031f412f5cacd43,0x00e5afb75dd20e94,0x001ce24b3452740e,0x00176d6dedf30ff1,0x0082e22e564fffca,0x001d56fbe007097f,0x0095b37c851a6918,0x008ec50ef97f8f4c)}, {FIELD_LITERAL(0x007e2b1c52251f57,0x00cbef37c9380033,0x0037ed652761bceb,0x00f1c2a5dc6dd232,0x0026e1b90d63ce0b,0x00938d732173a6b8,0x00d439aa45da993f,0x00d356b8deaccef7)}, {FIELD_LITERAL(0x00ed32377f56c67d,0x00c3b6a4de32e4a7,0x00481a36c0dd5d91,0x00bb557d20466ba7,0x00645f6d3200163e,0x005eb4c54df7c48c,0x00fd8e3d08f1e3b4,0x001156353f099147)}, {FIELD_LITERAL(0x00ae1b4c089b2756,0x00e686d2b916fb5f,0x007ac43ec2437dd8,0x00f7bfdf7e860ed2,0x0097dbcb8b786dc9,0x00ec7a90401c8b2f,0x00425ed017989bdb,0x00444bc9ca6d914d)}, {FIELD_LITERAL(0x00e5e7b83b53ab7f,0x004e4bed6ca44fc5,0x0008bd7a67c40d4d,0x009dbec74a4a2f0e,0x0077df3f4fc2c73f,0x0046b1af5e73ea8d,0x009f096cb7be8670,0x003ad0a29929141d)}, {FIELD_LITERAL(0x00991a1222e9b2e1,0x00be7583901d7dc7,0x00fd1d0c8169d3da,0x000fe0a94a68acf9,0x00b77bd05afc78a2,0x00a84f1697f87ebc,0x000097cfdb0c2ecb,0x007d51d70352ed1b)}, {FIELD_LITERAL(0x0025dc2a60643159,0x001f0d8ff85f95b4,0x00ed74a4bc598a73,0x00f30afe6f0574a9,0x0003788545d4d28c,0x009dc410ad120ac0,0x001950947e69961d,0x001ceb23cb0355b0)}, {FIELD_LITERAL(0x00ee2202ded9f1bd,0x002fa4fce658976d,0x00e7c15bc9716470,0x004f7ea99d500369,0x004b995a18318376,0x00246c4f8af91911,0x00cc77a07d09dbfe,0x007906f6f1364be6)}, {FIELD_LITERAL(0x003c97e6384da36e,0x00423d53eac81a09,0x00b70d68f3cdce35,0x00ee7959b354b92c,0x00f4e9718819c8ca,0x009349f12acbffe9,0x005aee7b62cb7da6,0x00d97764154ffc86)}, {FIELD_LITERAL(0x00d95d1c5fcb435a,0x0016d1ed6b5086f9,0x00792aa0b7e54d71,0x0067b65715f1925d,0x00a219755ec6176b,0x00bc3f026b12c28f,0x00700c897ffeb93e,0x0089b83f6ec50b46)}, {FIELD_LITERAL(0x00ad9cdb4544b923,0x00d11664c7284061,0x00815ae86b8f910b,0x005414fb2591c3c6,0x0094ba83e2d7ef9e,0x0001dbc16599386c,0x00c8721f0493911b,0x00c1be6b463c346c)}, {FIELD_LITERAL(0x0079680ce111ed3b,0x001a1ed82806122c,0x000c2e7466d15df3,0x002c407f6f7150fd,0x00c5e7c96b1b0ce3,0x009aa44626863ff9,0x00887b8b5b80be42,0x00b6023cec964825)}, {FIELD_LITERAL(0x00fed3cd80ca2292,0x0015b043a73ca613,0x000a9fd7bf9be227,0x003b5e03de2db983,0x005af72d46904ef7,0x00c0f1b5c49faa99,0x00dc86fc3bd305e1,0x00c92f08c1cb1797)}, {FIELD_LITERAL(0x001b571efb768f37,0x009d778487cf5cfd,0x00430e37327ebfd4,0x00a92447e5970a41,0x00eb13127c0edbac,0x00ec61e5aefeaf20,0x00447eebf57d2e5c,0x00f01433e550e558)}, {FIELD_LITERAL(0x0039dd7ce7fc6860,0x00d64f6425653da1,0x003e037c7f57d0af,0x0063477a06e2bcf2,0x001727dbb7ac67e6,0x0049589f5efafe2e,0x00fc0fef2e813d54,0x008baa5d087fb50d)}, {FIELD_LITERAL(0x00a7527958238159,0x0013ec9537a84cd6,0x001d7fee7d562525,0x00b9eefa6191d5e5,0x00dbc97db70bcb8a,0x00481affc7a4d395,0x006f73d3e70c31bb,0x00183f324ed96a61)}, {FIELD_LITERAL(0x00db04a6264ba838,0x00582b1f9fddc1b3,0x003ee72e4aaa027f,0x007d1de938cd0dd5,0x0032d5d66cf76afa,0x00c9c717c95c1ec2,0x00f27aa11764b8d6,0x00713a482b7ef36e)}, {FIELD_LITERAL(0x00ece96f95f2b66f,0x00ece7952813a27b,0x0026fc36592e489e,0x007157d1a2de0f66,0x00759dc111d86ddf,0x0012881e5780bb0f,0x00c8ccc83ad29496,0x0012b9bd1929eb71)}, {FIELD_LITERAL(0x001bf51f7d65cdfd,0x00d14cdafa16a97d,0x002c38e60fcd10e7,0x00a27446e393efbd,0x000b5d8946a71fdd,0x0063df2cde128f2f,0x006c8679569b1888,0x0059ffc4925d732d)}, {FIELD_LITERAL(0x00f05ea5df25a20f,0x00cb6224e5b932ce,0x00d3aed52e2718d9,0x00fb89ee0996ce72,0x006197045a6e1e80,0x00bcdf20057fc6f9,0x0059bf78b6ae5c2c,0x0049cacb87455db0)}, {FIELD_LITERAL(0x006a15bb20f75c0c,0x0079a144027a5d0c,0x00d19116ce0b4d70,0x0059b83bcb0b268e,0x005f58f63f16c127,0x0079958318ee2c37,0x00defbb063d07f82,0x00f1f0b931d2d446)}, {FIELD_LITERAL(0x009696510000d333,0x00ec2f788bc04826,0x000e4d02b1f67ba5,0x00659aa8dace08b6,0x00d7a38a3a3ae533,0x008856defa8c746b,0x004d7a4402d3da1a,0x00ea82e06229260f)}, {FIELD_LITERAL(0x0034a1b3c3ca2bdd,0x0072077a35bca880,0x0005af4e935c1b8e,0x00a5f1a71e8b7737,0x004d3133292cb2e5,0x000fe2a2dca1c916,0x0024d181b41935bb,0x00d9f54880ca0332)}, {FIELD_LITERAL(0x009ffd90abfeae96,0x00cba3c2b624a516,0x005ef08bcee46c91,0x00e6fde30afb6185,0x00f0b4db4f818ce4,0x006c54f45d2127f5,0x00040125035854c7,0x00372658a3287e13)}, {FIELD_LITERAL(0x006f6fd9baac61d5,0x002a7710a020a895,0x009de0db7fc03d4d,0x00cdedcb1875f40b,0x00050caf9b6b1e22,0x005e3a6654456ab0,0x00775fdf8c4423d4,0x0028701ea5738b5d)}, {FIELD_LITERAL(0x0028f8f04e414d54,0x0087037ba56c7694,0x00976b5b4d0ddb59,0x00a4227e6d462421,0x004c77c678b4c560,0x0006c9e74fb485a8,0x00c1c138a02d3981,0x0040a19403d6b6b5)}, {FIELD_LITERAL(0x0045e8dda9400888,0x002ff12e5fc05db7,0x00a7098d54afe69c,0x00cdbe846a500585,0x00879c1593ca1882,0x003f7a7fea76c8b0,0x002cd73dd0c8e0a1,0x00645d6ce96f51fe)}, {FIELD_LITERAL(0x00f19224ebba2aa5,0x0074f89d358e694d,0x00eea486597135ad,0x0081579a4555c7e1,0x0010b9b872930a9d,0x00f002e87a30ecc0,0x009b9d66b6de56e2,0x00a3c4f45e8004eb)}, {FIELD_LITERAL(0x00d4817c1edc2929,0x00c67cb908be637f,0x00bd6dd1aa6bfe9c,0x00a1803a9fe7795c,0x001770d311e2cefb,0x0018054eca0d1c88,0x004fa667b240f212,0x00f631f7f055a447)}, {FIELD_LITERAL(0x00f89335c2a59286,0x00a0f5c905d55141,0x00b41fb836ee9382,0x00e235d51730ca43,0x00a5cb37b5c0a69a,0x009b966ffe136c45,0x00cb2ea10bf80ed1,0x00fb2b370b40dc35)}, {FIELD_LITERAL(0x0085e78af7758979,0x00275a4ee1631a3a,0x00d26bc0ed78b683,0x004f8355ea21064f,0x00d618e1a32696e5,0x008d8d7b150e5680,0x00a74cd854b278d2,0x001dd62702203ea0)}, {FIELD_LITERAL(0x0029782e92b11745,0x008eadf422f96200,0x00217a39f2cdcaa2,0x00782d1ca9aefd0b,0x00321c6e47203654,0x001e72961020101a,0x00b562fa6e6ab16e,0x0005c92274af111a)}, {FIELD_LITERAL(0x006bc3d53011f470,0x00032d6e692b83e8,0x00059722f497cd0b,0x0009b4e6f0c497cc,0x0058a804b7cce6c0,0x002b71d3302bbd5d,0x00e2f82a36765fce,0x008dded99524c703)}, {FIELD_LITERAL(0x002e788749a865f7,0x006e4dc3116861ea,0x009f1428c37276e6,0x00e7d2e0fc1e1226,0x003aeebc6b6c45f6,0x0071a8073bf500c9,0x004b22ad986b530c,0x00f439e63c0d79d4)}, {FIELD_LITERAL(0x00b2fa76ac8b829b,0x008fe6bf01865590,0x0059df538e389f40,0x006acd49eeea748a,0x00ab81280b990cfe,0x00c34a54ac57bfe5,0x003889ce9731cedf,0x0081b71cc1b4654d)}, {FIELD_LITERAL(0x002f194eaafa46dc,0x008e38f57fe87613,0x00dc8e5ae25f4ab2,0x000a17809575e6bd,0x00d3ec7923ba366a,0x003a7e72e0ad75e3,0x0010024b88436e0a,0x00ed3c5444b64051)}, {FIELD_LITERAL(0x001b2fc57bf3c738,0x006a3f918993fb80,0x0026f7a14fdec288,0x0075a2cdccef08db,0x00d3ecbc9eecdbf1,0x0048c40f06e5bf7f,0x00d63e423009896b,0x000598bc99c056a8)}, {FIELD_LITERAL(0x007ce03ecbf50cbd,0x00369ba996b992ca,0x00896d4b33a5f7f0,0x00602b5b8536da60,0x00e1122082ba6d73,0x00c3fbb903ba0d74,0x00d3f8ec55c1daf8,0x006a8f96ca0f0be1)}, {FIELD_LITERAL(0x001fb73475c45509,0x00d2b2e5ea43345a,0x00cb3c3842077bd1,0x0029f90ad820946e,0x007c11b2380778aa,0x009e54ece62c1704,0x004bc60c41ca01c3,0x004525679a5a0b03)}, {FIELD_LITERAL(0x00766ae4190ec6d8,0x0065768cabc71380,0x00b902598416cdc2,0x00380021ad38df52,0x008f0b89d6551134,0x004254d4cc62c5a5,0x000d79f4484b9b94,0x00b516732ae3c50e)}, {FIELD_LITERAL(0x0039b0422412784c,0x00bf9fe2ee8ce055,0x0063ddb8a4906298,0x00db48625178a0ea,0x009e9012c0fd3c4e,0x00ff30c60950d2c4,0x003b9453f5565977,0x0054dc1d7ff25dfb)}, {FIELD_LITERAL(0x0017085f4a346148,0x00c7cf7a37f62272,0x001776e129bc5c30,0x009955134c9eef2a,0x001ba5bdf1df07be,0x00ec39497103a55c,0x006578354fda6cfb,0x005f02719d4f15ee)}, {FIELD_LITERAL(0x000b3a37617632b0,0x00597199fe1cfb6c,0x0042a7ccdfeafdd6,0x004cc9f15ebcea17,0x00f436e596a6b4a4,0x00168861142df0d8,0x000753edfec26af5,0x000c495d7e388116)}, {FIELD_LITERAL(0x00ad46264a269aa2,0x002b13845e4b9e3c,0x0006a20b68b0d7f4,0x00c271a35ee514ae,0x002b67e14a58f4d8,0x00f5065b099a60d6,0x00ba6737b90514bc,0x00b6265e7c5b898f)}, {FIELD_LITERAL(0x00b60167d9e7d065,0x00e60ba0d07381e8,0x003a4f17b725c2d4,0x006c19fe176b64fa,0x003b57b31af86ccb,0x0021047c286180fd,0x00bdc8fb00c6dbb6,0x00fe4a9f4bab4f3f)}, {FIELD_LITERAL(0x000a72d23dcb3f1f,0x00a3737f84011727,0x00f870c0fbbf4a47,0x00a7aadd04b5c9ca,0x000c7715c67bd072,0x00015a136afcd74e,0x0080d5caea499634,0x0026b448ec7514b7)}, {FIELD_LITERAL(0x0077003c5e9eee08,0x006eaa1bdba2f437,0x007ae297ddfa8d2a,0x00aa8531e1aeb2d6,0x00ce283cc626efdc,0x00efe2f51d153115,0x00db954c07c84995,0x002ade92c7e00acf)}, {FIELD_LITERAL(0x00a6295218dc136a,0x00563b3af0e9c012,0x00d3753b0145db1b,0x004550389c043dc1,0x00ea94ae27401bdf,0x002b0b949f2b7956,0x00c63f780ad8e23c,0x00e591c47d6bab15)}, {FIELD_LITERAL(0x0057e7ea35f36dae,0x00f47d7ad15de22e,0x00d757ea4b105115,0x008311457d579d7e,0x00b49b75b1edd4eb,0x0081c7ff742fd63a,0x00ddda3187433df6,0x00475727d55f9c66)}, {FIELD_LITERAL(0x00be93a7d4fa7149,0x00bef825a4d3396a,0x004c32daa951139b,0x003f4be7d981a85e,0x00e866d6ca8642d0,0x00b912bba6f1b2f8,0x00e28ba64c9cf5e1,0x0039504574996955)}, {FIELD_LITERAL(0x002419222c607674,0x00a7f23af89188b3,0x00ad127284e73d1c,0x008bba582fae1c51,0x00fc6aa7ca9ecab1,0x003df5319eb6c2ba,0x002a05af8a8b199a,0x004bf8354558407c)}, {FIELD_LITERAL(0x008d6009b26da3f8,0x00898e88ca06b1ca,0x00edb22b2ed7fe62,0x00fbc93516aabe80,0x008b4b470c42ce0d,0x00e0032ba7d0dcbb,0x00d76da3a956ecc8,0x007f20fe74e3852a)}, {FIELD_LITERAL(0x003182b5cf0f0340,0x002fd3d8d9d60fc2,0x00b73ffe08bff43d,0x00d3dec97fee6a72,0x00675aafc6e16949,0x00d27f499c6f0c86,0x00e0578789f3387a,0x00e52031ab49ec2a)}, {FIELD_LITERAL(0x006b7a0674f9f8de,0x00a742414e5c7cff,0x0041cbf3c6e13221,0x00e3a64fd207af24,0x0087c05f15fbe8d1,0x004c50936d9e8a33,0x001306ec21042b6d,0x00a4f4137d1141c2)}, {FIELD_LITERAL(0x001ed4dc71fa2523,0x005d0bff19bf9b5c,0x00c3801cee065a64,0x001ed0b504323fbf,0x0003ab9fdcbbc593,0x00df82070178b8d2,0x00a2bcaa9c251f85,0x00c628a3674bd02e)}, {FIELD_LITERAL(0x00f619046dea974f,0x004c39fedfde6ee7,0x00d593cb9f22afc5,0x00624e10ee9ab4ab,0x009c1b40f41869fd,0x0098f2cb44da6d46,0x002311d093becf31,0x004d97d1771880ab)}, {FIELD_LITERAL(0x00ddbe0750dd1add,0x004b3c7b885844b8,0x00363e7ecf12f1ae,0x0062e953e6438f9d,0x0023cc73b076afe9,0x00b09fa083b4da32,0x00c7c3d2456c541d,0x005b591ec6b694d4)}, {FIELD_LITERAL(0x000d5b4b3da135ab,0x00838f3e5064d81d,0x00d44eb50f6d94ed,0x0008931ab502ac6d,0x00debe01ca3d3586,0x0025c206775f0641,0x005ad4b6ae912763,0x007e2c318ad8f247)}, {FIELD_LITERAL(0x00d79a91e629d030,0x00ad5b50fc20eb72,0x00edd89a222eb1bd,0x000ddad6fb098ea8,0x00b8be69a49c90c4,0x009bbe2d69ecd346,0x00a1def906a95a48,0x00db8fd6a6d2cca3)}, {FIELD_LITERAL(0x00c41d1f9c1f1ac1,0x007b2df4e9f19146,0x00b469355fd5ba7a,0x00b5e1965afc852a,0x00388d5f1e2d8217,0x0022079e4c09ae93,0x0014268acd4ef518,0x00c1dd8d9640464c)}, {FIELD_LITERAL(0x003fe038eb92f894,0x000e6da1b72e8e32,0x003a1411bfcbe0fa,0x00b55d473164a9e4,0x00b9a775ac2df48d,0x0002ddf350659e21,0x00a279a69eb19cb3,0x00f844eab25cba44)}, {FIELD_LITERAL(0x00c7ad952112f3aa,0x00229739f81c017a,0x0008b9222b75a2a8,0x00bd0d6ad469c483,0x00e344297892a13c,0x00a1cbeb8f435a3d,0x0078e2be1f7a0bec,0x001ac54f670ba8cd)}, {FIELD_LITERAL(0x00adb2c1566e8b8f,0x0096c68a35771a9a,0x00869933356f334a,0x00ba9c93459f5962,0x009ec73fb6e8ca4b,0x003c3802c27202e1,0x0031f5b733e0c008,0x00f9058c19611fa9)}, {FIELD_LITERAL(0x004d51124797c831,0x008f5ae3750347ad,0x0070ced94c1a0c8e,0x00f6db2043898e64,0x000d00c9a5750cd0,0x000741ec59bad712,0x003c9d11aab37b7f,0x00a67ba169807714)}, {FIELD_LITERAL(0x00dc70fe7eb5cbde,0x003cda5bb49331d7,0x00dec9068514f18c,0x00f3537d975b501d,0x00dd02de725b8e4b,0x0062327200072106,0x0034607e7e266644,0x00ebc51a91215cb6)}, {FIELD_LITERAL(0x00a5187e6ee7341b,0x00e6d52e82d83b6e,0x00df3c41323094a7,0x00b3324f444e9de9,0x00689eb21a35bfe5,0x00f16363becd548d,0x00e187cc98e7f60f,0x00127d9062f0ccab)}, {FIELD_LITERAL(0x0000623bf87622c5,0x00a1966fdd069496,0x00c315b7b812f9fc,0x00bdf5efcd128b97,0x001d464f532e3e16,0x003cd94f081bfd7e,0x00ed9dae12ce4009,0x002756f5736eee70)}, {FIELD_LITERAL(0x00b528e4ce3d61bf,0x005a03531ed051d6,0x00bbda4aa68d7f12,0x001810a28e93ccb9,0x00ef4ac525bef536,0x006dcefdd9f9f364,0x006e3d9ed78d6381,0x00774bd6ff0713c4)}, {FIELD_LITERAL(0x00c13c5aae3ae341,0x009c6c9ed98373e7,0x00098f26864577a8,0x0015b886e9488b45,0x0037692c42aadba5,0x00b83170b8e7791c,0x001670952ece1b44,0x00fd932a39276da2)}, {FIELD_LITERAL(0x00f1e26e9762d4a8,0x00d9d74082183414,0x00ffec9bd57a0282,0x000919e128fd497a,0x00ab7ae7d00fe5f8,0x0054dc442851ff68,0x00c9ebeb3b861687,0x00507f7cab8b698f)}, {FIELD_LITERAL(0x007e5cda6410cc67,0x00ab7f000be9ef84,0x0031b09f82de4167,0x00c003f7b4be2064,0x00bc2f44effafd2d,0x0013ca0a8a45cd9e,0x0035e70988cff10c,0x001744f57d827ab7)}, {FIELD_LITERAL(0x009ae3b93a56c404,0x004a410b7a456699,0x00023a619355e6b2,0x009cdc7297387257,0x0055b94d4ae70d04,0x002cbd607f65b005,0x003208b489697166,0x00ea2aa058867370)}, {FIELD_LITERAL(0x00df76b3328ada72,0x002e20621604a7c2,0x00f910638a105b09,0x00ef4724d96ef2cd,0x00377d83d6b8a2f7,0x00b4f48805ade324,0x001cd5da8b152018,0x0045af671a20ca7f)}, {FIELD_LITERAL(0x000d62da6711c0cd,0x004b53ac7a27d523,0x0089cc150fb20e64,0x0055d2c2883154fe,0x00b5dcfd03448874,0x006d80dda2a505cb,0x00b57162afb80dc8,0x007ddb5162431acf)}, {FIELD_LITERAL(0x00c845923c084294,0x00072419a201bc25,0x0045f408b5f8e669,0x00e9d6a186b74dfe,0x00e19108c68fa075,0x0017b91d874177b7,0x002f0ca2c7912c5a,0x009400aa385a90a2)}, {FIELD_LITERAL(0x001cf640859b02f8,0x00758d1d5d5ce427,0x00763c784ef4604c,0x005fa81aee205270,0x00ac537bfdfc44cb,0x004b919bd342d670,0x00238508d9bf4b7a,0x00154888795644f3)}, {FIELD_LITERAL(0x008eeef4feb7de7b,0x003012ffbb0d4107,0x00cb0d6fe30b99d1,0x00c4b51d598067cb,0x003356469016b7ee,0x00addaf85188542f,0x004538bdd8de18c1,0x00999dd4f0c59d4f)}, {FIELD_LITERAL(0x0026ef1614e160af,0x00c023f9edfc9c76,0x00cff090da5f57ba,0x0076db7a66643ae9,0x0019462f8c646999,0x008fec00b3854b22,0x00d55041692a0a1c,0x0065db894215ca00)}, {FIELD_LITERAL(0x00f8ac5cf4705b6a,0x00867d82dcb457e3,0x007e13ab2ccc2ce9,0x009ee9a018d3930e,0x008370f8ecb42df8,0x002d9f019add263e,0x003302385b92d196,0x00a15654536e2c0c)}, {FIELD_LITERAL(0x0056dafc91f5bae3,0x00d5fc6f3c94933e,0x000d8fdf26f76b0b,0x00726f2ad342c280,0x001e2fec8c6d0c46,0x000fe83ea74ae570,0x00353cec2c128243,0x0046657e1c14bd2c)}, {FIELD_LITERAL(0x008cc9cd236315c0,0x0031d9c5b39fda54,0x00a5713ef37e1171,0x00293d5ae2886325,0x00c4aba3e05015e1,0x0003f35ef78e4fc6,0x0039d6bd3ac1527b,0x0019d7c3afb77106)}, {FIELD_LITERAL(0x00b54850275fe626,0x0053a3fd1ec71140,0x00e3d2d7dbe096fa,0x00e4ac7b595cce4c,0x0077bad449c0a494,0x00b7c98814afd5b3,0x0057226f58486cf9,0x00b1557154f0cc57)}, {FIELD_LITERAL(0x0084e9d6ce567a50,0x0052bf5d1f2558ec,0x00920d83bff60ee7,0x00afc160b1d17413,0x008ae58837d3e7d1,0x00fd676c8896dba4,0x00004e170540611a,0x00f7ccb8f91f6541)}, {FIELD_LITERAL(0x004246bfcecc627a,0x004ba431246c03a4,0x00bd1d101872d497,0x003b73d3f185ee16,0x001feb2e2678c0e3,0x00ff13c5a89dec76,0x00ed06042e771d8f,0x00a4fd2a897a83dd)}, {FIELD_LITERAL(0x00dbca4e98a7dcd9,0x00ee29cfc78bde99,0x00e4a3b6995f52e9,0x0045d70189ae8096,0x00fd2a8a3b9b0d1b,0x00af1793b107d8e1,0x00dbf92cbe4afa20,0x00da60f798e3681d)}, {FIELD_LITERAL(0x0065b5c41af29a68,0x0021ce9a03a5ef69,0x00b0c0a91cba4f38,0x0008408de2a54743,0x00bcec1b84f673ae,0x001b382a3f1e5244,0x00d1c1c24c9afae1,0x005b7f3d32956904)}, {FIELD_LITERAL(0x004ede34af2813f3,0x00d4a8e11c9e8216,0x004796d5041de8a5,0x00c4c6b4d21cc987,0x00e8a433ee07fa1e,0x0055720b5abcc5a1,0x008873ea9c74b080,0x005b3fec1ab65d48)}, {FIELD_LITERAL(0x00417fa30a7119ed,0x00af257758419751,0x00d358a487b463d4,0x0089703cc720b00d,0x00ce56314ff7f271,0x0064db171ade62c1,0x00640b36d4a22fed,0x00424eb88696d23f)}, {FIELD_LITERAL(0x00b81ad88248f13a,0x00f5f69399248294,0x004be9b33e8cfea6,0x00b56087c018df01,0x0057e8846bbb6242,0x006a5db00b65a660,0x00963e3a87daf343,0x00badfe6dec2140b)}, {FIELD_LITERAL(0x001bd59c09e982ea,0x00f72daeb937b289,0x0018b76dca908e0e,0x00edb498512384ad,0x00ce0243b6cc9538,0x00f96ff690cb4e70,0x007c77bf9f673c8d,0x005bf704c088a528)}, {FIELD_LITERAL(0x0021ce99e09ebda3,0x00fcbd9f91875ad0,0x009bbf6b7b7a0b5f,0x00388886a69b1940,0x00926a56d0f81f12,0x00e12903c3358d46,0x005dfce4e8e1ce9d,0x0044cfa94e2f7e23)}, {FIELD_LITERAL(0x006c2b9d7234cc41,0x006ad9c2ae2bda7d,0x00b64cdddba701f9,0x00180318c49ac580,0x00c35d14319f4c95,0x003a21dc65cd415b,0x009c474c28e04940,0x00c65114875e57c6)}, {FIELD_LITERAL(0x00fb22bb5fd3ce50,0x0017b48aada7ae54,0x00fd5c44ad19a536,0x000ccc4e4e55e45c,0x00fd637d45b4c3f5,0x0038914e023c37cf,0x00ac1881d6a8d898,0x00611ed8d3d943a8)}, {FIELD_LITERAL(0x007dc52da400336c,0x001fded1e15b9457,0x00902e00f5568e3a,0x00219bef40456d2d,0x005684161fb3dbc9,0x004a4e9be49a76ea,0x006e685ae88b78ff,0x0021c42f13042d3c)}, {FIELD_LITERAL(0x00a91dda62eec2d4,0x00a6b7e64d7b13e9,0x00384086b44c9969,0x008de118af683239,0x0008e416fb85d76c,0x0020945ebda9b120,0x0096a7f485e7b172,0x000fa91c7035f011)}, {FIELD_LITERAL(0x005e8694077a1535,0x008bef75f71c8f1d,0x000a7c1316423511,0x00906e1d70604320,0x003fc46c1a2ffbd6,0x00d1d5022e68f360,0x002515fba37bbf46,0x00ca16234e023b44)}, {FIELD_LITERAL(0x009df98566a18c6d,0x00cf3a200968f219,0x0044ba60da6d9086,0x00dbc9c0e344da03,0x000f9401c4466855,0x00d46a57c5b0a8d1,0x00875a635d7ac7c6,0x00ef4a933b7e0ae6)}, {FIELD_LITERAL(0x00878366a9e0b96f,0x0057a8573ea9e0d8,0x005ef206ddc3f601,0x0046756a9d1c4eab,0x00bccf478bb3c12c,0x001f97ed7f813a3b,0x001b309582460e1c,0x0026a4f760ecd5cb)}, {FIELD_LITERAL(0x00139078397030bd,0x000e3c447e859a00,0x0064a5b334c82393,0x00b8aabeb7358093,0x00020778bb9ae73b,0x0032ee94c7892a18,0x008215253cb41bda,0x005e2797593517ae)}, {FIELD_LITERAL(0x002922b39ca33eec,0x0090d12a5f3ab194,0x00ab60c02fb5f8ed,0x00188d292abba1cf,0x00e10edec9698f6e,0x0069a4d9934133c8,0x0024aac40e6d3d06,0x001702c2177661b0)}, {FIELD_LITERAL(0x007c89a5a07aa2b5,0x00ae492ecae4711d,0x00ee921ab74f0844,0x007842778fc5005f,0x006a4d33cb28022c,0x007b327e4ac0f437,0x007a9d0366acaf12,0x005c6544e6c9ae1c)}, {FIELD_LITERAL(0x0091868594265aa2,0x00797accae98ca6d,0x0008d8c5f0f8a184,0x00d1f4f1c2b2fe6e,0x0036783dfb48a006,0x008c165120503527,0x0025fd780058ce9b,0x0068beb007be7d27)}, {FIELD_LITERAL(0x0019e23f0474b114,0x00eb94c2ad3b437e,0x006ddb34683b75ac,0x00391f9209b564c6,0x00083b3bb3bff7aa,0x00eedcd0f6dceefc,0x00b50817f794fe01,0x0036474deaaa75c9)}, {FIELD_LITERAL(0x002f007755836f3d,0x004d39f2530acc6b,0x006b58d7b2699929,0x004126fdd3185e62,0x003aeaac0f32897c,0x003c0478f4edb66d,0x0072f43ac66a9364,0x0003730da744777a)}, {FIELD_LITERAL(0x0045fdc16487cda3,0x00b2d8e844cf2ed7,0x00612c50e88c1607,0x00a08aabc66c1672,0x006031fdcbb24d97,0x001b639525744b93,0x004409d62639ab17,0x00a1853d0347ab1d)}, {FIELD_LITERAL(0x003667bf998406f8,0x0000115c43a12975,0x001e662f3b20e8fd,0x0019ffa534cb24eb,0x00016be0dc8efb45,0x00ff76a8b26243f5,0x00ae20d241a541e3,0x0069bd6af13cd430)}, {FIELD_LITERAL(0x008a5e5a9140a3de,0x005c18d41653ac12,0x0010321e9d6e8f3d,0x00fbdda016e10aca,0x0077fb6038c20257,0x00b5438b7a81ed77,0x00db1dbcb9a8ce83,0x0026734c2c1aabc3)}, {FIELD_LITERAL(0x007e32c049b5c477,0x009d2bfdbd9bcfd8,0x00636e93045938c6,0x007fde4af7687298,0x0046a5184fafa5d3,0x0079b1e7f13a359b,0x00875adf1fb927d6,0x00333e21c61bcad2)}, {FIELD_LITERAL(0x00b4b53eab6bdb19,0x009b22d8b43711d0,0x00d948b9d961785d,0x00cb167b6f279ead,0x00191de3a678e1c9,0x00d9dd9511095c2e,0x00f284324cd43067,0x00ed74fa535151dd)}, {FIELD_LITERAL(0x00fb7feb08c27472,0x008a97b55f699c77,0x006d41820f923b83,0x006831432f0aa975,0x00a58ffb263b3955,0x004f13449a66db38,0x0026fccd22b6d583,0x00a803eb20eeb6c2)}, {FIELD_LITERAL(0x007df6cbb926830b,0x00d336058ae37865,0x007af47dac696423,0x0048d3011ec64ac8,0x006b87666e40049f,0x0036a2e0e51303d7,0x00ba319bd79dbc55,0x003e2737ecc94f53)}, {FIELD_LITERAL(0x0008ed8ea0ad95be,0x0041d324b9709645,0x00e25412257a19b4,0x0058df9f3423d8d2,0x00a9ab20def71304,0x009ae0dbf8ac4a81,0x00c9565977e4392a,0x003c9269444baf55)}, {FIELD_LITERAL(0x002d69008d9d8d26,0x00092f686d7030a8,0x001f19e95aa28fec,0x002150bab1261538,0x008c5a941210b26c,0x009330209036d1e6,0x0062e11ec8e58de7,0x0011c3d11bb9d27f)}, {FIELD_LITERAL(0x008132ae5c5d8cd1,0x00121d68324a1d9f,0x00d6be9dafcb8c76,0x00684d9070edf745,0x00519fbc96d7448e,0x00388182fdc1f27e,0x000235baed41f158,0x00bf6cf6f1a1796a)}, {FIELD_LITERAL(0x00437bce9bccdf9d,0x00e0c8e2f85dc0a3,0x00c91a7073995a19,0x00856ec9fe294559,0x009e4b33394b156e,0x00e245b0dc497e5c,0x006a54e687eeaeff,0x00f1cd1cd00fdb7c)}, {FIELD_LITERAL(0x00d523b4b2eb7de6,0x00cf7b525f2c56f5,0x00b9217554f0d1b1,0x00bad2cbd5984a02,0x002b4af0fe2b21dd,0x002492603f310486,0x0073e7b3795b9d32,0x001e837c89b2bd25)}, {FIELD_LITERAL(0x00ce382dc7993d92,0x00021153e938b4c8,0x00096f7567f48f51,0x0058f81ddfe4b0d5,0x00cc379a56b355c7,0x002c760770d3e819,0x00ee22d1d26e5a40,0x00de6d93d5b082d7)}, {FIELD_LITERAL(0x007b2743b9a1e01a,0x007847ffd42688c4,0x006c7844d610a316,0x00f0cb8b250aa4b0,0x00a19060143b3ae6,0x0014eb10b77cfd80,0x000170905729dd06,0x00063b5b9cd72477)}, {FIELD_LITERAL(0x00f56e5bd3ad1fa9,0x00e7a09488031815,0x00f7fc3ae69d094a,0x00ddad7a7d45a9c2,0x00bc07fbf167a928,0x007a5d6137e0479f,0x00a0659eeab60a00,0x003e068b1342b4f9)}, {FIELD_LITERAL(0x00ffc5c89d2b0cba,0x00d363d42e3e6fc3,0x0019a1a0118e2e8a,0x00f7baeff48882e1,0x001bd5af28c6b514,0x0055476ca2253cb2,0x00d8eb1977e2ddf3,0x00b173b1adb228a1)}, {FIELD_LITERAL(0x005b64c6fd65ec97,0x00c1fdd7f877bc7f,0x000d9cc6c89f841c,0x005c97b7f1aff9ad,0x0075e3c61475d47e,0x001ecb1ba8153011,0x00fe7f1c8d71d40d,0x003fa9757a229832)}, {FIELD_LITERAL(0x000d346622f528f8,0x001e1f7497a62227,0x00fff70d2f9af433,0x002812c6d079ea3c,0x006898af56b25d7f,0x00c17c44f1349645,0x00207172ea3eb539,0x000608e8bd6a263d)}, {FIELD_LITERAL(0x002389319450f9ba,0x003677f31aa1250a,0x0092c3db642f38cb,0x00f8b64c0dfc9773,0x00cd49fe3505b795,0x0068105a4090a510,0x00df0ba2072a8bb6,0x00eb396143afd8be)}, {FIELD_LITERAL(0x00f11cc8e0e70bcb,0x00e5dc689974e7dd,0x0014e409f9ee5870,0x00826e6689acbd63,0x008a6f4e3d895d88,0x00b26a8da41fd4ad,0x000fb7723f83efd7,0x009c749db0a5f6c3)}, {FIELD_LITERAL(0x005f2b1304db3200,0x0022507ff7459b86,0x000f4c1c92b4f0bb,0x00c8cb42c50e0eb9,0x004781d1038aad80,0x002dcf20aa2254af,0x00d9ecda851a93e2,0x0043f6b92eca6cb2)}, {FIELD_LITERAL(0x0067f8f0c4fe26c9,0x0079c4a3cc8f67b9,0x0082b1e62f23550d,0x00f2d409caefd7f5,0x0080e67dcdb26e81,0x0087ae993ea1f98a,0x00aa108becf61d03,0x001acf11efb608a3)}, {FIELD_LITERAL(0x00468711bd994651,0x0033108fa67561bf,0x0089d760192a54b4,0x00adc433de9f1871,0x000467d05f36e050,0x007847e0f0579f7f,0x00a2314ad320052d,0x00b3a93649f0b243)}, {FIELD_LITERAL(0x007dda014454af26,0x000c49fa1b22df7c,0x005cd4d7e761dc2d,0x002af81a1a14b368,0x00a5e57b1cfd7ddf,0x00f90ab3e3a0f738,0x005cb83734d7bc0f,0x00f608c16abb405a)}, {FIELD_LITERAL(0x00e828333c297f8b,0x009ef3cf8c3f7e1f,0x00ab45f8fff31cb9,0x00c8b4178cb0b013,0x00d0c50dd3260a3f,0x0097126ac257f5bc,0x0042376cc90c705a,0x001d96fdb4a1071e)}, {FIELD_LITERAL(0x006c59c9ae744185,0x009fc32f1b4282cd,0x004d6348ca59b1ac,0x00105376881be067,0x00af4096013147dc,0x004abfb5a5cb3124,0x000d2a7f8626c354,0x009c6ed568e07431)}, {FIELD_LITERAL(0x00abd2bb27611e57,0x00cf99bd1fbbd267,0x006f7ac78d478cc7,0x00dc9d340dd23fbb,0x00d3ddd520099c46,0x009836dbb6a03486,0x00f19de267c36883,0x0020885613349904)}, {FIELD_LITERAL(0x00832d02369b482c,0x00cba52ff0d93450,0x003fa9c908d554db,0x008d1e357b54122f,0x00abd91c2dc950c6,0x007eff1df4c0ec69,0x003f6aeb13fb2d31,0x00002d6179fc5b2c)}, {FIELD_LITERAL(0x002809e4bbf1814a,0x00b9e854f9fafb32,0x00d35e67c10f7a67,0x008f1bcb76e748cf,0x004224d9515687d2,0x005ba0b774e620c4,0x00b5e57db5d54119,0x00e15babe5683282)}, {FIELD_LITERAL(0x00b9361257e36376,0x0049f348e3709d03,0x00dd0a597c455aa7,0x00078ce603320668,0x00635f64ae3195dc,0x00a4ed450b508288,0x0075b9adb5e1cc1d,0x00fca588167741f2)}, {FIELD_LITERAL(0x00a9e7730a819691,0x00d9cc73c4992b70,0x00e299bde067de5a,0x008c314eb705192a,0x00e7226f17e8a3cc,0x0029dfd956e65a47,0x0053a8e839073b12,0x006f942b2ab1597e)}, {FIELD_LITERAL(0x00a7efe46a7dbe2f,0x002f66fd55014fe7,0x006a428afa1ff026,0x0056caaa9604ab72,0x0033f3bcd7fac8ae,0x00ccb1aa01c86764,0x00158d1edf13bf40,0x009848ee76fcf3b4)}, {FIELD_LITERAL(0x00e3c287f132a1c6,0x006b0db804233a01,0x002a387902ad889b,0x00490b258b0f24d5,0x007f0e0745232a02,0x000c95c8c52d1dc4,0x0007fb060bcbc40d,0x002e50bf139dc67d)}, {FIELD_LITERAL(0x0039343746531ebe,0x00c8509d835d429d,0x00e79eceff6b0018,0x004abfd31e8efce5,0x007bbfaaa1e20210,0x00e3be89c193e179,0x001c420f4c31d585,0x00f414a315bef5ae)}, {FIELD_LITERAL(0x0082aeace5f1b144,0x00f68b3108cf4dd3,0x00634af01dde3020,0x000beab5df5c2355,0x00e8b790d1b49b0b,0x00e48d15854e36f4,0x0040ab2d95f3db9f,0x002711c4ed9e899a)}, {FIELD_LITERAL(0x0083d695db66f207,0x002a2f8ada58aa77,0x002271eec16b4818,0x008443a70141f337,0x00d60ae50640352b,0x00816cee1385490c,0x006577b21e989cbc,0x00af2a0d2317b416)}, {FIELD_LITERAL(0x0098cddc8b39549a,0x006da37e3b05d22c,0x00ce633cfd4eb3cb,0x00fda288ef526acd,0x0025338878c5d30a,0x00f34438c4e5a1b4,0x00584efea7c310f1,0x0041a551f1b660ad)}, {FIELD_LITERAL(0x005fa020cca2450a,0x00491c29db6416d8,0x0037cefe3f9f9a85,0x003d405230647066,0x0049e835f0fdbe89,0x00feb78ac1a0815c,0x00828e4b32dc9724,0x00db84f2dc8d6fd4)}, {FIELD_LITERAL(0x002808570429bc85,0x009d78dbec40c8ac,0x0052b4434bc3a7b4,0x00801b6419fe281c,0x008839a68764540a,0x0014ba034f958be4,0x00a31dbb6ec068f7,0x0077bd9bfe8c9cd9)}, {FIELD_LITERAL(0x00a0b68ec1eb72d2,0x002c03235c0d45a0,0x00553627323fe8c5,0x006186e94b17af94,0x00a9906196e29f14,0x0025b3aee6567733,0x007e0dd840080517,0x0018eb5801a4ba93)}, {FIELD_LITERAL(0x007bf562ca768d7c,0x006c1f3a174e387c,0x00f024b447fee939,0x007e7af75f01143f,0x003adb70b4eed89d,0x00e43544021ad79a,0x0091f7f7042011f6,0x0093c1a1ee3a0ddc)}, {FIELD_LITERAL(0x0028018fe84095bf,0x0091c0f9db41f3bd,0x0000445dfaca7dba,0x000603d307e6bdc6,0x00726c4c840ea4b0,0x009220d1c741716a,0x00d4918640a03006,0x0054caa25bda1d21)}, {FIELD_LITERAL(0x003973d8938971d6,0x002aca26fa80c1f5,0x00108af1faa6b513,0x00daae275d7924e6,0x0053634ced721308,0x00d2355fe0bbd443,0x00357612b2d22095,0x00f9bb9dd4136cf3)}, {FIELD_LITERAL(0x00938f97e20be973,0x0099141a36aaf306,0x0057b0ca29e545a1,0x0085db571f9fbc13,0x008b333c554b4693,0x0043ab6ef3e241cb,0x0054fb20aa1e5c70,0x00be0ff852760adf)}, {FIELD_LITERAL(0x00d400ed30a1fc5a,0x00e424e0575e6307,0x0036e3986c07b2c6,0x0007960e4d145650,0x00a643ab823cdc93,0x0026e9ee292c7976,0x001f9d2555d3fdeb,0x0012c3fb833d437d)}, {FIELD_LITERAL(0x0062dd0fb31be374,0x00fcc96b84c8e727,0x003f64f1375e6ae3,0x0057d9b6dd1af004,0x00d6a167b1103c7b,0x00dd28f3180fb537,0x004ff27ad7167128,0x008934c33461f2ac)}, {FIELD_LITERAL(0x000050d70c32b31a,0x001939d576d437b3,0x00d709e598bf9fe6,0x00a885b34bd2ee9e,0x00dd4b5c08ab1a50,0x0091bebd50b55639,0x00cf79ff64acdbc6,0x006067a39d826336)}, {FIELD_LITERAL(0x009a4b8d486fffbc,0x00458102d00ef9b4,0x00f498293b3cfdf0,0x00ed2d7b960b1b92,0x00ce3cd6c68fc137,0x004b60f431eccf99,0x00081efbe9e7e2b8,0x00a36f0ae7981133)}, {FIELD_LITERAL(0x0006918f5dfce6dc,0x00d4bf1c793c57fb,0x0069a3f649435364,0x00e89a50e5b0cd6e,0x00b9f6a237e973af,0x006d4ed8b104e41d,0x00498946a3924cd2,0x00c136ec5ac9d4f7)}, {FIELD_LITERAL(0x0051207abd179101,0x00fc2a5c20d9c5da,0x00fb9d5f2701b6df,0x002dd040fdea82b8,0x00f163b0738442ff,0x00d9736bd68855b8,0x00e0d8e93005e61c,0x00df5a40b3988570)}, {FIELD_LITERAL(0x00ee563d6f53acc9,0x00d465d2b5959acc,0x006575973bba26c8,0x00c9e4d84f81a1a3,0x00c3fbc4e8aa468a,0x0048149930eeaa11,0x008850a6f611000d,0x006709f6788337f9)}, {FIELD_LITERAL(0x00b373076597455f,0x00e83f1af53ac0f5,0x0041f63c01dc6840,0x0097dea19b0c6f4b,0x007f9d63b4c1572c,0x00e692d492d0f5f0,0x00cbcb392e83b4ad,0x0069c0f39ed9b1a8)}, {FIELD_LITERAL(0x00ab13af436bf8f4,0x000bcf0a0dac8574,0x00d50c864f705045,0x00c40e611debc842,0x0085010489bd5caa,0x007c5050acec026f,0x00f67d943c8da6d1,0x00de1da0278074c6)}, {FIELD_LITERAL(0x0079efcffed8f836,0x00604423802b5504,0x0070a6e294aab7dd,0x0020f75be15e7521,0x0062827c19bd5414,0x006738e425c48700,0x00dd37618fde0ffa,0x00bb2d65c01e1c3b)}, {FIELD_LITERAL(0x00c903ee6d825540,0x00add6c4cf98473e,0x007636efed4227f1,0x00905124ae55e772,0x00e6b38fab12ed53,0x0045e132b863fe55,0x003974662edb366a,0x00b1787052be8208)}, {FIELD_LITERAL(0x00e748cd7b5c52f2,0x00ea9df883f89cc3,0x0018970df156b6c7,0x00c5a46c2a33a847,0x00cbde395e32aa09,0x0072474ebb423140,0x00fb00053086a23d,0x001dafcfe22d4e1f)}, {FIELD_LITERAL(0x0059eb4ff288a383,0x00283876be3388ab,0x00bdd22974a2543b,0x0059eef0fe982d74,0x0097a5cf63dad778,0x004bc6002aebc99f,0x00c9a91d6118c690,0x0038364612a527ab)}, {FIELD_LITERAL(0x00006e34a35d9fbc,0x00eee4e48b2f019a,0x006b344743003a5f,0x00541d514f04a7e3,0x00e81f9ee7647455,0x005e2b916c438f81,0x00116f8137b7eff0,0x009bd3decc7039d1)}, {FIELD_LITERAL(0x0040f7e7c5b37bf2,0x0064e4dc81181bba,0x00a8767ae2a366b6,0x001496b4f90546f2,0x002a28493f860441,0x0021f59513049a3a,0x00852d369a8b7ee3,0x00dd2e7d8b7d30a9)}, {FIELD_LITERAL(0x00fa2dd90bcbeef2,0x00507d774710de2a,0x00b585ad10e7e373,0x0041f487e4b4f921,0x00191c9d8212f81d,0x001bc55cbdd8d474,0x0017954bdba8827b,0x0004d6d3a991ca44)}, {FIELD_LITERAL(0x00e38abece3c82ab,0x005a51f18a2c7a86,0x009dafa2e86d592e,0x00495a62eb688678,0x00b79df74c0eb212,0x0023e8cc78b75982,0x005998cb91075e13,0x00735aa9ba61bc76)}, {FIELD_LITERAL(0x00334f5303ea1222,0x00dfb3dbeb0a5d3e,0x002940d9592335c1,0x00706a7a63e8938a,0x005a533558bc4caf,0x00558e33192022a9,0x00970d9faf74c133,0x002979fcb63493ca)}, {FIELD_LITERAL(0x00260857d22419d7,0x005e0387d77651f0,0x008e0025ed2eb499,0x00c830b135804c2a,0x0037f43dbd3a77f6,0x008a4073d2f7379c,0x0072be0ce503ad58,0x00e6869d130c78be)}, {FIELD_LITERAL(0x00bfc5fa1e4ea21f,0x00c21d7b6bb892e6,0x00cf043f3acf0291,0x00c13f2f849b3c90,0x00d1a97ebef10891,0x0061e130a445e7fe,0x0019513fdedbf22b,0x001d60c813bff841)}, {FIELD_LITERAL(0x006e9f475cccf2ee,0x00454b9cd506430c,0x00224a4fb79ee479,0x0062e3347ef0b5e2,0x0034fd2a3512232a,0x00b8b3cb0f457046,0x00eb20165daa38ec,0x00128eebc2d9c0f7)}, {FIELD_LITERAL(0x00e6a9e38030fdec,0x001c23597bc14288,0x0097156a46356df1,0x00642048f0daca6a,0x003970a6e7955fd4,0x00a511e335e3cfc6,0x0054865756c85e31,0x00465f1ab66a6190)}, {FIELD_LITERAL(0x003e4964fa8a8fc8,0x00f6a1cdbcf41689,0x00943cb18fe7fda7,0x00606dafbf34440a,0x005d37a86399c789,0x00e79a2a69417403,0x00fe34f7e68b8866,0x0011f448ed2df10e)}, {FIELD_LITERAL(0x00c79e0b6d97dfbd,0x00917c71fd2bc6e8,0x00db7529ccfb63d8,0x00be5be957f17866,0x00a9e11fdc2cdac1,0x007b91a8e1f44443,0x00a3065e4057d80f,0x004825f5b8d5f6d4)}, {FIELD_LITERAL(0x000e0a81033e033b,0x00aec986ee821eab,0x00d1a4a48379273c,0x00609b79a9e06304,0x00e9618b4fe8f307,0x006ffdfa50b50969,0x009530224887ac0c,0x0020e7b36f0cef97)}, {FIELD_LITERAL(0x00fd579ffb691713,0x00b76af4f81c412d,0x00f239de96110f82,0x00e965fb437f0306,0x00ca7e9436900921,0x00e487f1325fa24a,0x00633907de476380,0x00721c62ac5b8ea0)}, {FIELD_LITERAL(0x00b37396c3320791,0x00fc7b67175c5783,0x00c36d2cd73ecc38,0x0080ebcc0b328fc5,0x0043a5b22b35d35d,0x00466c9f1713c9da,0x0026ad346dcaa8da,0x007c684e701183a6)}, {FIELD_LITERAL(0x003f2ab1abd14b06,0x00b129a8e8e37230,0x0048bc5b083d5c64,0x0002606c12933a98,0x00cf8051ceec1a73,0x00a755a8836c3ce6,0x002dabaa90ca4cb9,0x00b6e5525ddfc0f2)}, {FIELD_LITERAL(0x00c4a1fb48635413,0x00b5dd54423ad59f,0x009ff5d53fd24a88,0x003c98d267fc06a7,0x002db7cb20013641,0x00bd1d6716e191f2,0x006dbc8b29094241,0x0044bbf233dafa2c)}, {FIELD_LITERAL(0x00dff3103786ff34,0x000144553b1f20c3,0x0095613baeb930e4,0x00098058275ea5d4,0x007cd1402b046756,0x0074d74e4d58aee3,0x005f93fc343ff69b,0x00873df17296b3b0)}, {FIELD_LITERAL(0x00aa7c72be0ace19,0x004095d22fc37e4d,0x00a7d85f9e3b7c61,0x00ff21d344c9553c,0x00d105d6268e8b86,0x000616d733758845,0x003ecb4ba7210610,0x006a75e7dddc03b7)}, {FIELD_LITERAL(0x007860d99db787cf,0x00fda8983018f4a8,0x008c8866bac4743c,0x00ef471f84c82a3f,0x00abea5976d3b8e7,0x00714882896cd015,0x00b49fae584ddac5,0x008e33a1a0b69c81)}, {FIELD_LITERAL(0x000a9ee23c06881f,0x002c727d3d871945,0x00f47d971512d24a,0x00671e816f9ef31a,0x00883af2cfaad673,0x00601f98583d6c9a,0x00b435f5adc79655,0x00ad87b71c04bff2)}, {FIELD_LITERAL(0x0084911d36175613,0x00dbaa24427629dd,0x009b6f30b1554fc7,0x0026da093cf7ea9e,0x00eac4cfb8218c7c,0x00c4bde074231490,0x0089e5b5afb62587,0x0067fcb73adfdbcc)}, {FIELD_LITERAL(0x00eebfd4e2312cc3,0x00474b2564e4fc8c,0x003303ef14b1da9b,0x003c93e0e66beb1d,0x0013619b0566925a,0x008817c24d901bf3,0x00b62bd8898d218b,0x0075a7716f1e88a2)}, {FIELD_LITERAL(0x007f8a43da97dd5c,0x00058539c800fc7b,0x0040f3cf5a28414a,0x00d68dd0d95283d6,0x004adce9da90146e,0x00befa41c7d4f908,0x007603bc2e3c3060,0x00bdf360ab3545db)}, {FIELD_LITERAL(0x00f6de725e1976f0,0x00d96f80a02fda8a,0x00b25412a0e629fa,0x00c540e7e78fdb62,0x004ad02fb7336d3a,0x004922ae1bea5a3a,0x0026147d42d4bfeb,0x00d379a5bc4b94bc)}, {FIELD_LITERAL(0x00c338b915d8fef0,0x00a893292045c39a,0x0028ab4f2eba6887,0x0060743cb519fd61,0x0006213964093ac0,0x007c0b7a43f6266d,0x008e3557c4fa5bda,0x002da976de7b8d9d)}, {FIELD_LITERAL(0x0070047189452f4c,0x00f7ad12e1ce78d5,0x00af1ba51ec44a8b,0x005f39f63e667cd6,0x00058eac4648425e,0x00d7fdab42bea03b,0x0028576a5688de15,0x00af973209e77c10)}, {FIELD_LITERAL(0x00b78d6075749232,0x0001dc47a33b2cdc,0x0018c7b2e91b24f1,0x00b5bdc68f9876bd,0x0013f489ccba2b44,0x003b8846066128de,0x003d6252c8884dcf,0x00e3ae84b9908209)}, {FIELD_LITERAL(0x00aa2261022d883f,0x00ebcca4548010ac,0x002528512e28a437,0x0070ca7676b66082,0x0084bda170f7c6d3,0x00581b4747c9b8bb,0x005c96a01061c7e2,0x00fb7c4a362b5273)}, {FIELD_LITERAL(0x006366c380f7b574,0x001c7d1f09ff0438,0x003e20a7301f5b22,0x00d3efb1916d28f6,0x0049f4f81060ce83,0x00c69d91ea43ced1,0x002b6f3e5cd269ed,0x005b0fb22ce9ec65)}, {FIELD_LITERAL(0x003cffdf14aed2fd,0x009f0d77d7c5b2d9,0x004812ec41321d9f,0x008a1448bddf0916,0x008fef86030175df,0x00e3d703200a76c7,0x00d1babb470b2094,0x009f3a43b0e5828c)}, {FIELD_LITERAL(0x00a94700032a093f,0x0076e96c225216e7,0x00a63a4316e45f91,0x007d8bbb4645d3b2,0x00340a6ff22793eb,0x006f935d4572aeb7,0x00b1fb69f00afa28,0x009e8f3423161ed3)}, {FIELD_LITERAL(0x00ae307cf069f701,0x005859f222dd618b,0x00212d6c46ec0b0d,0x00a0fe4642afb62d,0x00420d8e4a0a8903,0x00a80ff639bdf7b0,0x0019bee1490b5d8e,0x007439e4b9c27a86)}, {FIELD_LITERAL(0x00610b6394a312e8,0x005aaa19d96160f5,0x008190e286138c4a,0x006538796a5cd53b,0x00fe28804432a97c,0x007315e011f55112,0x000bd4157d5acb9d,0x00d1b95469350336)}, {FIELD_LITERAL(0x0060db815bc4786c,0x006fab25beedc434,0x00c610d06084797c,0x000c48f08537bec0,0x0031aba51c5b93da,0x007968fa6e01f347,0x0030070da52840c6,0x00c043c225a4837f)}, {FIELD_LITERAL(0x0051cfcc5885377a,0x00dce566cb1803ca,0x00430c7643f2c7d4,0x00dce1a1337bdcc0,0x0010d5bd7283c128,0x003b1b547f9b46fe,0x000f245e37e770ab,0x007b72511f022b37)}, {FIELD_LITERAL(0x00e4302ff9b6116c,0x0092314b81d5f02a,0x000d31425f30702f,0x004946262e04213c,0x007ead9d19b6f9ed,0x001080a31ce8989f,0x001b632f36672a74,0x00a03933d9645a83)}, {FIELD_LITERAL(0x004a2902926f8d3f,0x00ad79b42637ab75,0x0088f60b90f2d4e8,0x0030f54ef0e398c4,0x00021dc9bf99681e,0x007ebf66fde74ee3,0x004ade654386e9a4,0x00e7485066be4c27)}, {FIELD_LITERAL(0x008940211aa0d633,0x00addae28136571d,0x00d68fdbba20d673,0x003bc6129bc9e21a,0x000346cf184ebe9a,0x0068774d741ebc7f,0x0019d5e9e6966557,0x0003cbd7f981b651)}, {FIELD_LITERAL(0x00bba0ed9c67c41f,0x00b30c8e225ba195,0x008bb5762a5cef18,0x00e0df31b06fb7cc,0x0018b912141991d5,0x00f6ed54e093eac2,0x0009e288264dbbb3,0x00feb663299b89ef)} }; const gf API_NS(precomputed_wnaf_as_fe)[96] VECTOR_ALIGNED = { {FIELD_LITERAL(0x00cfc32590115acd,0x0079f0e2a5c7af1b,0x00dd94605b8d7332,0x0097dd6c75f5f3f3,0x00d9c59e36156de9,0x00edfbfd6cde47d7,0x0095b97c9f67c39a,0x007d7b90f587debc)}, {FIELD_LITERAL(0x00cfc32590115acd,0x0079f0e2a5c7af1b,0x00dd94605b8d7332,0x0017dd6c75f5f3f3,0x00d9c59e36156de8,0x00edfbfd6cde47d7,0x0095b97c9f67c39a,0x00fd7b90f587debc)}, {FIELD_LITERAL(0x001071dd4d8ae672,0x004f14ebe5f4f174,0x00e0987625c34c73,0x0092d00712c6f8c1,0x009ef424965e980b,0x00a8e0cf9369764b,0x000aa81907b4d207,0x00d5002c74d37924)}, {FIELD_LITERAL(0x00f3c4efe62b8b17,0x001e6acc1b6add7b,0x003367ef45836df5,0x000efc2d87a6ba53,0x00405a96933964ca,0x00572c2ae16357c6,0x00a9dc34ba6a7946,0x00151831e32ad161)}, {FIELD_LITERAL(0x00315f0372d1774a,0x007de9ed2960e79d,0x008b3d7c4c198add,0x00a5e6a45fa57892,0x00f32201aa80115a,0x007fb9386a433a1a,0x00abf6960b291ee6,0x002d8069294ebc2a)}, {FIELD_LITERAL(0x00fa5e878ae22827,0x00d33c7bb3963bd0,0x0053401a101efac6,0x0063df0bcbce59a5,0x007bca269c8b584b,0x00611a8a9978842c,0x00bb96e8da12b8a8,0x00e17844d01d394d)}, {FIELD_LITERAL(0x00c107c50e9b4d0d,0x00f6b65a5fada2f2,0x000bb67e79353fae,0x0018853f610ed92d,0x008c51f4d36d6915,0x00e3e9c096dd1c12,0x009d6b9ea6cde415,0x00304864dd66f4c6)}, {FIELD_LITERAL(0x00f3123b214085fb,0x00d005bafffb8f53,0x00d1606987dfe6ea,0x00e825edf73b018d,0x0082aa733829a933,0x00c857d8d7830d76,0x00ebdb8d2cbbe7e6,0x0063de0e9930722e)}, {FIELD_LITERAL(0x004ffebce35619ab,0x00d281a1543365c5,0x00ad17eeb3d098b8,0x008653b06bb7806d,0x0040026e64a28b62,0x00d9e06d52ea19df,0x008e7c684856876a,0x003ebbc191443f3b)}, {FIELD_LITERAL(0x00c0a062813b8884,0x0054d18cc36e636b,0x00e4493fcadba51a,0x005cda5b6577c9cf,0x00cc165615c315cf,0x001bbd5e155f17bb,0x004dee92a4f18e47,0x003e95412929bfb8)}, {FIELD_LITERAL(0x0015326f3e1f5fb6,0x0076886ca4eb6041,0x00fb34645ee36c23,0x006042a4cb8f7bb2,0x00b43e736403dd2f,0x00a8986566e7c60c,0x0010ea48904bf6d1,0x008b5ae8c5ddafbe)}, {FIELD_LITERAL(0x003a9f4a12faee9a,0x00e6ba523a29af6b,0x001dde79a8ef06ef,0x0033ed4361647314,0x00b0556ae76eb1c9,0x00e8b892762bd092,0x004709c83705e374,0x0077382d86f79b47)}, {FIELD_LITERAL(0x006638c5cee4113d,0x005c100c7276ed52,0x00d10562e281768d,0x0008e851e1eb2ed9,0x00d7cc086a7af373,0x00993ed528eb7942,0x0051677625b7df14,0x0029fbbcf6aaa3f7)}, {FIELD_LITERAL(0x001081503e396419,0x007a2c7aa8870415,0x00d372a4baf3490a,0x00b18821a1e18013,0x00b83fa876c54211,0x00e4bcf47a2ae1e9,0x0069a384ba9bf3c3,0x00b784d44ee9d468)}, {FIELD_LITERAL(0x00b4e3ad7c2ea1be,0x009962715cf7008a,0x00fbc6fdcc089d5e,0x001e29847c349313,0x00c1145569b3874d,0x0094f50069a1499b,0x004cec2bb8f423c8,0x0077eb0034c34627)}, {FIELD_LITERAL(0x008f00d279b21a44,0x00a5c81149c8116a,0x00cc8be3da721e9f,0x001935a34e6770b9,0x00e315426d5db99d,0x00cf6a842aff01bf,0x00e3cc9d5016ed3a,0x00ae78776098742d)}, {FIELD_LITERAL(0x0068db473197248f,0x0089874a12ff90c2,0x00420b4763f5428c,0x00d668b71fb38392,0x0022279b6d3c3687,0x003a5801405cf566,0x00127b8ea4b4fd44,0x00ce6a975208fb79)}, {FIELD_LITERAL(0x00797ca039d44238,0x0063cae935b6ef5e,0x006a938e072ff87c,0x006a3870309cdca0,0x0003800945fa3ddc,0x0032274c0728b5ad,0x0053a51e9217da91,0x00162b41712b79db)}, {FIELD_LITERAL(0x000911f06768bdc6,0x00bd27650f82c5b0,0x007b948017bcb94a,0x0095de039572c65e,0x0053743dabe00d25,0x0092b1d5888cd8cd,0x0065c6496b33c0d0,0x007a3f55d5bfb370)}, {FIELD_LITERAL(0x003f31eebfa20d27,0x00b1c0c84d6c2849,0x00dbefe8d1e53924,0x00472400b407ebc2,0x00c584bf62a91498,0x00c1f095f2010650,0x007e3b1b2c9ba41e,0x003189f894ed89dc)}, {FIELD_LITERAL(0x004d9eefe5de7ab7,0x003e35169bdbd884,0x0079625f58822d97,0x0043f4f607137c15,0x0029efd80717d455,0x0055b37a66623198,0x00153cecd460c01e,0x000464f30e396a2d)}, {FIELD_LITERAL(0x0057b28375dc4b6e,0x00771e6557974d80,0x00fa6792bc187316,0x000d7fed0f9f92d7,0x00e821281efdb64b,0x00a12bf7b4dc5064,0x00464f56bfa9bb8d,0x00526fa933114e0b)}, {FIELD_LITERAL(0x00bcf86d6aaed0f2,0x00b95ff679e8a71f,0x00c11d7bd57f8c87,0x00cb3362ed671b05,0x0068bb14b2ce4c10,0x00505313699af32f,0x005376e4cec89e51,0x00179b292d918f75)}, {FIELD_LITERAL(0x00246e4ca8018aa1,0x005e55abb4eaca63,0x0050b6ce5fe6aa8b,0x008979edb01ee510,0x002e152c38461080,0x00550a03a7f073ea,0x0018d841eb811e13,0x00c39e3e1ea88479)}, {FIELD_LITERAL(0x007f1264364f8cc7,0x000315388ba2d9ad,0x007562aa0a0d3396,0x0069318d20cfe53a,0x000acdcd1868b277,0x008e8d738518c6b8,0x006faf89fda8f887,0x00347e30277c4e4d)}, {FIELD_LITERAL(0x0062c03567cddf30,0x0032ee53437ac23b,0x00e8a6fbf62d80e2,0x002de89967f7d7fd,0x0005fedae4d7c736,0x0022d685f264ae39,0x0028936d3fba7df5,0x00acb4383b936fcc)}, {FIELD_LITERAL(0x00afee55215c8c25,0x00c57a8713769fcb,0x000df59aca05928e,0x00aead2ce1a57830,0x00d453e3719735cd,0x004f1cdc24b3ec7e,0x000e2a69482a51da,0x00151ba7f6834b1f)}, {FIELD_LITERAL(0x003eaec329954173,0x00fec61feee76bb2,0x009b544347f7f444,0x004c4f7dfdb8cebd,0x0039d610da25dbfb,0x000f513ccef26480,0x00af4ddd8b8d2732,0x00093756dd2be04b)}, {FIELD_LITERAL(0x006df537f064f2de,0x0007f0808cbfedb9,0x00792c87b64aa829,0x00fd42b4ce848ad1,0x004d9b9c66c5bd43,0x00df8fbdd58c4ed6,0x00cbe5355fc7f34c,0x00abe6eb22995e4d)}, {FIELD_LITERAL(0x00ef8a330d9484e0,0x0044944dece8fbcc,0x0016b6e52d9d2586,0x00610b0b72d2c7b3,0x00766d88f8990f61,0x00ea7bc69494eefe,0x0050c07989360110,0x00db9fc3bfd96ee7)}, {FIELD_LITERAL(0x0069991db096c6b8,0x0008ebceed962ba0,0x00ef0053e2f37ae3,0x009917f3c8c9cb68,0x000e0b52fef39f4e,0x00ea378bf7b8f008,0x009ae2a16388995b,0x007ec77e628ee921)}, {FIELD_LITERAL(0x0062284cece6ad83,0x00e18536b7278c56,0x0005ab4b910698c5,0x009910472a4fd019,0x008ab4e2c6d75150,0x00fbd9d538d59094,0x0086482b65914fd9,0x00ced958acabfefd)}, {FIELD_LITERAL(0x00c6cb4ee3a8dac4,0x0010cf7120de0b91,0x001ab166385e9e67,0x007f2a8eca89b19c,0x008ae3d846b943da,0x0022c7631b161ed6,0x005e5d402e327b23,0x00d0518c1aeb64cd)}, {FIELD_LITERAL(0x000d45c95be55ebb,0x005f3dd26b911e70,0x00755171065eb066,0x00110b2864e644c9,0x00718a31c2d84e02,0x0059a255fc4d65d8,0x0026337c97b14eba,0x0061e127f33d128b)}, {FIELD_LITERAL(0x006ee9a82004b322,0x003eff4833aac2f9,0x00bb62f8a13b9833,0x008f9deff439b18f,0x00bc30790842de17,0x000bfe23b4868215,0x00addb504d09d19a,0x002e121c04a5bd41)}, {FIELD_LITERAL(0x004126ac2e668677,0x0046c12e8a5dbed7,0x0078e3a69c049c9a,0x0035d20dffeb5878,0x000a263e2f4cbcdc,0x00090a6bd7e724f5,0x00b33f6e0b6366f9,0x00175e7759f40060)}, {FIELD_LITERAL(0x0083b4b835838c18,0x00ac69ddefc68cb4,0x00749b220f1ba281,0x004052a50d7a193d,0x007138ee3a4e5e56,0x003099ccfedc8067,0x006e811c0e9aaed9,0x00bead0cc8101227)}, {FIELD_LITERAL(0x00cd3889dfcd0517,0x001bf78dcd1f43de,0x000898cbb491727a,0x00440c964893d55d,0x0075e0b9391ea8f2,0x00ec9732687fc960,0x008ca65c62f86bcf,0x00fc9b9aed6debcb)}, {FIELD_LITERAL(0x00f8381236cfa255,0x00f5999b0d8c8fe3,0x000918786a1dff4e,0x00a2fa46132db8c1,0x00eb0a0e8379a878,0x003802d2e990566a,0x00b6c65d27147f1f,0x00ddbb45f6bd3e66)}, {FIELD_LITERAL(0x000f68a71ee1c67a,0x00e96102429b052c,0x0017776482925329,0x00ca322a71577df6,0x004325b8a79280b5,0x00c322234d786f77,0x00e9258fe7816ab4,0x006aa915d16d5532)}, {FIELD_LITERAL(0x00cde18980fd9d30,0x00d1a82889350971,0x0040d36b7eb0fbc8,0x003cc6e695329dd0,0x00e24b3318e1d88e,0x00e212a22459111d,0x00879f754eaab372,0x00f9801f5489c9a4)}, {FIELD_LITERAL(0x007354e942e00768,0x004c7668d3208ac0,0x0015712e1b92023f,0x00b018106b3a760b,0x00d4751647fa130b,0x00da3f7276d78b5a,0x00dc6c71672bb3b3,0x0008a6ecb3540963)}, {FIELD_LITERAL(0x00e13a624c26a6f1,0x00e161c0e3c0e7d2,0x00ba563c13d354eb,0x00f7e67a8d51498c,0x0088c48bf9742e97,0x00edaca155c6abcb,0x00bb24561c4448b5,0x00d045b2c38b42f1)}, {FIELD_LITERAL(0x0093d57b9871b4c4,0x0085e6b5532e7970,0x0012fdda50bdb89e,0x0025f590d6c39b47,0x00ef9d53a39585e6,0x00cf0a88a575110b,0x00fd53552894850f,0x00bef47029c5a860)}, {FIELD_LITERAL(0x00bd40f701996dd3,0x00cce747044b6173,0x0028a6b9ffb55eb3,0x0009fea794bd40e3,0x0038b30e26ed0198,0x005434c968b4cf52,0x00814878df362d47,0x0060ab54842b207a)}, {FIELD_LITERAL(0x00bd19d97479e8ae,0x00f722fb96aff3e9,0x004ae4a83cc75c02,0x0033bb6827a30094,0x00d0ec294a83cb5a,0x007c9ad150cfeefa,0x0033cbbd6b336c57,0x009f0b2fd7ef1d8f)}, {FIELD_LITERAL(0x00246036b708c7d9,0x000574c8b9127116,0x00ecd349a550414d,0x003c900c0186da47,0x007c82512cac2d00,0x001399e41f99830b,0x00a414712d16fdfb,0x0028822961a9b698)}, {FIELD_LITERAL(0x00576abc9c32ae74,0x0052e8eedb433484,0x009a0b95b52551ff,0x00e4e5a4d5691aff,0x00bc01db07dccd79,0x00996692751e0d3c,0x003acf0cd9be9606,0x003f06d2f83095a8)}, {FIELD_LITERAL(0x0028c4051a1ff7bb,0x0040ba689904a0ad,0x009e4b0a5acec321,0x00bc6d2b3c46aaeb,0x00f2caae4ef88adb,0x00ff6677bf11a28e,0x0092191cbfbb7484,0x00dae55afb78a291)}, {FIELD_LITERAL(0x00c95aa397ea26bc,0x007372e21066c24c,0x00d1f1e17008ce70,0x00277c5b46d24ff5,0x00d0a187e51cc6f8,0x00e58d524dca3f92,0x000d1a618c916355,0x00e5b4a71cfce6eb)}, {FIELD_LITERAL(0x00c40cbcbd853cbd,0x00523f5879bd473a,0x00fc476ce8a57ceb,0x009e5cb521a8fc43,0x0015c157448e29cc,0x0041f2065e0e673d,0x00b9227183e9ca04,0x000eadc022da2a1a)}, {FIELD_LITERAL(0x00d6313aad8c08f2,0x008fbb11d8a39cbf,0x00bf09c856cfea1d,0x00cc7448724a5516,0x00eb6e4d59ecdeb7,0x005eda293019421c,0x00a0853a9e457996,0x00e2a1515c045530)}, {FIELD_LITERAL(0x009cc09c03622bf9,0x0018ec007f1fb5bc,0x009f39168f0d29de,0x005a83280f20e76e,0x000dbf95aaf9af43,0x004f9bd6f102397b,0x00e154febb2e86e9,0x0032ea079c3d6c54)}, {FIELD_LITERAL(0x00fab169ca1c41ce,0x00f1bc0ce1d78d41,0x002fa4e361cc67be,0x009053af427e0267,0x0032387ad15144f5,0x00b00ae64f9e66e4,0x006f6617ef82b37a,0x00d8c1db3c95b59e)}, {FIELD_LITERAL(0x0035175500c7799c,0x00a167c5ca225e38,0x00854efcf271c80b,0x001b76bf0a2fcd01,0x0095c90610cf4ccd,0x0064190fc6a738a8,0x0079dce31456ebff,0x00742f0847dc1855)}, {FIELD_LITERAL(0x00f8f4bbbe10d3b9,0x00105a4fd7fe5ef6,0x0040f473c119b520,0x0075981f4cbad167,0x00e6e94e0d05858a,0x00287e587009323c,0x00797d31a81a36e6,0x0033eef622def25c)}, {FIELD_LITERAL(0x003077e1410a5ba5,0x00b14158718390d3,0x006f256df630d95f,0x0021d4d1b388a47b,0x008e29fce3c3ea50,0x002616d810e8828f,0x0076b1173dc76902,0x001c4c4bfe1be552)}, {FIELD_LITERAL(0x00a2657cac024d24,0x00aa33dfb739670f,0x00093b53769a8de7,0x00adafcb28c0514d,0x00bca8890425c381,0x008f15acedcdc343,0x0085efa2bb2f9604,0x0092437292387955)}, {FIELD_LITERAL(0x00dfb010d979be8f,0x007e6d963a211f07,0x00404b8ec1368699,0x00d9cc6590cb2087,0x00e0d919b389e23c,0x001001c50cec349f,0x001e848fec709fe4,0x000e91e3326121a1)}, {FIELD_LITERAL(0x00e8300e632c6b13,0x00010847ef6dda78,0x0019b7c68f200ab7,0x00220c952978bd9b,0x0019e887adc0331c,0x006c5993f36c4db5,0x0002c98eeb248079,0x0089ad282231d922)}, {FIELD_LITERAL(0x0059811830606614,0x00a8ec4d8a0d0097,0x000e2ac957beaec2,0x007dc4a64fdb8ed1,0x0063b9462f2c7312,0x00324ea6a55d282b,0x007c8a4cbdc26507,0x00f54f4ae9268708)}, {FIELD_LITERAL(0x0026d312845ed7bc,0x0051563888e17918,0x00b99c696ccab084,0x0059d7244957f3b8,0x00c5f4faf8c8d6ab,0x00bdeeec54ba3f26,0x001aba0f7c9d5485,0x00d731f784b29269)}, {FIELD_LITERAL(0x00bd7234c3aef4f0,0x00a7a9f815db44b1,0x00c8c940e9fc9785,0x003b81a973b01c38,0x00c32ffd7d7b79f9,0x00bc5b783c46e6c6,0x00b003fb1ef6a5f9,0x005b36765c2b46e7)}, {FIELD_LITERAL(0x0030b09f9659a719,0x00ac35ad7a6bc959,0x009b466b281c1ee8,0x0034b96465f80acb,0x00304970c66162b7,0x000f2347253e3918,0x000d54980ac74c5a,0x00aaabb0e875468a)}, {FIELD_LITERAL(0x00578872f1bd6085,0x00b3fd4fa6efa597,0x00e99ac49f625c00,0x002aef842e5ed2d8,0x004b8f706588e353,0x00449c499dfcc096,0x008d0cdddbf18dea,0x00e6bba4a6396ddd)}, {FIELD_LITERAL(0x0066485d97a2ac73,0x001d0e768483ffe7,0x00c5253731b7251c,0x00f76d892a3af3f3,0x00e8d035f85298e7,0x0034e58d0abf961a,0x00b11bd0eccaba4c,0x0087a079aec9d0e9)}, {FIELD_LITERAL(0x00d38488bd2e2026,0x00d35414e79dc3fe,0x00faa0a1c1fbbbb9,0x0093df0c4b10ab45,0x0039ffebe1394c9f,0x00cab0bc80e5cd5c,0x00453b9db5cadf06,0x003b7c08cb56f96e)}, {FIELD_LITERAL(0x00b63453c7af61ee,0x00eadcbafa2bd320,0x0086b04f4a7bf0e3,0x00b69bc8cbbfba5a,0x00ce4926bb1b064e,0x004df8ce753e0a27,0x00ff37bf2580a3a2,0x00ad90c8c5a377eb)}, {FIELD_LITERAL(0x00ac58c82bdd6e72,0x0008035e278a79da,0x003c9fcc92524fb3,0x000c71c26ea75e47,0x009631c4be717b38,0x00a2e968135e9152,0x00074295ca131ec2,0x00877a203d4a5015)}, {FIELD_LITERAL(0x00a49896f002be26,0x00ad6b0d720ae906,0x005786d8dbed0346,0x00f6749d6592e372,0x000542c37faf79a4,0x003281a4f5c7863a,0x00eacdc7def0cbdc,0x00ca8353efe160bd)}, {FIELD_LITERAL(0x003c9e851d9f8893,0x004df23c1696dd28,0x005e587fddb98f95,0x00359afa5adbfdbb,0x00ddb949d26e687c,0x00ebc6efd285564c,0x001750eec619bdd3,0x0037772e4ad0d4fa)}, {FIELD_LITERAL(0x0076e84babbbb048,0x000a6db83681bbe4,0x0059dff597eaead2,0x00f65bdd79fe2dab,0x00e3fc9faa642c8a,0x008a9cc9dfc634c9,0x00428a4b728b1cd4,0x00e80aea53cb6617)}, {FIELD_LITERAL(0x002ab17fdf7d2bd3,0x005aa55f23183393,0x009b88469f8c0eb9,0x007d101b314bca6b,0x0056dd4345fd97b9,0x00880e62e548ae7d,0x003d44d8c87b91a6,0x00fb2811386e22cc)}, {FIELD_LITERAL(0x00eacd58001be3a5,0x0014e1231ca72940,0x0022453384987584,0x0075848f0c37be5c,0x000e6dc40d82c0b2,0x00f4d8ec1270878c,0x00550981d6fb86fd,0x00bb66b58f4c6892)}, {FIELD_LITERAL(0x00bba772e57e297f,0x004f56f68df71b07,0x00ded9facaf23a81,0x00d78e832d78eedc,0x0004f7c3eff02685,0x00ba5fa931f9c020,0x005a29fb4b2295be,0x00e2543f745b1dc9)}, {FIELD_LITERAL(0x00712177652580f9,0x00e9ee16e21d1eca,0x0002465ba75b8e46,0x00a9cb7b1fc8ef2e,0x00ce337e6da1cf8e,0x009d3684c507fffa,0x00058cc115d71214,0x0017dba81e144377)}, {FIELD_LITERAL(0x003b778e67285805,0x00dbb06704ba87b5,0x00ba6ee1ea5ea2fe,0x00e2cdc2c8b3f699,0x006983c6eae69a9c,0x00c6c8c542d0c398,0x00f2d3a9ebcedbdc,0x00be30ddeabbd31c)}, {FIELD_LITERAL(0x0095f20a016490a6,0x005f2b00b9fbf26d,0x00b583124906cdaf,0x002e2077aa473ca8,0x0018c5b9f7902fa6,0x00b704f5229201a6,0x00e1fc5d70e4b1c2,0x00578e366ccf7289)}, {FIELD_LITERAL(0x00932127be1d579d,0x00e6729f50f54904,0x00e70f6247f618af,0x00b1953989fe9d9c,0x0015032e9df69633,0x00d3687b35cb6e82,0x00ab0fff86869218,0x0026054a3a68ddfb)}, {FIELD_LITERAL(0x00cf244d2e899137,0x00a793f52ec7aaa1,0x002e5cb0616e3883,0x009cbf752f176feb,0x0029edce4fa090a3,0x00f6540a960a0275,0x00513985eef0e3bc,0x00ce2e586f6c7228)}, {FIELD_LITERAL(0x00b42f011dbc757c,0x004a8e19d4f07c42,0x00a6d7828318b7ff,0x0004c9ce49ba3c0f,0x005fe71688087b6a,0x006e1d8f9a3d84ed,0x0089693e7e8e9a1f,0x0073bf4183ba45c5)}, {FIELD_LITERAL(0x0029e8ce35530d30,0x00d20f389f61fe3a,0x00cf9e8ddf74e1d4,0x004bec01b04d4979,0x007d92c9f6fd5ddd,0x00c072fa91981808,0x009afda4fe8a1676,0x00c96522ee879a14)}, {FIELD_LITERAL(0x005f0cd9cd83497b,0x00e382f098d97f00,0x0073e37e004eed2e,0x000707fe98b12237,0x0016d92a2b73d561,0x00a42926ab390165,0x00b394db4b1cc8fc,0x002fa14a3f6efa33)}, {FIELD_LITERAL(0x0055076a513d05ee,0x00f076d43cec14ad,0x00a4e386b252faf4,0x00c0713b79b313eb,0x00507efa72f46f19,0x00141bc1e7c66844,0x005629ef060c19ea,0x0085327113d1772c)}, {FIELD_LITERAL(0x00ed490108514e35,0x006bed897e6b4958,0x0000f2cae0dc546c,0x008175eb3e5008e4,0x0093e3fe8f3aed42,0x00e9dbc15fd54d1a,0x00844979a4cfc0c1,0x00ea3194d64ea60b)}, {FIELD_LITERAL(0x00b64d054ec7ed5c,0x007b924cd329fbce,0x00fe8805a8737293,0x00fb82f1d52b43ae,0x004ea745c72e1a76,0x0095ba2552861c0c,0x00f66846c3547784,0x003b815bd05dc23c)}, {FIELD_LITERAL(0x00669e32fd197ef7,0x001dfca2c5e2f7c9,0x00a2ae0964a1e5e2,0x00b4334b15c91232,0x0096419585110d96,0x009c0b2262172a58,0x009d7c87cf6d35ca,0x008a5ce50d3cabf6)}, {FIELD_LITERAL(0x00888b9c1cf73530,0x00375346c6afecd2,0x00142240b35b74d3,0x00d952835f86a5f5,0x000665c2658eaf9a,0x00f29f43062b2033,0x00a19a58c5bc85f9,0x00e62ac95724a937)}, {FIELD_LITERAL(0x003bedc9ae9d1730,0x00fedd7c04cbc775,0x00c19abc4540c61d,0x00115294c57fb687,0x00663fceb174cd8f,0x001671f572b885b0,0x002d14694ed85978,0x00127282078a8e44)}, {FIELD_LITERAL(0x00e6d2822aa72eca,0x00d832957cdc0058,0x00dc60e5bed23e18,0x00b94b4c418b03a3,0x00df3b85d410a430,0x0055e81b70bc79d4,0x00081d9369cbd1a0,0x00f7fee3acf0c656)}, {FIELD_LITERAL(0x003baba41b5abffb,0x00661ee09fca8193,0x00e0c6c92e6aea59,0x00886c207bcbe591,0x00aef9e7798e8004,0x00164f599f4d707a,0x00bb1597a76d21f2,0x00fda82d5e025626)}, {FIELD_LITERAL(0x00552b53a9640f0e,0x005985236f4d88bf,0x00b7aaec965a8ae5,0x00cedada7b5ccf95,0x007b1ea2088f1902,0x0028445e38b4a7fa,0x0057f10ddc50efed,0x007637a3147bc5cb)}, {FIELD_LITERAL(0x008174fe4db53757,0x00930c4f4a35ecc8,0x000e9f82c1c95a8f,0x00c6480547d66e5e,0x00dce888f9a7bf39,0x006671a5022cb906,0x004823c19b5337a0,0x00455338b7fec529)}, {FIELD_LITERAL(0x005ac123fdc45964,0x00395057c2221d17,0x003c09c74cf84eb1,0x00b5ca859bbebf9d,0x001b26b274a7d235,0x00e8c63508e96a48,0x00edbce4d51d721e,0x00c49436797d6f83)}, {FIELD_LITERAL(0x0071595be88a7f40,0x00a05e6ac1c0fc87,0x00a01bf6538b29eb,0x00badcd80b881fb8,0x005bfe7af8049f8b,0x0084918e6ae35537,0x00ed4bd54759316e,0x007f135988d6b548)}, {FIELD_LITERAL(0x0075656c41e06629,0x0086059d83396637,0x004f304ecb457b37,0x00e3b4887db6be65,0x0020b54c263bb0be,0x0060a69193e561c3,0x00e6863f20dc8ce9,0x00afe16ac56e6478)} }; cryptonite-0.26/cbits/decaf/ed448goldilocks/decaf.c0000644000000000000000000015240613414232447020322 0ustar0000000000000000/** * @file ed448goldilocks/decaf.c * @author Mike Hamburg * * @copyright * Copyright (c) 2015-2016 Cryptography Research, Inc. \n * Released under the MIT License. See LICENSE.txt for license information. * * @brief Decaf high-level functions. * * @warning This file was automatically generated in Python. * Please do not edit it. */ #define _XOPEN_SOURCE 600 /* for posix_memalign */ #include "word.h" #include "field.h" #include #include /* Template stuff */ #define API_NS(_id) cryptonite_decaf_448_##_id #define SCALAR_BITS CRYPTONITE_DECAF_448_SCALAR_BITS #define SCALAR_SER_BYTES CRYPTONITE_DECAF_448_SCALAR_BYTES #define SCALAR_LIMBS CRYPTONITE_DECAF_448_SCALAR_LIMBS #define scalar_t API_NS(scalar_t) #define point_t API_NS(point_t) #define precomputed_s API_NS(precomputed_s) #define IMAGINE_TWIST 0 #define COFACTOR 4 /* Comb config: number of combs, n, t, s. */ #define COMBS_N 5 #define COMBS_T 5 #define COMBS_S 18 #define CRYPTONITE_DECAF_WINDOW_BITS 5 #define CRYPTONITE_DECAF_WNAF_FIXED_TABLE_BITS 5 #define CRYPTONITE_DECAF_WNAF_VAR_TABLE_BITS 3 #define EDDSA_USE_SIGMA_ISOGENY 0 static const int EDWARDS_D = -39081; static const scalar_t point_scalarmul_adjustment = {{{ SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad), SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163) }}}, precomputed_scalarmul_adjustment = {{{ SC_LIMB(0xc873d6d54a7bb0cf), SC_LIMB(0xe933d8d723a70aad), SC_LIMB(0xbb124b65129c96fd), SC_LIMB(0x00000008335dc163) }}}; const uint8_t cryptonite_decaf_x448_base_point[CRYPTONITE_DECAF_X448_PUBLIC_BYTES] = { 0x05 }; #if COFACTOR==8 || EDDSA_USE_SIGMA_ISOGENY static const gf SQRT_ONE_MINUS_D = {FIELD_LITERAL( /* NONE */ )}; #endif /* End of template stuff */ /* Sanity */ #if (COFACTOR == 8) && !IMAGINE_TWIST && !UNSAFE_CURVE_HAS_POINTS_AT_INFINITY /* FUTURE MAGIC: Curve41417 doesn't have these properties. */ #error "Currently require IMAGINE_TWIST (and thus p=5 mod 8) for cofactor 8" /* OK, but why? * Two reasons: #1: There are bugs when COFACTOR == && IMAGINE_TWIST # #2: */ #endif #if IMAGINE_TWIST && (P_MOD_8 != 5) #error "Cannot use IMAGINE_TWIST except for p == 5 mod 8" #endif #if (COFACTOR != 8) && (COFACTOR != 4) #error "COFACTOR must be 4 or 8" #endif #if IMAGINE_TWIST extern const gf SQRT_MINUS_ONE; #endif #define WBITS CRYPTONITE_DECAF_WORD_BITS /* NB this may be different from ARCH_WORD_BITS */ extern const point_t API_NS(point_base); /* Projective Niels coordinates */ typedef struct { gf a, b, c; } niels_s, niels_t[1]; typedef struct { niels_t n; gf z; } VECTOR_ALIGNED pniels_s, pniels_t[1]; /* Precomputed base */ struct precomputed_s { niels_t table [COMBS_N<<(COMBS_T-1)]; }; extern const gf API_NS(precomputed_base_as_fe)[]; const precomputed_s *API_NS(precomputed_base) = (const precomputed_s *) &API_NS(precomputed_base_as_fe); const size_t API_NS(sizeof_precomputed_s) = sizeof(precomputed_s); const size_t API_NS(alignof_precomputed_s) = sizeof(big_register_t); /** Inverse. */ static void cryptonite_gf_invert(gf y, const gf x, int assert_nonzero) { gf t1, t2; cryptonite_gf_sqr(t1, x); // o^2 mask_t ret = cryptonite_gf_isr(t2, t1); // +-1/sqrt(o^2) = +-1/o (void)ret; if (assert_nonzero) assert(ret); cryptonite_gf_sqr(t1, t2); cryptonite_gf_mul(t2, t1, x); // not direct to y in case of alias. cryptonite_gf_copy(y, t2); } /** Return high bit of x = low bit of 2x mod p */ static mask_t cryptonite_gf_lobit(const gf x) { gf y; cryptonite_gf_copy(y,x); cryptonite_gf_strong_reduce(y); return -(y->limb[0]&1); } /** identity = (0,1) */ const point_t API_NS(point_identity) = {{{{{0}}},{{{1}}},{{{1}}},{{{0}}}}}; void API_NS(deisogenize) ( cryptonite_gf_s *__restrict__ s, cryptonite_gf_s *__restrict__ minus_t_over_s, const point_t p, mask_t toggle_hibit_s, mask_t toggle_hibit_t_over_s, mask_t toggle_rotation ); void API_NS(deisogenize) ( cryptonite_gf_s *__restrict__ s, cryptonite_gf_s *__restrict__ minus_t_over_s, const point_t p, mask_t toggle_hibit_s, mask_t toggle_hibit_t_over_s, mask_t toggle_rotation ) { #if COFACTOR == 4 && !IMAGINE_TWIST (void) toggle_rotation; gf b, d; cryptonite_gf_s *c = s, *a = minus_t_over_s; cryptonite_gf_mulw(a, p->y, 1-EDWARDS_D); cryptonite_gf_mul(c, a, p->t); /* -dYT, with EDWARDS_D = d-1 */ cryptonite_gf_mul(a, p->x, p->z); cryptonite_gf_sub(d, c, a); /* aXZ-dYT with a=-1 */ cryptonite_gf_add(a, p->z, p->y); cryptonite_gf_sub(b, p->z, p->y); cryptonite_gf_mul(c, b, a); cryptonite_gf_mulw(b, c, -EDWARDS_D); /* (a-d)(Z+Y)(Z-Y) */ mask_t ok = cryptonite_gf_isr (a,b); /* r in the paper */ (void)ok; assert(ok | cryptonite_gf_eq(b,ZERO)); cryptonite_gf_mulw (b, a, -EDWARDS_D); /* u in the paper */ cryptonite_gf_mul(c,a,d); /* r(aZX-dYT) */ cryptonite_gf_mul(a,b,p->z); /* uZ */ cryptonite_gf_add(a,a,a); /* 2uZ */ mask_t tg = toggle_hibit_t_over_s ^ ~cryptonite_gf_hibit(minus_t_over_s); cryptonite_gf_cond_neg(minus_t_over_s, tg); /* t/s <-? -t/s */ cryptonite_gf_cond_neg(c, tg); /* u <- -u if negative. */ cryptonite_gf_add(d,c,p->y); cryptonite_gf_mul(s,b,d); cryptonite_gf_cond_neg(s, toggle_hibit_s ^ cryptonite_gf_hibit(s)); #else /* More complicated because of rotation */ /* MAGIC This code is wrong for certain non-Curve25519 curves; * check if it's because of Cofactor==8 or IMAGINE_TWIST */ gf c, d; cryptonite_gf_s *b = s, *a = minus_t_over_s; #if IMAGINE_TWIST gf x, t; cryptonite_gf_div_qnr(x,p->x); cryptonite_gf_div_qnr(t,p->t); cryptonite_gf_add ( a, p->z, x ); cryptonite_gf_sub ( b, p->z, x ); cryptonite_gf_mul ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 - X^2 */ #else const cryptonite_gf_s *x = p->x, *t = p->t; cryptonite_gf_sqr ( a, p->z ); cryptonite_gf_sqr ( b, p->x ); cryptonite_gf_add ( c, a, b ); /* "zx" = Z^2 - aX^2 = Z^2 + X^2 */ #endif /* Here: c = "zx" in the SAGE code = Z^2 - aX^2 */ cryptonite_gf_mul ( a, p->z, t ); /* "tz" = T*Z */ cryptonite_gf_sqr ( b, a ); cryptonite_gf_mul ( d, b, c ); /* (TZ)^2 * (Z^2-aX^2) */ mask_t ok = cryptonite_gf_isr(b, d); (void)ok; assert(ok | cryptonite_gf_eq(d,ZERO)); cryptonite_gf_mul ( d, b, a ); /* "osx" = 1 / sqrt(z^2-ax^2) */ cryptonite_gf_mul ( a, b, c ); cryptonite_gf_mul ( b, a, d ); /* 1/tz */ mask_t rotate; #if (COFACTOR == 8) gf e; cryptonite_gf_sqr(e, p->z); cryptonite_gf_mul(a, e, b); /* z^2 / tz = z/t = 1/xy */ rotate = cryptonite_gf_hibit(a) ^ toggle_rotation; /* Curve25519: cond select between zx * 1/tz or sqrt(1-d); y=-x */ cryptonite_gf_mul ( a, b, c ); cryptonite_gf_cond_sel ( a, a, SQRT_ONE_MINUS_D, rotate ); cryptonite_gf_cond_sel ( e, p->y, x, rotate ); #else const cryptonite_gf_s *e = x; (void)toggle_rotation; rotate = 0; #endif cryptonite_gf_mul ( c, a, d ); // new "osx" cryptonite_gf_mul ( a, c, p->z ); cryptonite_gf_add ( minus_t_over_s, a, a ); // 2 * "osx" * Z cryptonite_gf_mul ( d, b, p->z ); mask_t tg = toggle_hibit_t_over_s ^~ cryptonite_gf_hibit(minus_t_over_s); cryptonite_gf_cond_neg ( minus_t_over_s, tg ); cryptonite_gf_cond_neg ( c, rotate ^ tg ); cryptonite_gf_add ( d, d, c ); cryptonite_gf_mul ( s, d, e ); /* here "x" = y unless rotate */ cryptonite_gf_cond_neg ( s, toggle_hibit_s ^ cryptonite_gf_hibit(s) ); #endif } void API_NS(point_encode)( unsigned char ser[SER_BYTES], const point_t p ) { gf s, mtos; API_NS(deisogenize)(s,mtos,p,0,0,0); cryptonite_gf_serialize(ser,s,0); } cryptonite_decaf_error_t API_NS(point_decode) ( point_t p, const unsigned char ser[SER_BYTES], cryptonite_decaf_bool_t allow_identity ) { gf s, a, b, c, d, e, f; mask_t succ = cryptonite_gf_deserialize(s, ser, 0); mask_t zero = cryptonite_gf_eq(s, ZERO); succ &= bool_to_mask(allow_identity) | ~zero; cryptonite_gf_sqr ( a, s ); /* s^2 */ #if IMAGINE_TWIST cryptonite_gf_sub ( f, ONE, a ); /* f = 1-as^2 = 1-s^2*/ #else cryptonite_gf_add ( f, ONE, a ); /* f = 1-as^2 = 1+s^2 */ #endif succ &= ~ cryptonite_gf_eq( f, ZERO ); cryptonite_gf_sqr ( b, f ); /* (1-as^2)^2 = 1 - 2as^2 + a^2 s^4 */ cryptonite_gf_mulw ( c, a, 4*IMAGINE_TWIST-4*EDWARDS_D ); cryptonite_gf_add ( c, c, b ); /* t^2 = 1 + (2a-4d) s^2 + s^4 */ cryptonite_gf_mul ( d, f, s ); /* s * (1-as^2) for denoms */ cryptonite_gf_sqr ( e, d ); /* s^2 * (1-as^2)^2 */ cryptonite_gf_mul ( b, c, e ); /* t^2 * s^2 * (1-as^2)^2 */ succ &= cryptonite_gf_isr(e,b) | cryptonite_gf_eq(b,ZERO); /* e = 1/(t s (1-as^2)) */ cryptonite_gf_mul ( b, e, d ); /* 1 / t */ cryptonite_gf_mul ( d, e, c ); /* t / (s(1-as^2)) */ cryptonite_gf_mul ( e, d, f ); /* t / s */ mask_t negtos = cryptonite_gf_hibit(e); cryptonite_gf_cond_neg(b, negtos); cryptonite_gf_cond_neg(d, negtos); #if IMAGINE_TWIST cryptonite_gf_add ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */ #else cryptonite_gf_sub ( p->z, ONE, a); /* Z = 1+as^2 = 1-s^2 */ #endif #if COFACTOR == 8 cryptonite_gf_mul ( a, p->z, d); /* t(1+s^2) / s(1-s^2) = 2/xy */ succ &= ~cryptonite_gf_lobit(a); /* = ~cryptonite_gf_hibit(a/2), since cryptonite_gf_hibit(x) = cryptonite_gf_lobit(2x) */ #endif cryptonite_gf_mul ( a, f, b ); /* y = (1-s^2) / t */ cryptonite_gf_mul ( p->y, p->z, a ); /* Y = yZ */ #if IMAGINE_TWIST cryptonite_gf_add ( b, s, s ); cryptonite_gf_mul(p->x, b, SQRT_MINUS_ONE); /* Curve25519 */ #else cryptonite_gf_add ( p->x, s, s ); #endif cryptonite_gf_mul ( p->t, p->x, a ); /* T = 2s (1-as^2)/t */ #if UNSAFE_CURVE_HAS_POINTS_AT_INFINITY /* This can't happen for any of the supported configurations. * * If it can happen (because s=1), it's because the curve has points * at infinity, which means that there may be critical security bugs * elsewhere in the library. In that case, it's better that you hit * the assertion in point_valid, which will happen in the test suite * since it tests s=1. * * This debugging option is to allow testing of IMAGINE_TWIST = 0 on * Ed25519, without hitting that assertion. Don't use it in * production. */ succ &= ~cryptonite_gf_eq(p->z,ZERO); #endif p->y->limb[0] -= zero; assert(API_NS(point_valid)(p) | ~succ); return cryptonite_decaf_succeed_if(mask_to_bool(succ)); } #if IMAGINE_TWIST #define TWISTED_D (-(EDWARDS_D)) #else #define TWISTED_D ((EDWARDS_D)-1) #endif #if TWISTED_D < 0 #define EFF_D (-(TWISTED_D)) #define NEG_D 1 #else #define EFF_D TWISTED_D #define NEG_D 0 #endif void API_NS(point_sub) ( point_t p, const point_t q, const point_t r ) { gf a, b, c, d; cryptonite_gf_sub_nr ( b, q->y, q->x ); /* 3+e */ cryptonite_gf_sub_nr ( d, r->y, r->x ); /* 3+e */ cryptonite_gf_add_nr ( c, r->y, r->x ); /* 2+e */ cryptonite_gf_mul ( a, c, b ); cryptonite_gf_add_nr ( b, q->y, q->x ); /* 2+e */ cryptonite_gf_mul ( p->y, d, b ); cryptonite_gf_mul ( b, r->t, q->t ); cryptonite_gf_mulw ( p->x, b, 2*EFF_D ); cryptonite_gf_add_nr ( b, a, p->y ); /* 2+e */ cryptonite_gf_sub_nr ( c, p->y, a ); /* 3+e */ cryptonite_gf_mul ( a, q->z, r->z ); cryptonite_gf_add_nr ( a, a, a ); /* 2+e */ if (GF_HEADROOM <= 3) cryptonite_gf_weak_reduce(a); /* or 1+e */ #if NEG_D cryptonite_gf_sub_nr ( p->y, a, p->x ); /* 4+e or 3+e */ cryptonite_gf_add_nr ( a, a, p->x ); /* 3+e or 2+e */ #else cryptonite_gf_add_nr ( p->y, a, p->x ); /* 3+e or 2+e */ cryptonite_gf_sub_nr ( a, a, p->x ); /* 4+e or 3+e */ #endif cryptonite_gf_mul ( p->z, a, p->y ); cryptonite_gf_mul ( p->x, p->y, c ); cryptonite_gf_mul ( p->y, a, b ); cryptonite_gf_mul ( p->t, b, c ); } void API_NS(point_add) ( point_t p, const point_t q, const point_t r ) { gf a, b, c, d; cryptonite_gf_sub_nr ( b, q->y, q->x ); /* 3+e */ cryptonite_gf_sub_nr ( c, r->y, r->x ); /* 3+e */ cryptonite_gf_add_nr ( d, r->y, r->x ); /* 2+e */ cryptonite_gf_mul ( a, c, b ); cryptonite_gf_add_nr ( b, q->y, q->x ); /* 2+e */ cryptonite_gf_mul ( p->y, d, b ); cryptonite_gf_mul ( b, r->t, q->t ); cryptonite_gf_mulw ( p->x, b, 2*EFF_D ); cryptonite_gf_add_nr ( b, a, p->y ); /* 2+e */ cryptonite_gf_sub_nr ( c, p->y, a ); /* 3+e */ cryptonite_gf_mul ( a, q->z, r->z ); cryptonite_gf_add_nr ( a, a, a ); /* 2+e */ if (GF_HEADROOM <= 3) cryptonite_gf_weak_reduce(a); /* or 1+e */ #if NEG_D cryptonite_gf_add_nr ( p->y, a, p->x ); /* 3+e or 2+e */ cryptonite_gf_sub_nr ( a, a, p->x ); /* 4+e or 3+e */ #else cryptonite_gf_sub_nr ( p->y, a, p->x ); /* 4+e or 3+e */ cryptonite_gf_add_nr ( a, a, p->x ); /* 3+e or 2+e */ #endif cryptonite_gf_mul ( p->z, a, p->y ); cryptonite_gf_mul ( p->x, p->y, c ); cryptonite_gf_mul ( p->y, a, b ); cryptonite_gf_mul ( p->t, b, c ); } static CRYPTONITE_DECAF_NOINLINE void point_double_internal ( point_t p, const point_t q, int before_double ) { gf a, b, c, d; cryptonite_gf_sqr ( c, q->x ); cryptonite_gf_sqr ( a, q->y ); cryptonite_gf_add_nr ( d, c, a ); /* 2+e */ cryptonite_gf_add_nr ( p->t, q->y, q->x ); /* 2+e */ cryptonite_gf_sqr ( b, p->t ); cryptonite_gf_subx_nr ( b, b, d, 3 ); /* 4+e */ cryptonite_gf_sub_nr ( p->t, a, c ); /* 3+e */ cryptonite_gf_sqr ( p->x, q->z ); cryptonite_gf_add_nr ( p->z, p->x, p->x ); /* 2+e */ cryptonite_gf_subx_nr ( a, p->z, p->t, 4 ); /* 6+e */ if (GF_HEADROOM == 5) cryptonite_gf_weak_reduce(a); /* or 1+e */ cryptonite_gf_mul ( p->x, a, b ); cryptonite_gf_mul ( p->z, p->t, a ); cryptonite_gf_mul ( p->y, p->t, d ); if (!before_double) cryptonite_gf_mul ( p->t, b, d ); } void API_NS(point_double)(point_t p, const point_t q) { point_double_internal(p,q,0); } void API_NS(point_negate) ( point_t nega, const point_t a ) { cryptonite_gf_sub(nega->x, ZERO, a->x); cryptonite_gf_copy(nega->y, a->y); cryptonite_gf_copy(nega->z, a->z); cryptonite_gf_sub(nega->t, ZERO, a->t); } /* Operations on [p]niels */ static CRYPTONITE_DECAF_INLINE void cond_neg_niels ( niels_t n, mask_t neg ) { cryptonite_gf_cond_swap(n->a, n->b, neg); cryptonite_gf_cond_neg(n->c, neg); } static CRYPTONITE_DECAF_NOINLINE void pt_to_pniels ( pniels_t b, const point_t a ) { cryptonite_gf_sub ( b->n->a, a->y, a->x ); cryptonite_gf_add ( b->n->b, a->x, a->y ); cryptonite_gf_mulw ( b->n->c, a->t, 2*TWISTED_D ); cryptonite_gf_add ( b->z, a->z, a->z ); } static CRYPTONITE_DECAF_NOINLINE void pniels_to_pt ( point_t e, const pniels_t d ) { gf eu; cryptonite_gf_add ( eu, d->n->b, d->n->a ); cryptonite_gf_sub ( e->y, d->n->b, d->n->a ); cryptonite_gf_mul ( e->t, e->y, eu); cryptonite_gf_mul ( e->x, d->z, e->y ); cryptonite_gf_mul ( e->y, d->z, eu ); cryptonite_gf_sqr ( e->z, d->z ); } static CRYPTONITE_DECAF_NOINLINE void niels_to_pt ( point_t e, const niels_t n ) { cryptonite_gf_add ( e->y, n->b, n->a ); cryptonite_gf_sub ( e->x, n->b, n->a ); cryptonite_gf_mul ( e->t, e->y, e->x ); cryptonite_gf_copy ( e->z, ONE ); } static CRYPTONITE_DECAF_NOINLINE void add_niels_to_pt ( point_t d, const niels_t e, int before_double ) { gf a, b, c; cryptonite_gf_sub_nr ( b, d->y, d->x ); /* 3+e */ cryptonite_gf_mul ( a, e->a, b ); cryptonite_gf_add_nr ( b, d->x, d->y ); /* 2+e */ cryptonite_gf_mul ( d->y, e->b, b ); cryptonite_gf_mul ( d->x, e->c, d->t ); cryptonite_gf_add_nr ( c, a, d->y ); /* 2+e */ cryptonite_gf_sub_nr ( b, d->y, a ); /* 3+e */ cryptonite_gf_sub_nr ( d->y, d->z, d->x ); /* 3+e */ cryptonite_gf_add_nr ( a, d->x, d->z ); /* 2+e */ cryptonite_gf_mul ( d->z, a, d->y ); cryptonite_gf_mul ( d->x, d->y, b ); cryptonite_gf_mul ( d->y, a, c ); if (!before_double) cryptonite_gf_mul ( d->t, b, c ); } static CRYPTONITE_DECAF_NOINLINE void sub_niels_from_pt ( point_t d, const niels_t e, int before_double ) { gf a, b, c; cryptonite_gf_sub_nr ( b, d->y, d->x ); /* 3+e */ cryptonite_gf_mul ( a, e->b, b ); cryptonite_gf_add_nr ( b, d->x, d->y ); /* 2+e */ cryptonite_gf_mul ( d->y, e->a, b ); cryptonite_gf_mul ( d->x, e->c, d->t ); cryptonite_gf_add_nr ( c, a, d->y ); /* 2+e */ cryptonite_gf_sub_nr ( b, d->y, a ); /* 3+e */ cryptonite_gf_add_nr ( d->y, d->z, d->x ); /* 2+e */ cryptonite_gf_sub_nr ( a, d->z, d->x ); /* 3+e */ cryptonite_gf_mul ( d->z, a, d->y ); cryptonite_gf_mul ( d->x, d->y, b ); cryptonite_gf_mul ( d->y, a, c ); if (!before_double) cryptonite_gf_mul ( d->t, b, c ); } static void add_pniels_to_pt ( point_t p, const pniels_t pn, int before_double ) { gf L0; cryptonite_gf_mul ( L0, p->z, pn->z ); cryptonite_gf_copy ( p->z, L0 ); add_niels_to_pt( p, pn->n, before_double ); } static void sub_pniels_from_pt ( point_t p, const pniels_t pn, int before_double ) { gf L0; cryptonite_gf_mul ( L0, p->z, pn->z ); cryptonite_gf_copy ( p->z, L0 ); sub_niels_from_pt( p, pn->n, before_double ); } static CRYPTONITE_DECAF_NOINLINE void prepare_fixed_window( pniels_t *multiples, const point_t b, int ntable ) { point_t tmp; pniels_t pn; int i; point_double_internal(tmp, b, 0); pt_to_pniels(pn, tmp); pt_to_pniels(multiples[0], b); API_NS(point_copy)(tmp, b); for (i=1; i> 1, NTABLE = 1<<(WINDOW-1); scalar_t scalar1x; API_NS(scalar_add)(scalar1x, scalar, point_scalarmul_adjustment); API_NS(scalar_halve)(scalar1x,scalar1x); /* Set up a precomputed table with odd multiples of b. */ pniels_t pn, multiples[NTABLE]; point_t tmp; prepare_fixed_window(multiples, b, NTABLE); /* Initialize. */ int i,j,first=1; i = SCALAR_BITS - ((SCALAR_BITS-1) % WINDOW) - 1; for (; i>=0; i-=WINDOW) { /* Fetch another block of bits */ word_t bits = scalar1x->limb[i/WBITS] >> (i%WBITS); if (i%WBITS >= WBITS-WINDOW && i/WBITSlimb[i/WBITS+1] << (WBITS - (i%WBITS)); } bits &= WINDOW_MASK; mask_t inv = (bits>>(WINDOW-1))-1; bits ^= inv; /* Add in from table. Compute t only on last iteration. */ constant_time_lookup(pn, multiples, sizeof(pn), NTABLE, bits & WINDOW_T_MASK); cond_neg_niels(pn->n, inv); if (first) { pniels_to_pt(tmp, pn); first = 0; } else { /* Using Hisil et al's lookahead method instead of extensible here * for no particular reason. Double WINDOW times, but only compute t on * the last one. */ for (j=0; j> 1, NTABLE = 1<<(WINDOW-1); scalar_t scalar1x, scalar2x; API_NS(scalar_add)(scalar1x, scalarb, point_scalarmul_adjustment); API_NS(scalar_halve)(scalar1x,scalar1x); API_NS(scalar_add)(scalar2x, scalarc, point_scalarmul_adjustment); API_NS(scalar_halve)(scalar2x,scalar2x); /* Set up a precomputed table with odd multiples of b. */ pniels_t pn, multiples1[NTABLE], multiples2[NTABLE]; point_t tmp; prepare_fixed_window(multiples1, b, NTABLE); prepare_fixed_window(multiples2, c, NTABLE); /* Initialize. */ int i,j,first=1; i = SCALAR_BITS - ((SCALAR_BITS-1) % WINDOW) - 1; for (; i>=0; i-=WINDOW) { /* Fetch another block of bits */ word_t bits1 = scalar1x->limb[i/WBITS] >> (i%WBITS), bits2 = scalar2x->limb[i/WBITS] >> (i%WBITS); if (i%WBITS >= WBITS-WINDOW && i/WBITSlimb[i/WBITS+1] << (WBITS - (i%WBITS)); bits2 ^= scalar2x->limb[i/WBITS+1] << (WBITS - (i%WBITS)); } bits1 &= WINDOW_MASK; bits2 &= WINDOW_MASK; mask_t inv1 = (bits1>>(WINDOW-1))-1; mask_t inv2 = (bits2>>(WINDOW-1))-1; bits1 ^= inv1; bits2 ^= inv2; /* Add in from table. Compute t only on last iteration. */ constant_time_lookup(pn, multiples1, sizeof(pn), NTABLE, bits1 & WINDOW_T_MASK); cond_neg_niels(pn->n, inv1); if (first) { pniels_to_pt(tmp, pn); first = 0; } else { /* Using Hisil et al's lookahead method instead of extensible here * for no particular reason. Double WINDOW times, but only compute t on * the last one. */ for (j=0; jn, inv2); add_pniels_to_pt(tmp, pn, i?-1:0); } /* Write out the answer */ API_NS(point_copy)(a,tmp); cryptonite_decaf_bzero(scalar1x,sizeof(scalar1x)); cryptonite_decaf_bzero(scalar2x,sizeof(scalar2x)); cryptonite_decaf_bzero(pn,sizeof(pn)); cryptonite_decaf_bzero(multiples1,sizeof(multiples1)); cryptonite_decaf_bzero(multiples2,sizeof(multiples2)); cryptonite_decaf_bzero(tmp,sizeof(tmp)); } void API_NS(point_dual_scalarmul) ( point_t a1, point_t a2, const point_t b, const scalar_t scalar1, const scalar_t scalar2 ) { const int WINDOW = CRYPTONITE_DECAF_WINDOW_BITS, WINDOW_MASK = (1<> 1, NTABLE = 1<<(WINDOW-1); scalar_t scalar1x, scalar2x; API_NS(scalar_add)(scalar1x, scalar1, point_scalarmul_adjustment); API_NS(scalar_halve)(scalar1x,scalar1x); API_NS(scalar_add)(scalar2x, scalar2, point_scalarmul_adjustment); API_NS(scalar_halve)(scalar2x,scalar2x); /* Set up a precomputed table with odd multiples of b. */ point_t multiples1[NTABLE], multiples2[NTABLE], working, tmp; pniels_t pn; API_NS(point_copy)(working, b); /* Initialize. */ int i,j; for (i=0; ilimb[i/WBITS] >> (i%WBITS), bits2 = scalar2x->limb[i/WBITS] >> (i%WBITS); if (i%WBITS >= WBITS-WINDOW && i/WBITSlimb[i/WBITS+1] << (WBITS - (i%WBITS)); bits2 ^= scalar2x->limb[i/WBITS+1] << (WBITS - (i%WBITS)); } bits1 &= WINDOW_MASK; bits2 &= WINDOW_MASK; mask_t inv1 = (bits1>>(WINDOW-1))-1; mask_t inv2 = (bits2>>(WINDOW-1))-1; bits1 ^= inv1; bits2 ^= inv2; pt_to_pniels(pn, working); constant_time_lookup(tmp, multiples1, sizeof(tmp), NTABLE, bits1 & WINDOW_T_MASK); cond_neg_niels(pn->n, inv1); /* add_pniels_to_pt(multiples1[bits1 & WINDOW_T_MASK], pn, 0); */ add_pniels_to_pt(tmp, pn, 0); constant_time_insert(multiples1, tmp, sizeof(tmp), NTABLE, bits1 & WINDOW_T_MASK); constant_time_lookup(tmp, multiples2, sizeof(tmp), NTABLE, bits2 & WINDOW_T_MASK); cond_neg_niels(pn->n, inv1^inv2); /* add_pniels_to_pt(multiples2[bits2 & WINDOW_T_MASK], pn, 0); */ add_pniels_to_pt(tmp, pn, 0); constant_time_insert(multiples2, tmp, sizeof(tmp), NTABLE, bits2 & WINDOW_T_MASK); } if (NTABLE > 1) { API_NS(point_copy)(working, multiples1[NTABLE-1]); API_NS(point_copy)(tmp , multiples2[NTABLE-1]); for (i=NTABLE-1; i>1; i--) { API_NS(point_add)(multiples1[i-1], multiples1[i-1], multiples1[i]); API_NS(point_add)(multiples2[i-1], multiples2[i-1], multiples2[i]); API_NS(point_add)(working, working, multiples1[i-1]); API_NS(point_add)(tmp, tmp, multiples2[i-1]); } API_NS(point_add)(multiples1[0], multiples1[0], multiples1[1]); API_NS(point_add)(multiples2[0], multiples2[0], multiples2[1]); point_double_internal(working, working, 0); point_double_internal(tmp, tmp, 0); API_NS(point_add)(a1, working, multiples1[0]); API_NS(point_add)(a2, tmp, multiples2[0]); } else { API_NS(point_copy)(a1, multiples1[0]); API_NS(point_copy)(a2, multiples2[0]); } cryptonite_decaf_bzero(scalar1x,sizeof(scalar1x)); cryptonite_decaf_bzero(scalar2x,sizeof(scalar2x)); cryptonite_decaf_bzero(pn,sizeof(pn)); cryptonite_decaf_bzero(multiples1,sizeof(multiples1)); cryptonite_decaf_bzero(multiples2,sizeof(multiples2)); cryptonite_decaf_bzero(tmp,sizeof(tmp)); cryptonite_decaf_bzero(working,sizeof(working)); } cryptonite_decaf_bool_t API_NS(point_eq) ( const point_t p, const point_t q ) { /* equality mod 2-torsion compares x/y */ gf a, b; cryptonite_gf_mul ( a, p->y, q->x ); cryptonite_gf_mul ( b, q->y, p->x ); mask_t succ = cryptonite_gf_eq(a,b); #if (COFACTOR == 8) && IMAGINE_TWIST cryptonite_gf_mul ( a, p->y, q->y ); cryptonite_gf_mul ( b, q->x, p->x ); #if !(IMAGINE_TWIST) cryptonite_gf_sub ( a, ZERO, a ); #else /* Interesting note: the 4tor would normally be rotation. * But because of the *i twist, it's actually * (x,y) <-> (iy,ix) */ /* No code, just a comment. */ #endif succ |= cryptonite_gf_eq(a,b); #endif return mask_to_bool(succ); } cryptonite_decaf_bool_t API_NS(point_valid) ( const point_t p ) { gf a,b,c; cryptonite_gf_mul(a,p->x,p->y); cryptonite_gf_mul(b,p->z,p->t); mask_t out = cryptonite_gf_eq(a,b); cryptonite_gf_sqr(a,p->x); cryptonite_gf_sqr(b,p->y); cryptonite_gf_sub(a,b,a); cryptonite_gf_sqr(b,p->t); cryptonite_gf_mulw(c,b,TWISTED_D); cryptonite_gf_sqr(b,p->z); cryptonite_gf_add(b,b,c); out &= cryptonite_gf_eq(a,b); out &= ~cryptonite_gf_eq(p->z,ZERO); return mask_to_bool(out); } void API_NS(point_debugging_torque) ( point_t q, const point_t p ) { #if COFACTOR == 8 && IMAGINE_TWIST gf tmp; cryptonite_gf_mul(tmp,p->x,SQRT_MINUS_ONE); cryptonite_gf_mul(q->x,p->y,SQRT_MINUS_ONE); cryptonite_gf_copy(q->y,tmp); cryptonite_gf_copy(q->z,p->z); cryptonite_gf_sub(q->t,ZERO,p->t); #else cryptonite_gf_sub(q->x,ZERO,p->x); cryptonite_gf_sub(q->y,ZERO,p->y); cryptonite_gf_copy(q->z,p->z); cryptonite_gf_copy(q->t,p->t); #endif } void API_NS(point_debugging_pscale) ( point_t q, const point_t p, const uint8_t factor[SER_BYTES] ) { gf gfac,tmp; /* NB this means you'll never pscale by negative numbers for p521 */ ignore_result(cryptonite_gf_deserialize(gfac,factor,0)); cryptonite_gf_cond_sel(gfac,gfac,ONE,cryptonite_gf_eq(gfac,ZERO)); cryptonite_gf_mul(tmp,p->x,gfac); cryptonite_gf_copy(q->x,tmp); cryptonite_gf_mul(tmp,p->y,gfac); cryptonite_gf_copy(q->y,tmp); cryptonite_gf_mul(tmp,p->z,gfac); cryptonite_gf_copy(q->z,tmp); cryptonite_gf_mul(tmp,p->t,gfac); cryptonite_gf_copy(q->t,tmp); } static void cryptonite_gf_batch_invert ( gf *__restrict__ out, const gf *in, unsigned int n ) { gf t1; assert(n>1); cryptonite_gf_copy(out[1], in[0]); int i; for (i=1; i<(int) (n-1); i++) { cryptonite_gf_mul(out[i+1], out[i], in[i]); } cryptonite_gf_mul(out[0], out[n-1], in[n-1]); cryptonite_gf_invert(out[0], out[0], 1); for (i=n-1; i>0; i--) { cryptonite_gf_mul(t1, out[i], out[0]); cryptonite_gf_copy(out[i], t1); cryptonite_gf_mul(t1, out[0], in[i]); cryptonite_gf_copy(out[0], t1); } } static void batch_normalize_niels ( niels_t *table, const gf *zs, gf *__restrict__ zis, int n ) { int i; gf product; cryptonite_gf_batch_invert(zis, zs, n); for (i=0; ia, zis[i]); cryptonite_gf_strong_reduce(product); cryptonite_gf_copy(table[i]->a, product); cryptonite_gf_mul(product, table[i]->b, zis[i]); cryptonite_gf_strong_reduce(product); cryptonite_gf_copy(table[i]->b, product); cryptonite_gf_mul(product, table[i]->c, zis[i]); cryptonite_gf_strong_reduce(product); cryptonite_gf_copy(table[i]->c, product); } cryptonite_decaf_bzero(product,sizeof(product)); } void API_NS(precompute) ( precomputed_s *table, const point_t base ) { const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S; assert(n*t*s >= SCALAR_BITS); point_t working, start, doubles[t-1]; API_NS(point_copy)(working, base); pniels_t pn_tmp; gf zs[n<<(t-1)], zis[n<<(t-1)]; unsigned int i,j,k; /* Compute n tables */ for (i=0; i>1); int idx = (((i+1)<<(t-1))-1) ^ gray; pt_to_pniels(pn_tmp, start); memcpy(table->table[idx], pn_tmp->n, sizeof(pn_tmp->n)); cryptonite_gf_copy(zs[idx], pn_tmp->z); if (j >= (1u<<(t-1)) - 1) break; int delta = (j+1) ^ ((j+1)>>1) ^ gray; for (k=0; delta>1; k++) delta >>=1; if (gray & (1<table,(const gf *)zs,zis,n<<(t-1)); cryptonite_decaf_bzero(zs,sizeof(zs)); cryptonite_decaf_bzero(zis,sizeof(zis)); cryptonite_decaf_bzero(pn_tmp,sizeof(pn_tmp)); cryptonite_decaf_bzero(working,sizeof(working)); cryptonite_decaf_bzero(start,sizeof(start)); cryptonite_decaf_bzero(doubles,sizeof(doubles)); } static CRYPTONITE_DECAF_INLINE void constant_time_lookup_niels ( niels_s *__restrict__ ni, const niels_t *table, int nelts, int idx ) { constant_time_lookup(ni, table, sizeof(niels_s), nelts, idx); } void API_NS(precomputed_scalarmul) ( point_t out, const precomputed_s *table, const scalar_t scalar ) { int i; unsigned j,k; const unsigned int n = COMBS_N, t = COMBS_T, s = COMBS_S; scalar_t scalar1x; API_NS(scalar_add)(scalar1x, scalar, precomputed_scalarmul_adjustment); API_NS(scalar_halve)(scalar1x,scalar1x); niels_t ni; for (i=s-1; i>=0; i--) { if (i != (int)s-1) point_double_internal(out,out,0); for (j=0; jlimb[bit/WBITS] >> (bit%WBITS) & 1) << k; } } mask_t invert = (tab>>(t-1))-1; tab ^= invert; tab &= (1<<(t-1)) - 1; constant_time_lookup_niels(ni, &table->table[j<<(t-1)], 1<<(t-1), tab); cond_neg_niels(ni, invert); if ((i!=(int)s-1)||j) { add_niels_to_pt(out, ni, j==n-1 && i); } else { niels_to_pt(out, ni); } } } cryptonite_decaf_bzero(ni,sizeof(ni)); cryptonite_decaf_bzero(scalar1x,sizeof(scalar1x)); } void API_NS(point_cond_sel) ( point_t out, const point_t a, const point_t b, cryptonite_decaf_bool_t pick_b ) { constant_time_select(out,a,b,sizeof(point_t),bool_to_mask(pick_b),0); } /* FUTURE: restore Curve25519 Montgomery ladder? */ cryptonite_decaf_error_t API_NS(direct_scalarmul) ( uint8_t scaled[SER_BYTES], const uint8_t base[SER_BYTES], const scalar_t scalar, cryptonite_decaf_bool_t allow_identity, cryptonite_decaf_bool_t short_circuit ) { point_t basep; cryptonite_decaf_error_t succ = API_NS(point_decode)(basep, base, allow_identity); if (short_circuit && succ != CRYPTONITE_DECAF_SUCCESS) return succ; API_NS(point_cond_sel)(basep, API_NS(point_base), basep, succ); API_NS(point_scalarmul)(basep, basep, scalar); API_NS(point_encode)(scaled, basep); API_NS(point_destroy)(basep); return succ; } void API_NS(point_mul_by_cofactor_and_encode_like_eddsa) ( uint8_t enc[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES], const point_t p ) { /* The point is now on the twisted curve. Move it to untwisted. */ gf x, y, z, t; point_t q; #if COFACTOR == 8 API_NS(point_double)(q,p); #else API_NS(point_copy)(q,p); #endif #if EDDSA_USE_SIGMA_ISOGENY { /* Use 4-isogeny like ed25519: * 2*x*y*sqrt(d/a-1)/(ax^2 + y^2 - 2) * (y^2 - ax^2)/(y^2 + ax^2) * with a = -1, d = -EDWARDS_D: * -2xysqrt(EDWARDS_D-1)/(2z^2-y^2+x^2) * (y^2+x^2)/(y^2-x^2) */ gf u; cryptonite_gf_sqr ( x, q->x ); // x^2 cryptonite_gf_sqr ( t, q->y ); // y^2 cryptonite_gf_add( u, x, t ); // x^2 + y^2 cryptonite_gf_add( z, q->y, q->x ); cryptonite_gf_sqr ( y, z); cryptonite_gf_sub ( y, u, y ); // -2xy cryptonite_gf_sub ( z, t, x ); // y^2 - x^2 cryptonite_gf_sqr ( x, q->z ); cryptonite_gf_add ( t, x, x); cryptonite_gf_sub ( t, t, z); // 2z^2 - y^2 + x^2 cryptonite_gf_mul ( x, y, z ); // 2xy(y^2-x^2) cryptonite_gf_mul ( y, u, t ); // (x^2+y^2)(2z^2-y^2+x^2) cryptonite_gf_mul ( u, z, t ); cryptonite_gf_copy( z, u ); cryptonite_gf_mul ( u, x, SQRT_ONE_MINUS_D ); cryptonite_gf_copy( x, u ); cryptonite_decaf_bzero(u,sizeof(u)); } #elif IMAGINE_TWIST { API_NS(point_double)(q,q); API_NS(point_double)(q,q); cryptonite_gf_mul_qnr(x, q->x); cryptonite_gf_copy(y, q->y); cryptonite_gf_copy(z, q->z); } #else { /* 4-isogeny: 2xy/(y^+x^2), (y^2-x^2)/(2z^2-y^2+x^2) */ gf u; cryptonite_gf_sqr ( x, q->x ); cryptonite_gf_sqr ( t, q->y ); cryptonite_gf_add( u, x, t ); cryptonite_gf_add( z, q->y, q->x ); cryptonite_gf_sqr ( y, z); cryptonite_gf_sub ( y, u, y ); cryptonite_gf_sub ( z, t, x ); cryptonite_gf_sqr ( x, q->z ); cryptonite_gf_add ( t, x, x); cryptonite_gf_sub ( t, t, z); cryptonite_gf_mul ( x, t, y ); cryptonite_gf_mul ( y, z, u ); cryptonite_gf_mul ( z, u, t ); cryptonite_decaf_bzero(u,sizeof(u)); } #endif /* Affinize */ cryptonite_gf_invert(z,z,1); cryptonite_gf_mul(t,x,z); cryptonite_gf_mul(x,y,z); /* Encode */ enc[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES-1] = 0; cryptonite_gf_serialize(enc, x, 1); enc[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES-1] |= 0x80 & cryptonite_gf_lobit(t); cryptonite_decaf_bzero(x,sizeof(x)); cryptonite_decaf_bzero(y,sizeof(y)); cryptonite_decaf_bzero(z,sizeof(z)); cryptonite_decaf_bzero(t,sizeof(t)); API_NS(point_destroy)(q); } cryptonite_decaf_error_t API_NS(point_decode_like_eddsa_and_ignore_cofactor) ( point_t p, const uint8_t enc[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES] ) { uint8_t enc2[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES]; memcpy(enc2,enc,sizeof(enc2)); mask_t low = ~word_is_zero(enc2[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES-1] & 0x80); enc2[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES-1] &= ~0x80; mask_t succ = cryptonite_gf_deserialize(p->y, enc2, 1); #if 0 == 0 succ &= word_is_zero(enc2[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES-1]); #endif cryptonite_gf_sqr(p->x,p->y); cryptonite_gf_sub(p->z,ONE,p->x); /* num = 1-y^2 */ #if EDDSA_USE_SIGMA_ISOGENY cryptonite_gf_mulw(p->t,p->z,EDWARDS_D); /* d-dy^2 */ cryptonite_gf_mulw(p->x,p->z,EDWARDS_D-1); /* num = (1-y^2)(d-1) */ cryptonite_gf_copy(p->z,p->x); #else cryptonite_gf_mulw(p->t,p->x,EDWARDS_D); /* dy^2 */ #endif cryptonite_gf_sub(p->t,ONE,p->t); /* denom = 1-dy^2 or 1-d + dy^2 */ cryptonite_gf_mul(p->x,p->z,p->t); succ &= cryptonite_gf_isr(p->t,p->x); /* 1/sqrt(num * denom) */ cryptonite_gf_mul(p->x,p->t,p->z); /* sqrt(num / denom) */ cryptonite_gf_cond_neg(p->x,~cryptonite_gf_lobit(p->x)^low); cryptonite_gf_copy(p->z,ONE); #if EDDSA_USE_SIGMA_ISOGENY { /* Use 4-isogeny like ed25519: * 2*x*y/sqrt(1-d/a)/(ax^2 + y^2 - 2) * (y^2 - ax^2)/(y^2 + ax^2) * (MAGIC: above formula may be off by a factor of -a * or something somewhere; check it for other a) * * with a = -1, d = -EDWARDS_D: * -2xy/sqrt(1-EDWARDS_D)/(2z^2-y^2+x^2) * (y^2+x^2)/(y^2-x^2) */ gf a, b, c, d; cryptonite_gf_sqr ( c, p->x ); cryptonite_gf_sqr ( a, p->y ); cryptonite_gf_add ( d, c, a ); // x^2 + y^2 cryptonite_gf_add ( p->t, p->y, p->x ); cryptonite_gf_sqr ( b, p->t ); cryptonite_gf_sub ( b, b, d ); // 2xy cryptonite_gf_sub ( p->t, a, c ); // y^2 - x^2 cryptonite_gf_sqr ( p->x, p->z ); cryptonite_gf_add ( p->z, p->x, p->x ); cryptonite_gf_sub ( a, p->z, p->t ); // 2z^2 - y^2 + x^2 cryptonite_gf_mul ( c, a, SQRT_ONE_MINUS_D ); cryptonite_gf_mul ( p->x, b, p->t); // (2xy)(y^2-x^2) cryptonite_gf_mul ( p->z, p->t, c ); // (y^2-x^2)sd(2z^2 - y^2 + x^2) cryptonite_gf_mul ( p->y, d, c ); // (y^2+x^2)sd(2z^2 - y^2 + x^2) cryptonite_gf_mul ( p->t, d, b ); cryptonite_decaf_bzero(a,sizeof(a)); cryptonite_decaf_bzero(b,sizeof(b)); cryptonite_decaf_bzero(c,sizeof(c)); cryptonite_decaf_bzero(d,sizeof(d)); } #elif IMAGINE_TWIST { cryptonite_gf_mul(p->t,p->x,SQRT_MINUS_ONE); cryptonite_gf_copy(p->x,p->t); cryptonite_gf_mul(p->t,p->x,p->y); } #else { /* 4-isogeny 2xy/(y^2-ax^2), (y^2+ax^2)/(2-y^2-ax^2) */ gf a, b, c, d; cryptonite_gf_sqr ( c, p->x ); cryptonite_gf_sqr ( a, p->y ); cryptonite_gf_add ( d, c, a ); cryptonite_gf_add ( p->t, p->y, p->x ); cryptonite_gf_sqr ( b, p->t ); cryptonite_gf_sub ( b, b, d ); cryptonite_gf_sub ( p->t, a, c ); cryptonite_gf_sqr ( p->x, p->z ); cryptonite_gf_add ( p->z, p->x, p->x ); cryptonite_gf_sub ( a, p->z, d ); cryptonite_gf_mul ( p->x, a, b ); cryptonite_gf_mul ( p->z, p->t, a ); cryptonite_gf_mul ( p->y, p->t, d ); cryptonite_gf_mul ( p->t, b, d ); cryptonite_decaf_bzero(a,sizeof(a)); cryptonite_decaf_bzero(b,sizeof(b)); cryptonite_decaf_bzero(c,sizeof(c)); cryptonite_decaf_bzero(d,sizeof(d)); } #endif cryptonite_decaf_bzero(enc2,sizeof(enc2)); assert(API_NS(point_valid)(p) || ~succ); return cryptonite_decaf_succeed_if(mask_to_bool(succ)); } cryptonite_decaf_error_t cryptonite_decaf_x448 ( uint8_t out[X_PUBLIC_BYTES], const uint8_t base[X_PUBLIC_BYTES], const uint8_t scalar[X_PRIVATE_BYTES] ) { gf x1, x2, z2, x3, z3, t1, t2; ignore_result(cryptonite_gf_deserialize(x1,base,1)); cryptonite_gf_copy(x2,ONE); cryptonite_gf_copy(z2,ZERO); cryptonite_gf_copy(x3,x1); cryptonite_gf_copy(z3,ONE); int t; mask_t swap = 0; for (t = X_PRIVATE_BITS-1; t>=0; t--) { uint8_t sb = scalar[t/8]; /* Scalar conditioning */ if (t/8==0) sb &= -(uint8_t)COFACTOR; else if (t == X_PRIVATE_BITS-1) sb = -1; mask_t k_t = (sb>>(t%8)) & 1; k_t = -k_t; /* set to all 0s or all 1s */ swap ^= k_t; cryptonite_gf_cond_swap(x2,x3,swap); cryptonite_gf_cond_swap(z2,z3,swap); swap = k_t; cryptonite_gf_add_nr(t1,x2,z2); /* A = x2 + z2 */ /* 2+e */ cryptonite_gf_sub_nr(t2,x2,z2); /* B = x2 - z2 */ /* 3+e */ cryptonite_gf_sub_nr(z2,x3,z3); /* D = x3 - z3 */ /* 3+e */ cryptonite_gf_mul(x2,t1,z2); /* DA */ cryptonite_gf_add_nr(z2,z3,x3); /* C = x3 + z3 */ /* 2+e */ cryptonite_gf_mul(x3,t2,z2); /* CB */ cryptonite_gf_sub_nr(z3,x2,x3); /* DA-CB */ /* 3+e */ cryptonite_gf_sqr(z2,z3); /* (DA-CB)^2 */ cryptonite_gf_mul(z3,x1,z2); /* z3 = x1(DA-CB)^2 */ cryptonite_gf_add_nr(z2,x2,x3); /* (DA+CB) */ /* 2+e */ cryptonite_gf_sqr(x3,z2); /* x3 = (DA+CB)^2 */ cryptonite_gf_sqr(z2,t1); /* AA = A^2 */ cryptonite_gf_sqr(t1,t2); /* BB = B^2 */ cryptonite_gf_mul(x2,z2,t1); /* x2 = AA*BB */ cryptonite_gf_sub_nr(t2,z2,t1); /* E = AA-BB */ /* 3+e */ cryptonite_gf_mulw(t1,t2,-EDWARDS_D); /* E*-d = a24*E */ cryptonite_gf_add_nr(t1,t1,z2); /* AA + a24*E */ /* 2+e */ cryptonite_gf_mul(z2,t2,t1); /* z2 = E(AA+a24*E) */ } /* Finish */ cryptonite_gf_cond_swap(x2,x3,swap); cryptonite_gf_cond_swap(z2,z3,swap); cryptonite_gf_invert(z2,z2,0); cryptonite_gf_mul(x1,x2,z2); cryptonite_gf_serialize(out,x1,1); mask_t nz = ~cryptonite_gf_eq(x1,ZERO); cryptonite_decaf_bzero(x1,sizeof(x1)); cryptonite_decaf_bzero(x2,sizeof(x2)); cryptonite_decaf_bzero(z2,sizeof(z2)); cryptonite_decaf_bzero(x3,sizeof(x3)); cryptonite_decaf_bzero(z3,sizeof(z3)); cryptonite_decaf_bzero(t1,sizeof(t1)); cryptonite_decaf_bzero(t2,sizeof(t2)); return cryptonite_decaf_succeed_if(mask_to_bool(nz)); } /* Thanks Johan Pascal */ void cryptonite_decaf_ed448_convert_public_key_to_x448 ( uint8_t x[CRYPTONITE_DECAF_X448_PUBLIC_BYTES], const uint8_t ed[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES] ) { gf y; { uint8_t enc2[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES]; memcpy(enc2,ed,sizeof(enc2)); /* retrieve y from the ed compressed point */ enc2[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES-1] &= ~0x80; ignore_result(cryptonite_gf_deserialize(y, enc2, 0)); cryptonite_decaf_bzero(enc2,sizeof(enc2)); } { gf n,d; #if EDDSA_USE_SIGMA_ISOGENY /* u = (1+y)/(1-y)*/ cryptonite_gf_add(n, y, ONE); /* n = y+1 */ cryptonite_gf_sub(d, ONE, y); /* d = 1-y */ cryptonite_gf_invert(d, d, 0); /* d = 1/(1-y) */ cryptonite_gf_mul(y, n, d); /* u = (y+1)/(1-y) */ cryptonite_gf_serialize(x,y,1); #else /* EDDSA_USE_SIGMA_ISOGENY */ /* u = y^2 * (1-dy^2) / (1-y^2) */ cryptonite_gf_sqr(n,y); /* y^2*/ cryptonite_gf_sub(d,ONE,n); /* 1-y^2*/ cryptonite_gf_invert(d,d,0); /* 1/(1-y^2)*/ cryptonite_gf_mul(y,n,d); /* y^2 / (1-y^2) */ cryptonite_gf_mulw(d,n,EDWARDS_D); /* dy^2*/ cryptonite_gf_sub(d, ONE, d); /* 1-dy^2*/ cryptonite_gf_mul(n, y, d); /* y^2 * (1-dy^2) / (1-y^2) */ cryptonite_gf_serialize(x,n,1); #endif /* EDDSA_USE_SIGMA_ISOGENY */ cryptonite_decaf_bzero(y,sizeof(y)); cryptonite_decaf_bzero(n,sizeof(n)); cryptonite_decaf_bzero(d,sizeof(d)); } } void cryptonite_decaf_x448_generate_key ( uint8_t out[X_PUBLIC_BYTES], const uint8_t scalar[X_PRIVATE_BYTES] ) { cryptonite_decaf_x448_derive_public_key(out,scalar); } void cryptonite_decaf_x448_derive_public_key ( uint8_t out[X_PUBLIC_BYTES], const uint8_t scalar[X_PRIVATE_BYTES] ) { /* Scalar conditioning */ uint8_t scalar2[X_PRIVATE_BYTES]; memcpy(scalar2,scalar,sizeof(scalar2)); scalar2[0] &= -(uint8_t)COFACTOR; scalar2[X_PRIVATE_BYTES-1] &= ~(-1u<<((X_PRIVATE_BITS+7)%8)); scalar2[X_PRIVATE_BYTES-1] |= 1<<((X_PRIVATE_BITS+7)%8); scalar_t the_scalar; API_NS(scalar_decode_long)(the_scalar,scalar2,sizeof(scalar2)); /* We're gonna isogenize by 2, so divide by 2. * * Why by 2, even though it's a 4-isogeny? * * The isogeny map looks like * Montgomery <-2-> Jacobi <-2-> Edwards * * Since the Jacobi base point is the PREimage of the iso to * the Montgomery curve, and we're going * Jacobi -> Edwards -> Jacobi -> Montgomery, * we pick up only a factor of 2 over Jacobi -> Montgomery. */ API_NS(scalar_halve)(the_scalar,the_scalar); point_t p; API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),the_scalar); /* Isogenize to Montgomery curve. * * Why isn't this just a separate function, eg cryptonite_decaf_encode_like_x448? * Basically because in general it does the wrong thing if there is a cofactor * component in the input. In this function though, there isn't a cofactor * component in the input. */ cryptonite_gf_invert(p->t,p->x,0); /* 1/x */ cryptonite_gf_mul(p->z,p->t,p->y); /* y/x */ cryptonite_gf_sqr(p->y,p->z); /* (y/x)^2 */ #if IMAGINE_TWIST cryptonite_gf_sub(p->y,ZERO,p->y); #endif cryptonite_gf_serialize(out,p->y,1); cryptonite_decaf_bzero(scalar2,sizeof(scalar2)); API_NS(scalar_destroy)(the_scalar); API_NS(point_destroy)(p); } /** * @cond internal * Control for variable-time scalar multiply algorithms. */ struct smvt_control { int power, addend; }; static int recode_wnaf ( struct smvt_control *control, /* [nbits/(table_bits+1) + 3] */ const scalar_t scalar, unsigned int table_bits ) { unsigned int table_size = SCALAR_BITS/(table_bits+1) + 3; int position = table_size - 1; /* at the end */ /* place the end marker */ control[position].power = -1; control[position].addend = 0; position--; /* PERF: Could negate scalar if it's large. But then would need more cases * in the actual code that uses it, all for an expected reduction of like 1/5 op. * Probably not worth it. */ uint64_t current = scalar->limb[0] & 0xFFFF; uint32_t mask = (1<<(table_bits+1))-1; unsigned int w; const unsigned int B_OVER_16 = sizeof(scalar->limb[0]) / 2; for (w = 1; w<(SCALAR_BITS-1)/16+3; w++) { if (w < (SCALAR_BITS-1)/16+1) { /* Refill the 16 high bits of current */ current += (uint32_t)((scalar->limb[w/B_OVER_16]>>(16*(w%B_OVER_16)))<<16); } while (current & 0xFFFF) { assert(position >= 0); uint32_t pos = __builtin_ctz((uint32_t)current), odd = (uint32_t)current >> pos; int32_t delta = odd & mask; if (odd & 1<<(table_bits+1)) delta -= (1<<(table_bits+1)); current -= delta << pos; control[position].power = pos + 16*(w-1); control[position].addend = delta; position--; } current >>= 16; } assert(current==0); position++; unsigned int n = table_size - position; unsigned int i; for (i=0; in, sizeof(niels_t)); cryptonite_gf_copy(zs[i], tmp[i]->z); } batch_normalize_niels(out, (const gf *)zs, zis, 1< control_pre[0].power) { pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]); contv++; } else if (i == control_pre[0].power && i >=0 ) { pniels_to_pt(combo, precmp_var[control_var[0].addend >> 1]); add_niels_to_pt(combo, API_NS(wnaf_base)[control_pre[0].addend >> 1], i); contv++; contp++; } else { i = control_pre[0].power; niels_to_pt(combo, API_NS(wnaf_base)[control_pre[0].addend >> 1]); contp++; } for (i--; i >= 0; i--) { int cv = (i==control_var[contv].power), cp = (i==control_pre[contp].power); point_double_internal(combo,combo,i && !(cv||cp)); if (cv) { assert(control_var[contv].addend); if (control_var[contv].addend > 0) { add_pniels_to_pt(combo, precmp_var[control_var[contv].addend >> 1], i&&!cp); } else { sub_pniels_from_pt(combo, precmp_var[(-control_var[contv].addend) >> 1], i&&!cp); } contv++; } if (cp) { assert(control_pre[contp].addend); if (control_pre[contp].addend > 0) { add_niels_to_pt(combo, API_NS(wnaf_base)[control_pre[contp].addend >> 1], i); } else { sub_niels_from_pt(combo, API_NS(wnaf_base)[(-control_pre[contp].addend) >> 1], i); } contp++; } } /* This function is non-secret, but whatever this is cheap. */ cryptonite_decaf_bzero(control_var,sizeof(control_var)); cryptonite_decaf_bzero(control_pre,sizeof(control_pre)); cryptonite_decaf_bzero(precmp_var,sizeof(precmp_var)); assert(contv == ncb_var); (void)ncb_var; assert(contp == ncb_pre); (void)ncb_pre; } void API_NS(point_destroy) ( point_t point ) { cryptonite_decaf_bzero(point, sizeof(point_t)); } void API_NS(precomputed_destroy) ( precomputed_s *pre ) { cryptonite_decaf_bzero(pre, API_NS(sizeof_precomputed_s)); } cryptonite-0.26/cbits/p256/p256.h0000644000000000000000000001366313414232447014511 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.26/cbits/blake2/ref/blake2.h0000644000000000000000000001446713414232447016400 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.26/cbits/blake2/ref/blake2-impl.h0000644000000000000000000001015113470442731017322 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 )((( uint32_t )( p[0] ) << 0) | (( uint32_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.26/cbits/blake2/sse/blake2b-load-sse2.h0000644000000000000000000001141313414232447020333 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.26/cbits/blake2/sse/blake2b-round.h0000644000000000000000000001156713414232447017703 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.26/cbits/blake2/sse/blake2s-load-sse41.h0000644000000000000000000001546113414232447020446 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.26/cbits/blake2/sse/blake2s-load-xop.h0000644000000000000000000002004713414232447020311 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.26/cbits/blake2/sse/blake2s-round.h0000644000000000000000000000552213414232447017716 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.26/cbits/blake2/sse/blake2.h0000644000000000000000000001446713414232447016416 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.26/cbits/blake2/sse/blake2b-load-sse41.h0000644000000000000000000001474613414232447020432 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.26/cbits/blake2/sse/blake2s-load-sse2.h0000644000000000000000000000601713414232447020360 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.26/cbits/blake2/sse/blake2-config.h0000644000000000000000000000253013414232447017645 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.26/cbits/blake2/sse/blake2-impl.h0000644000000000000000000001015113470442731017340 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 )((( uint32_t )( p[0] ) << 0) | (( uint32_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.26/cbits/argon2/blamka-round-ref.h0000644000000000000000000000525213414232447017632 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.26/cbits/argon2/core.h0000644000000000000000000002067013414232447015435 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.26/cbits/argon2/argon2.h0000644000000000000000000002115713414232447015676 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.26/cbits/argon2/blamka-round-opt.h0000644000000000000000000002563713414232447017671 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.26/cbits/argon2/thread.h0000644000000000000000000000453513414232447015756 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.26/cbits/argon2/opt.h0000644000000000000000000000245513414232447015310 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.26/cbits/argon2/ref.h0000644000000000000000000000237713414232447015265 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.26/cbits/argon2/opt.c0000644000000000000000000001443313414232447015302 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.26/cbits/argon2/thread.c0000644000000000000000000000305213414232447015742 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.26/cbits/argon2/ref.c0000644000000000000000000001530013414232447015246 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.26/cbits/argon2/core.c0000644000000000000000000005300013414232447015421 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.26/cbits/aes/x86ni_impl.c0000644000000000000000000002147313414232447016057 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); }