@@ -163,6 +163,252 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipien
163163 const secp256k1_pubkey * label
164164) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
165165
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+
166412#ifdef __cplusplus
167413}
168414#endif
0 commit comments