Coverage Report

Created: 2026-08-25 19:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/root/bitcoin/src/secp256k1/include/secp256k1_silentpayments.h
Line
Count
Source
1
#ifndef SECP256K1_SILENTPAYMENTS_H
2
#define SECP256K1_SILENTPAYMENTS_H
3
4
#include <stdint.h>
5
#include "secp256k1.h"
6
#include "secp256k1_extrakeys.h"
7
8
#ifdef __cplusplus
9
extern "C" {
10
#endif
11
12
/** This module provides an implementation for Silent Payments, as specified in
13
 *  BIP352. This particularly involves the creation of input tweak data by
14
 *  summing up secret or public keys and the derivation of a shared secret using
15
 *  Elliptic Curve Diffie-Hellman. Combined are either:
16
 *    - spender's secret keys and recipient's public key (a * B, sender side)
17
 *    - spender's public keys and recipient's secret key (A * b, recipient side)
18
 *  With this result, the necessary key material for ultimately creating/scanning
19
 *  or spending Silent Payments outputs can be determined.
20
 *
21
 *  Note that this module is _not_ a full implementation of BIP352, as it
22
 *  inherently doesn't deal with higher-level concepts like addresses, output
23
 *  script types or transactions. The intent is to provide a module for
24
 *  abstracting away the elliptic-curve operations required for the protocol. For
25
 *  any wallet software already using libsecp256k1, this API should provide all
26
 *  the functions needed for a Silent Payments implementation without requiring
27
 *  any further elliptic-curve operations from the wallet.
28
 */
29
30
/* Maximum number of Silent Payments recipients per group (i.e.
31
 * recipients sharing the same scan public key) as per BIP-352 */
32
0
#define SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT 2323
33
34
/** The data from a single recipient address
35
 *
36
 *  This struct serves as an input argument to `silentpayments_sender_create_outputs`.
37
 *
38
 *  `index` must be set to the position (starting with 0) of this recipient in the
39
 *  `recipients` array passed to `silentpayments_sender_create_outputs`. It is
40
 *  used to map the returned generated outputs back to the original recipient.
41
 *
42
 *  Note:
43
 *  The spend public key named `spend_pubkey` may have been optionally tweaked with
44
 *  a label by the recipient. Whether `spend_pubkey` has actually been tagged with
45
 *  a label is irrelevant for the sender. As a documentation convention in this API,
46
 *  `unlabeled_spend_pubkey` is used to indicate when the unlabeled spend public key
47
 *  must be used.
48
 */
49
typedef struct secp256k1_silentpayments_recipient {
50
    secp256k1_pubkey scan_pubkey;
51
    secp256k1_pubkey spend_pubkey;
52
    size_t index;
53
} secp256k1_silentpayments_recipient;
54
55
/** Create Silent Payments outputs for recipient(s).
56
 *
57
 *  Given a list of n secret keys a_1...a_n (one for each Silent Payments
58
 *  eligible input to spend), a serialized outpoint, and a list of recipients,
59
 *  create the taproot outputs. Inputs with conditional branches or multiple
60
 *  public keys are excluded from Silent Payments eligible inputs; see BIP352
61
 *  for more information.
62
 *
63
 *  `outpoint_smallest36` refers to the smallest outpoint lexicographically
64
 *  from the transaction inputs (both Silent Payments eligible and non-eligible
65
 *  inputs). This value MUST be the smallest outpoint out of all of the
66
 *  transaction inputs, otherwise the recipient will be unable to find the
67
 *  payment. Determining the smallest outpoint from the list of transaction
68
 *  inputs is the responsibility of the caller. It is strongly recommended
69
 *  that implementations ensure they are doing this correctly by using the
70
 *  test vectors from BIP352.
71
 *
72
 *  When creating more than one generated output, all of the generated outputs
73
 *  MUST be included in the final transaction. Dropping any of the generated
74
 *  outputs from the final transaction may make all or some of the outputs
75
 *  unfindable by the recipient.
76
 *
77
 *  Returns: 1 if creation of outputs was successful.
78
 *           0 on failure, i.e., when one of the following occurs:
79
 *             - The size of any group (i.e. recipients sharing the same scan public key)
80
 *               exceeds the protocol limit SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT.
81
 *             - The sum of all input secret keys is 0.
82
 *               (This occurs only with negligible probability if at least one of the
83
 *               input secret keys is uniformly random and independent of all other keys.)
84
 *             - An invalid output public key is created. (This can only happen for an
85
 *               adversarially chosen recipient spend public key.)
86
 *
87
 *  Args:                ctx: pointer to a context object
88
 *                            (not secp256k1_context_static).
89
 *  Out:   generated_outputs: pointer to an array of pointers to xonly public keys,
90
 *                            one per recipient.
91
 *                            The outputs are ordered to match the original
92
 *                            ordering of the recipient objects, i.e.,
93
 *                            `generated_outputs[0]` is the generated output
94
 *                            for the `secp256k1_silentpayments_recipient` object
95
 *                            with index = 0.
96
 *  In:           recipients: pointer to an array of pointers to Silent Payments
97
 *                            recipients, where each recipient is a scan public
98
 *                            key, a spend public key, and an index indicating
99
 *                            its position in the original ordering. This function
100
 *                            may reorder the pointers to the recipient objects
101
 *                            within the array, i.e., after the call (including on
102
 *                            failure), the index fields of the recipient objects
103
 *                            may no longer correspond to the positions in the
104
 *                            array. Multiple recipient objects with the same scan
105
 *                            public key and/or same spend public key can be passed
106
 *                            if they carry different indices.
107
 *              n_recipients: the size of the recipients array.
108
 *       outpoint_smallest36: serialized (36-byte) smallest outpoint
109
 *                            (lexicographically) from the transaction inputs
110
 *                  keypairs: pointer to an array of pointers to taproot
111
 *                            keypair inputs (can be NULL if no secret keys
112
 *                            of taproot inputs are used)
113
 *                n_keypairs: the size of the keypairs array.
114
 *                   seckeys: pointer to an array of pointers to 32-byte
115
 *                            secret keys of non-taproot inputs (can be NULL
116
 *                            if no secret keys of non-taproot inputs are
117
 *                            used)
118
 *                 n_seckeys: the size of the seckeys array.
119
 */
120
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs(
121
    const secp256k1_context *ctx,
122
    secp256k1_xonly_pubkey **generated_outputs,
123
    const secp256k1_silentpayments_recipient **recipients,
124
    size_t n_recipients,
125
    const unsigned char *outpoint_smallest36,
126
    const secp256k1_keypair * const *keypairs,
127
    size_t n_keypairs,
128
    const unsigned char * const *seckeys,
129
    size_t n_seckeys
130
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
131
132
/** Opaque data structure that holds a Silent Payments label.
133
 *
134
 *  Guaranteed to be 68 bytes in size. Serialized and parsed with
135
 *  `secp256k1_silentpayments_recipient_label_serialize` and
136
 *  `secp256k1_silentpayments_recipient_label_parse`.
137
 */
138
typedef struct secp256k1_silentpayments_label {
139
    unsigned char data[68];
140
} secp256k1_silentpayments_label;
141
142
/** Parse a Silent Payments label.
143
 *
144
 *  Returns: 1 when the label could be parsed, 0 otherwise.
145
 *  Args:    ctx: pointer to a context object
146
 *  Out:   label: pointer to a label object
147
 *  In:     in33: pointer to the 33-byte label to be parsed
148
 */
149
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_parse(
150
    const secp256k1_context *ctx,
151
    secp256k1_silentpayments_label *label,
152
    const unsigned char *in33
153
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
154
155
/** Serialize a Silent Payments label
156
 *
157
 *  Returns: 1 always
158
 *  Args:    ctx: pointer to a context object
159
 *  Out:   out33: pointer to a 33-byte array to store the serialized label
160
 *  In:    label: pointer to the label
161
 */
162
SECP256K1_API int secp256k1_silentpayments_recipient_label_serialize(
163
    const secp256k1_context *ctx,
164
    unsigned char *out33,
165
    const secp256k1_silentpayments_label *label
166
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
167
168
/** Create Silent Payments label tweak and label.
169
 *
170
 *  Given a recipient's 32 byte scan key and a label integer m, calculate the
171
 *  corresponding label tweak and label:
172
 *
173
 *      label_tweak = hash(scan_key || m)
174
 *            label = label_tweak * G
175
 *
176
 *  Returns: 1 if label tweak and label creation was successful.
177
 *           0 if scan_key32 is invalid or the hash output label_tweak32 is
178
 *             not a valid scalar (negligible probability per hash evaluation).
179
 *
180
 * WARNING: Creating a large number of labels may significantly degrade
181
 * scanning performance in certain Silent Payments wallet implementations,
182
 * such as light clients. The scanning function provided in this module,
183
 * which is designed for full nodes, performs consistently even with hundreds
184
 * of thousands of labels. Other implementations may not share this property
185
 * or may be unable to use it due to lacking full transaction data.
186
 *
187
 * To maximize wallet interoperability, it is recommended to create only
188
 * the change label (m = 0) and avoid distributing labeled addresses.
189
 *
190
 *  Args:                ctx: pointer to a context object
191
 *                            (not secp256k1_context_static)
192
 *  Out:               label: pointer to the resulting label
193
 *             label_tweak32: pointer to the 32 byte label tweak
194
 *  In:           scan_key32: pointer to the recipient's 32 byte scan key
195
 *                         m: integer for the m-th label (0 is used for change outputs)
196
 */
197
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_create(
198
    const secp256k1_context *ctx,
199
    secp256k1_silentpayments_label *label,
200
    unsigned char *label_tweak32,
201
    const unsigned char *scan_key32,
202
    uint32_t m
203
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
204
205
/** Create Silent Payments labeled spend public key.
206
 *
207
 *  Given a recipient's spend public key and a label, calculate the
208
 *  corresponding labeled spend public key:
209
 *
210
 *      labeled_spend_pubkey = unlabeled_spend_pubkey + label
211
 *
212
 *  The result is used by the recipient to create a Silent Payments address,
213
 *  consisting of the serialized and concatenated scan public key and
214
 *  (labeled) spend public key.
215
 *
216
 *  Returns: 1 if labeled spend public key creation was successful.
217
 *           0 if spend pubkey and label sum to zero (negligible probability for
218
 *             labels created according to BIP352).
219
 *
220
 *  Args:                    ctx: pointer to a context object
221
 *  Out:    labeled_spend_pubkey: pointer to the resulting labeled spend public key
222
 *  In:   unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key
223
 *                         label: pointer to the recipient's label
224
 */
225
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_labeled_spend_pubkey(
226
    const secp256k1_context *ctx,
227
    secp256k1_pubkey *labeled_spend_pubkey,
228
    const secp256k1_pubkey *unlabeled_spend_pubkey,
229
    const secp256k1_silentpayments_label *label
230
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
231
232
/** Opaque data structure that holds Silent Payments prevouts summary data.
233
 *
234
 *  The exact representation of data inside is implementation defined and not
235
 *  guaranteed to be portable between different platforms or versions. It is
236
 *  however guaranteed to be 101 bytes in size, and can be safely copied/moved.
237
 *  This structure does not contain secret data. It can be created with
238
 *  `secp256k1_silentpayments_recipient_prevouts_summary_create`.
239
 */
240
typedef struct secp256k1_silentpayments_prevouts_summary {
241
    unsigned char data[101];
242
} secp256k1_silentpayments_prevouts_summary;
243
244
/** Compute Silent Payments prevouts summary from prevout public keys and transaction
245
 *  inputs.
246
 *
247
 *  Given a list of n public keys A_1...A_n (one for each Silent Payments
248
 *  eligible input to spend) and a serialized outpoint_smallest36, create a
249
 *  `prevouts_summary` object. This object summarizes the prevout data from the
250
 *  transaction inputs needed for scanning.
251
 *
252
 *  `outpoint_smallest36` refers to the smallest outpoint lexicographically
253
 *  from the transaction inputs (both Silent Payments eligible and non-eligible
254
 *  inputs). This value MUST be the smallest outpoint out of all of the
255
 *  transaction inputs, otherwise the recipient will be unable to find the
256
 *  payment.
257
 *
258
 *  The public keys have to be passed in via two different parameter pairs, one
259
 *  for regular and one for x-only public keys, in order to avoid the need of
260
 *  users converting to a common public key format before calling this function.
261
 *  The resulting data can be used for scanning on the recipient side.
262
 *
263
 *  Returns: 1 if prevouts summary creation was successful.
264
 *           0 if the transaction is not a Silent Payments transaction.
265
 *
266
 *  Args:                 ctx: pointer to a context object
267
 *  Out:     prevouts_summary: pointer to prevouts_summary object containing the
268
 *                             summed public key and input_hash.
269
 *  In:   outpoint_smallest36: serialized smallest outpoint (lexicographically)
270
 *                             from the transaction inputs
271
 *              xonly_pubkeys: pointer to an array of pointers to taproot
272
 *                             x-only public keys (can be NULL if no taproot
273
 *                             inputs are used)
274
 *            n_xonly_pubkeys: the size of the xonly_pubkeys array.
275
 *                    pubkeys: pointer to an array of pointers to non-taproot
276
 *                             public keys (can be NULL if no non-taproot
277
 *                             inputs are used)
278
 *                  n_pubkeys: the size of the pubkeys array.
279
 */
280
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_prevouts_summary_create(
281
    const secp256k1_context *ctx,
282
    secp256k1_silentpayments_prevouts_summary *prevouts_summary,
283
    const unsigned char *outpoint_smallest36,
284
    const secp256k1_xonly_pubkey * const *xonly_pubkeys,
285
    size_t n_xonly_pubkeys,
286
    const secp256k1_pubkey * const *pubkeys,
287
    size_t n_pubkeys
288
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
289
290
/** Type of callback function for label lookups
291
 *
292
 *  A function of this type will be used to retrieve the label tweak for a given
293
 *  label during scanning. A typical implementation will perform a lookup in a
294
 *  key-value store called the "label cache".
295
 *
296
 *  For creating the label cache data,
297
 *  `secp256k1_silentpayments_recipient_label_create` and
298
 *  `secp256k1_silentpayments_recipient_label_serialize` can be used.
299
 *
300
 *  Returns: pointer to the 32-byte label tweak if there is a match.
301
 *           NULL pointer if there is no match.
302
 *
303
 *  In:         label: pointer to the serialized 33-byte label to check
304
 *                     (computed during scanning)
305
 *      label_context: pointer to the recipient's label cache.
306
 */
307
typedef const unsigned char* (*secp256k1_silentpayments_label_lookup)(const unsigned char* label33, const void* label_context);
308
309
/** Found outputs struct
310
 *
311
 *  Struct for holding a found output along with data needed to spend it later.
312
 *
313
 *            output: the x-only public key for the taproot output
314
 *             tweak: the 32-byte tweak needed to spend the output
315
 *  found_with_label: boolean value to indicate if the output was sent to a
316
 *                    labeled address. If true, label will be set to a valid value.
317
 *             label: the label used. If found_with_label = false, this is set to
318
 *                    an invalid value.
319
 */
320
typedef struct secp256k1_silentpayments_found_output {
321
    secp256k1_xonly_pubkey output;
322
    unsigned char tweak[32];
323
    int found_with_label;
324
    secp256k1_silentpayments_label label;
325
} secp256k1_silentpayments_found_output;
326
327
/** Scan for Silent Payments transaction outputs.
328
 *
329
 *  Given a prevouts_summary object, a recipient's 32 byte scan key and spend public key,
330
 *  and the relevant transaction outputs, scan for outputs belonging to
331
 *  the recipient and return the tweak(s) needed for spending the output(s). An
332
 *  optional label_lookup callback function and label_context can be passed if
333
 *  the recipient uses labels. This allows for checking if a label exists in
334
 *  the recipients label cache and retrieving the label tweak during scanning.
335
 *
336
 *  If used, the `label_lookup` function must return a pointer to a 32-byte label
337
 *  tweak if the label is found, or NULL otherwise. The returned pointer must remain
338
 *  valid until the next call to `label_lookup` or until the function returns,
339
 *  whichever comes first. It is not retained beyond that.
340
 *
341
 *  For creating the label cache, `secp256k1_silentpayments_recipient_label_create`
342
 *  and `secp256k1_silentpayments_recipient_label_serialize` can be used.
343
 *
344
 *  Note:
345
 *  Scanning is bounded by SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT and may
346
 *  miss outputs if a transaction contains more outputs for a single scan public
347
 *  key group than this limit.
348
 *
349
 *  Returns: 1 if output scanning was successful.
350
 *           0 if the transaction is not a Silent Payments transaction,
351
 *             or if the arguments are invalid.
352
 *
353
 *  Args:                   ctx: pointer to a context object
354
 *  Out:          found_outputs: pointer to an array of pointers to found
355
 *                               output objects. The found outputs array MUST
356
 *                               have the same length as the tx_outputs array.
357
 *              n_found_outputs: pointer to an integer indicating the final
358
 *                               size of the found outputs array. This number
359
 *                               represents the number of outputs found while
360
 *                               scanning (0 if none are found). Can't be larger than
361
 *                               SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT.
362
 *  In:              tx_outputs: pointer to the transaction's x-only public key outputs,
363
 *                               in their original transaction (vout) order
364
 *                 n_tx_outputs: the size of the tx_outputs array.
365
 *                   scan_key32: pointer to the recipient's 32 byte scan key. The scan
366
 *                               key is valid if it passes secp256k1_ec_seckey_verify
367
 *             prevouts_summary: pointer to the transaction prevouts summary data (see
368
 *                               `secp256k1_silentpayments_recipient_prevouts_summary_create`).
369
 *       unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key
370
 *                 label_lookup: pointer to a callback function for looking up
371
 *                               a label value. This function takes a serialized 33-byte
372
 *                               label as an argument and returns a pointer to the
373
 *                               32-byte label tweak if the label exists, otherwise
374
 *                               returns a NULL pointer (NULL if labels are not
375
 *                               used)
376
 *                label_context: pointer to a label context object (NULL if
377
 *                               labels are not used or context is not needed)
378
 */
379
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs(
380
    const secp256k1_context *ctx,
381
    secp256k1_silentpayments_found_output **found_outputs,
382
    uint32_t *n_found_outputs,
383
    const secp256k1_xonly_pubkey * const *tx_outputs,
384
    size_t n_tx_outputs,
385
    const unsigned char *scan_key32,
386
    const secp256k1_silentpayments_prevouts_summary *prevouts_summary,
387
    const secp256k1_pubkey *unlabeled_spend_pubkey,
388
    secp256k1_silentpayments_label_lookup label_lookup,
389
    const void *label_context
390
) 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);
391
392
#ifdef __cplusplus
393
}
394
#endif
395
396
#endif /* SECP256K1_SILENTPAYMENTS_H */