@@ -124,6 +124,38 @@ class MalformedPointError(AssertionError):
124124 pass
125125
126126
127+ def _truncate_and_convert_digest (digest , curve , allow_truncate ):
128+ """Truncates and converts digest to an integer."""
129+ if not allow_truncate :
130+ if len (digest ) > curve .baselen :
131+ raise BadDigestError (
132+ "this curve ({0}) is too short "
133+ "for the length of your digest ({1})" .format (
134+ curve .name , 8 * len (digest )
135+ )
136+ )
137+ else :
138+ digest = digest [: curve .baselen ]
139+ number = string_to_number (digest )
140+ if allow_truncate :
141+ max_length = bit_length (curve .order )
142+ # we don't use bit_length(number) as that truncates leading zeros
143+ length = len (digest ) * 8
144+
145+ # See NIST FIPS 186-4:
146+ #
147+ # When the length of the output of the hash function is greater
148+ # than N (i.e., the bit length of q), then the leftmost N bits of
149+ # the hash function output block shall be used in any calculation
150+ # using the hash function output during the generation or
151+ # verification of a digital signature.
152+ #
153+ # as such, we need to shift-out the low-order bits:
154+ number >>= max (0 , length - max_length )
155+
156+ return number
157+
158+
127159class VerifyingKey (object ):
128160 """
129161 Class for handling keys that can verify signatures (public keys).
@@ -435,7 +467,13 @@ def from_der(cls, string, hashfunc=sha1):
435467
436468 @classmethod
437469 def from_public_key_recovery (
438- cls , signature , data , curve , hashfunc = sha1 , sigdecode = sigdecode_string
470+ cls ,
471+ signature ,
472+ data ,
473+ curve ,
474+ hashfunc = sha1 ,
475+ sigdecode = sigdecode_string ,
476+ allow_truncate = False ,
439477 ):
440478 """
441479 Return keys that can be used as verifiers of the provided signature.
@@ -458,6 +496,9 @@ def from_public_key_recovery(
458496 a tuple with two integers, "r" as the first one and "s" as the
459497 second one. See :func:`ecdsa.util.sigdecode_string` and
460498 :func:`ecdsa.util.sigdecode_der` for examples.
499+ :param bool allow_truncate: if True, the provided hashfunc can generate
500+ values larger than the bit size of the order of the curve, the
501+ extra bits (at the end of the digest) will be truncated.
461502 :type sigdecode: callable
462503
463504 :return: Initialised VerifyingKey objects
@@ -466,7 +507,12 @@ def from_public_key_recovery(
466507 data = normalise_bytes (data )
467508 digest = hashfunc (data ).digest ()
468509 return cls .from_public_key_recovery_with_digest (
469- signature , digest , curve , hashfunc = hashfunc , sigdecode = sigdecode
510+ signature ,
511+ digest ,
512+ curve ,
513+ hashfunc = hashfunc ,
514+ sigdecode = sigdecode ,
515+ allow_truncate = allow_truncate ,
470516 )
471517
472518 @classmethod
@@ -477,6 +523,7 @@ def from_public_key_recovery_with_digest(
477523 curve ,
478524 hashfunc = sha1 ,
479525 sigdecode = sigdecode_string ,
526+ allow_truncate = False ,
480527 ):
481528 """
482529 Return keys that can be used as verifiers of the provided signature.
@@ -500,7 +547,9 @@ def from_public_key_recovery_with_digest(
500547 second one. See :func:`ecdsa.util.sigdecode_string` and
501548 :func:`ecdsa.util.sigdecode_der` for examples.
502549 :type sigdecode: callable
503-
550+ :param bool allow_truncate: if True, the provided hashfunc can generate
551+ values larger than the bit size of the order of the curve, the
552+ extra bits (at the end of the digest) will be truncated.
504553
505554 :return: Initialised VerifyingKey object
506555 :rtype: VerifyingKey
@@ -510,7 +559,9 @@ def from_public_key_recovery_with_digest(
510559 sig = ecdsa .Signature (r , s )
511560
512561 digest = normalise_bytes (digest )
513- digest_as_number = string_to_number (digest )
562+ digest_as_number = _truncate_and_convert_digest (
563+ digest , curve , allow_truncate
564+ )
514565 pks = sig .recover_public_keys (digest_as_number , generator )
515566
516567 # Transforms the ecdsa.Public_key object into a VerifyingKey
@@ -717,27 +768,9 @@ def verify_digest(
717768 # signature doesn't have to be a bytes-like-object so don't normalise
718769 # it, the decoders will do that
719770 digest = normalise_bytes (digest )
720- if not allow_truncate and len (digest ) > self .curve .baselen :
721- raise BadDigestError (
722- "this curve (%s) is too short "
723- "for your digest (%d)" % (self .curve .name , 8 * len (digest ))
724- )
725- number = string_to_number (digest )
726- if allow_truncate :
727- max_length = bit_length (self .curve .order )
728- # we don't use bit_length(number) as that truncates leading zeros
729- length = len (digest ) * 8
730-
731- # See NIST FIPS 186-4:
732- #
733- # When the length of the output of the hash function is greater
734- # than N (i.e., the bit length of q), then the leftmost N bits of
735- # the hash function output block shall be used in any calculation
736- # using the hash function output during the generation or
737- # verification of a digital signature.
738- #
739- # as such, we need to shift-out the low-order bits:
740- number >>= max (0 , length - max_length )
771+ number = _truncate_and_convert_digest (
772+ digest , self .curve , allow_truncate ,
773+ )
741774
742775 try :
743776 r , s = sigdecode (signature , self .pubkey .order )
@@ -1409,14 +1442,9 @@ def sign_digest(
14091442 :rtype: bytes or sigencode function dependant type
14101443 """
14111444 digest = normalise_bytes (digest )
1412- if allow_truncate :
1413- digest = digest [: self .curve .baselen ]
1414- if len (digest ) > self .curve .baselen :
1415- raise BadDigestError (
1416- "this curve (%s) is too short "
1417- "for your digest (%d)" % (self .curve .name , 8 * len (digest ))
1418- )
1419- number = string_to_number (digest )
1445+ number = _truncate_and_convert_digest (
1446+ digest , self .curve , allow_truncate ,
1447+ )
14201448 r , s = self .sign_number (number , entropy , k )
14211449 return sigencode (r , s , self .privkey .order )
14221450
0 commit comments