BIP460: CISA for Taproot Key Path Spends - #2212
Conversation
|
This completes the CISA BIP triplet with half-agg (458) and full-agg (459) and should get BIP number 460 but I will wait for the editor confirmation again :) |
vostrnad
left a comment
There was a problem hiding this comment.
Second pass of review for things I didn't notice the first time around, especially the opportunity to structure the specification around differences from SegWit v1 instead of reiterating many of its rules. The rationale for leaving out script path inputs reads great now.
| A work in progress implementation for Bitcoin Core is available at https://github.com/fjahr/bitcoin/tree/2026-07-cisa-txwide. | ||
| It implements the validation rules of this BIP and validates all consensus test vectors. | ||
|
|
||
| == Rationale == |
There was a problem hiding this comment.
It seems a bit inconsistent to have sections named Rationale (which describes rationale inline) and Footnotes (which describes rationale as footnotes). As an example, BIP-341 only has a Rationale section where all points are footnotes, and that way they can be referenced inline from places where the rationale needs explaining.
There was a problem hiding this comment.
I left this as is. It is consistent with, for example, BIP340 and BIP458 (where I didn't come up with the initial structure). Both mix prose rationale and a separate footnotes section. I think such a split can help with readability by keeping the parts that are deeper in the weeds in the footnotes.
I would also expect that whatever gets deployed first would get to use the next version and other proposals would shift. I guess you could write “version 2 (or the next unencumbered version available when this proposal is deployed)” or similar to be abundantly clear. At least one of the authors of BIP 360 was keen on using version 3 anyway, because he wanted quantum-resistant addresses to start with bc1r. |
|
Addressed inline comments from @vostrnad , thanks again for the extensive review! I also added a bit to the rationale section in response to waxwing's comment here: https://groups.google.com/g/bitcoindev/c/1XH6sBLWZuA/m/-zRSmrFZGQAJ See my response on the mailing list for a bit more detail. As mentioned, there are, well, I am still open to consider adding this if reviewers can envision possible use cases or are just generally of the opinion we should offer as much flexibility as possible. Also added the assigned number and made changes in response the recent renaming of BIP459.
I have something like this in the deployment section already, so I didn't make any further change in this regard. |
|
I have been working on a bigger revision of this proposal that I would like to ask if anyone sees downsides that I have missed before actually pushing it here. This new version would be making opted-out inputs plain BIP 341 key path spends. Draft version of the spec changes: fjahr/bips@cisa...cisa-plain-optout A bit more detail: the opt-out marker The motivation comes from the adoption discussion in the PQC output type thread: https://delvingbitcoin.org/t/pqc-output-type-discussion/2749/6. My perspective has changed because if external factors like PQ migration drive part of the adoption of the output type, opted-out spends may be less of an exception than I thought. With this change a wallet that never aggregates spends witness v2 outputs with its existing Taproot signing logic, no new sighash code path, no new witness logic. A CISA-enabled witness v2 becomes a strict superset of a plain "P2TRv2" with BIP 341 semantics. @vostrnad suggested the key elements of this in earlier review, the sighash byte trailing the signature and opting out by omitting the marker. I rejected both at the time because I saw opting out as a rare case that could afford an explicit byte. Due to the external motivation for adoption of the output type I now see this differently. I also didn't put these two suggestions together which caused me to expect this change to be more complicated than it ended up actually being. Pros of the new version:
Cons:
By now I believe that this is an improvement even if there is no combination with a PQ P2TRv2 proposal so I plan to update the pull shortly if I didn't overlook any serious issues. Feedback very welcome. |
|
Hey @fjahr, reviewing the spec changes, here's a few observations:
Nit: It's unusual to document the last element of an object's encoding first.
I think there would still be a difference w/r/t the witness program version, and perhaps some implementations naively assume the witness version during message hashing. So there will be some change needed during signing (otherwise replay can occur), but still changing a single byte is pretty minimal. Perhaps that one byte is still worth mentioning?
Crazy idea, but could you flip this logic on its head, and swap the signature message functions of the "opted out" and "half-agg" signatures? Then the default 'lazy path' (i.e. BIP341-style key spend with a new witness version) would be half-aggregatable, while the explicit opt-out signature would require manual changes by wallet devs. Then if we allow half-aggregation by third parties, users who upgrade to CISA addresses would automatically gain the benefits of half-aggregation without doing any work aside from changing the witness version, since half-agg will presumably be done automatically for them by someone in the mempool, or by miners themselves (they have incentive to). This has a security drawback though, for users who depend on adaptor signatures. They'd need to update their systems, using stock BIP341 signatures would subject their signatures to half-aggregation, possibly by accident. Is this a big deal? IDK. It also places an expected burden of doing half-agg work on the rest of the network, when really it should be the spender's wallet software. A few observations unrelated to the new changes:
Since the half-agg signature is variable-size scaling with I don't know of any limits applying in this situation. The 520b stack element size limit doesn't apply. The 10000 byte script size limit doesn't apply. Is there some other limit on witness sizes? Is there a reason you went with this design with a growing variable-size half-agg signature attached to one input, rather than the one i was expecting to see, where you distribute the nonce components across the individual inputs' witnesses? This approach would have the added bonus that all the keyspend witness elements will become fixed-size (33 bytes for half-agg placeholders, 65 bytes for half-agg finals, i think), making parsing a little easier. |
This is a BIP draft for transaction-wide cross-input signature aggregation (CISA). It introduces witness version 2, which enables Taproot-style key path spending where inputs can aggregate their signatures within a transaction. Each input chooses between half-aggregation, full-aggregation, or an explicit opt-out via a marker byte in its witness and the signature message commits to that choice. The aggregation schemes themselves are specified in BIP458 half-aggregation and BIP459 full-aggregation.
Compared to the version shared on the mailing list recently, this version incorporates feedback from vostrnad, most notably a rewritten rationale for excluding script path aggregation, describing the conflict with the
OP_SUCCESSupgrade mechanism.The test vectors are generated with Python code that builds on the reference implementations of BIP458 and BIP459, and the latest master of secp256k1lab is vendored with the BIP, same as it was done for BIP458/459.
Note to the BIP editors: I am aware that SegWit v2 here collides with BIP360. I am curious what you have to say about this, and I am happy to make a change here if you request it, but I couldn't find any rules assigning witness numbers in BIPs or anything that seemed close enough. Since witness versions are a scarce resource and not assigning them sequential would be kind of confusing, it seems whatever soft fork goes in next that requires a new witness version should get the next one available. Since both this one and BIP360 aren't close to activation, I am happy with whatever you decide to write into the specs in the meantime. Maybe we'll want to move to a more generic language for the version instead of prescribing it explicitly until activation comes close. On the other hand, maybe making it explicit and avoiding collisions makes sense for tests on Bitcoin Inquisition etc. Either way, it can't be avoided that there is a chance a "final" BIP might need a change in this regard at some point when it actually gets activated.