Skip to content

Accept ECDSA signatures shorter than 71 bytes - #69

Merged
raphjaph merged 4 commits into
rust-bitcoin:masterfrom
johnzilla:fix-ecdsa-signature-length
Jul 30, 2026
Merged

Accept ECDSA signatures shorter than 71 bytes#69
raphjaph merged 4 commits into
rust-bitcoin:masterfrom
johnzilla:fix-ecdsa-signature-length

Conversation

@johnzilla

Copy link
Copy Markdown
Contributor

verify_full_p2wpkh gated the encoded ECDSA signature length on 71 | 72 and rejected everything else with Error::SignatureLength. ECDSA signatures aren't fixed length — a low-S DER signature is shorter than 71 bytes when r or s serialize to fewer than 32 bytes (~1% of signatures) — so valid signatures that sign_simple itself produces were rejected by verify_simple.

This peels the trailing sighash flag off and lets from_der validate the remainder instead of gating on length, with an empty-input guard so the slice index can't panic. The taproot path is unchanged.

Adds a P2WPKH regression vector (a 70-byte signature); it fails on master and passes with this change. cargo fmt --check, cargo clippy --all --all-targets -- --deny warnings, and cargo test --all are green.

Fixes #68.

Comment thread src/verify.rs Outdated

@aagbotemi aagbotemi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 742487f

@johnzilla could you also sign your commits, to match the convention used by the rest of the codebase?

Comment thread src/error.rs Outdated
johnzilla and others added 2 commits June 30, 2026 09:56
ECDSA signatures are not fixed length: a low-S DER signature is shorter
than the usual 71 or 72 bytes when r or s serialize to fewer than 32
bytes (roughly 1% of signatures). verify_full_p2wpkh matched the encoded
signature length against `71 | 72` and rejected everything else with
Error::SignatureLength, so a valid signature that sign_simple itself can
produce was rejected by verify_simple.

Split the trailing sighash flag off and let from_der validate the
remainder rather than gating on length. The empty case is guarded so the
slice index cannot panic.
from_consensus folds unrecognized sighash bytes to All, so a signature
with a non-standard flag would pass the == All check. Parse with
from_standard instead, which errors on anything that isn't a standard
sighash type, matching the strictness of the taproot path. Adds a
SigHashTypeNonStandard error variant for the parse failure.

Co-authored-by: aagbotemi <63763418+aagbotemi@users.noreply.github.com>
@johnzilla
johnzilla force-pushed the fix-ecdsa-signature-length branch from 742487f to d33307e Compare June 30, 2026 13:56
@johnzilla

Copy link
Copy Markdown
Contributor Author

Heads up: I force-pushed to sign both commits with my SSH key (they show as Verified now). No content change from what you reviewed, just the signatures added.

johnzilla and others added 2 commits June 30, 2026 09:59
Co-authored-by: Abiodun Awoyemi <63763418+aagbotemi@users.noreply.github.com>
…a-signature-length

# Conflicts:
#	src/verify.rs

@raphjaph raphjaph left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@raphjaph
raphjaph merged commit 8db772b into rust-bitcoin:master Jul 30, 2026
13 checks passed
@johnzilla
johnzilla deleted the fix-ecdsa-signature-length branch July 30, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

verify_simple rejects valid ECDSA signatures shorter than 71 bytes

3 participants