|
77 | 77 | from .numbertheory import square_root_mod_prime, SquareRootError
|
78 | 78 | from .ecdsa import RSZeroError
|
79 | 79 | from .util import string_to_number, number_to_string, randrange
|
80 |
| -from .util import sigencode_string, sigdecode_string |
| 80 | +from .util import sigencode_string, sigdecode_string, bit_length |
81 | 81 | from .util import (
|
82 | 82 | oid_ecPublicKey,
|
83 | 83 | encoded_oid_ecPublicKey,
|
@@ -717,14 +717,28 @@ def verify_digest(
|
717 | 717 | # signature doesn't have to be a bytes-like-object so don't normalise
|
718 | 718 | # it, the decoders will do that
|
719 | 719 | digest = normalise_bytes(digest)
|
720 |
| - if allow_truncate: |
721 |
| - digest = digest[: self.curve.baselen] |
722 |
| - if len(digest) > self.curve.baselen: |
| 720 | + if not allow_truncate and len(digest) > self.curve.baselen: |
723 | 721 | raise BadDigestError(
|
724 | 722 | "this curve (%s) is too short "
|
725 | 723 | "for your digest (%d)" % (self.curve.name, 8 * len(digest))
|
726 | 724 | )
|
727 | 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) |
| 741 | + |
728 | 742 | try:
|
729 | 743 | r, s = sigdecode(signature, self.pubkey.order)
|
730 | 744 | except (der.UnexpectedDER, MalformedSignature) as e:
|
|
0 commit comments