/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. This is expected only with an adversarially chosen |
79 | | * recipient spend key. Specifically, failure occurs when: |
80 | | * - Input secret keys sum to 0 |
81 | | * (negligible probability if at least one of the input secret |
82 | | * keys is uniformly random and independent of all other keys) |
83 | | * - A hash output is not a valid scalar (negligible probability |
84 | | * per hash evaluation) |
85 | | * - Any group (i.e. recipients sharing the same scan public key) exceeds |
86 | | * the protocol limit SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT |
87 | | * |
88 | | * Args: ctx: pointer to a context object |
89 | | * (not secp256k1_context_static). |
90 | | * Out: generated_outputs: pointer to an array of pointers to xonly public keys, |
91 | | * one per recipient. |
92 | | * The outputs are ordered to match the original |
93 | | * ordering of the recipient objects, i.e., |
94 | | * `generated_outputs[0]` is the generated output |
95 | | * for the `secp256k1_silentpayments_recipient` object |
96 | | * with index = 0. |
97 | | * In: recipients: pointer to an array of pointers to Silent Payments |
98 | | * recipients, where each recipient is a scan public |
99 | | * key, a spend public key, and an index indicating |
100 | | * its position in the original ordering. The |
101 | | * recipient array will be grouped by scan public key |
102 | | * in place (as specified in BIP0352), but generated |
103 | | * outputs are saved in the `generated_outputs` array |
104 | | * to match the original ordering (using the index |
105 | | * field). This ensures the caller is able to match |
106 | | * the generated outputs to the correct Silent |
107 | | * Payments addresses. The same recipient can be |
108 | | * passed multiple times to create multiple outputs |
109 | | * for the same recipient. |
110 | | * n_recipients: the size of the recipients array. |
111 | | * outpoint_smallest36: serialized (36-byte) smallest outpoint |
112 | | * (lexicographically) from the transaction inputs |
113 | | * keypairs: pointer to an array of pointers to taproot |
114 | | * keypair inputs (can be NULL if no secret keys |
115 | | * of taproot inputs are used) |
116 | | * n_keypairs: the size of the keypairs array. |
117 | | * seckeys: pointer to an array of pointers to 32-byte |
118 | | * secret keys of non-taproot inputs (can be NULL |
119 | | * if no secret keys of non-taproot inputs are |
120 | | * used) |
121 | | * n_seckeys: the size of the seckeys array. |
122 | | */ |
123 | | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs( |
124 | | const secp256k1_context *ctx, |
125 | | secp256k1_xonly_pubkey **generated_outputs, |
126 | | const secp256k1_silentpayments_recipient **recipients, |
127 | | size_t n_recipients, |
128 | | const unsigned char *outpoint_smallest36, |
129 | | const secp256k1_keypair * const *keypairs, |
130 | | size_t n_keypairs, |
131 | | const unsigned char * const *seckeys, |
132 | | size_t n_seckeys |
133 | | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5); |
134 | | |
135 | | /** Opaque data structure that holds a Silent Payments label. |
136 | | * |
137 | | * Guaranteed to be 68 bytes in size. Serialized and parsed with |
138 | | * `secp256k1_silentpayments_recipient_label_serialize` and |
139 | | * `secp256k1_silentpayments_recipient_label_parse`. |
140 | | */ |
141 | | typedef struct secp256k1_silentpayments_label { |
142 | | unsigned char data[68]; |
143 | | } secp256k1_silentpayments_label; |
144 | | |
145 | | /** Parse a Silent Payments label. |
146 | | * |
147 | | * Returns: 1 when the label could be parsed, 0 otherwise. |
148 | | * Args: ctx: pointer to a context object |
149 | | * Out: label: pointer to a label object |
150 | | * In: in33: pointer to the 33-byte label to be parsed |
151 | | */ |
152 | | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_parse( |
153 | | const secp256k1_context *ctx, |
154 | | secp256k1_silentpayments_label *label, |
155 | | const unsigned char *in33 |
156 | | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); |
157 | | |
158 | | /** Serialize a Silent Payments label |
159 | | * |
160 | | * Returns: 1 always |
161 | | * Args: ctx: pointer to a context object |
162 | | * Out: out33: pointer to a 33-byte array to store the serialized label |
163 | | * In: label: pointer to the label |
164 | | */ |
165 | | SECP256K1_API int secp256k1_silentpayments_recipient_label_serialize( |
166 | | const secp256k1_context *ctx, |
167 | | unsigned char *out33, |
168 | | const secp256k1_silentpayments_label *label |
169 | | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); |
170 | | |
171 | | /** Create Silent Payments label tweak and label. |
172 | | * |
173 | | * Given a recipient's 32 byte scan key and a label integer m, calculate the |
174 | | * corresponding label tweak and label: |
175 | | * |
176 | | * label_tweak = hash(scan_key || m) |
177 | | * label = label_tweak * G |
178 | | * |
179 | | * Returns: 1 if label tweak and label creation was successful. |
180 | | * 0 if scan_key32 is invalid or the hash output label_tweak32 is |
181 | | * not a valid scalar (negligible probability per hash evaluation). |
182 | | * |
183 | | * WARNING: Creating a large number of labels may significantly degrade |
184 | | * scanning performance in certain Silent Payments wallet implementations, |
185 | | * such as light clients. The scanning function provided in this module, |
186 | | * which is designed for full nodes, performs consistently even with hundreds |
187 | | * of thousands of labels. Other implementations may not share this property |
188 | | * or may be unable to use it due to lacking full transaction data. |
189 | | * |
190 | | * To maximize wallet interoperability, it is recommended to create only |
191 | | * the change label (m = 0) and avoid distributing labeled addresses. |
192 | | * |
193 | | * Args: ctx: pointer to a context object |
194 | | * (not secp256k1_context_static) |
195 | | * Out: label: pointer to the resulting label |
196 | | * label_tweak32: pointer to the 32 byte label tweak |
197 | | * In: scan_key32: pointer to the recipient's 32 byte scan key |
198 | | * m: integer for the m-th label (0 is used for change outputs) |
199 | | */ |
200 | | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_create( |
201 | | const secp256k1_context *ctx, |
202 | | secp256k1_silentpayments_label *label, |
203 | | unsigned char *label_tweak32, |
204 | | const unsigned char *scan_key32, |
205 | | uint32_t m |
206 | | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); |
207 | | |
208 | | /** Create Silent Payments labeled spend public key. |
209 | | * |
210 | | * Given a recipient's spend public key and a label, calculate the |
211 | | * corresponding labeled spend public key: |
212 | | * |
213 | | * labeled_spend_pubkey = unlabeled_spend_pubkey + label |
214 | | * |
215 | | * The result is used by the recipient to create a Silent Payments address, |
216 | | * consisting of the serialized and concatenated scan public key and |
217 | | * (labeled) spend public key. |
218 | | * |
219 | | * Returns: 1 if labeled spend public key creation was successful. |
220 | | * 0 if spend pubkey and label sum to zero (negligible probability for |
221 | | * labels created according to BIP352). |
222 | | * |
223 | | * Args: ctx: pointer to a context object |
224 | | * Out: labeled_spend_pubkey: pointer to the resulting labeled spend public key |
225 | | * In: unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key |
226 | | * label: pointer to the recipient's label |
227 | | */ |
228 | | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_labeled_spend_pubkey( |
229 | | const secp256k1_context *ctx, |
230 | | secp256k1_pubkey *labeled_spend_pubkey, |
231 | | const secp256k1_pubkey *unlabeled_spend_pubkey, |
232 | | const secp256k1_silentpayments_label *label |
233 | | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); |
234 | | |
235 | | /** Opaque data structure that holds Silent Payments prevouts summary data. |
236 | | * |
237 | | * The exact representation of data inside is implementation defined and not |
238 | | * guaranteed to be portable between different platforms or versions. It is |
239 | | * however guaranteed to be 101 bytes in size, and can be safely copied/moved. |
240 | | * This structure does not contain secret data. It can be created with |
241 | | * `secp256k1_silentpayments_recipient_prevouts_summary_create`. |
242 | | */ |
243 | | typedef struct secp256k1_silentpayments_prevouts_summary { |
244 | | unsigned char data[101]; |
245 | | } secp256k1_silentpayments_prevouts_summary; |
246 | | |
247 | | /** Compute Silent Payments prevouts summary from prevout public keys and transaction |
248 | | * inputs. |
249 | | * |
250 | | * Given a list of n public keys A_1...A_n (one for each Silent Payments |
251 | | * eligible input to spend) and a serialized outpoint_smallest36, create a |
252 | | * `prevouts_summary` object. This object summarizes the prevout data from the |
253 | | * transaction inputs needed for scanning. |
254 | | * |
255 | | * `outpoint_smallest36` refers to the smallest outpoint lexicographically |
256 | | * from the transaction inputs (both Silent Payments eligible and non-eligible |
257 | | * inputs). This value MUST be the smallest outpoint out of all of the |
258 | | * transaction inputs, otherwise the recipient will be unable to find the |
259 | | * payment. |
260 | | * |
261 | | * The public keys have to be passed in via two different parameter pairs, one |
262 | | * for regular and one for x-only public keys, in order to avoid the need of |
263 | | * users converting to a common public key format before calling this function. |
264 | | * The resulting data can be used for scanning on the recipient side. |
265 | | * |
266 | | * Returns: 1 if prevouts summary creation was successful. |
267 | | * 0 if the transaction is not a Silent Payments transaction. |
268 | | * |
269 | | * Args: ctx: pointer to a context object |
270 | | * Out: prevouts_summary: pointer to prevouts_summary object containing the |
271 | | * summed public key and input_hash. |
272 | | * In: outpoint_smallest36: serialized smallest outpoint (lexicographically) |
273 | | * from the transaction inputs |
274 | | * xonly_pubkeys: pointer to an array of pointers to taproot |
275 | | * x-only public keys (can be NULL if no taproot |
276 | | * inputs are used) |
277 | | * n_xonly_pubkeys: the size of the xonly_pubkeys array. |
278 | | * pubkeys: pointer to an array of pointers to non-taproot |
279 | | * public keys (can be NULL if no non-taproot |
280 | | * inputs are used) |
281 | | * n_pubkeys: the size of the pubkeys array. |
282 | | */ |
283 | | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_prevouts_summary_create( |
284 | | const secp256k1_context *ctx, |
285 | | secp256k1_silentpayments_prevouts_summary *prevouts_summary, |
286 | | const unsigned char *outpoint_smallest36, |
287 | | const secp256k1_xonly_pubkey * const *xonly_pubkeys, |
288 | | size_t n_xonly_pubkeys, |
289 | | const secp256k1_pubkey * const *pubkeys, |
290 | | size_t n_pubkeys |
291 | | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); |
292 | | |
293 | | /** Type of callback function for label lookups |
294 | | * |
295 | | * A function of this type will be used to retrieve the label tweak for a given |
296 | | * label during scanning. A typical implementation will perform a lookup in a |
297 | | * key-value store called the "label cache". |
298 | | * |
299 | | * For creating the label cache data, |
300 | | * `secp256k1_silentpayments_recipient_label_create` and |
301 | | * `secp256k1_silentpayments_recipient_label_serialize` can be used. |
302 | | * |
303 | | * Returns: pointer to the 32-byte label tweak if there is a match. |
304 | | * NULL pointer if there is no match. |
305 | | * |
306 | | * In: label: pointer to the serialized 33-byte label to check |
307 | | * (computed during scanning) |
308 | | * label_context: pointer to the recipient's label cache. |
309 | | */ |
310 | | typedef const unsigned char* (*secp256k1_silentpayments_label_lookup)(const unsigned char* label33, const void* label_context); |
311 | | |
312 | | /** Found outputs struct |
313 | | * |
314 | | * Struct for holding a found output along with data needed to spend it later. |
315 | | * |
316 | | * output: the x-only public key for the taproot output |
317 | | * tweak: the 32-byte tweak needed to spend the output |
318 | | * found_with_label: boolean value to indicate if the output was sent to a |
319 | | * labeled address. If true, label will be set to a valid value. |
320 | | * label: the label used. If found_with_label = false, this is set to |
321 | | * an invalid value. |
322 | | */ |
323 | | typedef struct secp256k1_silentpayments_found_output { |
324 | | secp256k1_xonly_pubkey output; |
325 | | unsigned char tweak[32]; |
326 | | int found_with_label; |
327 | | secp256k1_silentpayments_label label; |
328 | | } secp256k1_silentpayments_found_output; |
329 | | |
330 | | /** Scan for Silent Payments transaction outputs. |
331 | | * |
332 | | * Given a prevouts_summary object, a recipient's 32 byte scan key and spend public key, |
333 | | * and the relevant transaction outputs, scan for outputs belonging to |
334 | | * the recipient and return the tweak(s) needed for spending the output(s). An |
335 | | * optional label_lookup callback function and label_context can be passed if |
336 | | * the recipient uses labels. This allows for checking if a label exists in |
337 | | * the recipients label cache and retrieving the label tweak during scanning. |
338 | | * |
339 | | * If used, the `label_lookup` function must return a pointer to a 32-byte label |
340 | | * tweak if the label is found, or NULL otherwise. The returned pointer must remain |
341 | | * valid until the next call to `label_lookup` or until the function returns, |
342 | | * whichever comes first. It is not retained beyond that. |
343 | | * |
344 | | * For creating the label cache, `secp256k1_silentpayments_recipient_label_create` |
345 | | * and `secp256k1_silentpayments_recipient_label_serialize` can be used. |
346 | | * |
347 | | * Note: |
348 | | * Scanning is bounded by SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT and may |
349 | | * miss outputs if a transaction contains more outputs for a single scan public |
350 | | * key group than this limit. |
351 | | * |
352 | | * Returns: 1 if output scanning was successful. |
353 | | * 0 if the transaction is not a Silent Payments transaction, |
354 | | * or if the arguments are invalid. |
355 | | * |
356 | | * Args: ctx: pointer to a context object |
357 | | * Out: found_outputs: pointer to an array of pointers to found |
358 | | * output objects. The found outputs array MUST |
359 | | * have the same length as the tx_outputs array. |
360 | | * n_found_outputs: pointer to an integer indicating the final |
361 | | * size of the found outputs array. This number |
362 | | * represents the number of outputs found while |
363 | | * scanning (0 if none are found). Can't be larger than |
364 | | * SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT. |
365 | | * In: tx_outputs: pointer to the transaction's x-only public key outputs, |
366 | | * in their original transaction (vout) order |
367 | | * n_tx_outputs: the size of the tx_outputs array. |
368 | | * scan_key32: pointer to the recipient's 32 byte scan key. The scan |
369 | | * key is valid if it passes secp256k1_ec_seckey_verify |
370 | | * prevouts_summary: pointer to the transaction prevouts summary data (see |
371 | | * `secp256k1_silentpayments_recipient_prevouts_summary_create`). |
372 | | * unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key |
373 | | * label_lookup: pointer to a callback function for looking up |
374 | | * a label value. This function takes a serialized 33-byte |
375 | | * label as an argument and returns a pointer to the |
376 | | * 32-byte label tweak if the label exists, otherwise |
377 | | * returns a NULL pointer (NULL if labels are not |
378 | | * used) |
379 | | * label_context: pointer to a label context object (NULL if |
380 | | * labels are not used or context is not needed) |
381 | | */ |
382 | | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs( |
383 | | const secp256k1_context *ctx, |
384 | | secp256k1_silentpayments_found_output **found_outputs, |
385 | | uint32_t *n_found_outputs, |
386 | | const secp256k1_xonly_pubkey * const *tx_outputs, |
387 | | size_t n_tx_outputs, |
388 | | const unsigned char *scan_key32, |
389 | | const secp256k1_silentpayments_prevouts_summary *prevouts_summary, |
390 | | const secp256k1_pubkey *unlabeled_spend_pubkey, |
391 | | secp256k1_silentpayments_label_lookup label_lookup, |
392 | | const void *label_context |
393 | | ) 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); |
394 | | |
395 | | #ifdef __cplusplus |
396 | | } |
397 | | #endif |
398 | | |
399 | | #endif /* SECP256K1_SILENTPAYMENTS_H */ |