算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
bitcoin-schnorr【设计与创意】BIP340 Schnorr signatures over secp256k1: sign/verify, x-only pubkeys, tagged hashes, batch verification, key tweaking. Building block for Taproot, MuSig2, FROST, adaptor signatures, DLCs. Quick refs: signing pseudocode, batch verification, common mistakes. USE WHEN: signing/verifying Taproot key-path or Tapscript spends, designing aggregation protoc…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Quick refs: pseudocode.md, batch-verify.md, pitfalls.md
Schnorr is the signature scheme used in Taproot. Discovered in 1989, patent-encumbered until 2008, finally proposed for Bitcoin in 2018 (BIP340), activated 2021.
| Property | ECDSA | Schnorr (BIP340) |
|---|---|---|
| Signature size | ~71-72 bytes (DER) | 64 bytes flat |
| Linearity | No | Yes |
| Batch verification | No | Yes (sub-linear) |
| Malleability | Yes (low-s normalization required) | No (canonical by construction) |
| Provable security | requires assumption | reducible to ECDLP in ROM |
| Key aggregation | impossible | enables MuSig2 / FROST |
Linearity is the killer feature: Sig(k1+k2, m) ≠ Sig(k1,m) + Sig(k2,m)
in ECDSA, but ... = ... in Schnorr (in a precise sense). This enables
n-of-n key aggregation, MuSig2, FROST, adaptor signatures, scriptless
scripts, DLCs.
TaggedHash(tag, msg) = SHA256(SHA256(tag) || SHA256(tag) || msg)
Domain separation tags used in BIP340:
BIP0340/aux — for nonce derivation (auxiliary entropy).BIP0340/nonce — for the deterministic nonce hash.BIP0340/challenge — for the challenge hash e.Schnorr in BIP340 uses 32-byte x-only pubkeys. Implicit "even y"
convention: when computing operations, you lift_x(P_x) to choose the
point with even y, and adjust sign of secret key accordingly.
This halves key size and simplifies tweaking math.
Inputs: secret key d (32 bytes), message m (any length), aux_rand (32 bytes optional)
1. P = d * G; if P.y is odd, d = n - d (force even-y).
2. t = d XOR TaggedHash("BIP0340/aux", aux_rand) [nonce binding]
3. rand = TaggedHash("BIP0340/nonce", t || P.x || m)
4. k = int(rand) mod n; if k == 0, abort.
5. R = k * G; if R.y is odd, k = n - k.
6. e = TaggedHash("BIP0340/challenge", R.x || P.x || m) mod n
7. s = (k + e*d) mod n
8. Output: (R.x, s) → 64 bytes.
m was restricted to 32 bytes until BIP340's 2023-04 revision lifted
it; it is arbitrary-length now. In Bitcoin m is always the 32-byte
BIP341 sighash. See pitfalls.md #5.
Inputs: pubkey P_x (32 bytes), message m, sig (R_x, s)
1. P = lift_x(P_x).
2. e = TaggedHash("BIP0340/challenge", R_x || P_x || m) mod n.
3. R' = s*G - e*P
4. Verify R'.y is even AND R'.x == R_x.
n signatures can be verified together in O(n) but with a smaller constant than n individual verifications. Random linear combinations prevent forgery:
For batch of (Pi, Ri, si, mi) for i in 1..n:
1. Generate random ai for each (a1=1 fixed for security).
2. Compute LHS = sum(ai * si) * G
3. Compute RHS = sum(ai * Ri) + sum(ai * ei * Pi)
4. If LHS == RHS, batch valid.
Typical speedup: 2-3x for ~100 sigs — but this is theory, not a deployed code path. libsecp256k1 exposes no batch-verify API and Bitcoin Core verifies each Taproot signature individually (as of September 2026). See batch-verify.md.
Taproot tweak: Q = P + t*G where t = TaggedHash("TapTweak", P_x || R).
For signing on tweaked output:
secret_for_Q = (secret_for_P + t) mod n (with parity adjustment)
This means: a Taproot wallet that holds d and knows the script tree
can sign for Q using the standard BIP340 signing with the tweaked key.
SIGHASH_DEFAULT (= 0x00 byte after sig): omit, sig is 64 bytes.BIP340 keys are the exposed surface in the quantum debate: Shor's algorithm recovers a secret key from a public key, and a Taproot key-path output publishes its 32-byte x-only key in the scriptPubKey, so it is breakable-in-principle long before it is ever spent ("long exposure"). A key revealed only in a mempool spend is the harder "short exposure" case.
Two drafts frame the response. Neither is activated and neither has consensus:
bc1z.
It targets long exposure only and deliberately picks no PQ
signature algorithm, leaving that to a later soft fork. Renamed from
"P2QRH" (2025-09) then "P2TSH" (2026-02).Nothing here changes how you sign or verify BIP340 today.
Neither BIP above is a signature scheme — they define output types and migration policy. What would actually sign is a separate track, and it is signature-scheme material, so it lives here rather than with the proposals skill.
SHRINCS ("Shrunken SPHINCS") is the candidate written specifically for Bitcoin. First draft BIP posted to the bitcoindev list by conduition on 2026-08-26 on behalf of the SHRINCS working group; authors are conduition, Ethan Heilman, Mikhail Kudinov, Oleksandr Kurbatov, Jonas Nick and remix7531. Status Draft, Type Specification, no BIP number assigned, and the draft states its security proof is TODO.
It is hash-based and instantiated entirely on SHA256 — no lattice or other extra hardness assumption — and combines two components under one key:
Either component alone verifies, so losing signing state degrades signature size rather than bricking the key.
| Property | BIP340 | SHRINCS (draft, 2026-08) |
|---|---|---|
| Public key | 32 bytes (x-only) | 48 bytes |
| Signature | 64 bytes | 548-4,619 stateful; 5,777 stateless |
| Assumption | ECDLP in ROM | SHA256 security only |
| Target level | ~128-bit classical | NIST category 1 (128 classical, 64 quantum) |
Two consequences that matter to the rest of this skill:
The other families in the field are the NIST-standardized ones — SLH-DSA (FIPS-205), which SHRINCS reuses as its stateless component, and the lattice-based ML-DSA (FIPS-204), which it only compares against on size. The draft cites its combined pubkey+stateful-signature size as ~13x smaller than SLH-DSA-SHA2-128s and ~6x smaller than ML-DSA-44 — the latter at a different security level, since ML-DSA-44 targets NIST category 2 where SHRINCS targets category 1.
Maturity caveats, straight from the draft: the reference implementation is a naive, non-constant-time Python one explicitly not for production, comprehensive test vectors are still TODO and are required to move the proposal from Draft to Complete, and an optimized implementation is TODO. The draft stops at the signature scheme and says nothing about deployment; per the bitcoindev discussion, exposing SHRINCS onchain would need a new opcode or output type in a separate proposal. See ../../protocol/proposals/SKILL.md for that deployment and migration dimension.
See quick-ref/pitfalls.md. Headlines: