packages feed

cryptocipher 0.4.0 → 0.5.0

raw patch · 15 files changed

+15/−1086 lines, 15 filesdep −crypto-pubkey-typesdep −taggedPVP ok

version bump matches the API change (PVP)

Dependencies removed: crypto-pubkey-types, tagged

API changes (from Hackage documentation)

- Crypto.Cipher.DH: data PrivateNumber :: *
- Crypto.Cipher.DH: data PublicNumber :: *
- Crypto.Cipher.DH: data SharedKey :: *
- Crypto.Cipher.DH: generateParams :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Params, g)
- Crypto.Cipher.DH: generatePrivate :: CryptoRandomGen g => g -> Int -> Either GenError (PrivateNumber, g)
- Crypto.Cipher.DH: generatePublic :: Params -> PrivateNumber -> PublicNumber
- Crypto.Cipher.DH: getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey
- Crypto.Cipher.DH: type Params = (Integer, Integer)
- Crypto.Cipher.DSA: InvalidSignature :: Error
- Crypto.Cipher.DSA: PrivateKey :: Params -> Integer -> PrivateKey
- Crypto.Cipher.DSA: PublicKey :: Params -> Integer -> PublicKey
- Crypto.Cipher.DSA: RandomGenFailure :: GenError -> Error
- Crypto.Cipher.DSA: data Error
- Crypto.Cipher.DSA: data PrivateKey :: *
- Crypto.Cipher.DSA: data PublicKey :: *
- Crypto.Cipher.DSA: instance Eq Error
- Crypto.Cipher.DSA: instance Show Error
- Crypto.Cipher.DSA: private_params :: PrivateKey -> Params
- Crypto.Cipher.DSA: private_x :: PrivateKey -> Integer
- Crypto.Cipher.DSA: public_params :: PublicKey -> Params
- Crypto.Cipher.DSA: public_y :: PublicKey -> Integer
- Crypto.Cipher.DSA: sign :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> PrivateKey -> ByteString -> Either GenError (Signature, g)
- Crypto.Cipher.DSA: type Params = (Integer, Integer, Integer)
- Crypto.Cipher.DSA: type Signature = (Integer, Integer)
- Crypto.Cipher.DSA: verify :: Signature -> (ByteString -> ByteString) -> PublicKey -> ByteString -> Either Error Bool
- Crypto.Cipher.RSA: KeyInternalError :: Error
- Crypto.Cipher.RSA: MessageNotRecognized :: Error
- Crypto.Cipher.RSA: MessageSizeIncorrect :: Error
- Crypto.Cipher.RSA: MessageTooLong :: Error
- Crypto.Cipher.RSA: PrivateKey :: PublicKey -> Integer -> Integer -> Integer -> Integer -> Integer -> Integer -> PrivateKey
- Crypto.Cipher.RSA: PublicKey :: Int -> Integer -> Integer -> PublicKey
- Crypto.Cipher.RSA: RandomGenFailure :: GenError -> Error
- Crypto.Cipher.RSA: SignatureTooLong :: Error
- Crypto.Cipher.RSA: data Error
- Crypto.Cipher.RSA: data PrivateKey :: *
- Crypto.Cipher.RSA: data PublicKey :: *
- Crypto.Cipher.RSA: decrypt :: PrivateKey -> ByteString -> Either Error ByteString
- Crypto.Cipher.RSA: encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> Either Error (ByteString, g)
- Crypto.Cipher.RSA: generate :: CryptoRandomGen g => g -> Int -> Integer -> Either Error ((PublicKey, PrivateKey), g)
- Crypto.Cipher.RSA: instance Eq Error
- Crypto.Cipher.RSA: instance Show Error
- Crypto.Cipher.RSA: private_d :: PrivateKey -> Integer
- Crypto.Cipher.RSA: private_dP :: PrivateKey -> Integer
- Crypto.Cipher.RSA: private_dQ :: PrivateKey -> Integer
- Crypto.Cipher.RSA: private_p :: PrivateKey -> Integer
- Crypto.Cipher.RSA: private_pub :: PrivateKey -> PublicKey
- Crypto.Cipher.RSA: private_q :: PrivateKey -> Integer
- Crypto.Cipher.RSA: private_qinv :: PrivateKey -> Integer
- Crypto.Cipher.RSA: public_e :: PublicKey -> Integer
- Crypto.Cipher.RSA: public_n :: PublicKey -> Integer
- Crypto.Cipher.RSA: public_size :: PublicKey -> Int
- Crypto.Cipher.RSA: sign :: HashF -> HashASN1 -> PrivateKey -> ByteString -> Either Error ByteString
- Crypto.Cipher.RSA: type HashASN1 = ByteString
- Crypto.Cipher.RSA: type HashF = ByteString -> ByteString
- Crypto.Cipher.RSA: verify :: HashF -> HashASN1 -> PublicKey -> ByteString -> ByteString -> Either Error Bool

Files

Crypto/Cipher/AES.hs view
@@ -5,6 +5,13 @@ -- Maintainer  : Vincent Hanquez <vincent@snarc.org> -- Stability   : experimental -- Portability : Good+--+-- This module just re-export Crypto.Cipher.AES from the+-- cipher-aes module.+--+-- Documentation can be found at+-- <http://hackage.haskell.org/package/cipher-aes>+--  module Crypto.Cipher.AES 	( module Crypto.Cipher.AES
− Crypto/Cipher/DH.hs
@@ -1,46 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---- |--- Module      : Crypto.Cipher.DH--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good----module Crypto.Cipher.DH {-# DEPRECATED "Use crypto-pubkey Crypto.PubKey.DH" #-}-	( Params-	, PublicNumber-	, PrivateNumber-	, SharedKey-	, generateParams-	, generatePrivate-	, generatePublic-	, getShared-	) where--import Number.ModArithmetic (exponantiation)-import Number.Prime (generateSafePrime)-import Number.Generate (generateOfSize)-import Crypto.Types.PubKey.DH-import Crypto.Random-import Control.Arrow (first)---- | 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 :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Params, g)-generateParams rng bits generator =-	either Left (Right . first (\p -> (p, generator))) $ generateSafePrime rng bits---- | generate a private number with no specific property--- this number is usually called X in DH text.-generatePrivate :: CryptoRandomGen g => g -> Int -> Either GenError (PrivateNumber, g)-generatePrivate rng bits = either Left (Right . first PrivateNumber) $ generateOfSize rng bits---- | generate a public number that is for the other party benefits.--- this number is usually called Y in DH text.-generatePublic :: Params -> PrivateNumber -> PublicNumber-generatePublic (p,g) (PrivateNumber x) = PublicNumber $ exponantiation g x p---- | generate a shared key using our private number and the other party public number-getShared :: Params -> PrivateNumber -> PublicNumber -> SharedKey-getShared (p,_) (PrivateNumber x) (PublicNumber y) = SharedKey $ exponantiation y x p
− Crypto/Cipher/DSA.hs
@@ -1,67 +0,0 @@--- |--- Module      : Crypto.Cipher.DSA--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good-----module Crypto.Cipher.DSA {-# DEPRECATED "Use crypto-pubkey Crypto.PubKey.DSA" #-}-	( Error(..)-	, Params-	, Signature-	, PublicKey(..)-	, PrivateKey(..)-	, sign-	, verify-	) where--import Crypto.Random-import Data.Maybe-import Data.ByteString (ByteString)-import Number.ModArithmetic (exponantiation, inverse)-import Number.Serialize-import Number.Generate-import Crypto.Types.PubKey.DSA--data Error = -	  InvalidSignature          -- ^ signature is not valid r or s is not between the bound 0..q-	| RandomGenFailure GenError -- ^ the random generator returns an error. give the opportunity to reseed for example.-	deriving (Show,Eq)--{-| sign message using the private key. -}-sign :: CryptoRandomGen g => g -> (ByteString -> ByteString) -> PrivateKey -> ByteString -> Either GenError (Signature, g)-sign rng hash pk m =-	-- Recalculate the signature in the unlikely case that r = 0 or s = 0-	case generateMax rng q of-		Left err        -> Left err-		Right (k, rng') ->-			let kinv = fromJust $ inverse k q in-			let r    = expmod g k p `mod` q in-			let s    = (kinv * (hm + x * r)) `mod` q in-			if r == 0 || s == 0-				then sign rng' hash pk m-				else Right ((r, s), rng')-	where-		(p,g,q)   = private_params pk-		x         = private_x pk-		hm        = os2ip $ hash m--{- | verify a bytestring using the public key. -}-verify :: Signature -> (ByteString -> ByteString) -> PublicKey -> ByteString -> Either Error Bool-verify (r,s) hash pk m-	-- Reject the signature if either 0 < r <q or 0 < s < q is not satisfied.-	| r <= 0 || r >= q || s <= 0 || s >= q = Left InvalidSignature-	| otherwise                            = Right $ v == r-	where-		(p,g,q) = public_params pk-		y       = public_y pk-		hm      = os2ip $ hash m--		w       = fromJust $ inverse s q-		u1      = (hm*w) `mod` q-		u2      = (r*w) `mod` q-		v       = ((expmod g u1 p) * (expmod y u2 p)) `mod` p `mod` q--expmod :: Integer -> Integer -> Integer -> Integer-expmod = exponantiation
− Crypto/Cipher/ElGamal.hs
@@ -1,73 +0,0 @@--- |--- Module      : Crypto.Cipher.ElGamal--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- 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----module Crypto.Cipher.ElGamal {-# DEPRECATED "Use crypto-pubkey Crypto.PubKey.ElGamal" #-}-	( Params-	, PublicNumber-	, PrivateNumber-	, SharedKey-    , generatePrivate-    , generatePublic-    , encryptWith-    , encrypt-    , decrypt-{--    , sign-    , verify--}-    ) where--import Number.ModArithmetic (exponantiation, inverse)-import Number.Generate (generateOfSize)-import Crypto.Types.PubKey.DH-import Crypto.Random-import Control.Arrow (first)-import Control.Applicative ((<$>))-import Data.Maybe (fromJust)---- | generate a private number with no specific property--- this number is usually called a.--- --- FIXME replace generateOfSize by generateBetween [0, q-1]-generatePrivate :: CryptoRandomGen g => g -> Int -> Either GenError (PrivateNumber, g)-generatePrivate rng bits = either Left (Right . first PrivateNumber) $ generateOfSize rng bits---- | generate a public number that is for the other party benefits.--- this number is usually called h=g^a-generatePublic :: Params -> PrivateNumber -> PublicNumber-generatePublic (p,g) (PrivateNumber a) = PublicNumber $ exponantiation g a p---- | encrypt with a specified ephemeral key--- do not reuse ephemeral key.-encryptWith :: PrivateNumber -> Params -> PublicNumber -> Integer -> (Integer,Integer)-encryptWith (PrivateNumber b) (p,g) (PublicNumber h) m = (c1,c2)-    where s  = exponantiation h b p-          c1 = exponantiation g b p-          c2 = (s * m) `mod` p---- | encrypt a message using params and public keys--- will generate b (called the ephemeral key)-encrypt :: CryptoRandomGen g => g -> Params -> PublicNumber -> Integer -> Either GenError ((Integer,Integer), g)-encrypt rng params public m = (\(b,rng') -> (encryptWith b params public m,rng')) <$> generatePrivate rng 1024---- | decrypt message-decrypt :: Params -> PrivateNumber -> (Integer, Integer) -> Integer-decrypt (p,_) (PrivateNumber a) (c1,c2) = (c2 * sm1) `mod` p-    where s   = exponantiation c1 a p-          sm1 = fromJust $ inverse s p -- always inversible in Zp--{--sign = undefined--verify = undefined--}
Crypto/Cipher/RC4.hs view
@@ -5,6 +5,12 @@ -- Stability   : experimental -- Portability : Good --+-- This module just re-export Crypto.Cipher.RC4 from the+-- cipher-rc4 module.+--+-- Documentation can be found at+-- <http://hackage.haskell.org/package/cipher-rc4>+--  {-# LANGUAGE PackageImports #-} module Crypto.Cipher.RC4 (module Crypto.Cipher.RC4) where
− Crypto/Cipher/RSA.hs
@@ -1,180 +0,0 @@-{-# LANGUAGE FlexibleInstances, CPP #-}---- |--- Module      : Crypto.Cipher.RSA--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good----module Crypto.Cipher.RSA {-# DEPRECATED "Use crypto-pubkey Crypto.PubKey.RSA" #-}-	( Error(..)-	, PublicKey(..)-	, PrivateKey(..)-	, HashF-	, HashASN1-	, generate-	, decrypt-	, encrypt-	, sign-	, verify-	) where--import Control.Arrow (first)-import Crypto.Random-import Crypto.Types.PubKey.RSA-import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import Number.ModArithmetic (exponantiation, inverse)-import Number.Prime (generatePrime)-import Number.Serialize-import Data.Maybe (fromJust)--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 (>= private_size - 11)-	| MessageNotRecognized      -- ^ the message decrypted doesn't have a PKCS15 structure (0 2 .. 0 msg)-	| SignatureTooLong          -- ^ the signature generated through the hash is too long to process with this key-	| RandomGenFailure GenError -- ^ the random generator returns an error. give the opportunity to reseed for example.-	| KeyInternalError          -- ^ the whole key is probably not valid, since the message is bigger than the key size-	deriving (Show,Eq)--type HashF = ByteString -> ByteString-type HashASN1 = ByteString--#if ! (MIN_VERSION_base(4,3,0))-instance Monad (Either Error) where-	return          = Right-	(Left x) >>= _  = Left x-	(Right x) >>= f = f x-#endif--padPKCS1 :: CryptoRandomGen g => g -> Int -> ByteString -> Either Error (ByteString, g)-padPKCS1 rng len m = do-	(padding, rng') <- getRandomBytes rng (len - B.length m - 3)-	return (B.concat [ B.singleton 0, B.singleton 2, padding, B.singleton 0, m ], rng')--unpadPKCS1 :: ByteString -> Either Error ByteString-unpadPKCS1 packed-	| signal_error = Left MessageNotRecognized-	| otherwise    = Right m-	where-		(zt, ps0m)   = B.splitAt 2 packed-		(ps, zm)     = B.span (/= 0) ps0m-		(z, m)       = B.splitAt 1 zm-		signal_error = (B.unpack zt /= [0, 2]) || (B.unpack z /= [0]) || (B.length ps < 8)--{- dpSlow computes the decrypted message not using any precomputed cache value.-   only n and d need to valid. -}-dpSlow :: PrivateKey -> ByteString -> Either Error ByteString-dpSlow pk c = i2ospOf (private_size pk) $ expmod (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 :: PrivateKey -> ByteString -> Either Error ByteString-dpFast pk c = i2ospOf (private_size pk) (m2 + h * (private_q pk))-	where-		iC = os2ip c-		m1 = expmod iC (private_dP pk) (private_p pk)-		m2 = expmod iC (private_dQ pk) (private_q pk)-		h  = ((private_qinv pk) * (m1 - m2)) `mod` (private_p pk)--{-| decrypt message using the private key. -}-decrypt :: PrivateKey -> ByteString -> Either Error ByteString-decrypt pk c-	| B.length c /= (private_size pk) = Left MessageSizeIncorrect-	| otherwise                       = dp pk c >>= unpadPKCS1-		where dp = if private_p pk /= 0 && private_q pk /= 0 then dpFast else dpSlow--{- | encrypt a bytestring using the public key and a CryptoRandomGen random generator.- - the message need to be smaller than the key size - 11- -}-encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> Either Error (ByteString, g)-encrypt rng pk m-	| B.length m > public_size pk - 11 = Left MessageTooLong-	| otherwise                        = do-		(em, rng') <- padPKCS1 rng (public_size pk) m-		c          <- i2ospOf (public_size pk) $ expmod (os2ip em) (public_e pk) (public_n pk)-		return (c, rng')--{-| sign message using private key, a hash and its ASN1 description -}-sign :: HashF -> HashASN1 -> PrivateKey -> ByteString -> Either Error ByteString-sign hash hashdesc pk m = makeSignature hash hashdesc (private_size pk) m >>= d pk-	where d = if private_p pk /= 0 && private_q pk /= 0 then dpFast else dpSlow--{-| verify message with the signed message -}-verify :: HashF -> HashASN1 -> PublicKey -> ByteString -> ByteString -> Either Error Bool-verify hash hashdesc pk m sm = do-	s  <- makeSignature hash hashdesc (public_size pk) m-	em <- i2ospOf (public_size pk) $ expmod (os2ip sm) (public_e pk) (public_n pk)-	Right (s == em)---- | generate a pair of (private, public) key of size in bytes.-generate :: CryptoRandomGen g => g -> Int -> Integer -> Either Error ((PublicKey, PrivateKey), g)-generate rng size e = do-	((p,q), rng') <- generatePQ rng-	let n   = p * q-	let phi = (p-1)*(q-1)-	case inverse e phi of-		Nothing -> generate rng' size e-		Just d  -> do-			let pub = PublicKey-				{ public_size = size-				, public_n    = n-				, public_e    = e-				}-			let priv = 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 = fromJust $ inverse q p -- q and p are coprime, so fromJust is safe.-				}-			Right ((pub, priv), rng')-	where-		generatePQ g = do-			(p, g')  <- genPrime g (8 * (size `div` 2))-			(q, g'') <- generateQ p g'-			return ((p,q), g'')-		generateQ p h = do-			(q, h') <- genPrime h (8 * (size - (size `div` 2)))-			if p == q then generateQ p h' else return (q, h')-		genPrime g sz = either (Left . RandomGenFailure) Right $ generatePrime g sz--{- makeSignature for sign and verify -}-makeSignature :: HashF -> HashASN1 -> Int -> ByteString -> Either Error ByteString-makeSignature hash descr klen m-	| klen < siglen+1 = Left SignatureTooLong-	| otherwise       = Right $ B.concat [B.singleton 0,B.singleton 1,padding,B.singleton 0,signature]-	where-		signature = descr `B.append` hash m-		siglen    = B.length signature-		padding   = B.replicate (klen - siglen - 3) 0xff--{- get random non-null bytes for encryption padding. -}-getRandomBytes :: CryptoRandomGen g => g -> Int -> Either Error (ByteString, g)-getRandomBytes rng n = do-	gend <- either (Left . RandomGenFailure) Right $ genBytes n rng-	let (bytes, rng') = first (B.pack . filter (/= 0) . B.unpack) gend-	let left          = (n - B.length bytes)-	if left == 0-		then return (bytes, rng')-		else getRandomBytes rng' left >>= return . first (B.append bytes)--{- convert a positive integer into a bytestring of specific size.-   if the number is too big, this will returns an error, otherwise it will pad-   the bytestring of 0 -}-i2ospOf :: Int -> Integer -> Either Error ByteString-i2ospOf len m -	| lenbytes < len  = Right $ B.replicate (len - lenbytes) 0 `B.append` bytes-	| lenbytes == len = Right bytes-	| otherwise       = Left KeyInternalError-	where-		lenbytes = B.length bytes-		bytes    = i2osp m--expmod :: Integer -> Integer -> Integer -> Integer-expmod = exponantiation
− Number/Basic.hs
@@ -1,88 +0,0 @@-{-# LANGUAGE BangPatterns #-}--- |--- Module      : Number.Basic--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good--module Number.Basic-	( sqrti-	, gcde-	, gcde_binary-	, areEven-	) where--import Data.Bits---- | sqrti returns two integer (l,b) so that l <= sqrt i <= b--- the implementation is quite naive, use an approximation for the first number--- and use a dichotomy algorithm to compute the bound relatively efficiently.-sqrti :: Integer -> (Integer, Integer)-sqrti i-	| i < 0     = error "cannot compute negative square root"-	| i == 0    = (0,0)-	| i == 1    = (1,1)-	| i == 2    = (1,2)-	| otherwise = loop x0-		where-			nbdigits = length $ show i-			x0n = (if even nbdigits then nbdigits - 2 else nbdigits - 1) `div` 2-			x0  = if even nbdigits then 2 * 10 ^ x0n else 6 * 10 ^ x0n-			loop x = case compare (sq x) i of-				LT -> iterUp x-				EQ -> (x, x)-				GT -> iterDown x-			iterUp lb = if sq ub >= i then iter lb ub else iterUp ub-				where ub = lb * 2-			iterDown ub = if sq lb >= i then iterDown lb else iter lb ub-				where lb = ub `div` 2-			iter lb ub-				| lb == ub   = (lb, ub)-				| lb+1 == ub = (lb, ub)-				| otherwise  =-					let d = (ub - lb) `div` 2 in-					if sq (lb + d) >= i-						then iter lb (ub-d)-						else iter (lb+d) ub-			sq a = a * a---- | get the extended GCD of two integer using integer divMod-gcde :: Integer -> Integer -> (Integer, Integer, Integer)-gcde 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))---- | get the extended GCD of two integer using the extended binary algorithm (HAC 14.61)--- get (x,y,d) where d = gcd(a,b) and x,y satisfying ax + by = d-gcde_binary :: Integer -> Integer -> (Integer, Integer, Integer)-gcde_binary a' b'-	| b' == 0   = (1,0,a')-	| a' >= b'  = compute a' b'-	| otherwise = (\(x,y,d) -> (y,x,d)) $ compute b' a'-	where-		getEvenMultiplier !g !x !y-			| areEven [x,y] = getEvenMultiplier (g `shiftL` 1) (x `shiftR` 1) (y `shiftR` 1)-			| otherwise     = (x,y,g)-		halfLoop !x !y !u !i !j-			| areEven [u,i,j] = halfLoop x y (u `shiftR` 1) (i `shiftR` 1) (j `shiftR` 1)-			| even u          = halfLoop x y (u `shiftR` 1) ((i + y) `shiftR` 1) ((j - x) `shiftR` 1)-			| otherwise       = (u, i, j)-		compute a b =-			let (x,y,g) = getEvenMultiplier 1 a b in-			loop g x y x y 1 0 0 1--		loop g _ _ 0  !v _  _  !c !d = (c, d, g * v)-		loop g x y !u !v !a !b !c !d =-			let (u2,a2,b2) = halfLoop x y u a b in-			let (v2,c2,d2) = halfLoop x y v c d in-			if u2 >= v2-				then loop g x y (u2 - v2) v2 (a2 - c2) (b2 - d2) c2 d2-				else loop g x y u2 (v2 - u2) a2 b2 (c2 - a2) (d2 - b2)---- | check if a list of integer are all even-areEven :: [Integer] -> Bool-areEven = and . map even
− Number/Generate.hs
@@ -1,38 +0,0 @@--- |--- Module      : Number.Generate--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good--module Number.Generate-	( generateMax-	, generateBetween-	, generateOfSize-	) where--import Number.Serialize-import Crypto.Random-import qualified Data.ByteString as B-import Data.Bits ((.|.))---- | generate a positive integer between 0 and m.--- using as many bytes as necessary to the same size as m, that are converted to integer.-generateMax :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)-generateMax rng m = case genBytes (lengthBytes m) rng of-	Left err         -> Left err-	Right (bs, rng') -> Right (os2ip bs `mod` m, rng')---- | generate a number between the inclusive bound [low,high].-generateBetween :: CryptoRandomGen g => g -> Integer -> Integer -> Either GenError (Integer, g)-generateBetween rng low high = case generateMax rng (high - low + 1) of-	Left err        -> Left err-	Right (v, rng') -> Right (low + v, rng')---- | generate a positive integer of a specific size in bits.--- the number of bits need to be multiple of 8. It will always returns--- an integer that is close 2^(1+bits/8) by setting the 2 highest bits to 1.-generateOfSize :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)-generateOfSize rng bits = case genBytes (bits `div` 8) rng of-	Left err         -> Left err-	Right (bs, rng') -> Right (os2ip $ snd $ B.mapAccumL (\acc w -> (0, w .|. acc)) 0xc0 bs, rng')
− Number/ModArithmetic.hs
@@ -1,45 +0,0 @@-{-# LANGUAGE BangPatterns #-}--- |--- Module      : Number.ModArithmetic--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good--module Number.ModArithmetic-	( exponantiation_rtl_binary-	, exponantiation-	, inverse-	) where--import Number.Basic (gcde_binary)-import Data.Bits---- note on exponantiation: 0^0 is treated as 1 for mimicking the standard library;--- the mathematic debate is still open on whether or not this is true, but pratically--- in computer science it shouldn't be useful for anything anyway.---- | exponantiation_rtl_binary computes modular exponantiation as b^e mod m--- using the right-to-left binary exponentiation algorithm (HAC 14.79)-exponantiation_rtl_binary :: Integer -> Integer -> Integer -> Integer-exponantiation_rtl_binary 0 0 m = 1 `mod` m-exponantiation_rtl_binary b e m = loop e b 1-	where-		sq x          = (x * x) `mod` m-		loop !0 _  !a = a `mod` m-		loop !i !s !a = loop (i `shiftR` 1) (sq s) (if odd i then a * s else a)---- | exponantiation computes modular exponantiation as b^e mod m--- using repetitive squaring.-exponantiation :: Integer -> Integer -> Integer -> Integer-exponantiation b e m-             | e == 0    = 1-             | e == 1    = b `mod` m-             | even e    = let p = (exponantiation b (e `div` 2) m) `mod` m-                           in  (p^(2::Integer)) `mod` m-             | otherwise = (b * exponantiation 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 = if d > 1 then Nothing else Just (x `mod` m)-	where (x,_,d) = gcde_binary g m
− Number/Polynomial.hs
@@ -1,133 +0,0 @@-{-# LANGUAGE BangPatterns #-}--- |--- Module      : Number.Polynomial--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good--module Number.Polynomial-	( Monomial(..)-	-- * polynomial operations-	, Polynomial-	, toList-	, fromList-	, addPoly-	, subPoly-	, mulPoly-	, squarePoly-	, expPoly-	, divPoly-	, negPoly-	) where--import Data.List (intercalate, sort)-import Data.Vector ((!), Vector)-import qualified Data.Vector as V-import Control.Arrow (first)--data Monomial = Monomial {-# UNPACK #-} !Int !Integer-	deriving (Eq)--data Polynomial = Polynomial (Vector Monomial)-	deriving (Eq)--instance Ord Monomial where-	compare (Monomial w1 v1) (Monomial w2 v2) =-		case compare w1 w2 of-			EQ -> compare v1 v2-			r  -> r--instance Show Monomial where-	show (Monomial w v) = show v ++ "x^" ++ show w--instance Show Polynomial where-	show (Polynomial p) = intercalate "+" $ map show $ V.toList p--toList :: Polynomial -> [Monomial]-toList (Polynomial p) = V.toList p--fromList :: [Monomial] -> Polynomial-fromList = Polynomial . V.fromList . reverse . sort . filterZero-	where-		filterZero = filter (\(Monomial _ v) -> v /= 0)--getWeight :: Polynomial -> Int -> Maybe Integer-getWeight (Polynomial p) n = look 0-	where-		plen = V.length p-		look !i-			| i >= plen = Nothing-			| otherwise =-				let (Monomial w v) = p ! i in-				case compare w n of-					LT -> Nothing-					EQ -> Just v-					GT -> look (i+1)-		--mergePoly :: (Integer -> Integer -> Integer) -> Polynomial -> Polynomial -> Polynomial-mergePoly f (Polynomial p1) (Polynomial p2) = fromList $ loop 0 0-	where-		l1 = V.length p1-		l2 = V.length p2-		loop !i1 !i2-			| i1 == l1 && i2 == l2 = []-			| i1 == l1             = (p2 ! i2) : loop i1 (i2+1)-			| i2 == l2             = (p1 ! i1) : loop (i1+1) i2-			| otherwise            =-				let (coef, i1inc, i2inc) = addCoef (p1 ! i1) (p2 ! i2) in-				coef : loop (i1+i1inc) (i2+i2inc)-		addCoef m1@(Monomial w1 v1) (Monomial w2 v2) =-			case compare w1 w2 of-				LT -> (Monomial w2 (f 0 v2), 0, 1)-				EQ -> (Monomial w1 (f v1 v2), 1, 1)-				GT -> (m1, 1, 0)--addPoly :: Polynomial -> Polynomial -> Polynomial-addPoly = mergePoly (+)--subPoly :: Polynomial -> Polynomial -> Polynomial-subPoly = mergePoly (-)--negPoly :: Polynomial -> Polynomial-negPoly (Polynomial p) = Polynomial $ V.map negateMonomial p-	where negateMonomial (Monomial w v) = Monomial w (-v)--mulPoly :: Polynomial -> Polynomial -> Polynomial-mulPoly p1@(Polynomial v1) p2@(Polynomial v2) =-	fromList $ filter (\(Monomial _ v) -> v /= 0) $ map (\i -> Monomial i (c i)) $ reverse [0..(m+n)]-	where-		(Monomial m _) = v1 ! 0-		(Monomial n _) = v2 ! 0-		c r = foldl (\acc i -> (b $ r-i) * (a $ i) + acc) 0 [0..r]-			where-				a = maybe 0 id . getWeight p1-				b = maybe 0 id . getWeight p2--squarePoly :: Polynomial -> Polynomial-squarePoly p = p `mulPoly` p--expPoly :: Polynomial -> Integer -> Polynomial-expPoly p e = loop p e-	where-		loop t 0 = t-		loop t n = loop (squarePoly t) (n-1)--divPoly :: Polynomial -> Polynomial -> (Polynomial, Polynomial)-divPoly p1 p2@(Polynomial pp2) = first fromList $ divLoop p1-	where divLoop d1@(Polynomial pp1)-		| V.null pp1 = ([], d1)-		| otherwise  =-			let (Monomial w1 v1) = pp1 ! 0 in-			let (Monomial w2 v2) = pp2 ! 0 in-			let w = w1 - w2 in-			let (v,r) = v1 `divMod` v2 in-			if w >= 0 && r == 0-				then-					let mono = (Monomial w v) in-					let remain = d1 `subPoly` (p2 `mulPoly` (fromList [mono])) in-					let (l, finalRem) = divLoop remain in-					(mono : l, finalRem)-				else-					([], d1)
− Number/Prime.hs
@@ -1,180 +0,0 @@-{-# LANGUAGE BangPatterns #-}--- |--- Module      : Number.Prime--- License     : BSD-style--- Maintainer  : Vincent Hanquez <vincent@snarc.org>--- Stability   : experimental--- Portability : Good--module Number.Prime-	( generatePrime-	, generateSafePrime-	, isProbablyPrime-	, findPrimeFrom-	, findPrimeFromWith-	, primalityTestNaive-	, primalityTestMillerRabin-	, primalityTestFermat-	, isCoprime-	) where--import Crypto.Random-import Data.Bits-import Number.Generate-import Number.Basic (sqrti, gcde_binary)-import Number.ModArithmetic (exponantiation)---- | 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 :: CryptoRandomGen g => g -> Integer -> Either GenError (Bool, g)-isProbablyPrime rng !n-	| any (\p -> p `divides` n) (filter (< n) smallPrimes) = Right (False, rng)-	| primalityTestFermat 50 (n`div`2) n                   = primalityTestMillerRabin rng 30 n-	| otherwise                                            = Right (False, rng)---- | generate a prime number of the required bitsize-generatePrime :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)-generatePrime rng bits = case generateOfSize rng bits of-	Left err         -> Left err-	Right (sp, rng') -> findPrimeFrom rng' sp---- | 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.-generateSafePrime :: CryptoRandomGen g => g -> Int -> Either GenError (Integer, g)-generateSafePrime rng bits = case generateOfSize rng bits of-	Left err         -> Left err-	Right (sp, rng') -> case findPrimeFromWith rng' (\g i -> isProbablyPrime g (2*i+1)) (sp `div` 2) of-		Left err         -> Left err-		Right (p, rng'') -> Right (2*p+1, rng'')---- | find a prime from a starting point where the property hold.-findPrimeFromWith :: CryptoRandomGen g => g -> (g -> Integer -> Either GenError (Bool,g)) -> Integer -> Either GenError (Integer, g)-findPrimeFromWith rng prop !n-	| even n        = findPrimeFromWith rng prop (n+1)-	| otherwise     = case isProbablyPrime rng n of-		Left err               -> Left err-		Right (False, rng')    -> findPrimeFromWith rng' prop (n+2)-		Right (True, rng')     ->-			case prop rng' n of-				Left err             -> Left err-				Right (False, rng'') -> findPrimeFromWith rng'' prop (n+2)-				Right (True, rng'')  -> Right (n, rng'')---- | find a prime from a starting point with no specific property.-findPrimeFrom :: CryptoRandomGen g => g -> Integer -> Either GenError (Integer, g)-findPrimeFrom rng n = findPrimeFromWith rng (\g _ -> Right (True, g)) 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 :: CryptoRandomGen g => g -> Int -> Integer -> Either GenError (Bool, g)-primalityTestMillerRabin rng tries !n-	| n <= 3     = error "Miller-Rabin requires tested value to be > 3"-	| even n     = Right (False, rng)-	| tries <= 0 = error "Miller-Rabin tries need to be > 0"-	| otherwise  = loop rng (factorise 0 (n-1)) tries where-		-- factorise n-1 into the form 2^s*d-		factorise :: Integer -> Integer -> (Integer, Integer)-		factorise !s !v-			| v `testBit` 0 = (s, v)-			| otherwise     = factorise (s+1) (v `shiftR` 1)-		expmod = exponantiation-		-- when iteration reach zero, we have a probable prime-		loop g _       0 = Right (True, g)-		loop g t@(_,d) k = case generateBetween g 2 (n-2) of-			Left err      -> Left err-			Right (a, g') ->-				let x = expmod a d n in-				if x == (1 :: Integer) || x == (n-1)-					then loop g' t (k-1)-					else loop' g' t (k-1) ((x*x) `mod` n) 1-		-- loop from 1 to s-1. if we reach the end then it's composite-		loop' g t@(s,_) km1 !x2 !r-			| r == s      = Right (False, g)-			| x2 == 1     = Right (False, g)-			| x2 /= (n-1) = loop' g t km1 ((x2*x2) `mod` n) (r+1)-			| otherwise   = loop g t km1---- | 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 = exponantiation 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 = loop 3 where-		ubound = snd $ sqrti n-		loop i-			| i > ubound    = True-			| i `divides` n = False-			| otherwise     = loop (i+2)---- | Test is two integer are coprime to each other-isCoprime :: Integer -> Integer -> Bool-isCoprime m n = case gcde_binary m n of (_,_,d) -> d == 1---- | list of the first primes till 2903..-smallPrimes :: [Integer]-smallPrimes =-	[ 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
− Number/Serialize.hs
@@ -1,26 +0,0 @@-module Number.Serialize-	( i2osp-	, os2ip-	, lengthBytes-	) where--import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import Data.Bits---- | os2ip converts a byte string into a positive integer-os2ip :: ByteString -> Integer-os2ip = B.foldl' (\a b -> (256 * a) .|. (fromIntegral b)) 0---- | i2osp converts a positive integer into a byte string-i2osp :: Integer -> ByteString-i2osp m = B.reverse $ B.unfoldr divMod256 m-	where-		divMod256 0 = Nothing-		divMod256 n = Just (fromIntegral a,b) where (b,a) = n `divMod` 256---- | returns the number of bytes to store an integer with i2osp-lengthBytes :: Integer -> Int-lengthBytes n-	| n < 256   = 1-	| otherwise = 1 + lengthBytes (n `div` 256)
Tests/KAT.hs view
@@ -228,7 +228,7 @@     ]  vectors =-	[ ("RC4",        vectors_rc4,         encryptStream RC4.initCtx RC4.encrypt)+	[ ("RC4",        vectors_rc4,         encryptStream RC4.initCtx RC4.combine) 	-- AES haskell implementation 	, ("AES 128 Enc", vectors_aes128_enc,  encryptBlock aes128InitKey AES.encryptECB) 	, ("AES 192 Enc", vectors_aes192_enc,  encryptBlock aes192InitKey AES.encryptECB)
Tests/tests.hs view
@@ -21,185 +21,13 @@ -- for DSA import qualified Crypto.Hash.SHA1 as SHA1 --- numbers-{--import Number.ModArithmetic-import Number.Basic-import Number.Prime-import Number.Serialize--} -- ciphers/Kexch import AES (aesTests) import qualified Crypto.Cipher.AES as AES-import qualified Crypto.Cipher.RSA as RSA-import qualified Crypto.Cipher.DSA as DSA-import qualified Crypto.Cipher.DH as DH import Crypto.Random import KAT -{--prop_gcde_binary_valid (Positive a, Positive b) =-	let (x,y,v)    = gcde_binary a b in-	let (x',y',v') = gcde a b in-	and [v==v', a*x' + b*y' == v', a*x + b*y == v, gcd a b == v]--prop_modexp_rtl_valid (NonNegative a, NonNegative b, Positive m) =-	exponantiation_rtl_binary a b m == ((a ^ b) `mod` m)--prop_modinv_valid (Positive a, Positive m)-	| m > 1 =-		case inverse a m of-			Just ainv -> (ainv * a) `mod` m == 1-			Nothing   -> True-	| otherwise       = True--prop_sqrti_valid (Positive i) = l*l <= i && i <= u*u where (l, u) = sqrti i--prop_generate_prime_valid i =-	-- becuase of the next naive test, we can't generate easily number above 32 bits-	-- otherwise it slows down the tests to uselessness. when AKS or ECPP is implemented-	-- we can revisit the number here-	let p = withAleasInteger rng i (\g -> generatePrime g 32) in-	-- FIXME test if p is around 32 bits-	primalityTestNaive p--prop_miller_rabin_valid i-	| i <= 3    = True-	| otherwise =-		-- miller rabin only returns with certitude that the integer is composite.-		let b = withAleasInteger rng i (\g -> isProbablyPrime g i) in-		(b == False && primalityTestNaive i == False) || b == True--withAleasInteger rng i f = case reseed (i2osp (if i < 0 then -i else i)) rng of-	Left _     -> error "impossible"-	Right rng' -> case f rng' of-		Left _  -> error "impossible"-		Right v -> fst v--}--newtype RSAMessage = RSAMessage B.ByteString deriving (Show, Eq)--instance Arbitrary RSAMessage where-	arbitrary = do-		sz <- choose (0, 128 - 11)-		ws <- replicateM sz (choose (0,255) :: Gen Int)-		return $ RSAMessage $ B.pack $ map fromIntegral ws--{- this is a just test rng. this is absolutely not a serious RNG. DO NOT use elsewhere -}-data Rng = Rng (Int, Int)--getByte :: Rng -> (Word8, Rng)-getByte (Rng (mz, mw)) =-	let mz2 = 36969 * (mz `mod` 65536) in-	let mw2 = 18070 * (mw `mod` 65536) in-	(fromIntegral (mz2 + mw2), Rng (mz2, mw2))--getBytes 0 rng = ([], rng)-getBytes n rng =-	let (b, rng')  = getByte rng in-	let (l, rng'') = getBytes (n-1) rng' in-	(b:l, rng'')--instance CryptoRandomGen Rng where-	newGen _       = Right (Rng (2,3))-	genSeedLength  = 0-	genBytes len g = Right $ first B.pack $ getBytes len g-	reseed bs (Rng (a,b)) = Right $ Rng (fromIntegral a', b) where-		a' = ((fromIntegral a) + i * 36969) `mod` 65536-		i = B.head bs--rng = Rng (1,2) - {-----------------------------------------------------------------------------------------------}-{- testing RSA -}-{-----------------------------------------------------------------------------------------------}--{--prop_rsa_generate_valid (Positive i, RSAMessage msgz) =-	let keysz = 64 in-	let (pub,priv) = withAleasInteger rng i (\g -> RSA.generate g keysz 65537) in-	let msg = B.take (keysz - 11) msgz in-	(RSA.private_p priv * RSA.private_q priv == RSA.private_n priv) &&-	((RSA.private_d priv * RSA.public_e pub) `mod` ((RSA.private_p priv - 1) * (RSA.private_q priv - 1)) == 1) &&-	(either Left (RSA.decrypt priv . fst) $ RSA.encrypt rng pub msg) == Right msg--}--prop_rsa_valid fast (RSAMessage msg) =-	(either Left (RSA.decrypt pk . fst) $ RSA.encrypt rng rsaPublickey msg) == Right msg-	where pk       = if fast then rsaPrivatekey else rsaPrivatekey { RSA.private_p = 0, RSA.private_q = 0 }--prop_rsa_fast_valid  = prop_rsa_valid True-prop_rsa_slow_valid  = prop_rsa_valid False--prop_rsa_sign_valid fast (RSAMessage msg) = (either Left (\smsg -> verify msg smsg) $ sign msg) == Right True-	where-		verify   = RSA.verify (SHA1.hash) sha1desc rsaPublickey-		sign     = RSA.sign (SHA1.hash) sha1desc pk-		sha1desc = B.pack [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03, 0x02,0x1a,0x05,0x00,0x04,0x14]-		pk       = if fast then rsaPrivatekey else rsaPrivatekey { RSA.private_p = 0, RSA.private_q = 0 }--prop_rsa_sign_fast_valid = prop_rsa_sign_valid True-prop_rsa_sign_slow_valid = prop_rsa_sign_valid False--rsaPrivatekey = RSA.PrivateKey-	{ RSA.private_pub  = rsaPublickey-	, RSA.private_d    = 133764127300370985476360382258931504810339098611363623122953018301285450176037234703101635770582297431466449863745848961134143024057267778947569638425565153896020107107895924597628599677345887446144410702679470631826418774397895304952287674790343620803686034122942606764275835668353720152078674967983573326257-	, RSA.private_p    = 12909745499610419492560645699977670082358944785082915010582495768046269235061708286800087976003942261296869875915181420265794156699308840835123749375331319-	, RSA.private_q    = 10860278066550210927914375228722265675263011756304443428318337179619069537063135098400347475029673115805419186390580990519363257108008103841271008948795129-	, RSA.private_dP   = 5014229697614831746694710412330921341325464081424013940131184365711243776469716106024020620858146547161326009604054855316321928968077674343623831428796843-	, RSA.private_dQ   = 3095337504083058271243917403868092841421453478127022884745383831699720766632624326762288333095492075165622853999872779070009098364595318242383709601515849-	, RSA.private_qinv = 11136639099661288633118187183300604127717437440459572124866697429021958115062007251843236337586667012492941414990095176435990146486852255802952814505784196-	}--rsaPublickey = RSA.PublicKey-	{ RSA.public_size = 128-	, RSA.public_n    = 140203425894164333410594309212077886844966070748523642084363106504571537866632850620326769291612455847330220940078873180639537021888802572151020701352955762744921926221566899281852945861389488419179600933178716009889963150132778947506523961974222282461654256451508762805133855866018054403911588630700228345151-	, RSA.public_e    = 65537-	}--{-----------------------------------------------------------------------------------------------}-{- testing DSA -}-{-----------------------------------------------------------------------------------------------}---dsaParams = (p,g,q)-	where-		p = 0x00a8c44d7d0bbce69a39008948604b9c7b11951993a5a1a1fa995968da8bb27ad9101c5184bcde7c14fb79f7562a45791c3d80396cefb328e3e291932a17e22edd-		g = 0x0bf9fe6c75d2367b88912b2252d20fdcad06b3f3a234b92863a1e30a96a123afd8e8a4b1dd953e6f5583ef8e48fc7f47a6a1c8f24184c76dba577f0fec2fcd1c-		q = 0x0096674b70ef58beaaab6743d6af16bb862d18d119--dsaPrivatekey = DSA.PrivateKey-	{ DSA.private_params = dsaParams-	, DSA.private_x      = 0x229bac7aa1c7db8121bfc050a3426eceae23fae8-	}--dsaPublickey = DSA.PublicKey-	{ DSA.public_params = dsaParams-	, DSA.public_y      = 0x4fa505e86e32922f1fa1702a120abdba088bb4be801d4c44f7fc6b9094d85cd52c429cbc2b39514e30909b31e2e2e0752b0fc05c1a7d9c05c3e52e49e6edef4c-	}--prop_dsa_valid (RSAMessage msg) =-	case DSA.verify signature (SHA1.hash) dsaPublickey msg of-		Left err -> False-		Right b  -> b-	where-		Right (signature, rng') = DSA.sign rng (SHA1.hash) dsaPrivatekey msg--{-----------------------------------------------------------------------------------------------}-{- testing DH -}-{-----------------------------------------------------------------------------------------------}-instance Arbitrary DH.PrivateNumber where-	arbitrary = fromIntegral <$> (suchThat (arbitrary :: Gen Integer) (\x -> x >= 1))--prop_dh_valid (xa, xb) = sa == sb-	where-		sa = DH.getShared dhparams xa yb-		sb = DH.getShared dhparams xb ya-		yb = DH.generatePublic dhparams xb-		ya = DH.generatePublic dhparams xa-		dhparams = (11, 7)--{-----------------------------------------------------------------------------------------------} {- testing AES -} {-----------------------------------------------------------------------------------------------} data AES128Message = AES128Message B.ByteString B.ByteString B.ByteString deriving (Show, Eq)@@ -277,35 +105,11 @@ 	, testProperty "AES256 (CBC)" prop_aes256_cbc_valid 	] -asymEncryptionTests = testGroup "assymmetric cipher encryption"-	[ testProperty "RSA (slow)" prop_rsa_slow_valid-	, testProperty "RSA (fast)" prop_rsa_fast_valid-	]--asymSignatureTests = testGroup "assymmetric cipher signature"-	[ testProperty "RSA (slow)" prop_rsa_sign_slow_valid-	, testProperty "RSA (fast)" prop_rsa_sign_fast_valid-	, testProperty "DSA" prop_dsa_valid-	]--asymOtherTests = testGroup "assymetric other tests"-	[ testProperty "DH valid" prop_dh_valid-	]--arithmeticTests = testGroup "arithmetic"-	[]--{- run_test "RSA generate" prop_rsa_generate_valid -}- tests :: [Test] tests = 	[ symCipherExpectedTests 	, symCipherMarshallTests 	, testGroup "AES" aesTests-	, arithmeticTests-	, asymEncryptionTests-	, asymSignatureTests-	, asymOtherTests 	]  main = defaultMain tests
cryptocipher.cabal view
@@ -1,5 +1,5 @@ Name:                cryptocipher-Version:             0.4.0+Version:             0.5.0 Description:         Symmetrical block and stream ciphers. License:             BSD3 License-file:        LICENSE@@ -28,23 +28,11 @@                    , cipher-aes                    , cipher-rc4                    , crypto-api >= 0.5-                   , crypto-pubkey-types >= 0.2 && < 0.3-                   , tagged                    , cereal   Exposed-modules:   Crypto.Cipher.RC4                      Crypto.Cipher.AES                      Crypto.Cipher.Blowfish                      Crypto.Cipher.Camellia-                     Crypto.Cipher.RSA-                     Crypto.Cipher.DSA-                     Crypto.Cipher.DH-  other-modules:     Number.ModArithmetic-                     Number.Serialize-                     Number.Generate-                     Number.Basic-                     Number.Polynomial-                     Number.Prime-                     Crypto.Cipher.ElGamal   ghc-options:       -Wall  Test-Suite test-cryptocipher