Do DSS truncation on verify

RFC 4880 and FIPS 186-4 require that DSA signatures truncate the
hash to the size of q.  This changes Crypto.PubKey.DSA.verify
to do so in all cases.
This commit is contained in:
Clint Adams 2016-01-10 17:05:37 -05:00
parent 08edce4ec7
commit 4c6b774a3d

View File

@ -29,14 +29,17 @@ module Crypto.PubKey.DSA
) where
import Crypto.Random.Types
import Data.Bits (testBit)
import Data.Data
import Data.Maybe
import Crypto.Number.Basic (numBits)
import Crypto.Number.ModArithmetic (expFast, expSafe, inverse)
import Crypto.Number.Serialize
import Crypto.Number.Generate
import Crypto.Internal.ByteArray (ByteArrayAccess)
import Crypto.Internal.ByteArray (ByteArrayAccess(length), convert, index, dropView, takeView)
import Crypto.Internal.Imports
import Crypto.Hash
import Prelude hiding (length)
-- | DSA Public Number, usually embedded in DSA Public Key
type PublicNumber = Integer
@ -145,9 +148,11 @@ verify hashAlg pk (Signature r s) m
| otherwise = v == r
where (Params p g q) = public_params pk
y = public_y pk
hm = os2ip $ hashWith hashAlg m
hm = os2ip . truncateHash $ hashWith hashAlg m
w = fromJust $ inverse s q
u1 = (hm*w) `mod` q
u2 = (r*w) `mod` q
v = ((expFast g u1 p) * (expFast y u2 p)) `mod` p `mod` q
-- 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