ECDSA with digest
This commit is contained in:
parent
15327ecd4f
commit
b9a8a6b83d
@ -37,8 +37,11 @@ module Crypto.PubKey.ECDSA
|
|||||||
, signatureToIntegers
|
, signatureToIntegers
|
||||||
-- * Generation and verification
|
-- * Generation and verification
|
||||||
, signWith
|
, signWith
|
||||||
|
, signDigestWith
|
||||||
, sign
|
, sign
|
||||||
|
, signDigest
|
||||||
, verify
|
, verify
|
||||||
|
, verifyDigest
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
@ -162,11 +165,11 @@ toPublic :: EllipticCurveECDSA curve
|
|||||||
=> proxy curve -> PrivateKey curve -> PublicKey curve
|
=> proxy curve -> PrivateKey curve -> PublicKey curve
|
||||||
toPublic = pointBaseSmul
|
toPublic = pointBaseSmul
|
||||||
|
|
||||||
-- | Sign message using the private key and an explicit k scalar.
|
-- | Sign digest using the private key and an explicit k scalar.
|
||||||
signWith :: (EllipticCurveECDSA curve, ByteArrayAccess msg, HashAlgorithm hash)
|
signDigestWith :: (EllipticCurveECDSA curve, HashAlgorithm hash)
|
||||||
=> proxy curve -> Scalar curve -> PrivateKey curve -> hash -> msg -> Maybe (Signature curve)
|
=> proxy curve -> Scalar curve -> PrivateKey curve -> Digest hash -> Maybe (Signature curve)
|
||||||
signWith prx k d hashAlg msg = do
|
signDigestWith prx k d digest = do
|
||||||
let z = tHash prx hashAlg msg
|
let z = tHashDigest prx digest
|
||||||
point = pointBaseSmul prx k
|
point = pointBaseSmul prx k
|
||||||
r <- pointX prx point
|
r <- pointX prx point
|
||||||
kInv <- scalarInv prx k
|
kInv <- scalarInv prx k
|
||||||
@ -174,24 +177,34 @@ signWith prx k d hashAlg msg = do
|
|||||||
when (scalarIsZero prx r || scalarIsZero prx s) Nothing
|
when (scalarIsZero prx r || scalarIsZero prx s) Nothing
|
||||||
return $ Signature r s
|
return $ Signature r s
|
||||||
|
|
||||||
|
-- | Sign message using the private key and an explicit k scalar.
|
||||||
|
signWith :: (EllipticCurveECDSA curve, ByteArrayAccess msg, HashAlgorithm hash)
|
||||||
|
=> proxy curve -> Scalar curve -> PrivateKey curve -> hash -> msg -> Maybe (Signature curve)
|
||||||
|
signWith prx k d hashAlg msg = signDigestWith prx k d (hashWith hashAlg msg)
|
||||||
|
|
||||||
|
-- | Sign a digest using hash and private key.
|
||||||
|
signDigest :: (EllipticCurveECDSA curve, MonadRandom m, HashAlgorithm hash)
|
||||||
|
=> proxy curve -> PrivateKey curve -> Digest hash -> m (Signature curve)
|
||||||
|
signDigest prx pk digest = do
|
||||||
|
k <- curveGenerateScalar prx
|
||||||
|
case signDigestWith prx k pk digest of
|
||||||
|
Nothing -> signDigest prx pk digest
|
||||||
|
Just sig -> return sig
|
||||||
|
|
||||||
-- | Sign a message using hash and private key.
|
-- | Sign a message using hash and private key.
|
||||||
sign :: (EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg, HashAlgorithm hash)
|
sign :: (EllipticCurveECDSA curve, MonadRandom m, ByteArrayAccess msg, HashAlgorithm hash)
|
||||||
=> proxy curve -> PrivateKey curve -> hash -> msg -> m (Signature curve)
|
=> proxy curve -> PrivateKey curve -> hash -> msg -> m (Signature curve)
|
||||||
sign prx pk hashAlg msg = do
|
sign prx pk hashAlg msg = signDigest prx pk (hashWith hashAlg msg)
|
||||||
k <- curveGenerateScalar prx
|
|
||||||
case signWith prx k pk hashAlg msg of
|
|
||||||
Nothing -> sign prx pk hashAlg msg
|
|
||||||
Just sig -> return sig
|
|
||||||
|
|
||||||
-- | Verify a signature using hash and public key.
|
-- | Verify a digest using hash and public key.
|
||||||
verify :: (EllipticCurveECDSA curve, ByteArrayAccess msg, HashAlgorithm hash)
|
verifyDigest :: (EllipticCurveECDSA curve, HashAlgorithm hash)
|
||||||
=> proxy curve -> hash -> PublicKey curve -> Signature curve -> msg -> Bool
|
=> proxy curve -> PublicKey curve -> Signature curve -> Digest hash -> Bool
|
||||||
verify prx hashAlg q (Signature r s) msg
|
verifyDigest prx q (Signature r s) digest
|
||||||
| not (scalarIsValid prx r) = False
|
| not (scalarIsValid prx r) = False
|
||||||
| not (scalarIsValid prx s) = False
|
| not (scalarIsValid prx s) = False
|
||||||
| otherwise = maybe False (r ==) $ do
|
| otherwise = maybe False (r ==) $ do
|
||||||
w <- scalarInv prx s
|
w <- scalarInv prx s
|
||||||
let z = tHash prx hashAlg msg
|
let z = tHashDigest prx digest
|
||||||
u1 = scalarMul prx z w
|
u1 = scalarMul prx z w
|
||||||
u2 = scalarMul prx r w
|
u2 = scalarMul prx r w
|
||||||
x = pointsSmulVarTime prx u1 u2 q
|
x = pointsSmulVarTime prx u1 u2 q
|
||||||
@ -199,13 +212,21 @@ verify prx hashAlg q (Signature r s) msg
|
|||||||
-- Note: precondition q /= PointO is not tested because we assume
|
-- Note: precondition q /= PointO is not tested because we assume
|
||||||
-- point decoding never decodes point at infinity.
|
-- point decoding never decodes point at infinity.
|
||||||
|
|
||||||
-- | Truncate and hash.
|
-- | Verify a signature using hash and public key.
|
||||||
tHash :: (EllipticCurveECDSA curve, ByteArrayAccess msg, HashAlgorithm hash)
|
verify :: (EllipticCurveECDSA curve, ByteArrayAccess msg, HashAlgorithm hash)
|
||||||
=> proxy curve -> hash -> msg -> Scalar curve
|
=> proxy curve -> hash -> PublicKey curve -> Signature curve -> msg -> Bool
|
||||||
tHash prx hashAlg m =
|
verify prx hashAlg q sig msg = verifyDigest prx q sig (hashWith hashAlg msg)
|
||||||
|
|
||||||
|
-- | Truncate a digest based on curve order size.
|
||||||
|
tHashDigest :: (EllipticCurveECDSA curve, HashAlgorithm hash)
|
||||||
|
=> proxy curve -> Digest hash -> Scalar curve
|
||||||
|
tHashDigest prx digest =
|
||||||
throwCryptoError $ scalarFromInteger prx (if d > 0 then shiftR e d else e)
|
throwCryptoError $ scalarFromInteger prx (if d > 0 then shiftR e d else e)
|
||||||
where e = os2ip $ hashWith hashAlg m
|
where e = os2ip digest
|
||||||
d = hashDigestSize hashAlg * 8 - curveOrderBits prx
|
d = hashDigestSize (getHashAlg digest) * 8 - curveOrderBits prx
|
||||||
|
|
||||||
|
getHashAlg :: Digest hash -> hash
|
||||||
|
getHashAlg _ = undefined
|
||||||
|
|
||||||
|
|
||||||
ecScalarIsValid :: Simple.Curve c => proxy c -> Simple.Scalar c -> Bool
|
ecScalarIsValid :: Simple.Curve c => proxy c -> Simple.Scalar c -> Bool
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user