1
1
#ifndef SECP256K1_SILENTPAYMENTS_H
2
2
#define SECP256K1_SILENTPAYMENTS_H
3
3
4
+ #include <stdint.h>
4
5
#include "secp256k1.h"
5
6
#include "secp256k1_extrakeys.h"
6
7
@@ -26,6 +27,8 @@ extern "C" {
26
27
* any further elliptic-curve operations from the wallet.
27
28
*/
28
29
30
+ static const unsigned char secp256k1_silentpayments_public_data_magic [4 ] = { 0xa7 , 0x1c , 0xd3 , 0x5e };
31
+
29
32
/** This struct serves as an input parameter for passing the silent payment
30
33
* address data to `silentpayments_sender_create_outputs`.
31
34
*
@@ -158,6 +161,252 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipien
158
161
const secp256k1_pubkey * label
159
162
) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
160
163
164
+ /** Opaque data structure that holds silent payments public input data.
165
+ *
166
+ * This structure does not contain secret data. Guaranteed to be 101 bytes in
167
+ * size. It can be safely copied/moved. Created with
168
+ * `secp256k1_silentpayments_recipient_public_data_create`. Can be serialized as a
169
+ * compressed public key using
170
+ * `secp256k1_silentpayments_recipient_public_data_serialize`. The serialization is
171
+ * intended for sending the public input data to light clients. Light clients
172
+ * can use this serialization with
173
+ * `secp256k1_silentpayments_recipient_public_data_parse`.
174
+ */
175
+ typedef struct {
176
+ unsigned char data [101 ];
177
+ } secp256k1_silentpayments_recipient_public_data ;
178
+
179
+ /** Compute Silent Payment public data from input public keys and transaction
180
+ * inputs.
181
+ *
182
+ * Given a list of n public keys A_1...A_n (one for each silent payment
183
+ * eligible input to spend) and a serialized outpoint_smallest, create a
184
+ * `public_data` object. This object summarizes the public data from the
185
+ * transaction inputs needed for scanning.
186
+ *
187
+ * `outpoint_smallest36` refers to the smallest outpoint lexicographically
188
+ * from the transaction inputs (both silent payments eligible and non-eligible
189
+ * inputs). This value MUST be the smallest outpoint out of all of the
190
+ * transaction inputs, otherwise the recipient will be unable to find the the
191
+ * payment.
192
+ *
193
+ * The public keys have to be passed in via two different parameter pairs, one
194
+ * for regular and one for x-only public keys, in order to avoid the need of
195
+ * users converting to a common pubkey format before calling this function.
196
+ * The resulting data can be used for scanning on the recipient side, or
197
+ * stored in an index for later use (e.g. wallet rescanning, vending data to
198
+ * light clients).
199
+ *
200
+ * If calling this function for simply aggregating the public transaction data
201
+ * for later use, the caller can save the result with
202
+ * `silentpayments_recipient_public_data_serialize`.
203
+ *
204
+ * Returns: 1 if public data creation was successful. 0 if an error occured.
205
+ * Args: ctx: pointer to a context object
206
+ * Out: public_data: pointer to public_data object containing the
207
+ * summed public key and input_hash.
208
+ * In: outpoint_smallest36: serialized smallest outpoint (lexicographically)
209
+ * from the transaction inputs
210
+ * xonly_pubkeys: pointer to an array of pointers to taproot
211
+ * x-only public keys (can be NULL if no taproot
212
+ * inputs are used)
213
+ * n_xonly_pubkeys: the number of taproot input public keys
214
+ * plain_pubkeys: pointer to an array of pointers to non-taproot
215
+ * public keys (can be NULL if no non-taproot
216
+ * inputs are used)
217
+ * n_plain_pubkeys: the number of non-taproot input public keys
218
+ */
219
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_public_data_create (
220
+ const secp256k1_context * ctx ,
221
+ secp256k1_silentpayments_recipient_public_data * public_data ,
222
+ const unsigned char * outpoint_smallest36 ,
223
+ const secp256k1_xonly_pubkey * const * xonly_pubkeys ,
224
+ size_t n_xonly_pubkeys ,
225
+ const secp256k1_pubkey * const * plain_pubkeys ,
226
+ size_t n_plain_pubkeys
227
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
228
+
229
+ /** Serialize a silentpayments_recipient_public_data object into a 33-byte sequence.
230
+ *
231
+ * Returns: 1 always.
232
+ *
233
+ * Args: ctx: pointer to a context object
234
+ * Out: output33: pointer to a 33-byte array to place the serialized
235
+ * `silentpayments_recipient_public_data` in
236
+ * In: public_data: pointer to an initialized silentpayments_recipient_public_data
237
+ * object
238
+ */
239
+ SECP256K1_API int secp256k1_silentpayments_recipient_public_data_serialize (
240
+ const secp256k1_context * ctx ,
241
+ unsigned char * output33 ,
242
+ const secp256k1_silentpayments_recipient_public_data * public_data
243
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
244
+
245
+ /** Parse a 33-byte sequence into a silent_payments_public_data object.
246
+ *
247
+ * Returns: 1 if the data was able to be parsed.
248
+ * 0 if the sequence is invalid (e.g. does not represent a valid
249
+ * public key).
250
+ *
251
+ * Args: ctx: pointer to a context object.
252
+ * Out: public_data: pointer to a silentpayments_recipient_public_data object. If 1 is
253
+ * returned, it is set to a parsed version of input33.
254
+ * In: input33: pointer to a serialized silentpayments_recipient_public_data.
255
+ */
256
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_public_data_parse (
257
+ const secp256k1_context * ctx ,
258
+ secp256k1_silentpayments_recipient_public_data * public_data ,
259
+ const unsigned char * input33
260
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
261
+
262
+ /** Callback function for label lookups
263
+ *
264
+ * This function is implemented by the recipient to check if a value exists in
265
+ * the recipients label cache during scanning.
266
+ *
267
+ * For creating the labels cache,
268
+ * `secp256k1_silentpayments_recipient_create_label_tweak` can be used.
269
+ *
270
+ * Returns: pointer to the 32-byte label tweak if there is a match.
271
+ * NULL pointer if there is no match.
272
+ *
273
+ * In: label: pointer to the label pubkey to check (computed during
274
+ * scanning)
275
+ * label_context: pointer to the recipients label cache.
276
+ */
277
+ typedef const unsigned char * (* secp256k1_silentpayments_label_lookup )(const unsigned char * label33 , const void * label_context );
278
+
279
+ /** Found outputs struct
280
+ *
281
+ * Struct for holding a found output along with data needed to spend it later.
282
+ *
283
+ * output: the x-only public key for the taproot output
284
+ * tweak: the 32-byte tweak needed to spend the output
285
+ * found_with_label: boolean value to indicate if the output was sent to a
286
+ * labelled address. If true, label will be set with a valid
287
+ * public key.
288
+ * label: public key representing the label used.
289
+ * If found_with_label = false, this is set to an invalid
290
+ * public key.
291
+ */
292
+ typedef struct {
293
+ secp256k1_xonly_pubkey output ;
294
+ unsigned char tweak [32 ];
295
+ int found_with_label ;
296
+ secp256k1_pubkey label ;
297
+ } secp256k1_silentpayments_found_output ;
298
+
299
+ /** Scan for Silent Payment transaction outputs.
300
+ *
301
+ * Given a public_data object, a recipient's scan key and spend public key,
302
+ * and the relevant transaction outputs, scan for outputs belonging to
303
+ * the recipient and return the tweak(s) needed for spending the output(s). An
304
+ * optional label_lookup callback function and label_context can be passed if
305
+ * the recipient uses labels. This allows for checking if a label exists in
306
+ * the recipients label cache and retrieving the label tweak during scanning.
307
+ *
308
+ * For the labels cache, `secp256k1_silentpayments_recipient_create_label`
309
+ * can be used.
310
+ *
311
+ * Returns: 1 if output scanning was successful.
312
+ * 0 if an error occured.
313
+ *
314
+ * Args: ctx: pointer to a context object
315
+ * Out: found_outputs: pointer to an array of pointers to found
316
+ * output objects. The found outputs array MUST
317
+ * be initialized to be the same length as the
318
+ * tx_outputs array
319
+ * n_found_outputs: pointer to an integer indicating the final
320
+ * size of the found outputs array. This number
321
+ * represents the number of outputs found while
322
+ * scanning (0 if none are found)
323
+ * In: tx_outputs: pointer to the tx's x-only public key outputs
324
+ * n_tx_outputs: the number of tx_outputs being scanned
325
+ * recipient_scan_key: pointer to the recipient's scan key
326
+ * public_data: pointer to the transaction public data
327
+ * (see `_recipient_public_data_create`).
328
+ * recipient_spend_pubkey: pointer to the recipient's spend pubkey
329
+ * label_lookup: pointer to a callback function for looking up
330
+ * a label value. This function takes a label
331
+ * pubkey as an argument and returns a pointer to
332
+ * the label tweak if the label exists, otherwise
333
+ * returns a NULL pointer (NULL if labels are not
334
+ * used)
335
+ * label_context: pointer to a label context object (NULL if
336
+ * labels are not used)
337
+ */
338
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs (
339
+ const secp256k1_context * ctx ,
340
+ secp256k1_silentpayments_found_output * * found_outputs ,
341
+ size_t * n_found_outputs ,
342
+ const secp256k1_xonly_pubkey * const * tx_outputs ,
343
+ size_t n_tx_outputs ,
344
+ const unsigned char * recipient_scan_key ,
345
+ const secp256k1_silentpayments_recipient_public_data * public_data ,
346
+ const secp256k1_pubkey * recipient_spend_pubkey ,
347
+ const secp256k1_silentpayments_label_lookup label_lookup ,
348
+ const void * label_context
349
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 )
350
+ SECP256K1_ARG_NONNULL (6 ) SECP256K1_ARG_NONNULL (7 ) SECP256K1_ARG_NONNULL (8 );
351
+
352
+ /** Create Silent Payment shared secret.
353
+ *
354
+ * Given the public input data (secp256k1_silentpayments_recipient_public_data),
355
+ * and the recipient's scan key, calculate the shared secret.
356
+ *
357
+ * The resulting shared secret is needed as input for creating silent payments
358
+ * outputs belonging to the same recipient scan public key. This function is
359
+ * intended for light clients, i.e., scenarios where the caller does not have
360
+ * access to the full transaction. If the caller does have access to the full
361
+ * transaction, `secp256k1_silentpayments_recipient_scan_outputs` should be
362
+ * used instead.
363
+ *
364
+ * Returns: 1 if shared secret creation was successful. 0 if an error occured.
365
+ * Args: ctx: pointer to a context object
366
+ * Out: shared_secret33: pointer to the resulting 33-byte shared secret
367
+ * In: recipient_scan_key: pointer to the recipient's scan key
368
+ * public_data: pointer to the input public key sum, tweaked
369
+ * with the input_hash (see
370
+ * `_recipient_public_data_create`)
371
+ */
372
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_shared_secret (
373
+ const secp256k1_context * ctx ,
374
+ unsigned char * shared_secret33 ,
375
+ const unsigned char * recipient_scan_key ,
376
+ const secp256k1_silentpayments_recipient_public_data * public_data
377
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
378
+
379
+ /** Create Silent Payment output public key.
380
+ *
381
+ * Given a shared_secret, a public key B_spend, and an output counter k,
382
+ * create an output public key.
383
+ *
384
+ * This function is used by the recipient when scanning for outputs without
385
+ * access to the transaction outputs (e.g. using BIP158 block filters). When
386
+ * scanning with this function, it is the scanners responsibility to determine
387
+ * if the generated output exists in a block before proceeding to the next
388
+ * value of `k`.
389
+ *
390
+ * Returns: 1 if output creation was successful. 0 if an error occured.
391
+ * Args: ctx: pointer to a context object
392
+ * Out: P_output_xonly: pointer to the resulting output x-only pubkey
393
+ * In: shared_secret33: shared secret, derived from either sender's
394
+ * or recipient's perspective with routines from
395
+ * above
396
+ * recipient_spend_pubkey: pointer to the recipient's spend pubkey
397
+ * (labelled or unlabelled)
398
+ * k: output counter (initially set to 0, must be
399
+ * incremented for each additional output created
400
+ * or after each output found when scanning)
401
+ */
402
+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_output_pubkey (
403
+ const secp256k1_context * ctx ,
404
+ secp256k1_xonly_pubkey * P_output_xonly ,
405
+ const unsigned char * shared_secret33 ,
406
+ const secp256k1_pubkey * recipient_spend_pubkey ,
407
+ uint32_t k
408
+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
409
+
161
410
#ifdef __cplusplus
162
411
}
163
412
#endif
0 commit comments