packages feed

RSA 1.0.6.3 → 1.2.0.0

raw patch · 3 files changed

+70/−59 lines, 3 filesdep +DRBGdep +crypto-apidep +monadcryptorandomdep −randomdep ~test-frameworkdep ~test-framework-quickcheck2PVP ok

version bump matches the API change (PVP)

Dependencies added: DRBG, crypto-api, monadcryptorandom, tagged

Dependencies removed: random

Dependency ranges changed: test-framework, test-framework-quickcheck2

API changes (from Hackage documentation)

- Codec.Crypto.RSA: encrypt :: RandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)
+ Codec.Crypto.RSA: encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)
- Codec.Crypto.RSA: encrypt' :: RandomGen g => EncryptionOptions -> g -> PublicKey -> ByteString -> (ByteString, g)
+ Codec.Crypto.RSA: encrypt' :: CryptoRandomGen g => EncryptionOptions -> g -> PublicKey -> ByteString -> (ByteString, g)
- Codec.Crypto.RSA: generateKeyPair :: RandomGen g => g -> Int -> (PublicKey, PrivateKey, g)
+ Codec.Crypto.RSA: generateKeyPair :: CryptoRandomGen g => g -> Int -> (PublicKey, PrivateKey, g)
- Codec.Crypto.RSA: rsaes_oaep_encrypt :: HashFunction -> MGF -> PublicKey -> Integer -> ByteString -> ByteString -> ByteString
+ Codec.Crypto.RSA: rsaes_oaep_encrypt :: CryptoRandomGen g => g -> HashFunction -> MGF -> PublicKey -> ByteString -> ByteString -> (ByteString, g)
- Codec.Crypto.RSA: rsaes_pkcs1_v1_5_encrypt :: RandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)
+ Codec.Crypto.RSA: rsaes_pkcs1_v1_5_encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)

Files

Codec/Crypto/RSA.hs view
@@ -53,7 +53,8 @@ import Data.Digest.Pure.SHA import Data.Int import Data.Word-import System.Random+import Crypto.Random+import Control.Monad.CryptoRandom  #ifdef USE_BINARY import Data.Binary@@ -119,8 +120,8 @@ -- |Randomly generate a key pair of the given modulus length (in bits) to -- use in any of the following functions. Use of a good random number  -- generator is of considerable importance when using this function; the --- input RandomGen should never be used again for any other purpose.-generateKeyPair :: RandomGen g => g -> Int -> (PublicKey, PrivateKey, g)+-- input CryptoRandomGen should never be used again for any other purpose.+generateKeyPair :: CryptoRandomGen g => g -> Int -> (PublicKey, PrivateKey, g) generateKeyPair g sizeBits = (PublicKey kLen n e, PrivateKey kLen n d, g')  where   kLen       = fromIntegral $ sizeBits `div` 8@@ -151,7 +152,7 @@ -- function, and not adding a label). If the message is longer than the  -- underlying encryption function can support, it is broken up into parts -- and each part is encrypted.-encrypt :: RandomGen g => g -> PublicKey -> ByteString -> (ByteString, g)+encrypt :: CryptoRandomGen g => g -> PublicKey -> ByteString -> (ByteString, g) encrypt = encrypt' (UseOAEP sha256' (generate_MGF1 sha256') BS.empty)  -- |Decrypt an arbitrarily-sized message using the defaults for RSA@@ -182,7 +183,7 @@ verify = rsassa_pkcs1_v1_5_verify ha_SHA256  -- |Encrypt an arbitrarily-sized message using the given options.-encrypt' :: RandomGen g => +encrypt' :: CryptoRandomGen g =>              EncryptionOptions -> g -> PublicKey -> ByteString ->              (ByteString, g) encrypt' (UseOAEP hash mgf l) gen pub m = foldl enc1 (BS.empty, gen) chunks@@ -190,8 +191,7 @@   hLen              = BS.length $ hash BS.empty   chunkSize         = public_size pub - (2 * hLen) - 2   chunks            = chunkify chunkSize m-  enc1 (!res, !g) !cur = let (seed, g') = random g-                             !newc = rsaes_oaep_encrypt hash mgf pub seed l cur+  enc1 (!res, !g) !cur = let !(!newc,!g') = rsaes_oaep_encrypt g hash mgf pub l cur                          in (res `BS.append` newc, g') encrypt' UsePKCS1_v1_5        gen pub m = foldl enc1 (BS.empty, gen) chunks  where@@ -234,17 +234,18 @@ -- I have not put in a check for the length of the label, because I don't -- expect you to use more than 2^32 bytes. So don't make me regret that, eh? ---rsaes_oaep_encrypt :: HashFunction -> MGF -> -                      PublicKey -> Integer -> ByteString -> ByteString ->-                      ByteString-rsaes_oaep_encrypt hash mgf k seed_int l m+rsaes_oaep_encrypt :: CryptoRandomGen g => g -> HashFunction -> MGF -> +                      PublicKey -> ByteString -> ByteString ->+                      (ByteString,g)+rsaes_oaep_encrypt g hash mgf k l m   | message_too_long = error "message too long (rsaes_oaep_encrypt)"-  | otherwise        = c+  | otherwise        = (c,g')  where   mLen = BS.length m -- Int64   hLen = BS.length $ hash BS.empty -- Int64   kLen = public_size k-  seed = i2osp seed_int hLen+  (seedStrict,g') = throwLeft $ genBytes (fromIntegral hLen) g+  seed = BS.fromChunks [seedStrict]   -- Step 1   message_too_long = mLen > (kLen - (2 * hLen) - 2)   -- Step 2@@ -332,7 +333,7 @@ -- randomness, and (b) choose a decent instance of RandomGen for passing to -- this function. ---rsaes_pkcs1_v1_5_encrypt :: RandomGen g => +rsaes_pkcs1_v1_5_encrypt :: CryptoRandomGen g =>                              g -> PublicKey -> ByteString ->                              (ByteString, g) rsaes_pkcs1_v1_5_encrypt rGen k m @@ -576,21 +577,12 @@   | BS.length bstr <= len = [bstr]   | otherwise             = (BS.take len bstr):(chunkify len $ BS.drop len bstr)  -#if !MIN_VERSION_random(1,0,1)-instance Random Word8 where-  randomR (a,b) g = let aI::Int = fromIntegral a -                        bI::Int = fromIntegral b-                        (x, g') = randomR (aI, bI) g-                    in (fromIntegral x, g')-  random          = randomR (minBound, maxBound)-#endif--generate_random_bytestring :: RandomGen g => g -> Int64 -> (ByteString, g)+generate_random_bytestring :: CryptoRandomGen g => g -> Int64 -> (ByteString, g) generate_random_bytestring g 0 = (BS.empty, g) generate_random_bytestring g x = (BS.cons' first rest, g'')  where   (rest, g')   = generate_random_bytestring g (x - 1)-  (first, g'') = randomR (1,255) g' +  (first, g'') = throwLeft $ crandomR (1,255) g'  -- Divide a by b, rounding towards positive infinity. divCeil :: Integral a => a -> a -> a@@ -600,7 +592,7 @@  -- Generate p and q. This is not necessarily the best way to do this, but the -- ANSI standard dealing with this cost money, and I was in a hurry.-generate_pq :: RandomGen g => g -> Int64 -> (Integer, Integer, g)+generate_pq :: CryptoRandomGen g => g -> Int64 -> (Integer, Integer, g) generate_pq g len    | len < 2   = error "length to short for generate_pq"   | p == q    = generate_pq g'' len@@ -610,7 +602,7 @@   (baseQ, g'') = large_random_prime g' (len - (len `div` 2))   (p, q)       = if baseP < baseQ then (baseQ, baseP) else (baseP, baseQ) -large_random_prime :: RandomGen g => g -> Int64 -> (Integer, g)+large_random_prime :: CryptoRandomGen g => g -> Int64 -> (Integer, g) large_random_prime g len = (prime, g''')  where   ([startH, startT], g') = random8s g 2@@ -619,14 +611,14 @@   start                  = os2ip $ BS.pack start_ls   (prime, g''')          = find_next_prime g'' start    -random8s :: RandomGen g => g -> Int64 -> ([Word8], g)+random8s :: CryptoRandomGen g => g -> Int64 -> ([Word8], g) random8s g 0 = ([], g) random8s g x =    let (rest, g') = random8s g (x - 1)-      (next8, g'') = random g'+      (next8, g'') = throwLeft (crandom g')   in (next8:rest, g'') -find_next_prime :: RandomGen g => g -> Integer -> (Integer, g)+find_next_prime :: CryptoRandomGen g => g -> Integer -> (Integer, g) find_next_prime g n   | even n             = error "Even number sent to find_next_prime"   | n `mod` 65537 == 1 = find_next_prime g (n + 2)@@ -635,7 +627,7 @@  where   (got_a_prime, g') = is_probably_prime g n -is_probably_prime :: RandomGen g => g -> Integer -> (Bool, g)+is_probably_prime :: CryptoRandomGen g => g -> Integer -> (Bool, g) is_probably_prime !g !n    | any (\ x -> n `mod` x == 0) small_primes = (False, g)   | otherwise                                = miller_rabin g n 20@@ -658,12 +650,12 @@                    877,  881,  883,  887,  907,  911,  919,  929,  937,  941,                    947,  953,  967,  971,  977,  983,  991,  997, 1009, 1013  ] -miller_rabin :: RandomGen g => g -> Integer -> Int -> (Bool, g)+miller_rabin :: CryptoRandomGen g => g -> Integer -> Int -> (Bool, g) miller_rabin g _ 0             = (True, g) miller_rabin g n k | test a n  = (False, g')                    | otherwise = miller_rabin g' n (k - 1)  where-  (a, g') = randomR (2, n - 2) g+  (a, g') = throwLeft (crandomR (2, n - 2) g)   base_b = tail $ reverse $ toBinary (n - 1)    --    test a' n' = pow base_b a
RSA.cabal view
@@ -1,6 +1,6 @@ name:       RSA category:   Cryptography, Codec-version:    1.0.6.3+version:    1.2.0.0 license:    BSD3 license-file: LICENSE author:     Adam Wick <awick@galois.com>@@ -32,7 +32,7 @@   Default: False  Library- build-depends: bytestring, random+ build-depends: bytestring, crypto-api >= 0.10, monadcryptorandom  GHC-Options: -O2 -Wall -fno-ignore-asserts -fno-warn-orphans  if flag(OldBase)    build-depends: base >= 3 && < 4, SHA < 1.4.1@@ -56,9 +56,11 @@       build-depends: base >= 3 && < 4, SHA < 1.4.1     else       build-depends: base >= 4 && < 5, SHA-    build-depends: bytestring, test-framework >= 0.3 && < 0.4,+    build-depends: bytestring, test-framework >= 0.3 && < 0.7,                    QuickCheck >= 2 && < 3,-                   test-framework-quickcheck2 >= 0.2 && < 0.3+                   test-framework-quickcheck2 >= 0.2 && < 0.7,+                   DRBG >= 0.2.3 && < 0.4,+                   tagged >= 0.2.3 && < 0.4   else     Buildable: False   GHC-Options: -O2 -Wall -fno-ignore-asserts -fno-warn-orphans 
Test.hs view
@@ -1,33 +1,49 @@+{-# LANGUAGE FlexibleInstances #-} import Codec.Crypto.RSA import Control.Monad+import Data.ByteString(pack) import Data.ByteString.Lazy(ByteString) import qualified Data.ByteString.Lazy as BS import Data.Digest.Pure.SHA-import Data.Word-import System.Random+import Data.Tagged import Test.QuickCheck+import Crypto.Random+import Crypto.Random.DRBG+import Crypto.Types  import Test.Framework (defaultMain, testGroup, Test) import Test.Framework.Providers.QuickCheck2 (testProperty)  -- -------------------------------------------------------------------------- +buildGen :: Gen (GenAutoReseed HashDRBG HashDRBG)+buildGen = do+  let len = genSeedLength :: Tagged (GenAutoReseed HashDRBG HashDRBG) ByteLength+  bytes <- pack `fmap` replicateM (unTagged len) arbitrary+  let Right seed = newGen bytes+  return seed++instance Show (GenAutoReseed HashDRBG HashDRBG) where+  show _ = "<randomGen>"++instance Arbitrary (GenAutoReseed HashDRBG HashDRBG) where+  arbitrary = buildGen++-- --------------------------------------------------------------------------+ data KeyPair     = KP1K PublicKey PrivateKey  deriving (Show)  data KeyPair2048 = KP2K PublicKey PrivateKey  deriving (Show) -getRNGSeed :: Gen StdGen-getRNGSeed  = fmap mkStdGen arbitrary- instance Arbitrary KeyPair where-  arbitrary   = do g <- getRNGSeed+  arbitrary   = do g <- buildGen                    let (pub, priv, _) = generateKeyPair g 1024                    return $ KP1K pub priv  instance Arbitrary KeyPair2048 where-  arbitrary   = do g <- getRNGSeed+  arbitrary   = do g <- buildGen                    let (pub, priv, _) = generateKeyPair g 2048                    return $ KP2K pub priv @@ -39,7 +55,7 @@   show (LP x) = show x  instance Arbitrary LargePrime where-  arbitrary   = do g <- getRNGSeed+  arbitrary   = do g <- buildGen                    let (res, _) = large_random_prime g 64                    return (LP res) @@ -134,20 +150,21 @@  -- -------------------------------------------------------------------------- -prop_oaep_inverts :: HashInfo -> KeyPair2048 -> PositiveInteger -> +prop_oaep_inverts :: GenAutoReseed HashDRBG HashDRBG ->+                     HashInfo -> KeyPair2048 -> PositiveInteger ->                      ByteString -> NonEmptyByteString ->                       Bool-prop_oaep_inverts hi (KP2K pub priv) (PI seed) l (NEBS x) = m == m'+prop_oaep_inverts g hi (KP2K pub priv) (PI seed) l (NEBS x) = m == m'  where-  hash = hashFunction hi-  kLen = public_size pub-  hLen = BS.length $ hash BS.empty-  mgf  = generate_MGF1 hash-  m    = BS.take (kLen - (2 * hLen) - 2) x-  c    = rsaes_oaep_encrypt hash mgf pub  seed l m-  m'   = rsaes_oaep_decrypt hash mgf priv      l c+  hash  = hashFunction hi+  kLen  = public_size pub+  hLen  = BS.length $ hash BS.empty+  mgf   = generate_MGF1 hash+  m     = BS.take (kLen - (2 * hLen) - 2) x+  (c,_) = rsaes_oaep_encrypt g hash mgf pub  l m+  m'    = rsaes_oaep_decrypt   hash mgf priv l c -prop_pkcs_inverts :: RandomGen g => g -> KeyPair -> NonEmptyByteString -> Bool+prop_pkcs_inverts :: CryptoRandomGen g => g -> KeyPair -> NonEmptyByteString -> Bool prop_pkcs_inverts g (KP1K pub priv) (NEBS x) = m == m'  where   kLen  = public_size pub@@ -161,13 +178,13 @@  -- -------------------------------------------------------------------------- -prop_encrypt_inverts :: RandomGen g => +prop_encrypt_inverts :: CryptoRandomGen g =>                          g -> KeyPair2048 -> NonEmptyByteString ->                          Bool prop_encrypt_inverts g (KP2K pub priv) (NEBS m) =   m == decrypt priv (fst $ encrypt g pub m) -prop_encrypt_plus_inverts :: RandomGen g =>+prop_encrypt_plus_inverts :: CryptoRandomGen g =>                              g -> EncryptionOptions -> KeyPair2048 ->                               NonEmptyByteString ->                              Bool@@ -183,10 +200,10 @@   putStrLn "hurry, Control-C is your friend."   putStrLn "WARNING WARNING WARNING\n" -  g <- getStdGen+  g <- newGenIO :: IO SystemRandom   defaultMain $ tests g -tests :: StdGen -> [Test]+tests :: SystemRandom -> [Test] tests g = [   testGroup "Testing basic helper functions" [      testProperty "prop_chunkify_works"         prop_chunkify_works,