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