Merge pull request #265 from crockeea/master

Fixed hash truncation bug in DSA
This commit is contained in:
Olivier Chéron 2019-02-04 21:22:04 +01:00
commit 1d82f647a4
4 changed files with 262 additions and 41 deletions

View File

@ -28,18 +28,17 @@ module Crypto.PubKey.DSA
, toPrivateKey , toPrivateKey
) where ) where
import Crypto.Random.Types
import Data.Bits (testBit) import Data.Data
import Data.Data import Data.Maybe
import Data.Maybe
import Crypto.Number.Basic (numBits) import Crypto.Number.ModArithmetic (expFast, expSafe, inverse)
import Crypto.Number.ModArithmetic (expFast, expSafe, inverse) import Crypto.Number.Generate
import Crypto.Number.Serialize import Crypto.Internal.ByteArray (ByteArrayAccess)
import Crypto.Number.Generate import Crypto.Internal.Imports
import Crypto.Internal.ByteArray (ByteArrayAccess(length), convert, index, dropView, takeView) import Crypto.Hash
import Crypto.Internal.Imports import Crypto.PubKey.Internal (dsaTruncHash)
import Crypto.Hash import Crypto.Random.Types
import Prelude hiding (length)
-- | DSA Public Number, usually embedded in DSA Public Key -- | DSA Public Number, usually embedded in DSA Public Key
type PublicNumber = Integer type PublicNumber = Integer
@ -126,7 +125,7 @@ signWith k pk hashAlg msg
x = private_x pk x = private_x pk
-- compute r,s -- compute r,s
kInv = fromJust $ inverse k q kInv = fromJust $ inverse k q
hm = os2ip $ hashWith hashAlg msg hm = dsaTruncHash hashAlg msg q
r = expSafe g k p `mod` q r = expSafe g k p `mod` q
s = (kInv * (hm + x * r)) `mod` q s = (kInv * (hm + x * r)) `mod` q
@ -148,11 +147,8 @@ verify hashAlg pk (Signature r s) m
| otherwise = v == r | otherwise = v == r
where (Params p g q) = public_params pk where (Params p g q) = public_params pk
y = public_y pk y = public_y pk
hm = os2ip . truncateHash $ hashWith hashAlg m hm = dsaTruncHash hashAlg m q
w = fromJust $ inverse s q w = fromJust $ inverse s q
u1 = (hm*w) `mod` q u1 = (hm*w) `mod` q
u2 = (r*w) `mod` q u2 = (r*w) `mod` q
v = ((expFast g u1 p) * (expFast y u2 p)) `mod` p `mod` q v = ((expFast g u1 p) * (expFast y u2 p)) `mod` p `mod` q
-- if the hash is larger than the size of q, truncate it; FIXME: deal with the case of a q not evenly divisible by 8
truncateHash h = if numBits (os2ip h) > numBits q then takeView h (numBits q `div` 8) else dropView h 0

View File

@ -16,18 +16,16 @@ module Crypto.PubKey.ECC.ECDSA
) where ) where
import Control.Monad import Control.Monad
import Crypto.Random.Types
import Data.Bits (shiftR)
import Crypto.Internal.ByteArray (ByteArrayAccess)
import Data.Data import Data.Data
import Crypto.Number.Basic (numBits)
import Crypto.Hash
import Crypto.Internal.ByteArray (ByteArrayAccess)
import Crypto.Number.ModArithmetic (inverse) import Crypto.Number.ModArithmetic (inverse)
import Crypto.Number.Serialize
import Crypto.Number.Generate import Crypto.Number.Generate
import Crypto.PubKey.ECC.Types import Crypto.PubKey.ECC.Types
import Crypto.PubKey.ECC.Prim import Crypto.PubKey.ECC.Prim
import Crypto.Hash import Crypto.PubKey.Internal (dsaTruncHash)
import Crypto.Hash.Types (hashDigestSize) import Crypto.Random.Types
-- | Represent a ECDSA signature namely R and S. -- | Represent a ECDSA signature namely R and S.
data Signature = Signature data Signature = Signature
@ -69,7 +67,7 @@ signWith :: (ByteArrayAccess msg, HashAlgorithm hash)
-> msg -- ^ message to sign -> msg -- ^ message to sign
-> Maybe Signature -> Maybe Signature
signWith k (PrivateKey curve d) hashAlg msg = do signWith k (PrivateKey curve d) hashAlg msg = do
let z = tHash hashAlg msg n let z = dsaTruncHash hashAlg msg n
CurveCommon _ _ g n _ = common_curve curve CurveCommon _ _ g n _ = common_curve curve
let point = pointMul curve k g let point = pointMul curve k g
r <- case point of r <- case point of
@ -99,7 +97,7 @@ verify hashAlg pk@(PublicKey curve q) (Signature r s) msg
| r < 1 || r >= n || s < 1 || s >= n = False | r < 1 || r >= n || s < 1 || s >= n = False
| otherwise = maybe False (r ==) $ do | otherwise = maybe False (r ==) $ do
w <- inverse s n w <- inverse s n
let z = tHash hashAlg msg n let z = dsaTruncHash hashAlg msg n
u1 = z * w `mod` n u1 = z * w `mod` n
u2 = r * w `mod` n u2 = r * w `mod` n
x = pointAddTwoMuls curve u1 g u2 q x = pointAddTwoMuls curve u1 g u2 q
@ -109,11 +107,3 @@ verify hashAlg pk@(PublicKey curve q) (Signature r s) msg
where n = ecc_n cc where n = ecc_n cc
g = ecc_g cc g = ecc_g cc
cc = common_curve $ public_curve pk cc = common_curve $ public_curve pk
-- | Truncate and hash.
tHash :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> msg -> Integer -> Integer
tHash hashAlg m n
| d > 0 = shiftR e d
| otherwise = e
where e = os2ip $ hashWith hashAlg m
d = hashDigestSize hashAlg * 8 - numBits n

View File

@ -8,10 +8,17 @@
module Crypto.PubKey.Internal module Crypto.PubKey.Internal
( and' ( and'
, (&&!) , (&&!)
, dsaTruncHash
) where ) where
import Data.Bits (shiftR)
import Data.List (foldl') 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 -- | This is a strict version of and
and' :: [Bool] -> Bool and' :: [Bool] -> Bool
and' l = foldl' (&&!) True l and' l = foldl' (&&!) True l
@ -22,3 +29,11 @@ True &&! True = True
True &&! False = False True &&! False = False
False &&! True = False False &&! True = False
False &&! False = False False &&! False = False
-- | Truncate and hash for DSA and ECDSA.
dsaTruncHash :: (ByteArrayAccess msg, HashAlgorithm hash) => hash -> msg -> Integer -> Integer
dsaTruncHash hashAlg m n
| d > 0 = shiftR e d
| otherwise = e
where e = os2ip $ hashWith hashAlg m
d = hashDigestSize hashAlg * 8 - numBits n

View File

@ -106,7 +106,43 @@ vectorsSHA1 =
, r = 0x8c2fab489c34672140415d41a65cef1e70192e23 , r = 0x8c2fab489c34672140415d41a65cef1e70192e23
, s = 0x3df86a9e2efe944a1c7ea9c30cac331d00599a0e , s = 0x3df86a9e2efe944a1c7ea9c30cac331d00599a0e
, pgq = dsaParams , 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) where -- (p,g,q)
dsaParams = DSA.Params dsaParams = DSA.Params
@ -115,6 +151,174 @@ vectorsSHA1 =
, DSA.params_q = 0xf85f0f83ac4df7ea0cdf8f469bfeeaea14156495 , 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 :: VectorDSA -> DSA.PrivateKey
vectorToPrivate vector = DSA.PrivateKey vectorToPrivate vector = DSA.PrivateKey
{ DSA.private_x = x vector { DSA.private_x = x vector
@ -127,16 +331,32 @@ vectorToPublic vector = DSA.PublicKey
, DSA.public_params = pgq vector , DSA.public_params = pgq vector
} }
doSignatureTest (i, vector) = testCase (show i) (expected @=? actual) doSignatureTest hashAlg (i, vector) = testCase (show i) (expected @=? actual)
where expected = Just $ DSA.Signature (r vector) (s vector) where expected = Just $ DSA.Signature (r vector) (s vector)
actual = DSA.signWith (k vector) (vectorToPrivate vector) SHA1 (msg vector) actual = DSA.signWith (k vector) (vectorToPrivate vector) hashAlg (msg vector)
doVerifyTest (i, vector) = testCase (show i) (True @=? actual) doVerifyTest hashAlg (i, vector) = testCase (show i) (True @=? actual)
where actual = DSA.verify SHA1 (vectorToPublic vector) (DSA.Signature (r vector) (s vector)) (msg vector) where actual = DSA.verify hashAlg (vectorToPublic vector) (DSA.Signature (r vector) (s vector)) (msg vector)
dsaTests = testGroup "DSA" dsaTests = testGroup "DSA"
[ testGroup "SHA1" [ testGroup "SHA1"
[ testGroup "signature" $ map doSignatureTest (zip [katZero..] vectorsSHA1) [ testGroup "signature" $ map (doSignatureTest SHA1) (zip [katZero..] vectorsSHA1)
, testGroup "verify" $ map doVerifyTest (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)
] ]
] ]