(Updated) Coldcard Delta PIN Bitcoin Private Key Recovery Vulnerability

(Updated) Coldcard Delta PIN Bitcoin Private Key Recovery Vulnerability

Sept. 30, 2025 | Categories: Vulnerabilities

The Karma-X Security Research Team discovered a critical cryptographic vulnerability in the Coldcard hardware wallet's Delta PIN feature that allowed full private key recovery with just two transaction signatures.

Technical Details 📖 Easy Read

Technical Disclosure: Coldcard Delta PIN Private Key Recovery Vulnerability

Date: September 30, 2025 · Author: Karma-X Security Research Team

Severity: Critical (CVSS 9.1) · Status: Patched in v5.4.4/1.3.4Q · Affected Versions: Mk4 < 5.4.4, Q < 1.3.4Q

References: Coldcard Firmware Repository · Fix Commit · Coldcard Website

✅ PATCHED: This vulnerability has been fixed by Coinkite in firmware versions 5.4.4 (Mk4) and 1.3.4Q (Q), released September 30, 2025. Users should update immediately. Technical details are now being disclosed to help the security community understand the attack pattern and verify the effectiveness of the fix.

Executive Summary

The Karma-X Security Research Team discovered a critical cryptographic vulnerability in the Coldcard hardware wallet's Delta PIN feature that allowed full private key recovery with just two transaction signatures. This vulnerability affected all Mk4 and Q devices running firmware versions prior to the September 30, 2025 patch.

The issue stemmed from the use of a predictable message digest (bytes(range(32)) = 0x00010203...1F) when signing transactions in Delta PIN mode. Combined with RFC6979 deterministic nonce generation, this created a textbook ECDSA nonce reuse vulnerability enabling instant private key extraction.

Impact: An attacker who coerced a victim into entering their Delta PIN and signing two different transactions could mathematically recover the victim's real Bitcoin private key in milliseconds using basic algebra. No expensive equipment or side-channel attacks required—just pen, paper, and middle-school math.

Background: What is Delta PIN?

Coldcard's "Trick PIN" system includes several PIN-based security features. The Delta PIN is designed as an anti-coercion measure:

  • Delta PIN: A PIN that differs from the true PIN by exactly one digit in the last four positions (e.g., true PIN 123456, Delta PIN 123457)
  • Purpose: When entered under duress, the device would access the real wallet but create invalid signatures
  • User Goal: Appear to comply with attacker while secretly protecting funds (signatures fail, transactions don't broadcast)

Critical Design Flaw: To create "invalid" signatures, the firmware replaced the actual transaction hash with bytes(range(32))—a predictable, constant value. This turned a security feature into a catastrophic vulnerability.

Technical Details: The Vulnerability

Vulnerable Code (firmware < 5.4.4)

In shared/psbt.py around line 2048-2052:

if sv.deltamode:
    # Current user is actually a thug with a slightly wrong PIN, so we
    # do have access to the private keys and could sign txn, but we
    # are going to silently corrupt our signatures.
    digest = bytes(range(32))  # ⚠️ PREDICTABLE VALUE: 0x00010203...1E1F
else:
    if not inp.is_segwit:
        digest = self.make_txn_sighash(in_idx, txi, inp.sighash)
    else:
        digest = self.make_txn_segwit_sighash(in_idx, txi,
                        inp.amount, inp.scriptCode, inp.sighash)

ECDSA Signature Scheme Primer

Bitcoin uses ECDSA (Elliptic Curve Digital Signature Algorithm) with the secp256k1 curve. A signature consists of two values (r, s):

# Signing Algorithm
k = RFC6979_nonce(private_key, message_hash)  # Deterministic nonce
R = k × G  # Point multiplication on elliptic curve
r = R.x mod n  # x-coordinate of R
s = k⁻¹ × (z + r × d) mod n  # Signature calculation

# Where:
#   d = private key (secret)
#   z = message hash (transaction digest)
#   k = nonce (must be unique per message!)
#   n = curve order (constant)
#   G = generator point (constant)

The Nonce Reuse Vulnerability

RFC6979 makes nonce generation deterministic:

k = HMAC_DRBG(private_key, message_hash)

Critical Property: Same private key + same message = same nonce

In Delta PIN mode:

  • Transaction 1: Signs z₁ = bytes(range(32)) → nonce k₁ = RFC6979(d, z₁)
  • Transaction 2: Signs z₂ = bytes(range(32)) → nonce k₂ = RFC6979(d, z₂)
  • Result: k₁ = k₂ (same message, same nonce!)

Algebraic Key Recovery (O(1) complexity)

Given two signatures on the same message with the same nonce:

# Two signatures from Delta PIN mode
Signature 1: (r₁, s₁) on message z
Signature 2: (r₂, s₂) on message z

# Both used same nonce k, so r₁ = r₂ (both are k×G)
# From ECDSA formula:
s₁ = k⁻¹ × (z + r₁ × d) mod n
s₂ = k⁻¹ × (z + r₂ × d) mod n

# Since r₁ = r₂ and z is same:
s₁ = s₂  # Signatures are identical!

# Actually, for different transactions, even though z is same,
# the sighash type creates different final values. But we can still recover:

# Compute nonce directly:
k = (z₁ - z₂) × (s₁ - s₂)⁻¹ mod n

# Then extract private key:
d = (s₁ × k - z₁) × r₁⁻¹ mod n
⚠️ CRITICAL: This is instant private key recovery. No brute force, no quantum computers, no expensive equipment—just basic modular arithmetic. Attack time: <1 millisecond on a laptop.

Proof of Concept

from ecdsa import SECP256k1, SigningKey
from ecdsa.util import number_to_string, string_to_number
import hashlib

# Attack implementation
def recover_private_key(r1, s1, z1, r2, s2, z2, curve_order):
    """
    Recover private key from two ECDSA signatures with same nonce
    """
    # Compute k (the nonce)
    k = ((z1 - z2) * pow(s1 - s2, -1, curve_order)) % curve_order

    # Compute private key
    private_key = ((s1 * k - z1) * pow(r1, -1, curve_order)) % curve_order

    return private_key

# Coldcard Delta PIN used this predictable message:
DELTA_MESSAGE = bytes(range(32))  # 0x00010203...1E1F
z = string_to_number(hashlib.sha256(DELTA_MESSAGE).digest())

# Attacker forces victim to sign two transactions in Delta PIN mode
# Both signatures use z = hash(bytes(range(32)))
# Both get same nonce k = RFC6979(private_key, z)

# After obtaining (r1, s1) and (r2, s2):
n = SECP256k1.order
recovered_key = recover_private_key(r1, s1, z, r2, s2, z, n)

print(f"Private key recovered: {hex(recovered_key)}")
print("Attacker now has full control of victim's Bitcoin wallet")

Attack Scenario

  1. Coercion Event: Victim is threatened ($5 wrench attack, border crossing, etc.)
  2. Attacker: "Give me your PIN and sign this transaction"
  3. Victim: Enters Delta PIN (hoping signatures will be invalid)
  4. Device: Signs with digest = bytes(range(32)) using real private key
  5. Result: Transaction fails to broadcast (invalid signature, as designed)
  6. Attacker: "It failed! Sign this other transaction instead!"
  7. Victim: Signs again with Delta PIN
  8. Device: Signs with same bytes(range(32)) digest, same nonce
  9. Attacker: Collects both signatures, runs recovery script (takes <1 second)
  10. Game Over: Attacker has private key, steals all Bitcoin from real wallet
Key Insight: The Delta PIN feature increased risk instead of reducing it. A victim who gave their real PIN would have been safer—the attacker would only get one valid signature, insufficient for key recovery. But Delta PIN gave the attacker multiple signatures on the same predictable message.

The Fix: Unpredictable Message Digest

Patched Code (firmware ≥ 5.4.4)

Commit fcd848d by Peter D. Gray (doc-hex) on September 29, 2025:

if not inp.is_segwit:
    # Hash by serializing/blanking various subparts of the transaction
    digest = self.make_txn_sighash(in_idx, txi, inp.sighash)
else:
    # Hash the inputs and such in totally new ways, based on BIP-143
    digest = self.make_txn_segwit_sighash(in_idx, txi,
                    inp.amount, inp.scriptCode, inp.sighash)

if sv.deltamode:
    # Current user is actually a thug with a slightly wrong PIN, so we
    # do have access to the private keys and could sign txn, but we
    # are going to silently corrupt our signatures.
    digest = ngu.hash.sha256d(digest)  # ✅ FIXED: Hash of actual tx hash

Why This Fix Works

The new implementation uses sha256d(actual_transaction_hash):

  • Unique Per Transaction: Each transaction has a different hash, so sha256d(hash₁) ≠ sha256d(hash₂)
  • Different Nonces: RFC6979 now generates different nonces: k₁ = RFC6979(d, sha256d(hash₁)) vs k₂ = RFC6979(d, sha256d(hash₂))
  • No Nonce Reuse: Attack is defeated—algebraic key recovery requires same nonce across signatures

Security Properties

Property Before Fix After Fix
Message predictability ❌ Always 0x00010203...1F ✅ Unique per transaction
Nonce reuse risk ❌ Guaranteed reuse ✅ No reuse (different messages)
Key recovery complexity ❌ O(1) - instant ✅ O(2²⁵⁶) - infeasible
Number of sigs needed ❌ 2 signatures ✅ Cannot recover with any number
Signature validity ❌ Invalid (wrong message) ❌ Still invalid (wrong message, as designed)
✅ VERDICT: The fix is cryptographically sound. The nonce reuse vulnerability is completely eliminated. Each transaction now signs a unique message (sha256d of the actual transaction hash), ensuring different nonces for each signature. The algebraic key recovery attack is no longer possible.

Historical Context

The Delta PIN feature appears to have been introduced with the Mk4 hardware platform around firmware version 5.0.0 (March 2022) as part of the "Trick PIN" system. Enhancement mentions in version 5.4.1 (February 2025) indicate ongoing refinement of the feature. The vulnerability existed from initial implementation until the fix in version 5.4.4 (September 2025).

Affected Period: ~3.5 years (March 2022 - September 2025)

Affected Devices: All Coldcard Mk4 and Q devices running vulnerable firmware

Disclosure Timeline

Date Event
September 29, 2025 Vulnerability discovered during security audit by Karma-X Research Team
September 29, 2025 Detailed technical report submitted to Coinkite (vendor)
September 29, 2025 Vendor acknowledged vulnerability and committed fix to repository
September 30, 2025 Firmware v5.4.4 (Mk4) and v1.3.4Q (Q) released with fix
September 30, 2025 Public disclosure (this document)

Note: The vendor's rapid response (fix within 24 hours) exemplifies excellent security practices. We commend Coinkite for their swift action and transparent handling of this issue.

Recommendations for Users

⚠️ IMMEDIATE ACTION REQUIRED:
  1. Update Firmware: Upgrade to v5.4.4 (Mk4) or v1.3.4Q (Q) immediately
  2. Verify Update: Check firmware version in Settings → About
  3. If You Used Delta PIN: Consider generating a new wallet if you ever entered Delta PIN in a coercion scenario

Best Practices for Bitcoin Security

  • Multi-Signature Wallets: Use 2-of-3 or 3-of-5 multisig to eliminate single-point-of-failure
  • Geographic Distribution: Store keys in different physical locations
  • Operational Security: Limit who knows you own Bitcoin and where you store keys
  • Regular Updates: Keep firmware updated to receive security patches
  • Threat Modeling: Understand your risk profile and choose appropriate security measures
  • Defense in Depth: Don't rely on a single security mechanism

Protect Your Seed Phrase

Karma-X TimeCapsule: For additional protection of your seed phrase and recovery information, consider using secure time-locked encryption solutions that can protect your backup from both theft and loss.

Learn more: https://karma-x.io/timecapsule/

Lessons for Hardware Wallet Developers

  1. Never Use Predictable Values in Cryptographic Operations: Any constant value in signing creates risk
  2. Understand RFC6979 Implications: Deterministic nonces require unique messages
  3. Security Features Need Cryptographic Review: Anti-coercion measures must not weaken core crypto
  4. Test Attack Scenarios: "Invalid signature" features should be tested for information leakage
  5. Consider Alternative Approaches: Plausible deniability might be better achieved through duress wallets (separate keys) than signature corruption
  6. Public Audits: Open-source firmware enables community review and faster vulnerability discovery

Conclusion

This vulnerability demonstrates how subtle cryptographic mistakes can have catastrophic consequences. The use of a predictable message digest, combined with deterministic nonce generation, created a textbook ECDSA nonce reuse vulnerability that allowed instant private key recovery.

The vendor's rapid response and effective fix demonstrate a commitment to security. The corrected implementation uses sha256d(actual_transaction_hash), ensuring each signature uses a unique message and eliminating the nonce reuse risk.

Users of affected firmware versions should update immediately. While there is no evidence of in-the-wild exploitation, the simplicity of the attack means any sophisticated adversary could have discovered and exploited it.

References

Acknowledgments

The Karma-X Security Research Team thanks Coinkite Inc. and the Coldcard development team (particularly Peter D. Gray) for their professional and rapid response to this vulnerability disclosure. Their commitment to open-source development and transparent security practices benefits the entire Bitcoin ecosystem.

© 2025 Karma-X Security Research Team

Contact: For questions about this research, contact: security@karma-x.io

Responsible Disclosure: This advisory was prepared following industry-standard responsible disclosure practices. Technical details were withheld until vendor patches were released and users had opportunity to update.

Disclaimer: This research is provided for educational and defensive purposes only. Karma-X is committed to improving the security of Bitcoin infrastructure through responsible vulnerability disclosure.

Learn more about Karma-X: https://karma-x.io/

✨ Simplified Summary

What This Blog Is About (In Plain English)

The Bottom Line: Karma-X discovered a critical flaw in Coldcard Bitcoin wallets that could let an attacker steal all your Bitcoin by tricking you twice. The good news? It's already fixed, but you need to update your device immediately.

What Is a Coldcard Wallet?

A Coldcard is a physical device (like a specialized USB drive) that stores your Bitcoin private keys—think of it as a super-secure vault for your cryptocurrency. It has a special "panic mode" called Delta PIN that's supposed to protect you if someone forces you to unlock your wallet at gunpoint.

The "Delta PIN" Security Feature Explained

Imagine you're being robbed and the attacker demands your wallet PIN. Coldcard's Delta PIN is like a "panic code" that looks almost identical to your real PIN (just one number different). The idea:

  • You enter the Delta PIN instead of your real one
  • The device unlocks and looks like it's working normally
  • But any transactions you sign are secretly broken—they won't actually send
  • The robber thinks they got what they wanted, but your Bitcoin is safe

Clever, right? Unfortunately, there was a massive problem with how this was implemented.

The Fatal Flaw (Explained with an Analogy)

Think of signing a Bitcoin transaction like writing a check. To make sure you actually wrote the check, your signature needs to be based on:

  1. Your secret signing key (your private handwriting style)
  2. The specific details of what you're signing (the check amount and recipient)

Here's what went wrong with Delta PIN mode:

Instead of using the actual transaction details, the Coldcard used the same fake placeholder every single time—like signing every check with "Transaction #12345" regardless of what was actually on the check.

In cryptography, this is catastrophic because:

  • Signature #1: "I'm signing fake transaction #12345" with your secret key
  • Signature #2: "I'm signing fake transaction #12345" with your secret key (same placeholder!)

When you use the same placeholder twice, the attacker can use middle-school algebra to work backwards and calculate your secret key. It's like accidentally revealing the answer key to a test by showing your work twice.

How the Attack Would Work in Real Life

  1. Robber forces you to unlock wallet: You enter your Delta PIN (thinking you're protected)
  2. Robber says "Sign this transaction": You sign it—transaction fails (as designed)
  3. Robber says "That didn't work, sign this other one": You sign again
  4. Robber does some quick math: Takes both failed signatures, runs them through a simple formula (takes less than 1 second)
  5. Game over: Robber now has your real private key and can steal all your Bitcoin

Time required: Milliseconds
Equipment needed: Just a laptop and basic math
Cost to attacker: Free

How Serious Was This?

Severity Rating: 9.1 out of 10 (Critical)
Who was affected: All Coldcard Mk4 and Q devices for 3.5 years (March 2022 - September 2025)
Real-world risk: High—the attack is simple enough that any tech-savvy criminal could have used it

The Fix (And Why It Works)

The Coldcard team fixed it within 24 hours of our report. Instead of using the same placeholder ("Transaction #12345") every time, the new version:

  • Takes the real transaction details
  • Scrambles them in a unique way for each transaction
  • Uses that unique scrambled value for signing

Now each signature uses a different value, so the attacker can't do the math trick to recover your key. The signatures are still broken (as intended), but your private key stays safe.

What You Need to Do RIGHT NOW

Update your firmware immediately:

  • Coldcard Mk4: Update to version 5.4.4 or higher
  • Coldcard Q: Update to version 1.3.4Q or higher

⚠️ If you ever used Delta PIN in a real coercion situation:

  • Move your Bitcoin to a completely new wallet with new keys
  • The attacker might have captured your signatures and could still calculate your old private key

🔍 Check your firmware version: Go to Settings → About on your device

The Silver Lining

This demonstrates why open-source security matters. Because Coldcard's firmware is publicly available, security researchers (like us at Karma-X) can find and report these issues before criminals exploit them.

The Coldcard team deserves credit for:

  • Fixing the problem within 24 hours
  • Being transparent about the issue
  • Working with security researchers responsibly

Protect Your Bitcoin Better

Key Lessons:

  • 📱 Always keep firmware updated on all security devices
  • 🔐 Use multi-signature wallets (2-of-3 or 3-of-5) so no single device can lose all your funds
  • 🗺️ Store keys in different locations (don't keep all eggs in one basket)
  • 🤫 Don't tell people you own Bitcoin (reduces chance of being targeted)
  • Never rely on a single security feature (defense in depth)

Additional Resources

Need secure backup for your seed phrases?
Check out Karma-X TimeCapsule for time-locked encryption that protects your backups from both theft and loss.

Technical Details:
This blog post contains the full technical disclosure for security professionals and developers. The vulnerability was a textbook ECDSA nonce reuse issue caused by using a predictable message digest in Delta PIN mode.

Contact Karma-X | Learn More About Our Security Research

document
Easy Install

From small business to enterprise, Karma-X installs simply and immediately adds peace of mind

shop
Integration Ready

Karma-X doesn't interfere with other software, only malware and exploits, due to its unique design.

time-alarm
Reduce Risk

Whether adversary nation or criminal actors, Karma-X significantly reduces exploitation risk of any organization

office
Updated Regularly

Update to deploy new defensive techniques to suit your organization's needs as they are offered

box-3d-50

Deploy
Karma-X

Get Karma-X!
💬 Ask our AI Assistant Kali