built on top of f42e0dde59943ad0c9247c61f7af521b70838e8f.
BIP352 requires senders to compute output scripts using ECDH shared secrets from the same secret keys used to sign the inputs. Generating an incorrect signature will produce an invalid transaction that will be rejected by consensus. An incorrectly generated output script can still be consensus-valid, meaning funds may be lost if it gets broadcast. By producing a DLEQ proof for the generated ECDH shared secrets, the signing entity can prove to other entities that the output scripts have been generated correctly without revealing the private keys.
(from BIP 374)
This PR:
- adds support for DLEQ proof generation and verification using
secp256k1_dleq_prove
,secp256k1_dleq_verify
based on implementation in secp256k1-zkp - introduces a new structure for storing proofs in silent payment module -
secp256k1_silentpayments_dleq_data
which stores the shared secret computed using ECDH, DLEQ proof and also the index of which recipient in the original unsorted recipient array the proof refers to. - adds 4 new APIs in silent payments module to create, verify, serialize and parse proof
- sender can create proof using
secp256k1_silentpayments_sender_create_outputs_with_proof
- in the existing
secp256k1_silentpayments_sender_create_outputs
API, output pubkey is created by iterating over all the recipients and computing ECDH for each unique recipient. - since creating the proof also requites iterating over all recipients and computing ECDH for each unique recipient, compute both proof(s) and output pubkey(s) in a new function -
secp256k1_silentpayments_sender_create_outputs_with_proof
. secp256k1_silentpayments_sender_create_outputs
can usesecp256k1_silentpayments_sender_create_outputs_with_proof
internally.
- in the existing
- both sender and receiver can verify proof using
secp256k1_silentpayments_verify_proof
- Serialisation function (
secp256k1_silentpayments_dleq_data_serialize
) serialisessecp256k1_silentpayments_dleq_data
structure into bytes.secp256k1_silentpayments_dleq_data_parse
parses the bytes back intosecp256k1_silentpayments_dleq_data
structure.- useful if proof creation is done on 1 sender side device (ex: hardware wallet) and proof verification is done on another sender side device (ex: software wallet).
secp256k1_silentpayments_dleq_data
structure can be serialised into bytes usingsecp256k1_silentpayments_dleq_data_serialize
and then the bytes can be sent from 1 device to another. secp256k1_silentpayments_dleq_data_parse
can reconstruct the bytes back intosecp256k1_silentpayments_dleq_data
structure which can then be used for proof verification.
- useful if proof creation is done on 1 sender side device (ex: hardware wallet) and proof verification is done on another sender side device (ex: software wallet).
- sender can create proof using
open questions:
- is the API design ok?
- see
examples/silentpayments.c
for 2 scenarios in which proof verification could be useful. (Alice sends bitcoins to Bob and Carol in 1 silent payment transaction)- useful situation - On Alice’s side
- Alice’s hardware wallet creates proof
- Alice’s hardware wallet sends proof to Alice’s software wallet
- Alice’s software wallet verifies proof and makes sure ECDH shared secrets for generating SP output is computed correctly. Alice can get additional safety guarantee about computed SP output before sending funds.
- not sure if this situation is useful - On Bob’s/Carol’s side
- Alice’s software wallet sends proof to Bob’s/Carol’s software wallet
- Bob’s/Carol’s software wallet verifies proof and makes sure ECDH shared secrets for generating SP output is computed correctly.
- useful situation - On Alice’s side
- see
- should this be shipped with SP module or separately? only problem with separate release would be redundant APIs like
secp256k1_silentpayments_sender_create_outputs
andsecp256k1_silentpayments_sender_create_outputs_with_proof
for backward compatibility.
Huge thanks to @ theStack for brainstorming and discussing this with me! ❤️