Skip to content

Instantly share code, notes, and snippets.

@andrewtoth
Last active October 17, 2024 09:53
Show Gist options
  • Save andrewtoth/dc26f683010cd53aca8e477504c49260 to your computer and use it in GitHub Desktop.
Save andrewtoth/dc26f683010cd53aca8e477504c49260 to your computer and use it in GitHub Desktop.

  BIP: TBD
  Layer: Applications
  Title: Silent Payments with PSBT
  Author: Andrew Toth <andrewstoth@gmail.com>
          Ava Chow <me@achow101.com>
          josibake <josibake@protonmail.com>
  Comments-Summary: No comments yet.
  Comments-URI: TBD
  Status: Draft
  Type: Standards Track
  Created: 2024-05-14
  License: BSD-2-Clause

Table of Contents

Introduction

Abstract

This document proposes additional fields and updated role responsibilities for BIP 370 PSBTv2 which adds support for sending to silent payments as described in BIP352.

Copyright

This BIP is licensed under the 2-clause BSD license.

Motivation

Partially Signed Bitcoin Transaction Version 2 as described in BIP 370 is not compatible with sending to silent payments as described in BIP352. In particular, the output script of a silent payment cannot be computed until after all transaction inputs have been added. Also, any inputs that the Signer has the private keys for must be signed with SIGHASH_ALL and all inputs must not have any scriptPubKeys with Segwit version > 1. Additionally, the silent payment outputs computed by a signer must be verifiable to other entities. Therefore, new fields and role responsibilities must be added to carry, compute, and verify the silent payment data.

Specification

This document specifies new fields and new field inclusion/exclusion requirements.

PSBT_OUT_SCRIPT is modified to be optional for outputs in silent payments capable PSBTs. If this field is not included in the output, then the field PSBT_OUT_SP_V0_INFO must be included.

The new global types are defined as follows:

Name <keytype> <keydata> <keydata> Description <valuedata> <valuedata> Description Versions Requiring Inclusion Versions Requiring Exclusion Versions Allowing Inclusion
Silent Payment Global ECDH Share PSBT_GLOBAL_SP_ECDH_SHARE = 0x07 <33 byte scan key> <34 byte outpoint>* The scan key and a list of outpoints corresponding to the prevouts of the inputs that this ECDH share is for. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. <32 byte share> An ECDH share for a scan key, followed by a list of outpoints. The ECDH shared is computed with a * B_scan, where a is the sum of all private keys of the inputs matching the list of outpoints, and B_scan is the scan key of a recipient. 0 2
Silent Payment Global DLEQ Proof PSBT_GLOBAL_SP_DLEQ = 0x08 <33 byte scan key> <34 byte outpoint>* The scan key and a list of outpoints corresponding to the prevouts of the inputs that this proof covers. The outpoints are composed of a 32 byte txid followed by a 32-bit little endian uint. <64-byte proof> A DLEQ proof computed for the matching ECDH share. 0 2

One new per-output type is defined as follows:

Name <keytype> <keydata> <keydata> Description <valuedata> <valuedata> Description Versions Requiring Inclusion Versions Requiring Exclusion Versions Allowing Inclusion
Silent Payment Data PSBT_OUT_SP_V0_INFO = 0x08 None No key data <33 byte scan key> <33 byte spend key> The scan and spend public keys from the silent payments address. 0 2

Unique Identification

Silent payment capable PSBTs can be uniquely identified the same way as PSBTv2s, except when including silent payment outputs. For silent payment capable PSBTs, all silent payment outputs must use the PSBT_OUT_SP_V0_INFO instead of PSBT_OUT_SCRIPT as the output script when creating the unsigned transaction used for unique identification.

Roles

This document modifies some existing roles.

Constructor

All rules must be followed from PSBTv2 for this role, with the following exception: When an output is added, it must have either PSBT_OUT_SCRIPT or PSBT_OUT_SP_V0_INFO, or both, set.

Additionally to PSBTv2, the Constructor must also follow additional rules:

Inputs must not spend an output with Segwit version > 1 may only be added if no silent payment outputs are added. Outputs with PSBT_OUT_SP_V0_INFO set may only be added if there are no inputs spending an output with Segwit version > 1.

Signer

All rules must be followed from PSBTv2 for this role, in addition to the following:

If there are any silent payment outputs present and any input is spending from a Segwit version > 1, the Signer must fail.

For all outputs with PSBT_OUT_SP_V0_INFO set, the Signer should:

 - Compute and set an ECDH share and DLEQ proof using all inputs it has the private key for.
 - Verify the DLEQ proofs for all inputs it does not have the private keys for.
 - If all eligible inputs have an ECDH share, compute and set the PSBT_OUT_SCRIPT.

If the Signer sets any missing PSBT_OUT_SCRIPTs, it must set the Inputs Modifiable flag to False.

If any output does not have PSBT_OUT_SCRIPT set, the Signer must not yet add a signature.

The Signer should additionally compute the silent payment addresses, optionally showing this data to the user instead of the computed segwit v1 addresses.

If a sighash type is provided and there are silent payment outputs present, the signer must fail if the sighash type is not SIGHASH_ALL. If a sighash type is not provided and there are silent payment outputs present, the signer must sign using SIGHASH_ALL.

Computing the DLEQ Proof

For each output, the Signer may generate a proof for other entities to generate the output scripts and verify that the output scripts were generated correctly.

Generate a global ECDH share for each scan key Bscan and all eligible inputs the Signer has private keys for as follows:

Using the notation from BIP352

  • Let An be the sum of the public keys A of all eligible inputs
  • Let an be the sum of the private keys a of all eligible inputs
  • Let C = an·Bscan
Use a key Bscan followed by a list of the outpoints of all eligible inputs.

Set the value for the key of PSBT_GLOBAL_SP_ECDH_SHARE to C.

Compute the DLEQ proof for C using an and Bscan. Set the value for the key of PSBT_GLOBAL_SP_DLEQ to the proof.

Verifying the DLEQ Proof

For each output, the Signer should verify the ECDH shares for all eligible inputs it does not have the private key for using the proofs provided by other Signers.

Computing the Output Scripts

Compute the PSBT_OUT_SCRIPT using the procedure in BIP352 but substituting a·Bscan with the sum of all PSBT_GLOBAL_SP_ECDH_SHAREs for that scan key. If there are multiple silent payment codes with the same scan key, sort the codes lexicographically in descending order to determine the ordering of the k value. If there are multiple silent payment codes with both the same scan and spend keys, sort the subgroup by output index in descending order.

Change Detection

Updaters may add two PSBT_OUT_BIP32_DERIVATION key-value-pairs with the corresponding derivation path of both the scan and spend keys. The Signer can then use these fields to verify that the silent payment code is change.

Transaction Extractor

For silent payment capable PSBTs, the transaction extractor should compute all output scripts for silent payment codes and verify they are correct using the ECDH shares and DLEQ proofs, otherwise fail.

Backwards Compatibility

Silent payment capable PSBTs are backwards compatible with PSBTv2 once all outputs have PSBT_OUT_SCRIPT set. Otherwise they are not backwards compatible.

Test Vectors

Todo

Rationale

    Reference implementation

    Todo

    @real-or-random
    Copy link

    real-or-random commented Jun 22, 2024

    Hi, I took a brief look at the DLEQ proof. Some minor comments:

    • It will be good practice to use a tagged hash as in BIP340.
    • It will be even better practice to derive r deterministically from the inputs and the secret, or even better using synthetic randomness as in BIP340. (Feel free to steal from BIP340). This will also make it easier to implement for libraries which already have BIP340.
    • I know it's a bit more work, but I think it will be nice to have the DLEQ proof in a separate BIP. DLEQ proofs are a nice tool that are useful in many different contexts and other protocols. Having them defined independently of a PSBT extension will make the spec reusable in applications.

    @andrewtoth
    Copy link
    Author

    @real-or-random
    Copy link

    Nice. I haven't read every single line, but looks exactly like what I've asked for!

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