Skip to content

bug: nonce-reuse recovery without pubkey silently returns wrong key on BIP62-mixed signatures #19

Description

@oritwoen

When recovering a private key from nonce reuse without a pubkey, the tool only tries the original s-values as-is. If the two signatures have mixed low-s/high-s normalization (BIP62), the math produces an incorrect private key — and the tool reports it as successfully recovered with no warning.

The pubkey code path handles this correctly by trying both s2 and -s2 and verifying d*G == pubkey. But the no-pubkey path at nonce_reuse.rs:77-86 skips that entirely:

// pubkey is None — uses raw s values, no polarity check
let k = recover_nonce(&sig1.z, &sig2.z, &sig1.s, &sig2.s)?;
let priv_key = recover_private_key(&sig1.r, &sig1.s, &sig1.z, &k)?;
Some(RecoveredKey { ... }) // returned as "recovered", no verification

Mixed s-normalization is common in real Bitcoin transaction data (pre-BIP62 vs post-BIP62 signatures from the same key). The tool confidently outputs a wrong key in this case.

Expected behavior: Without a pubkey, the tool should either try both s-polarities and return both candidate keys, or flag the result as unverified. Even a note in the output that the result is one of two possibilities would prevent misuse.

Affected: src/attack/nonce_reuse.rs, try_recover_pair() — the else branch (no pubkey).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions