Glossary / Protocol & upgrades
SIGHASH_ANYPREVOUT
Also known as APO.
- What is SIGHASH_ANYPREVOUT?
- SIGHASH_ANYPREVOUT is a proposed signing mode for Taproot scripts that lets one signature spend any coin locked to a matching script, instead of the single coin it was made for.
Specified in BIP-118.
BIP-118 defines a new public key type for tapscript, 33 bytes beginning with 0x01, rather than a flag added to ordinary keys. Assigned in February 2017, it has never been activated, and it works in script path spends only, never key path spends. Nothing in your wallet can sign this way, so any product promising eltoo channels on mainnet is describing a future.
How it works
Status: BIP-118 is a Draft, assigned 2017-02-28, requiring BIP-340, BIP-341 and BIP-342, and its own Deployment section reads TODO. Nothing was replaced, because nothing went live.
A Taproot signature commits to the outpoint of the coin being spent, 36 bytes of txid and index in the ANYONECANPAY digest that BIP-118 modifies, welding it to one coin forever. Remove the outpoint from the message being signed and the signature stops naming a coin and starts naming a shape, so any UTXO of that shape can be bound to it later. The BIP calls this dynamic rebinding.
Two variants are defined, and the difference between them is what still gets committed to.
- SIGHASH_ANYPREVOUT, bit value 0x40, drops the outpoint but keeps the input's amount (8 bytes), its scriptPubKey (always 35 bytes here) and the tapleaf hash. The signature then fits any coin holding the same value under the same script.
- SIGHASH_ANYPREVOUTANYSCRIPT, bit value 0xc0, drops the amount, the scriptPubKey and the tapleaf hash as well. It fits any coin whose script that key can satisfy.
Opting in happens at address creation, not at signing time. These keys work only through a tapscript leaf, so the address has to carry such a leaf in its merkle tree, and until it is spent it is indistinguishable from any other Taproot address. One constant seals the two apart: key_version is 0x01 for a BIP-118 key against 0x00 for a plain tapscript key, so one private key cannot make a signature valid under both rules. Six new hash_type bytes become legal: 0x41, 0x42, 0x43, 0xc1, 0xc2 and 0xc3.
Where you see it
SIGHASH_ANYPREVOUT appears on no mainnet transaction, and BIP-118 expects it will "only be rarely used in practice" even once it exists, since script path spends are heavier and more identifiable.
The design it was written for is eltoo, an off-chain update scheme. Off-chain protocols have to answer whichever old state a counterparty publishes, and because an ordinary signature commits to the exact transaction it answers, a fresh signature is needed for every state that might appear. Eltoo instead uses script and nLockTime to make signatures asymmetric, so a transaction carrying a later signature can spend one carrying an earlier signature but never the reverse, and one update signature can be applied on top of any earlier update your counterparty published.
The name records a correction. Joseph Poon proposed the idea as SIGHASH_NOINPUT in February 2016, after the original Lightning paper raised it, and the rename says the input is not really ignored: nSequence is always signed, and under SIGHASH_ANYPREVOUT the script and amount are signed too.
The BIP's security section names the price: replay. An ANYPREVOUT signature can be reused against any other UTXO with the same script and the same value, and an ANYPREVOUTANYSCRIPT signature against any UTXO reusing that key in one of its scripts, so key reuse turns from a privacy nuisance into a way to lose money. These transactions are malleable by strangers too: anyone able to supply a matching input can change the txid without a private key.
SIGHASH_ANYPREVOUT vs SIGHASH_ANYONECANPAY
SIGHASH_ANYONECANPAY exists on the network today and removes every input except the one being signed; SIGHASH_ANYPREVOUT removes part of that surviving one too. BIP-118 describes its digest as the ANYONECANPAY digest with the outpoint left out, a one line difference with a large consequence. An ANYONECANPAY signature cannot be replayed, because the outpoint it names can only be spent once. Give that commitment up and replay protection has to come from the protocol built on top, not from the signature.