AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
High 72 Bitcoin

btcutil: reject out-of-range private keys in DecodeWIF

Public commit record

What the developer wrote

Authored by Lrifton92

88/100 · Strong
btcutil: reject out-of-range private keys in DecodeWIF

DecodeWIF did not validate that the decoded private key falls within the
valid range [1, N-1] for a secp256k1 private key. The raw 32-byte key
material was passed straight to btcec.PrivKeyFromBytes, which reduces the
scalar modulo the group order N and clamps to zero, returning no error.

As a result, a WIF encoding a private key of zero, the group order N, or
any value >= N was silently accepted. For keys >= N this is particularly
dangerous: DecodeWIF returned a private key that differs from the one
actually encoded in the WIF (e.g. a WIF for N+5 decoded to the key 5),
so an application importing such a WIF would obtain a valid-looking but
wrong key pair, with no indication that anything was off. This is also
inconsistent with hdkeychain.NewKeyFromString in the same package, which
already rejects private keys outside [1, N-1].

Validate the range using a ModNScalar (constant time): SetByteSlice
reports an overflow when the value is >= N, and IsZero covers the zero
key. Out-of-range keys now return ErrMalformedPrivateKey.

Add regression test cases (zero, N, and N+5) to TestEncodeDecodeWIF.

Signed-off-by: Lrifton92 <Lrifton92@users.noreply.github.com>
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Names security-relevant behavior explicitly
The short version

What changed, and why it matters

This commit fixes a bug in how btcd decodes Bitcoin private keys stored in the common Wallet Import Format (WIF). Previously, the software silently accepted invalid private keys, including the all-zero key and keys larger than the allowed secp256k1 group order. For keys larger than the allowed maximum, the library would quietly reduce the value modulo the group order, returning a different, valid-looking private key than the one actually encoded in the WIF. This could cause a wallet or application to import the wrong key without any warning, potentially leading to loss of funds or unexpected addresses. The fix now rejects these out-of-range keys and returns an error instead.

Recommended action

Upgrade to a btcd version containing this commit. Applications that import WIF strings should treat prior DecodeWIF behavior as potentially unsafe and re-validate any imported keys. Developers should audit any code paths that previously relied on DecodeWIF accepting arbitrary 32-byte values.

Security signals we found

01

Silent acceptance of out-of-range secp256k1 private keys

02

Private key scalar reduced modulo group order without error

03

Potential key mismatch between WIF encoding and decoded key

04

Inconsistent validation compared to hdkeychain.NewKeyFromString

05

Addition of constant-time range validation using ModNScalar

Risk score

Why this scored 72/100

Our methodology →
Potential impact 22/30
Exploitability 14/25
Stealth signal 12/15
Affected reach 10/15
Confidence 9/10
Evidence quality 5/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.