Add BIP352 module (take 3) #1698

pull josibake wants to merge 10 commits into bitcoin-core:master from josibake:bip352-silentpayments-module-2025 changing 24 files +9984 −12
  1. josibake commented at 8:53 am on July 10, 2025: member

    This PR implements BIP352 - Silent payments. It is recommended to read through the BIP before reviewing this PR.

    This is a continuation of the work in #1519 and only opened as a new PR due to the comment history on #1519 becoming quite long and difficult to sift through. It is recommended reviewers go through #1519 for background context, if interested.

  2. build: add skeleton for new silentpayments (BIP352) module cf44324b5e
  3. silentpayments: sending
    Add a routine for the entire sending flow which takes a set of private keys,
    the smallest outpoint, and list of recipients and returns a list of
    x-only public keys by performing the following steps:
    
    1. Sum up the private keys
    2. Calculate the input_hash
    3. For each recipient group:
        3a. Calculate a shared secret
        3b. Create the requested number of outputs
    
    This function assumes a single sender context in that it requires the
    sender to have access to all of the private keys. In the future, this
    API may be expanded to allow for a multiple senders or for a single
    sender who does not have access to all private keys at any given time,
    but for now these modes are considered out of scope / unsafe.
    
    Internal to the library, add:
    
    1. A function for creating shared secrets (i.e., a*B or b*A)
    2. A function for generating the "SharedSecret" tagged hash
    3. A function for creating a single output public key
    70e20b7145
  4. silentpayments: recipient label support
    Add function for creating a label tweak. This requires a tagged hash
    function for labels. This function is used by the receiver for creating
    labels to be used for a) creating labeled addresses and b) to populate
    a labels cache when scanning.
    
    Add function for creating a labeled spend pubkey. This involves taking
    a label tweak, turning it into a public key and adding it to the spend
    public key. This function is used by the receiver to create a labeled
    silent payment address.
    
    Add tests for the label API.
    3c9362dd6a
  5. silentpayments: receiving
    Add routine for scanning a transaction and returning the necessary
    spending data for any found outputs. This function works with labels via
    a lookup callback and requires access to the transaction outputs.
    Requiring access to the transaction outputs is not suitable for light
    clients, but light client support is enabled by exposing the
    `_create_shared_secret` and `_create_output_pubkey` functions in the
    API. This means the light client will need to manage their own scanning
    state, so wherever possible it is preferrable to use the
    `_recipient_scan_ouputs` function.
    
    Add an opaque data type for passing around the summed input public key (A_sum)
    and the input hash tweak (input_hash). This data is passed to the scanner
    before the ECDH step as two separate elements so that the scanner can
    multiply b_scan * input_hash before doing ECDH.
    
    Add functions for deserializing / serializing a public_data object to
    and from a public key. When serializing a public_data object, the
    input_hash is multplied into A_sum. This is so the object can be stored
    as public key for wallet rescanning later, or to vend to light clients.
    For the light client, a `_parse` function is added which parses the
    compressed public key serialization into a `public_data` object.
    
    Finally, add test coverage for the recieiving API.
    ed3a44b10a
  6. silentpayments: add examples/silentpayments.c
    Demonstrate sending, scanning, and light client scanning.
    1de8b7e854
  7. silentpayments: add benchmarks for scanning
    Add a benchmark for a full transaction scan and for scanning a single
    output. Only benchmarks for scanning are added as this is the most
    performance critical portion of the protocol.
    eabeedb752
  8. tests: add BIP-352 test vectors
    Add the BIP-352 test vectors. The vectors are generated with a Python script
    that converts the .json file from the BIP to C code:
    
    $ ./tools/tests_silentpayments_generate.py test_vectors.json > ./src/modules/silentpayments/vectors.h
    b5b73bcd99
  9. tests: add constant time tests
    Co-authored-by: Jonas Nick <2582071+jonasnick@users.noreply.github.com>
    Co-authored-by: Sebastian Falbesoner <91535+thestack@users.noreply.github.com>
    b821a467e2
  10. ci: enable silentpayments module f825d34260
  11. docs: update README 6264c3d093
  12. in include/secp256k1_silentpayments.h:342 in 6264c3d093
    337+ *                               pubkey as an argument and returns a pointer to
    338+ *                               the label tweak if the label exists, otherwise
    339+ *                               returns a NULL pointer (NULL if labels are not
    340+ *                               used)
    341+ *                label_context: pointer to a label context object (NULL if
    342+ *                               labels are not used)
    


    antonilol commented at 12:37 pm on July 10, 2025:
    0 *                label_context: pointer to a label context object (NULL if
    1 *                               labels are not used or context is not needed)
    

    (was changed after #1519 (review))

  13. in include/secp256k1_silentpayments.h:340 in 6264c3d093
    335+ *                 label_lookup: pointer to a callback function for looking up
    336+ *                               a label value. This function takes a label
    337+ *                               pubkey as an argument and returns a pointer to
    338+ *                               the label tweak if the label exists, otherwise
    339+ *                               returns a NULL pointer (NULL if labels are not
    340+ *                               used)
    


    antonilol commented at 4:26 pm on July 10, 2025:
    I think it should be documented for how long the returned pointer from label_lookup should be valid. I think it is obvious it should be valid until the next call of label_lookup, but it is currently not clear (from the docs) whether it should remain valid until secp256k1_silentpayments_recipient_scan_outputs returns. The current implementation of secp256k1_silentpayments_recipient_scan_outputs does not need this (from looking at the code) and in a safe Rust abstraction for this function (code, does contain some outdated comments) suggested for https://github.com/rust-bitcoin/rust-secp256k1/pull/721 (WIP bindings to this pull request’s code) I relied on this not being a requirement (though that can be changed).

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin-core/secp256k1. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2025-07-12 12:15 UTC

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