|
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,
|
@@ -694,14 +694,28 @@ def verify_digest(
|
694 | 694 | # signature doesn't have to be a bytes-like-object so don't normalise
|
695 | 695 | # it, the decoders will do that
|
696 | 696 | digest = normalise_bytes(digest)
|
697 |
| - if allow_truncate: |
698 |
| - digest = digest[: self.curve.baselen] |
699 |
| - if len(digest) > self.curve.baselen: |
| 697 | + if not allow_truncate and len(digest) > self.curve.baselen: |
700 | 698 | raise BadDigestError(
|
701 | 699 | "this curve (%s) is too short "
|
702 | 700 | "for your digest (%d)" % (self.curve.name, 8 * len(digest))
|
703 | 701 | )
|
704 | 702 | number = string_to_number(digest)
|
| 703 | + if allow_truncate: |
| 704 | + max_length = bit_length(self.curve.order) |
| 705 | + # we don't use bit_length(number) as that truncates leading zeros |
| 706 | + length = len(digest) * 8 |
| 707 | + |
| 708 | + # See NIST FIPS 186-4: |
| 709 | + # |
| 710 | + # When the length of the output of the hash function is greater |
| 711 | + # than N (i.e., the bit length of q), then the leftmost N bits of |
| 712 | + # the hash function output block shall be used in any calculation |
| 713 | + # using the hash function output during the generation or |
| 714 | + # verification of a digital signature. |
| 715 | + # |
| 716 | + # as such, we need to shift-out the low-order bits: |
| 717 | + number >>= max(0, length - max_length) |
| 718 | + |
705 | 719 | try:
|
706 | 720 | r, s = sigdecode(signature, self.pubkey.order)
|
707 | 721 | except (der.UnexpectedDER, MalformedSignature) as e:
|
|
0 commit comments