11#ifndef SECP256K1_SILENTPAYMENTS_H
22#define SECP256K1_SILENTPAYMENTS_H
33
4+ #include <stdint.h>
45#include "secp256k1.h"
56#include "secp256k1_extrakeys.h"
67
@@ -26,7 +27,6 @@ extern "C" {
2627 * any further elliptic-curve operations from the wallet.
2728 */
2829
29-
3030/** The data from a single recipient address
3131 *
3232 * This struct serves as an input argument to `silentpayments_sender_create_outputs`.
@@ -180,6 +180,157 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipien
180180 const secp256k1_pubkey * label
181181) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
182182
183+ /** Opaque data structure that holds silent payments prevout summary data.
184+ *
185+ * This structure does not contain secret data. Guaranteed to be 101 bytes in
186+ * size. It can be safely copied/moved. Created with
187+ * `secp256k1_silentpayments_recipient_prevouts_summary_create`.
188+ */
189+ typedef struct secp256k1_silentpayments_prevouts_summary {
190+ unsigned char data [101 ];
191+ } secp256k1_silentpayments_prevouts_summary ;
192+
193+ /** Compute Silent Payment prevout summary from prevout public keys and transaction
194+ * inputs.
195+ *
196+ * Given a list of n public keys A_1...A_n (one for each silent payment
197+ * eligible input to spend) and a serialized outpoint_smallest36, create a
198+ * `prevouts_summary` object. This object summarizes the prevout data from the
199+ * transaction inputs needed for scanning.
200+ *
201+ * `outpoint_smallest36` refers to the smallest outpoint lexicographically
202+ * from the transaction inputs (both silent payments eligible and non-eligible
203+ * inputs). This value MUST be the smallest outpoint out of all of the
204+ * transaction inputs, otherwise the recipient will be unable to find the
205+ * payment.
206+ *
207+ * The public keys have to be passed in via two different parameter pairs, one
208+ * for regular and one for x-only public keys, in order to avoid the need of
209+ * users converting to a common public key format before calling this function.
210+ * The resulting data can be used for scanning on the recipient side.
211+ *
212+ * Returns: 1 if prevout summary creation was successful.
213+ * 0 if the transaction is not a silent payments transaction.
214+ *
215+ * Args: ctx: pointer to a context object
216+ * Out: prevouts_summary: pointer to prevouts_summary object containing the
217+ * summed public key and input_hash.
218+ * In: outpoint_smallest36: serialized smallest outpoint (lexicographically)
219+ * from the transaction inputs
220+ * xonly_pubkeys: pointer to an array of pointers to taproot
221+ * x-only public keys (can be NULL if no taproot
222+ * inputs are used)
223+ * n_xonly_pubkeys: the size of the xonly_pubkeys array.
224+ * plain_pubkeys: pointer to an array of pointers to non-taproot
225+ * public keys (can be NULL if no non-taproot
226+ * inputs are used)
227+ * n_plain_pubkeys: the size of the plain_pubkeys array.
228+ */
229+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_prevouts_summary_create (
230+ const secp256k1_context * ctx ,
231+ secp256k1_silentpayments_prevouts_summary * prevouts_summary ,
232+ const unsigned char * outpoint_smallest36 ,
233+ const secp256k1_xonly_pubkey * const * xonly_pubkeys ,
234+ size_t n_xonly_pubkeys ,
235+ const secp256k1_pubkey * const * plain_pubkeys ,
236+ size_t n_plain_pubkeys
237+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
238+
239+ /** Callback function for label lookups
240+ *
241+ * This function is implemented by the recipient to check if a value exists in
242+ * the recipients label cache during scanning.
243+ *
244+ * For creating the labels cache data,
245+ * `secp256k1_silentpayments_recipient_create_label` can be used.
246+ *
247+ * Returns: pointer to the 32-byte label tweak if there is a match.
248+ * NULL pointer if there is no match.
249+ *
250+ * In: label: pointer to the label public key to check (computed during
251+ * scanning)
252+ * label_context: pointer to the recipients label cache.
253+ */
254+ typedef const unsigned char * (* secp256k1_silentpayments_label_lookup )(const unsigned char * label33 , const void * label_context );
255+
256+ /** Found outputs struct
257+ *
258+ * Struct for holding a found output along with data needed to spend it later.
259+ *
260+ * output: the x-only public key for the taproot output
261+ * tweak: the 32-byte tweak needed to spend the output
262+ * found_with_label: boolean value to indicate if the output was sent to a
263+ * labeled address. If true, label will be set with a valid
264+ * public key.
265+ * label: public key representing the label used.
266+ * If found_with_label = false, this is set to an invalid
267+ * public key.
268+ */
269+ typedef struct secp256k1_silentpayments_found_output {
270+ secp256k1_xonly_pubkey output ;
271+ unsigned char tweak [32 ];
272+ int found_with_label ;
273+ secp256k1_pubkey label ;
274+ } secp256k1_silentpayments_found_output ;
275+
276+ /** Scan for Silent Payment transaction outputs.
277+ *
278+ * Given a prevouts_summary object, a recipient's 32 byte scan key and spend public key,
279+ * and the relevant transaction outputs, scan for outputs belonging to
280+ * the recipient and return the tweak(s) needed for spending the output(s). An
281+ * optional label_lookup callback function and label_context can be passed if
282+ * the recipient uses labels. This allows for checking if a label exists in
283+ * the recipients label cache and retrieving the label tweak during scanning.
284+ *
285+ * If used, the `label_lookup` function must return a pointer to a 32-byte label
286+ * tweak if the label is found, or NULL otherwise. The returned pointer must remain
287+ * valid until the next call to `label_lookup` or until the function returns,
288+ * whichever comes first. It is not retained beyond that.
289+ *
290+ * For creating the labels cache, `secp256k1_silentpayments_recipient_create_label`
291+ * can be used.
292+ *
293+ * Returns: 1 if output scanning was successful.
294+ * 0 if the transaction is not a silent payments transaction,
295+ * or if the arguments are invalid.
296+ *
297+ * Args: ctx: pointer to a context object
298+ * Out: found_outputs: pointer to an array of pointers to found
299+ * output objects. The found outputs array MUST
300+ * have the same length as the tx_outputs array.
301+ * n_found_outputs: pointer to an integer indicating the final
302+ * size of the found outputs array. This number
303+ * represents the number of outputs found while
304+ * scanning (0 if none are found).
305+ * In: tx_outputs: pointer to the transaction's x-only public key outputs
306+ * n_tx_outputs: the size of the tx_outputs array.
307+ * scan_key32: pointer to the recipient's 32 byte scan key. The scan
308+ * key is valid if it passes secp256k1_ec_seckey_verify
309+ * prevouts_summary: pointer to the transaction prevouts summary data
310+ * (see `_recipient_prevouts_summary_create`).
311+ * unlabeled_spend_pubkey: pointer to the recipient's unlabeled spend public key
312+ * label_lookup: pointer to a callback function for looking up
313+ * a label value. This function takes a label
314+ * public key as an argument and returns a pointer to
315+ * the label tweak if the label exists, otherwise
316+ * returns a NULL pointer (NULL if labels are not
317+ * used)
318+ * label_context: pointer to a label context object (NULL if
319+ * labels are not used or context is not needed)
320+ */
321+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs (
322+ const secp256k1_context * ctx ,
323+ secp256k1_silentpayments_found_output * * found_outputs ,
324+ size_t * n_found_outputs ,
325+ const secp256k1_xonly_pubkey * const * tx_outputs ,
326+ size_t n_tx_outputs ,
327+ const unsigned char * scan_key32 ,
328+ const secp256k1_silentpayments_prevouts_summary * prevouts_summary ,
329+ const secp256k1_pubkey * unlabeled_spend_pubkey ,
330+ const secp256k1_silentpayments_label_lookup label_lookup ,
331+ const void * label_context
332+ ) 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 );
333+
183334#ifdef __cplusplus
184335}
185336#endif
0 commit comments