Skip to content

Conversation

@jurvis
Copy link

@jurvis jurvis commented Oct 15, 2025

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!

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks complete, labelling as needing number assignment.

@jurvis
Copy link
Author

jurvis commented Nov 30, 2025

@arminsabouri @jonatack thank you for taking the time to review! I've gone ahead and addressed your comments in
9a47c29

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@jonatack jonatack changed the title BIP: Chain Code Delegation for Private Collaborative Custody BIP 89: Chain Code Delegation for Private Collaborative Custody Dec 3, 2025
@jurvis jurvis force-pushed the master branch 2 times, most recently from 2604b20 to af0ec04 Compare December 3, 2025 22:33
@jurvis
Copy link
Author

jurvis commented Dec 3, 2025

thanks @jonatack! i think i got everything!

@jonatack
Copy link
Member

jonatack commented Dec 6, 2025

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.

@jurvis
Copy link
Author

jurvis commented Dec 6, 2025

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:

Signing
======
When 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:

# Inputs:
#   chain_code : 32-byte chain code (hidden from custodian)
#   P_par      : custodian’s parent public key (compressed)
#   i          : child index for spending

I   = HMAC-SHA512(key = chain_code,
                 data = serP(P_par) || ser32(i))
I_L = I[0:32]            # left half
t_i = parse256(I_L)      # scalar tweak mod n
# (I_R would be the child chain code—discarded here.)

# Counterparty → Custodian: send t_i

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

=== Tweak Calculation ===
To 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>.

<div>
Algorithm ''ComputeBIP32Tweak(P, I)'':
* Inputs:
** ''P'': base public key at depth ''d''
** ''I = (i<sub>d+1</sub>, …, i<sub>n</sub>)'': ordered sequence of non-hardened child indices
* Let ''t = 0'' and ''E = P''.
* For each index ''i'' in ''I'' (from left to right):
** 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).
** Let ''t = (t + δ) mod n''.
** Let ''E = P<sub>child</sub>''.
* If ''I'' is empty, let ''P′ = P''; otherwise let ''P′ = P<sub>child</sub>'' from the final iteration.
* Return ''(t, P′)''.
</div>

Hope that helps.

@jonatack
Copy link
Member

jonatack commented Dec 6, 2025

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

Gave it the BIP draft only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants