Add Silent Payments for the Liquid Network#37
Conversation
A Standards Track draft specifying BIP-352 Silent Payments adapted to the Liquid Network's Confidential Transactions. Each normative rule is tagged as BIP-352-derived, a Liquid adaptation, or an open design choice (stated preferentially). Includes worked test vectors and abstract data structures.
|
|
||
| ==Reference Implementation== | ||
|
|
||
| A reference implementation demonstrating address encoding, input aggregation, |
There was a problem hiding this comment.
A reference implementation in python would be nice to review this ELIP
There was a problem hiding this comment.
I have working examples using LWK in Rust, is that acceptable? not too familiar with Python
There was a problem hiding this comment.
| Because <code>bk_k</code> and <code>t_k</code> are outputs of a random oracle (a | ||
| tagged hash) evaluated on '''disjoint domains''' over the same secret <code>S</code>, | ||
| they are independent: knowledge of one does not assist in recovering the other or | ||
| <code>S</code>. The domain tag <code>LiquidSilentPayments/Blind</code> MUST differ |
There was a problem hiding this comment.
Would a third person who wants to detect silent payments, be able to compute blinding keys for each transaction and then check if it unblinds to identify Silent payments?
There was a problem hiding this comment.
It should not be possible as this is using the same hardness assumption from BIP-352 that the blinding key is computed from the sender+receiver Diffie Hellman shared secret, which should never be computable by third parties.
Trim BIP-352 re-explanation to focus on Liquid-specific differences: - Shorten abstract and motivation prose - Reduce BIP-352-compliant sections to brief restatements - Remove Rationale section (reasoning is stated inline in each [Liquid]/[Choice] design section)
The flow is essentially identical to BIP-352; fold the three subsections (filter omission, server interface) into one paragraph plus the interface example.
Switch silent-payment outputs from confidential P2WPKH to confidential Taproot (OP_1 <x_only(P_k)>), with P_k used directly per BIP-352 (no script tree, no taptweak). This aligns the output, spend path, and index-server data with BIP-352's x-only conventions verbatim. - Output is now Taproot-only; eligible inputs keep BIP-352's full set (P2TR, P2WPKH, P2SH-P2WPKH, P2PKH), so an SP output is itself eligible as a later input and the even-Y rule applies unchanged. - Spending is an ordinary BIP-340 key-path spend (even-Y normalized). - Collapse the now-pure-BIP-352 sections (input aggregation, eligible inputs, shared secret, output representation) into one consolidated 'Reused from BIP-352 unchanged' section. - Update test vectors (Taproot scriptPubKeys) and reference-implementation note (verified against LWK, reproduces vectors byte-for-byte).
…ls section The previous lq/tlq HRP collided with ordinary Liquid CONFIDENTIAL addresses (blech32 lq/tlq), defeating the distinct-HRP goal. Switch to lqsp/tlqsp, which differ from every existing Liquid HRP (ex/tex unconfidential, lq/tlq confidential) and from Bitcoin's sp/tsp. Update the test-vector address accordingly (verified against LWK). Also fold the Labels section into the consolidated BIP-352 reused section (labels need no Liquid adaptation); the one substantive note — the blinding key is label-independent — moves to the blinding-key section.
Reduce the Reference Implementation paragraph to what the public reference covers: it reproduces the test vectors byte-for-byte and demonstrates non-interactive unblinding of the shared-secret-blinded output. Wallet integration (scanning, signing, transaction building) is left to implementations, rather than enumerated here.
| non-interactively by the receiver. Wallet integration — scanning, signing, and | ||
| transaction building — is left to implementations. | ||
|
|
||
| ==Acknowledgements== |
There was a problem hiding this comment.
JAN3 should be in the acknowledgements if this BIP is awarded the bounty
| tweaks, which does not exist in common protocols today; until then, silent-payment | ||
| outputs are usable with software signing. | ||
|
|
||
| ==Reference Implementation== |
There was a problem hiding this comment.
The point of the reference implementation in the BIP is like a sort of documentation. I will review your rust code but I feel it should be in python, or something thats close to human readable code. You can check https://github.com/bitcoin/bips/blob/master/bip-0352/reference.py
There was a problem hiding this comment.
There should also be implementation of the tweak server and decryption by the wallet
| # aggregates the private keys of its eligible transaction inputs into a single scalar <code>a</code> and forms <code>A = a·G</code> '''[BIP-352]'''; | ||
| # computes a transaction-bound <code>input_hash</code> and an ECDH shared secret <code>S</code> with the receiver's scan key '''[BIP-352]'''; | ||
| # derives, for output index <code>k</code>, a spend public key <code>P_k</code> that only the receiver can later re-derive '''[BIP-352]'''; | ||
| # places <code>P_k</code> in a Taproot (P2TR) output '''[BIP-352]''', and blinds that output's asset and amount to a blinding key that is itself derived from <code>S</code> '''[Liquid]'''. |
There was a problem hiding this comment.
Actually, we need to think harder on this. On-chain, there is actually some Taproot usage, so SP payments get masked. But on liquid, if there is no usage at all, we might run into issues.
A taproot output will definitely be SP in liquid I think. We need to analyse usage
| Throughout this document, every normative rule is tagged to make its origin explicit: | ||
|
|
||
| * '''[BIP-352]''' — the rule is taken unchanged from BIP-352. Implementations SHOULD reuse existing, reviewed BIP-352 logic for these parts. | ||
| * '''[Liquid]''' — the rule is an adaptation made necessary by a structural difference between Liquid and Bitcoin (most importantly, Confidential Transactions and Liquid's deployed output types). These are the substantive technical contributions of this document. |
There was a problem hiding this comment.
| * '''[Liquid]''' — the rule is an adaptation made necessary by a structural difference between Liquid and Bitcoin (most importantly, Confidential Transactions and Liquid's deployed output types). These are the substantive technical contributions of this document. | |
| * '''[Liquid]''' — the rule is an adaptation due to Confidential Transactions and Liquid's deployed output types. |
Theres still a lot of AI generated verboseness, imo. I feel they can be cleaned up and we dont need to add anything new in this BIP than whats absolutely needed.
For me it feels like ===Output blinding key '''[Liquid]'''=== is the only real specification in this doc and the remaining spec is just to use exisiting BIP 352 logic. Everything can be condensed imo
| bk_k = hashLiquidSilentPayments/Blind( serP(S) || ser32(k) ) (a 32-byte scalar) | ||
| BK_k = bk_k·G |
There was a problem hiding this comment.
This bit is still not clear to me.
A and S can be computed by a third party. What is k?
Actually what is hashLiquidSilentPayments/Blind( serP(S) || ser32(k) ) ? can we just write the math and not generic fn names
This ELIP specifies BIP-352 Silent Payments adapted to the Liquid Network's Confidential Transactions. Each normative rule is tagged as BIP-352-derived, a Liquid adaptation, or an open design choice (stated preferentially). Includes worked test vectors and abstract data structures.