gpg --verify Needs the Data File

For detached signatures, this command is easily bypassable:

gpg --verify SHA256SUMS.asc

The correct command requires the data file:

gpg --verify SHA256SUMS.asc SHA256SUMS

Without the second argument, gpg succeeds even if the .asc file contains an arbitrary embedded message instead of a signature of the actual SHA256SUMS file. gpg prints a warning, but it is easily missed in its output. The gpg manpage explicitly discourages the single-argument form and keeps it only for backward compatibility.

This appears to be a common mistake. I keep a list of gpg pitfalls, and this is number 8. Mehdi Kerimov reported it in nix-bitcoin’s self-updater through the nix-bitcoin bounty program. nix-bitcoin had originally followed the verification instructions on bitcoincore.org, which had the same issue and have since been fixed. That this sat unnoticed on bitcoincore.org since 2018 shows how little known this footgun is.

It is unlikely that bad signatures were ever published at scale, because anyone noticing the warning or using the two-argument command would have caught it immediately.

BIP SHRINCS

We published BIP SHRINCS, the first concrete proposal for a post-quantum signature scheme designed specifically for Bitcoin. The draft BIP turns what began as a rough idea into exact algorithms with an executable reference implementation. The discussion can now focus on analyzing, criticizing, and improving a concrete proposal.

The BIP makes choices ranging from major design questions, such as whether to support flexible XMSS and how to balance signature size against verification time, to the many smaller decisions involved in saving a byte here or there. All of these choices are up for debate.

A lot more work lies ahead:

  • The draft BIP specifies only the cryptography. Using SHRINCS in Bitcoin Script will require a separate BIP.
  • We are working on a security proof for the exact construction and parameters.
  • Wallet integration and user experience, for example around backups and recovery after state loss, are still at an early stage.

SHRINCS is not intended to be Bitcoin’s “final” signature scheme, and it is not optimal along every axis. I do think it is a very good trade-off among the options we have now.

Thanks to Mike Casey, conduition, Ethan Heilman, Mikhail Kudinov, Oleksandr Kurbatov, Boris Nagaev, and remix7531 for their contributions. The announcement is on the bitcoin-dev mailing list.

Background

SHRINCS combines a stateful and a stateless hash-based signature scheme. The signer primarily uses the stateful scheme and falls back to the stateless scheme when the signing state is unavailable, for example after seed recovery. In the current version of the draft BIP, stateful signatures are 548 to 4,619 bytes, depending on the shape of the signer’s tree and how often the key has signed, and stateless signatures are 5,777 bytes. These numbers may still change.

The stateful scheme is limited to a single device. SHRIMPS addresses multiple devices: assuming an upper bound on the number of devices initialized from the same seed (e.g., 1024), any of them creates signatures of about 2.5 KB, three times smaller than SLH-DSA. Combined, the primary device signs with SHRINCS and backup devices with SHRIMPS, all from the same static seed backup.

At OP_NEXT 2026, I presented a toy proposal for hash-based signatures in Bitcoin that includes SHRINCS (video, slides). remix7531 and I also published libshrincs, a proof-of-concept C implementation of WOTS+C, the one-time signature used by SHRINCS. Its machine-checked proofs connect the C implementation to an unforgeability theorem, which does not yet give a full post-quantum security bound.

Hash-Based Signatures for Bitcoin

Mikhail Kudinov and I at Blockstream Research published Hash-based Signatures for Bitcoin, an analysis of post-quantum signature schemes. The paper is a gentle introduction to hash-based schemes and explores how to optimize them for Bitcoin.

Hash-based signatures are conceptually simple and rely solely on hash functions, a primitive Bitcoin already trusts. NIST has standardized SLH-DSA (SPHINCS+), but the paper investigates alternatives that are better suited to Bitcoin’s needs. It explores in detail how optimizations and parameter choices affect size and performance. Signatures can be reduced to about 3–4 KB, which is comparable to the lattice-based ML-DSA.

The paper also discusses:

  • trade-offs between stateless and stateful schemes,
  • compatibility with HD wallets,
  • limitations of current approaches for multi- and threshold signatures,
  • security targets.

We welcome feedback, particularly on hardware performance requirements and standardization choices. The scripts that generate the parameter analysis are on GitHub.

Provable Cryptography for Bitcoin: An Introduction

Provable Cryptography for Bitcoin: An Introduction is a workbook that teaches formal security definitions and proofs through exercises. Solutions are included.

The workbook was tested during a multi-day workshop, and I thank the participants for their feedback and contributions. Nadav Kohen’s prework material is a good preparation. For more context, see the Delving Bitcoin post.

Feedback and contributions as GitHub issues and pull requests are welcome.

ChillDKG at Real World Crypto 2025

FROST enables t-of-n wallets, but its distributed key generation (DKG) has been notoriously difficult to implement securely. My talk at Real World Crypto 2025 presents the draft ChillDKG BIP from Blockstream Research as a ready-to-implement solution.

DahLIAS: Discrete Logarithm-Based Interactive Aggregate Signatures

Tim Ruffing, Yannick Seurin and I published DahLIAS, the first protocol for full cross-input signature aggregation (CISA) that can reuse Bitcoin’s curve, secp256k1.

  • Aggregate signatures are 64 bytes.
  • Verification is about twice as fast as for half-aggregated Schnorr signatures.
  • Signing takes two rounds.

For more background on cross-input signature aggregation in Bitcoin, see Fabian Jahr’s report for the Human Rights Foundation.

MuSig2 in libsecp256k1

The MuSig2 module has been merged into libsecp256k1 and will be part of the next release. This makes MuSig2 available to all projects that use libsecp256k1.

The module is designed to be as safe to use as possible. Its documentation gives two rules that prevent nonce reuse if the implementer follows them. See the example for how to use it.

Since its merge into libsecp256k1-zkp, the module received 333 review comments, and no significant security issue was found. Thanks to the reviewers Tim Ruffing, Sebastian Falbesoner, Pieter Wuille, Josie Baker, Sivaram Dhakshinamoorthy, Martin Habovštiak, and Bastien Teinturier.

Update: The module was released in libsecp256k1 v0.6.0 on November 4, 2024.

Shielded CSV: Private and Efficient Client-Side Validation

Liam Eagen, Robin Linus and I published Shielded CSV, the first fully private client-side validation (CSV) protocol, which hides the transaction history.

  • The size and verification cost of a coin proof are independent of the transaction history.
  • Every transaction costs 64 bytes on-chain, regardless of its size.
  • It supports t-of-n accounts and atomic swaps.

Assuming a bridge to Bitcoin, Shielded CSV enables 100 private Bitcoin transactions per second. Compared to private cryptocurrencies, the expensive zero-knowledge proofs never land on-chain and need not be verified by all full nodes. The protocol specification is written in Rust.

It took me a very long time to realize the potential of client-side validation, but I think this may be just the beginning.

Update: I gave a talk about Shielded CSV at the Bitcoin Conference 2025 (slides). This write-up on the btc++ insider is a good introduction as well.

Intuition for Zero-Knowledge Proofs

While working on Bulletproofs++ I realized there were gaps in my understanding of zero-knowledge proofs. I did a quick search through the literature to find proofs for zero-knowledge that can help my understanding. I found that either the protocols were too different to Bulletproofs(++) or the proofs seemed incomplete.

For example, in Bulletproofs, removing blinding values from the protocol does not affect the proof. This would make it seem like the changed protocol is ZK, but upon closer inspection, it isn’t.

To help developing an intuition for ZK, I created a little demo proof for a toy ZK protocol. You can find at at

https://github.com/jonasnick/little-crypto-notebook

The toy protocol is a heavily simplified variant of Bulletproofs range proofs. In short, it proves that a committed value is the product of two other committed values.

I hope you find the demo useful too. My goal is to continue expanding the little crypto notebook if time permits.

Provably Bug-Free BIPs & Implementations

At TABConf 2022, I gave a talk titled “Provably Bug-Free BIPs & Implementations”.

Specifications should be free of bugs, easy to implement, and hard to misinterpret, which makes writing them a slow and exhausting process. Cryptographic BIPs such as BIP-MuSig2 contain pseudocode, which is not executable, and Python reference code, which is tested but means whatever the Python interpreter does. Errors can creep in between the paper with its security proof, the specification, the reference code, and the implementations.

The talk presents a small step towards improving this. The specification in the draft BIP for half-aggregation of BIP 340 signatures is written in hacspec, a language for succinct, executable, and verifiable cryptographic specifications embedded in Rust. Because hacspec has formal semantics, proof assistants can be used to prove that the specification is free of out-of-bounds array accesses and integer overflows, that it is complete (aggregating valid BIP 340 signatures always yields a valid half-aggregate signature), and that an implementation behaves exactly like the specification. Such proofs, for example in Coq, currently require very specialized skills and a lot of work. Perhaps proof engineering gets easier in the future.

Slides