# Conflicts:
#	cryptonite.cabal
#	tests/KAT_PubKey.hs
This commit is contained in:
Carlos Rodriguez 2018-11-03 20:23:25 +01:00
commit 314a9caba7
12 changed files with 177 additions and 34 deletions

View File

@ -1,20 +1,20 @@
# compiler supported and their equivalent LTS
compiler: ghc-8.0 lts-9.21
compiler: ghc-8.2 lts-11.6
compiler: ghc-8.4 ghc-8.4.2
compiler: ghc-8.2 lts-11.22
compiler: ghc-8.4 lts-12.15
compiler: ghc-8.6 nightly-2018-10-21
# options
# option: alias x=y z=v
option: testdeps extradep=QuickCheck-2.11.3 extradep=ansi-terminal-0.8.0.1 extradep=async-2.1.1.1 extradep=call-stack-0.1.0 extradep=clock-0.7.2 extradep=optparse-applicative-0.14.0.0 extradep=random-1.1 extradep=tagged-0.8.5 extradep=unbounded-delays-0.1.1.0 extradep=tasty-1.0.0.1 extradep=tasty-hunit-0.10.0.1 extradep=tasty-kat-0.0.3 extradep=tasty-quickcheck-0.9.2 extradep=ansi-wl-pprint-0.6.8.2 extradep=colour-2.3.4 extradep=tf-random-0.5 extradep=transformers-compat-0.5.1.4 extradep=primitive-0.6.3.0 allow-newer
option: gaugedeps extradep=gauge-0.2.1
option: basementmin extradep=basement-0.0.6 extradep=foundation-0.0.19 extradep=memory-0.14.14
# builds
build: ghc-8.2 basementmin gaugedeps
build: ghc-8.2
build: ghc-8.0 basementmin gaugedeps
build: ghc-8.0 basementmin gaugedeps os=osx
build: ghc-8.4 basementmin testdeps gaugedeps extradep=vector-0.12.0.1
build: ghc-8.4
build: ghc-8.6
# packages
package: '.'

View File

@ -1,4 +1,4 @@
# ~*~ auto-generated by haskell-ci with config : 7d7fe90696706f37292f4d718fa1a63b938490d653e3abf049623087b2e6e901 ~*~
# ~*~ auto-generated by haskell-ci with config : c5de1915986b17c62e2a4cbe1fb7b3d47a6b1dc45a8f4d4fa78654695dfd1f43 ~*~
# Use new container infrastructure to enable caching
sudo: false
@ -16,6 +16,7 @@ matrix:
- { env: BUILD=stack RESOLVER=ghc-8.0, compiler: ghc-8.0, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } }
- { env: BUILD=stack RESOLVER=ghc-8.0, compiler: ghc-8.0, language: generic, addons: { apt: { packages: [ libgmp-dev ] } }, os: osx }
- { env: BUILD=stack RESOLVER=ghc-8.4, compiler: ghc-8.4, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } }
- { env: BUILD=stack RESOLVER=ghc-8.6, compiler: ghc-8.6, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } }
- { env: BUILD=hlint, compiler: hlint, language: generic }
- { env: BUILD=weeder, compiler: weeder, language: generic, addons: { apt: { packages: [ libgmp-dev ] } } }
allow_failures:
@ -48,7 +49,7 @@ script:
# create the build stack.yaml
case "$RESOLVER" in
ghc-8.2)
echo "{ resolver: lts-11.6, packages: [ '.' ], extra-deps: [ basement-0.0.6, foundation-0.0.19, memory-0.14.14, gauge-0.2.1 ], flags: {} }" > stack.yaml
echo "{ resolver: lts-11.22, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml
stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps
;;
ghc-8.0)
@ -60,7 +61,11 @@ script:
stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps
;;
ghc-8.4)
echo "{ resolver: ghc-8.4.2, packages: [ '.' ], extra-deps: [ vector-0.12.0.1, basement-0.0.6, foundation-0.0.19, memory-0.14.14, QuickCheck-2.11.3, ansi-terminal-0.8.0.1, async-2.1.1.1, call-stack-0.1.0, clock-0.7.2, optparse-applicative-0.14.0.0, random-1.1, tagged-0.8.5, unbounded-delays-0.1.1.0, tasty-1.0.0.1, tasty-hunit-0.10.0.1, tasty-kat-0.0.3, tasty-quickcheck-0.9.2, ansi-wl-pprint-0.6.8.2, colour-2.3.4, tf-random-0.5, transformers-compat-0.5.1.4, primitive-0.6.3.0, gauge-0.2.1 ], flags: {}, allow-newer: true }" > stack.yaml
echo "{ resolver: lts-12.15, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml
stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps
;;
ghc-8.6)
echo "{ resolver: nightly-2018-10-21, packages: [ '.' ], extra-deps: [], flags: {} }" > stack.yaml
stack --no-terminal build --install-ghc --coverage --test --bench --no-run-benchmarks --haddock --no-haddock-deps
;;
esac
@ -75,4 +80,3 @@ script:
esac
set +ex

View File

@ -12,7 +12,6 @@
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
@ -21,28 +20,31 @@ module Crypto.Hash.SHAKE
( SHAKE128 (..), SHAKE256 (..)
) where
import Control.Monad (when)
import Crypto.Hash.Types
import Foreign.Ptr (Ptr)
import Foreign.Ptr (Ptr, castPtr)
import Foreign.Storable (Storable(..))
import Data.Bits
import Data.Data
import Data.Typeable
import Data.Word (Word8, Word32)
import Data.Proxy (Proxy(..))
import GHC.TypeLits (Nat, KnownNat, natVal)
import GHC.TypeLits (Nat, KnownNat, type (+))
import Crypto.Internal.Nat
-- | SHAKE128 (128 bits) extendable output function. Supports an arbitrary
-- digest size (multiple of 8 bits), to be specified as a type parameter
-- of kind 'Nat'.
-- 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, Typeable)
deriving (Show, Data, Typeable)
instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE128 bitlen) where
instance KnownNat bitlen => HashAlgorithm (SHAKE128 bitlen) where
type HashBlockSize (SHAKE128 bitlen) = 168
type HashDigestSize (SHAKE128 bitlen) = Div8 bitlen
type HashDigestSize (SHAKE128 bitlen) = Div8 (bitlen + 7)
type HashInternalContextSize (SHAKE128 bitlen) = 376
hashBlockSize _ = 168
hashDigestSize _ = byteLen (Proxy :: Proxy bitlen)
@ -52,18 +54,17 @@ instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE128 bit
hashInternalFinalize = shakeFinalizeOutput (Proxy :: Proxy bitlen)
-- | SHAKE256 (256 bits) extendable output function. Supports an arbitrary
-- digest size (multiple of 8 bits), to be specified as a type parameter
-- of kind 'Nat'.
-- 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, Typeable)
deriving (Show, Data, Typeable)
instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE256 bitlen) where
instance KnownNat bitlen => HashAlgorithm (SHAKE256 bitlen) where
type HashBlockSize (SHAKE256 bitlen) = 136
type HashDigestSize (SHAKE256 bitlen) = Div8 bitlen
type HashDigestSize (SHAKE256 bitlen) = Div8 (bitlen + 7)
type HashInternalContextSize (SHAKE256 bitlen) = 344
hashBlockSize _ = 136
hashDigestSize _ = byteLen (Proxy :: Proxy bitlen)
@ -72,7 +73,7 @@ instance (IsDivisibleBy8 bitlen, KnownNat bitlen) => HashAlgorithm (SHAKE256 bit
hashInternalUpdate = c_sha3_update
hashInternalFinalize = shakeFinalizeOutput (Proxy :: Proxy bitlen)
shakeFinalizeOutput :: (IsDivisibleBy8 bitlen, KnownNat bitlen)
shakeFinalizeOutput :: KnownNat bitlen
=> proxy bitlen
-> Ptr (Context a)
-> Ptr (Digest a)
@ -80,6 +81,16 @@ shakeFinalizeOutput :: (IsDivisibleBy8 bitlen, KnownNat bitlen)
shakeFinalizeOutput d ctx dig = do
c_sha3_finalize_shake 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 ()

View File

@ -8,6 +8,7 @@
-- Crypto hash types definitions
--
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
@ -28,6 +29,7 @@ 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.
--
@ -76,7 +78,7 @@ newtype Context a = Context Bytes
-- Creating a digest from a bytearray is also possible with function
-- 'Crypto.Hash.digestFromByteString'.
newtype Digest a = Digest (Block Word8)
deriving (Eq,Ord,ByteArrayAccess)
deriving (Eq,Ord,ByteArrayAccess, Data)
instance NFData (Digest a) where
rnf (Digest u) = u `deepseq` ()

View File

@ -15,8 +15,8 @@ module Crypto.Internal.Nat
import GHC.TypeLits
byteLen :: (KnownNat bitlen, IsDivisibleBy8 bitlen, Num a) => proxy bitlen -> a
byteLen d = fromInteger (natVal d `div` 8)
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

View File

@ -39,9 +39,8 @@ instance Exception CoprimesAssertionError
-- from expFast, and thus provide the same unstudied and dubious
-- timing and side channels claims.
--
-- with GHC 7.10, the powModSecInteger is missing from integer-gmp
-- (which is now integer-gmp2), so is has the same security as old
-- ghc version.
-- 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

View File

@ -111,8 +111,8 @@ pad len m
-- | Produce a standard PKCS1.5 padding for signature
padSignature :: ByteArray signature => Int -> signature -> Either Error signature
padSignature klen signature
| klen < siglen+1 = Left SignatureTooLong
| otherwise = Right (B.pack padding `B.append` signature)
| 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])

View File

@ -36,7 +36,7 @@ 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.4.2, GHC==8.2.2, GHC==8.0.2
tested-with: GHC==8.6.1, 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
@ -412,6 +412,7 @@ Test-Suite test-cryptonite
KAT_PubKey.OAEP
KAT_PubKey.PSS
KAT_PubKey.P256
KAT_PubKey.RSA
KAT_PubKey.Rabin
KAT_PubKey
KAT_RC4

3
stack.yaml Normal file
View File

@ -0,0 +1,3 @@
# ~*~ auto-generated by haskell-ci with config : c5de1915986b17c62e2a4cbe1fb7b3d47a6b1dc45a8f4d4fa78654695dfd1f43 ~*~
{ resolver: lts-12.15, packages: [ '.' ], extra-deps: [], flags: {} }

View File

@ -1,5 +1,4 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE DataKinds #-}
module Hash
@ -9,7 +8,9 @@ module Hash
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
@ -235,7 +236,25 @@ makeTestChunk (hashName, hashAlg, _) =
runhash hashAlg inp `propertyEq` runhashinc hashAlg (chunkS ckLen inp)
]
-- SHAKE128 truncation example with expected byte at final position
-- <https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/ShakeTruncation.pdf>
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)
]
]

View File

@ -16,6 +16,7 @@ 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
@ -36,6 +37,7 @@ vectorsMGF =
tests = testGroup "PubKey"
[ testGroup "MGF1" $ map doMGFTest (zip [katZero..] vectorsMGF)
, rsaTests
, pssTests
, oaepTests
, dsaTests

102
tests/KAT_PubKey/RSA.hs Normal file
View File

@ -0,0 +1,102 @@
{-# 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)
]
]