BIP 89: Chain Code Delegation for Private Collaborative Custody #2004

pull jurvis wants to merge 4 commits into bitcoin:master from jurvis:master changing 20 files +2327 −0
  1. jurvis commented at 3:28 am on October 15, 2025: none

    We propose a new BIP for Chain Code Delegation, a collaborative custody technique that involves privileged participants (delegatee) withholding BIP32 chain codes at key setup time from a delegator, and sharing only enough information for non‑privileged participants to provide their signature.

    For non-blinded signing, the delegatee derives a per‑spend scalar tweak t from the (withheld) chain code, the delegator computes the child key (x+t, P+tG), and produces a standard signature over the transaction’s sighash. For blind signing, the nonce and challenge are blinded so the delegator returns a blind Schnorr signature that the counterparty unblinds; thanks to Schnorr’s linearity, the same tweak is incorporated without revealing the final message or linkable details (optionally with predicate proofs for policy).

    This enables participants like collaborative custodians to co‑sign when needed, while avoiding the broad visibility that comes with holding an xpub.

    More background and discussions can be found: https://delvingbitcoin.org/t/chain-code-delegation-private-access-control-for-bitcoin-keys/1837.

    This is joint work with @jesseposner. Feedback appreciated!

  2. Add Chaincode Delegation BIP 4283e3ec57
  3. Update license to BSD-3-Clause and expand blinded signing documentation edb4360fa7
  4. jonatack added the label New BIP on Oct 15, 2025
  5. in bip-chaincode-delegation.mediawiki:391 in edb4360fa7
    386+
    387+* '''0.1.0''' (2025-10-14): Publication of draft BIP
    388+
    389+== Acknowledgements ==
    390+* Arik Sosman and Wilmer Paulino for the initial discussions and validation of this idea.  
    391+* Sanket Kajalkar, Jordan Mecom, Gregory Sanders, ZmnSCPxj, Yuval Krogman, and John Cantrell for code and design review.
    


    arminsabouri commented at 12:44 pm on November 12, 2025:
    0* Sanket Kajalkar, Jordan Mecom, Gregory Sanders, ZmnSCPxj, Yuval Kogman, and John Cantrell for code and design review.
    
  6. in bip-0089.mediawiki:9 in edb4360fa7 outdated
    0@@ -0,0 +1,394 @@
    1+<pre>
    2+BIP: ???? 
    3+Layer: Applications
    4+Title: Chain Code Delegation
    5+Author: Jesse Posner <jesse@vora.io>, Jurvis Tan <jurvis@block.xyz>
    6+Status: Draft
    7+Type: Standards Track
    8+Created: 2025-10-14
    9+License: BSD-3-Clause
    


    jonatack commented at 7:23 pm on November 25, 2025:

    Suggested header additions (Version is BIP3 only, so only add it if BIP3 is activated:

    0Post-History: delvingbitcoin.org/t/chain-code-delegation-private-access-control-for-bitcoin-keys/1837.
    1Version: 0.1.0
    2Requires: 32, 340, 341
    
  7. in bip-chaincode-delegation.mediawiki:385 in edb4360fa7
    380+
    381+To help implementers understand updates to this document, we attach a version number that resembles ''semantic versioning'' (<code>MAJOR.MINOR.PATCH</code>).
    382+The <code>MAJOR</code> version is incremented if changes to the BIP are introduced that are incompatible with prior versions.
    383+An exception to this rule is <code>MAJOR</code> version zero (0.y.z) which is for development and does not need to be incremented if backwards incompatible changes are introduced.
    384+The <code>MINOR</code> version is incremented whenever the inputs or the output of an algorithm changes in a backward-compatible way or new backward-compatible functionality is added.
    385+The <code>PATCH</code> version is incremented for other changes that are noteworthy (bug fixes, test vectors, important clarifications, etc.).
    


    jonatack commented at 7:41 pm on November 25, 2025:
    nit, can probably drop this explanatory text. BIP3 includes a similar explanation for all BIPs, and until then, semver is assumed.
  8. in bip-chaincode-delegation.mediawiki:379 in edb4360fa7
    374+== Test Vectors ==
    375+A [[bip-chaincode-delegation/vectors|collection of JSON test vectors]] are provided, along with a [[bip-chaincode-delegation/reference.py|python reference implementation]].
    376+
    377+You may also find example code of CCD in action [https://github.com/jurvis/chaincode-delegation here].
    378+
    379+== Change Log ==
    


    jonatack commented at 7:42 pm on November 25, 2025:

    nit, BIP3 standardizes this title

    0== Changelog ==
    
  9. in bip-chaincode-delegation.mediawiki:375 in edb4360fa7
    370+* Delegators MUST verify change outputs when tweak data is provided (for example via ''ChangeOutputVerification'') to avoid authorizing unexpected scripts.
    371+* Reusing the same k' (first 32 bytes in blindsecnonce) across two BlindSign calls allows recovery of the base secret key.
    372+* When using blinded signing, opening multiple sessions concurrently against the same signer can allow an attacker to learn the base secret key. If concurrency is required, use the concurrently secure variant (encryption + ZK) instead (not specified in this BIP).
    373+
    374+== Test Vectors ==
    375+A [[bip-chaincode-delegation/vectors|collection of JSON test vectors]] are provided, along with a [[bip-chaincode-delegation/reference.py|python reference implementation]].
    


    jonatack commented at 7:43 pm on November 25, 2025:

    nit, file naming throughout would be clearer as “chain code” (instead of “chaincode”), per BIP32 usage

    0A [[bip-chain-code-delegation/vectors|collection of JSON test vectors]] are provided, along with a [[bip-chaincode-delegation/reference.py|python reference implementation]].
    
  10. jonatack commented at 7:51 pm on November 25, 2025: member
    Looks complete, labelling as needing number assignment.
  11. jonatack added the label Needs number assignment on Nov 25, 2025
  12. Address initial PR comments 9a47c29dd9
  13. jurvis commented at 11:39 pm on November 30, 2025: none
    @arminsabouri @jonatack thank you for taking the time to review! I’ve gone ahead and addressed your comments in 9a47c29
  14. in bip-chaincode-delegation.mediawiki:10 in 9a47c29dd9
     5+Author: Jesse Posner <jesse@vora.io>, Jurvis Tan <jurvis@block.xyz>
     6+Status: Draft
     7+Type: Standards Track
     8+Created: 2025-10-14
     9+License: BSD-3-Clause
    10+Post-History: delvingbitcoin.org/t/chain-code-delegation-private-access-control-for-bitcoin-keys/1837.
    


    jonatack commented at 8:36 pm on December 3, 2025:
    0Post-History: delvingbitcoin.org/t/chain-code-delegation-private-access-control-for-bitcoin-keys/1837
    
  15. in bip-0089.mediawiki:387 in 9a47c29dd9 outdated
    382+== Changelog ==
    383+
    384+To help implementers understand updates to this document, we attach a version number that resembles ''semantic versioning'' (<code>MAJOR.MINOR.PATCH</code>).
    385+
    386+* '''0.1.0''' (2025-10-14): Publication of draft BIP
    387+* '''0.1.1''' (2025-11-30): Fix acknowledgments spelling, BIP3 formatting, and use "Chain Code" with a space throughout.
    


    jonatack commented at 8:39 pm on December 3, 2025:
    BIP 3: “Changelog section sorted by most recent version first”
  16. jonatack commented at 8:45 pm on December 3, 2025: member

    Assigned 89.

    Please update the file names and BIP draft headers, including “Created: 2025-12-03” for the date of assignment, and add an entry to the README.

  17. jonatack removed the label Needs number assignment on Dec 3, 2025
  18. jonatack renamed this:
    BIP: Chain Code Delegation for Private Collaborative Custody
    BIP 89: Chain Code Delegation for Private Collaborative Custody
    on Dec 3, 2025
  19. jurvis force-pushed on Dec 3, 2025
  20. jurvis force-pushed on Dec 3, 2025
  21. Update with BIP number assignment c5aac26a86
  22. jurvis force-pushed on Dec 3, 2025
  23. jurvis commented at 10:48 pm on December 3, 2025: none
    thanks @jonatack! i think i got everything!
  24. jonatack commented at 5:57 pm on December 6, 2025: member

    Thanks for updating.

    Final verdict: 95 % LLM-generated or LLM-heavy, with ~5 % human origination of the core idea and final review. @jurvis can you help me out, please: Is this accurate? I’m trying to adapt our process and understanding.

  25. jurvis commented at 6:11 pm on December 6, 2025: none

    hi @jonatack, happy to help. does the scan run through the sample code as well? the sample code contains a lot of boilerplate that we leveraged LLMs to help us with, and may be the reason why it registers high.

    However, the contents of the mediawiki itself should be ~90% original. We leaned on LLM use in the mediawiki mostly to ensure that our formatting was aligned with existing conventions (heavily referencing BIP 340, BIP 352, BIP 32, and BIP 3), and to convert it from Markdown, which we had originally used to write our draft.

    For example, we wrote out our original one of the algorithms in the following format originally:

     0Signing
     1======
     2When the counterparty requests that the collaborative custodian sign a transaction, it derives the BIP32 scalar tweak from the xpub (i.e. the value `parse_256(I_L)` from BIP32) and provides it to the custodian:
     3
     4# Inputs:
     5#   chain_code : 32-byte chain code (hidden from custodian)
     6#   P_par      : custodian’s parent public key (compressed)
     7#   i          : child index for spending
     8
     9I   = HMAC-SHA512(key = chain_code,
    10                 data = serP(P_par) || ser32(i))
    11I_L = I[0:32]            # left half
    12t_i = parse256(I_L)      # scalar tweak mod n
    13# (I_R would be the child chain code—discarded here.)
    14
    15# Counterparty → Custodian: send t_i
    

    Which we got ultimately turned into this, to align with how BIP 32 reads:

     0=== Tweak Calculation ===
     1To produce CCD tweak data, a delegatee computes a per-participant scalar that aggregates the non-hardened derivation tweaks along the remaining path. Let the extended key retained by the delegatee be P at depth d, and let the target index vector be I = (i<sub>d+1</sub>, …, i<sub>n</sub>) with each i<sub>k</sub> < 2<sup>31</sup>.
     2
     3<div>
     4Algorithm ''ComputeBIP32Tweak(P, I)'':
     5* Inputs:
     6** ''P'': base public key at depth ''d''
     7** ''I = (i<sub>d+1</sub>, …, i<sub>n</sub>)'': ordered sequence of non-hardened child indices
     8* Let ''t = 0'' and ''E = P''.
     9* For each index ''i'' in ''I'' (from left to right):
    10** Run the BIP32 non-hardened derivation ''CKDpub'' on ''E'' with child index ''i'', yielding the child extended key ''P<sub>child</sub>'' and its scalar tweak ''δ'' (the parse<sub>256</sub>(''I<sub>L</sub>'') term from BIP32).
    11** Let ''t = (t + δ) mod n''.
    12** Let ''E = P<sub>child</sub>''.
    13* If ''I'' is empty, let ''P′ = P''; otherwise let ''P′ = P<sub>child</sub>'' from the final iteration.
    14* Return ''(t, P′)''.
    15</div>
    

    Hope that helps.

  26. jonatack commented at 6:15 pm on December 6, 2025: member

    hi @jonatack, happy to help. does the scan run through the sample code as well?

    Gave it the BIP draft only.


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bips. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-12-10 00:10 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me