Bitcoin Core 31.99.0
P2P Digital Currency
Classes | Macros | Typedefs | Functions
secp256k1_silentpayments.h File Reference
#include <stdint.h>
#include "secp256k1.h"
#include "secp256k1_extrakeys.h"
Include dependency graph for secp256k1_silentpayments.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  secp256k1_silentpayments_recipient
 The data from a single recipient address. More...
 
struct  secp256k1_silentpayments_label
 Opaque data structure that holds a Silent Payments label. More...
 
struct  secp256k1_silentpayments_prevouts_summary
 Opaque data structure that holds Silent Payments prevouts summary data. More...
 
struct  secp256k1_silentpayments_found_output
 Found outputs struct. More...
 

Macros

#define SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT   2323
 This module provides an implementation for Silent Payments, as specified in BIP352. More...
 

Typedefs

typedef struct secp256k1_silentpayments_recipient secp256k1_silentpayments_recipient
 The data from a single recipient address. More...
 
typedef struct secp256k1_silentpayments_label secp256k1_silentpayments_label
 Opaque data structure that holds a Silent Payments label. More...
 
typedef struct secp256k1_silentpayments_prevouts_summary secp256k1_silentpayments_prevouts_summary
 Opaque data structure that holds Silent Payments prevouts summary data. More...
 
typedef const unsigned char *(* secp256k1_silentpayments_label_lookup) (const unsigned char *label33, const void *label_context)
 Type of callback function for label lookups. More...
 
typedef struct secp256k1_silentpayments_found_output secp256k1_silentpayments_found_output
 Found outputs struct. More...
 

Functions

SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs (const secp256k1_context *ctx, secp256k1_xonly_pubkey **generated_outputs, const secp256k1_silentpayments_recipient **recipients, size_t n_recipients, const unsigned char *outpoint_smallest36, const secp256k1_keypair *const *keypairs, size_t n_keypairs, const unsigned char *const *seckeys, size_t n_seckeys) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5)
 Create Silent Payments outputs for recipient(s). More...
 
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_parse (const secp256k1_context *ctx, secp256k1_silentpayments_label *label, const unsigned char *in33) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
 Parse a Silent Payments label. More...
 
SECP256K1_API int secp256k1_silentpayments_recipient_label_serialize (const secp256k1_context *ctx, unsigned char *out33, const secp256k1_silentpayments_label *label) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
 Serialize a Silent Payments label. More...
 
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_create (const secp256k1_context *ctx, secp256k1_silentpayments_label *label, unsigned char *label_tweak32, const unsigned char *scan_key32, uint32_t m) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
 Create Silent Payments label tweak and label. More...
 
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_labeled_spend_pubkey (const secp256k1_context *ctx, secp256k1_pubkey *labeled_spend_pubkey, const secp256k1_pubkey *unlabeled_spend_pubkey, const secp256k1_silentpayments_label *label) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
 Create Silent Payments labeled spend public key. More...
 
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_prevouts_summary_create (const secp256k1_context *ctx, secp256k1_silentpayments_prevouts_summary *prevouts_summary, const unsigned char *outpoint_smallest36, const secp256k1_xonly_pubkey *const *xonly_pubkeys, size_t n_xonly_pubkeys, const secp256k1_pubkey *const *pubkeys, size_t n_pubkeys) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
 Compute Silent Payments prevouts summary from prevout public keys and transaction inputs. More...
 
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs (const secp256k1_context *ctx, secp256k1_silentpayments_found_output **found_outputs, uint32_t *n_found_outputs, const secp256k1_xonly_pubkey *const *tx_outputs, size_t n_tx_outputs, const unsigned char *scan_key32, const secp256k1_silentpayments_prevouts_summary *prevouts_summary, const secp256k1_pubkey *unlabeled_spend_pubkey, secp256k1_silentpayments_label_lookup label_lookup, const void *label_context) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8)
 Scan for Silent Payments transaction outputs. More...
 

Macro Definition Documentation

◆ SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT

#define SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT   2323

This module provides an implementation for Silent Payments, as specified in BIP352.

This particularly involves the creation of input tweak data by summing up secret or public keys and the derivation of a shared secret using Elliptic Curve Diffie-Hellman. Combined are either:

  • spender's secret keys and recipient's public key (a * B, sender side)
  • spender's public keys and recipient's secret key (A * b, recipient side) With this result, the necessary key material for ultimately creating/scanning or spending Silent Payments outputs can be determined.

Note that this module is not a full implementation of BIP352, as it inherently doesn't deal with higher-level concepts like addresses, output script types or transactions. The intent is to provide a module for abstracting away the elliptic-curve operations required for the protocol. For any wallet software already using libsecp256k1, this API should provide all the functions needed for a Silent Payments implementation without requiring any further elliptic-curve operations from the wallet.

Definition at line 32 of file secp256k1_silentpayments.h.

Typedef Documentation

◆ secp256k1_silentpayments_found_output

Found outputs struct.

Struct for holding a found output along with data needed to spend it later.

      output: the x-only public key for the taproot output
       tweak: the 32-byte tweak needed to spend the output

found_with_label: boolean value to indicate if the output was sent to a labeled address. If true, label will be set to a valid value. label: the label used. If found_with_label = false, this is set to an invalid value.

◆ secp256k1_silentpayments_label

Opaque data structure that holds a Silent Payments label.

Guaranteed to be 68 bytes in size. Serialized and parsed with secp256k1_silentpayments_recipient_label_serialize and secp256k1_silentpayments_recipient_label_parse.

◆ secp256k1_silentpayments_label_lookup

typedef const unsigned char *(* secp256k1_silentpayments_label_lookup) (const unsigned char *label33, const void *label_context)

Type of callback function for label lookups.

A function of this type will be used to retrieve the label tweak for a given label during scanning. A typical implementation will perform a lookup in a key-value store called the "label cache".

For creating the label cache data, secp256k1_silentpayments_recipient_label_create and secp256k1_silentpayments_recipient_label_serialize can be used.

Returns: pointer to the 32-byte label tweak if there is a match. NULL pointer if there is no match.

In: label: pointer to the serialized 33-byte label to check (computed during scanning) label_context: pointer to the recipient's label cache.

Definition at line 310 of file secp256k1_silentpayments.h.

◆ secp256k1_silentpayments_prevouts_summary

Opaque data structure that holds Silent Payments prevouts summary data.

The exact representation of data inside is implementation defined and not guaranteed to be portable between different platforms or versions. It is however guaranteed to be 101 bytes in size, and can be safely copied/moved. This structure does not contain secret data. It can be created with secp256k1_silentpayments_recipient_prevouts_summary_create.

◆ secp256k1_silentpayments_recipient

The data from a single recipient address.

This struct serves as an input argument to silentpayments_sender_create_outputs.

index must be set to the position (starting with 0) of this recipient in the recipients array passed to silentpayments_sender_create_outputs. It is used to map the returned generated outputs back to the original recipient.

Note: The spend public key named spend_pubkey may have been optionally tweaked with a label by the recipient. Whether spend_pubkey has actually been tagged with a label is irrelevant for the sender. As a documentation convention in this API, unlabeled_spend_pubkey is used to indicate when the unlabeled spend public key must be used.

Function Documentation

◆ secp256k1_silentpayments_recipient_create_labeled_spend_pubkey()

SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_labeled_spend_pubkey ( const secp256k1_context ctx,
secp256k1_pubkey labeled_spend_pubkey,
const secp256k1_pubkey unlabeled_spend_pubkey,
const secp256k1_silentpayments_label label 
)

Create Silent Payments labeled spend public key.

Given a recipient's spend public key and a label, calculate the corresponding labeled spend public key:

labeled_spend_pubkey = unlabeled_spend_pubkey + label

The result is used by the recipient to create a Silent Payments address, consisting of the serialized and concatenated scan public key and (labeled) spend public key.

Returns: 1 if labeled spend public key creation was successful. 0 if spend pubkey and label sum to zero (negligible probability for labels created according to BIP352).

Args: ctx: pointer to a context object Out: labeled_spend_pubkey: pointer to the resulting labeled spend public key In: unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key label: pointer to the recipient's label

Definition at line 430 of file main_impl.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ secp256k1_silentpayments_recipient_label_create()

SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_create ( const secp256k1_context ctx,
secp256k1_silentpayments_label label,
unsigned char *  label_tweak32,
const unsigned char *  scan_key32,
uint32_t  m 
)

Create Silent Payments label tweak and label.

Given a recipient's 32 byte scan key and a label integer m, calculate the corresponding label tweak and label:

label_tweak = hash(scan_key || m)
      label = label_tweak * G

Returns: 1 if label tweak and label creation was successful. 0 if scan_key32 is invalid or the hash output label_tweak32 is not a valid scalar (negligible probability per hash evaluation).

WARNING: Creating a large number of labels may significantly degrade scanning performance in certain Silent Payments wallet implementations, such as light clients. The scanning function provided in this module, which is designed for full nodes, performs consistently even with hundreds of thousands of labels. Other implementations may not share this property or may be unable to use it due to lacking full transaction data.

To maximize wallet interoperability, it is recommended to create only the change label (m = 0) and avoid distributing labeled addresses.

Args: ctx: pointer to a context object (not secp256k1_context_static) Out: label: pointer to the resulting label label_tweak32: pointer to the 32 byte label tweak In: scan_key32: pointer to the recipient's 32 byte scan key m: integer for the m-th label (0 is used for change outputs)

Definition at line 393 of file main_impl.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ secp256k1_silentpayments_recipient_label_parse()

SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_parse ( const secp256k1_context ctx,
secp256k1_silentpayments_label label,
const unsigned char *  in33 
)

Parse a Silent Payments label.

Returns: 1 when the label could be parsed, 0 otherwise. Args: ctx: pointer to a context object Out: label: pointer to a label object In: in33: pointer to the 33-byte label to be parsed

Definition at line 362 of file main_impl.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ secp256k1_silentpayments_recipient_label_serialize()

SECP256K1_API int secp256k1_silentpayments_recipient_label_serialize ( const secp256k1_context ctx,
unsigned char *  out33,
const secp256k1_silentpayments_label label 
)

Serialize a Silent Payments label.

Returns: 1 always Args: ctx: pointer to a context object Out: out33: pointer to a 33-byte array to store the serialized label In: label: pointer to the label

Definition at line 378 of file main_impl.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ secp256k1_silentpayments_recipient_prevouts_summary_create()

SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_prevouts_summary_create ( const secp256k1_context ctx,
secp256k1_silentpayments_prevouts_summary prevouts_summary,
const unsigned char *  outpoint_smallest36,
const secp256k1_xonly_pubkey *const *  xonly_pubkeys,
size_t  n_xonly_pubkeys,
const secp256k1_pubkey *const *  pubkeys,
size_t  n_pubkeys 
)

Compute Silent Payments prevouts summary from prevout public keys and transaction inputs.

Given a list of n public keys A_1...A_n (one for each Silent Payments eligible input to spend) and a serialized outpoint_smallest36, create a prevouts_summary object. This object summarizes the prevout data from the transaction inputs needed for scanning.

outpoint_smallest36 refers to the smallest outpoint lexicographically from the transaction inputs (both Silent Payments eligible and non-eligible inputs). This value MUST be the smallest outpoint out of all of the transaction inputs, otherwise the recipient will be unable to find the payment.

The public keys have to be passed in via two different parameter pairs, one for regular and one for x-only public keys, in order to avoid the need of users converting to a common public key format before calling this function. The resulting data can be used for scanning on the recipient side.

Returns: 1 if prevouts summary creation was successful. 0 if the transaction is not a Silent Payments transaction.

Args: ctx: pointer to a context object Out: prevouts_summary: pointer to prevouts_summary object containing the summed public key and input_hash. In: outpoint_smallest36: serialized smallest outpoint (lexicographically) from the transaction inputs xonly_pubkeys: pointer to an array of pointers to taproot x-only public keys (can be NULL if no taproot inputs are used) n_xonly_pubkeys: the size of the xonly_pubkeys array. pubkeys: pointer to an array of pointers to non-taproot public keys (can be NULL if no non-taproot inputs are used) n_pubkeys: the size of the pubkeys array.

Compute Silent Payments prevouts summary from prevout public keys and transaction inputs.

The prevouts_summary object contains:

[magic: 4 bytes][boolean: 1 byte][prevouts_pubkey_sum: 64 bytes][input_hash: 32 bytes]

The magic bytes are checked by functions using the prevouts_summary object to check that the prevouts_summary object was initialized correctly.

The boolean (combined) indicates whether or not the summed prevout public keys and the input_hash scalar have already been combined or are both included. The reason for keeping input_hash and the summed prevout public keys separate is so that an elliptic curve multiplication can be avoided when creating the shared secret, i.e., (recipient_scan_key * input_hash) * prevouts_pubkey_sum.

But when storing the prevouts_summary object (not supported yet), either to send to light clients or for wallet rescans, we can save 32-bytes by combining the input_hash and prevouts_pubkey_sum and saving the resulting point serialized as a compressed public key, i.e., input_hash * prevouts_pubkey_sum.

For each function:

  • _recipient_prevouts_summary_create always creates a prevouts_summary object with combined = false

Definition at line 488 of file main_impl.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ secp256k1_silentpayments_recipient_scan_outputs()

SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs ( const secp256k1_context ctx,
secp256k1_silentpayments_found_output **  found_outputs,
uint32_t *  n_found_outputs,
const secp256k1_xonly_pubkey *const *  tx_outputs,
size_t  n_tx_outputs,
const unsigned char *  scan_key32,
const secp256k1_silentpayments_prevouts_summary prevouts_summary,
const secp256k1_pubkey unlabeled_spend_pubkey,
secp256k1_silentpayments_label_lookup  label_lookup,
const void *  label_context 
)

Scan for Silent Payments transaction outputs.

Given a prevouts_summary object, a recipient's 32 byte scan key and spend public key, and the relevant transaction outputs, scan for outputs belonging to the recipient and return the tweak(s) needed for spending the output(s). An optional label_lookup callback function and label_context can be passed if the recipient uses labels. This allows for checking if a label exists in the recipients label cache and retrieving the label tweak during scanning.

If used, the label_lookup function must return a pointer to a 32-byte label tweak if the label is found, or NULL otherwise. The returned pointer must remain valid until the next call to label_lookup or until the function returns, whichever comes first. It is not retained beyond that.

For creating the label cache, secp256k1_silentpayments_recipient_label_create and secp256k1_silentpayments_recipient_label_serialize can be used.

Note: Scanning is bounded by SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT and may miss outputs if a transaction contains more outputs for a single scan public key group than this limit.

Returns: 1 if output scanning was successful. 0 if the transaction is not a Silent Payments transaction, or if the arguments are invalid.

Args: ctx: pointer to a context object Out: found_outputs: pointer to an array of pointers to found output objects. The found outputs array MUST have the same length as the tx_outputs array. n_found_outputs: pointer to an integer indicating the final size of the found outputs array. This number represents the number of outputs found while scanning (0 if none are found). Can't be larger than SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT. In: tx_outputs: pointer to the transaction's x-only public key outputs, in their original transaction (vout) order n_tx_outputs: the size of the tx_outputs array. scan_key32: pointer to the recipient's 32 byte scan key. The scan key is valid if it passes secp256k1_ec_seckey_verify prevouts_summary: pointer to the transaction prevouts summary data (see secp256k1_silentpayments_recipient_prevouts_summary_create). unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key label_lookup: pointer to a callback function for looking up a label value. This function takes a serialized 33-byte label as an argument and returns a pointer to the 32-byte label tweak if the label exists, otherwise returns a NULL pointer (NULL if labels are not used) label_context: pointer to a label context object (NULL if labels are not used or context is not needed)

Definition at line 603 of file main_impl.h.

Here is the call graph for this function:
Here is the caller graph for this function:

◆ secp256k1_silentpayments_sender_create_outputs()

SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs ( const secp256k1_context ctx,
secp256k1_xonly_pubkey **  generated_outputs,
const secp256k1_silentpayments_recipient **  recipients,
size_t  n_recipients,
const unsigned char *  outpoint_smallest36,
const secp256k1_keypair *const *  keypairs,
size_t  n_keypairs,
const unsigned char *const *  seckeys,
size_t  n_seckeys 
)

Create Silent Payments outputs for recipient(s).

Given a list of n secret keys a_1...a_n (one for each Silent Payments eligible input to spend), a serialized outpoint, and a list of recipients, create the taproot outputs. Inputs with conditional branches or multiple public keys are excluded from Silent Payments eligible inputs; see BIP352 for more information.

outpoint_smallest36 refers to the smallest outpoint lexicographically from the transaction inputs (both Silent Payments eligible and non-eligible inputs). This value MUST be the smallest outpoint out of all of the transaction inputs, otherwise the recipient will be unable to find the payment. Determining the smallest outpoint from the list of transaction inputs is the responsibility of the caller. It is strongly recommended that implementations ensure they are doing this correctly by using the test vectors from BIP352.

When creating more than one generated output, all of the generated outputs MUST be included in the final transaction. Dropping any of the generated outputs from the final transaction may make all or some of the outputs unfindable by the recipient.

Returns: 1 if creation of outputs was successful. 0 on failure. This is expected only with an adversarially chosen recipient spend key. Specifically, failure occurs when:

  • Input secret keys sum to 0 (negligible probability if at least one of the input secret keys is uniformly random and independent of all other keys)
  • A hash output is not a valid scalar (negligible probability per hash evaluation)
  • Any group (i.e. recipients sharing the same scan public key) exceeds the protocol limit SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT

Args: ctx: pointer to a context object (not secp256k1_context_static). Out: generated_outputs: pointer to an array of pointers to xonly public keys, one per recipient. The outputs are ordered to match the original ordering of the recipient objects, i.e., generated_outputs[0] is the generated output for the secp256k1_silentpayments_recipient object with index = 0. In: recipients: pointer to an array of pointers to Silent Payments recipients, where each recipient is a scan public key, a spend public key, and an index indicating its position in the original ordering. The recipient array will be grouped by scan public key in place (as specified in BIP0352), but generated outputs are saved in the generated_outputs array to match the original ordering (using the index field). This ensures the caller is able to match the generated outputs to the correct Silent Payments addresses. The same recipient can be passed multiple times to create multiple outputs for the same recipient. n_recipients: the size of the recipients array. outpoint_smallest36: serialized (36-byte) smallest outpoint (lexicographically) from the transaction inputs keypairs: pointer to an array of pointers to taproot keypair inputs (can be NULL if no secret keys of taproot inputs are used) n_keypairs: the size of the keypairs array. seckeys: pointer to an array of pointers to 32-byte secret keys of non-taproot inputs (can be NULL if no secret keys of non-taproot inputs are used) n_seckeys: the size of the seckeys array.

Definition at line 187 of file main_impl.h.

Here is the call graph for this function:
Here is the caller graph for this function: