@@ -139,6 +139,139 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipien
139139 const secp256k1_pubkey * label
140140) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 );
141141
142+ /** Opaque data structure that holds silent payments public input data.
143+ *
144+ * This structure does not contain secret data. Guaranteed to be 98 bytes in size. It can be safely
145+ * copied/moved. Created with `secp256k1_silentpayments_public_data_create`. Can be serialized as
146+ * a compressed public key using `secp256k1_silentpayments_public_data_serialize`. The serialization
147+ * is intended for sending the public input data to light clients. Light clients can use this
148+ * serialization with `secp256k1_silentpayments_public_data_parse`.
149+ */
150+ typedef struct {
151+ unsigned char data [98 ];
152+ } secp256k1_silentpayments_public_data ;
153+
154+ /** Compute Silent Payment public data from input public keys and transaction inputs.
155+ *
156+ * Given a list of n public keys A_1...A_n (one for each silent payment
157+ * eligible input to spend) and a serialized outpoint_smallest, compute
158+ * the corresponding input public tweak data:
159+ *
160+ * A_sum = A_1 + A_2 + ... + A_n
161+ * input_hash = hash(outpoint_lowest || A_sum)
162+ *
163+ * The public keys have to be passed in via two different parameter pairs,
164+ * one for regular and one for x-only public keys, in order to avoid the need
165+ * of users converting to a common pubkey format before calling this function.
166+ * The resulting data is can be used for scanning on the recipient side, or stored
167+ * in an index for late use (e.g. wallet rescanning, vending data to light clients).
168+ *
169+ * If calling this function for scanning, the reciever must provide an output param
170+ * for the `input_hash`. If calling this function for simply aggregating the inputs
171+ * for later use, the caller can save the result with `silentpayments_public_data_serialize`.
172+ *
173+ * Returns: 1 if tweak data creation was successful. 0 if an error occured.
174+ * Args: ctx: pointer to a context object
175+ * Out: public_data: pointer to public_data object containing the summed public key and
176+ * input_hash.
177+ * In: outpoint_smallest36: serialized smallest outpoint
178+ * xonly_pubkeys: pointer to an array of pointers to taproot x-only
179+ * public keys (can be NULL if no taproot inputs are used)
180+ * n_xonly_pubkeys: the number of taproot input public keys
181+ * plain_pubkeys: pointer to an array of pointers to non-taproot
182+ * public keys (can be NULL if no non-taproot inputs are used)
183+ * n_plain_pubkeys: the number of non-taproot input public keys
184+ */
185+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_public_data_create (
186+ const secp256k1_context * ctx ,
187+ secp256k1_silentpayments_public_data * public_data ,
188+ const unsigned char * outpoint_smallest36 ,
189+ const secp256k1_xonly_pubkey * const * xonly_pubkeys ,
190+ size_t n_xonly_pubkeys ,
191+ const secp256k1_pubkey * const * plain_pubkeys ,
192+ size_t n_plain_pubkeys
193+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
194+
195+ /** Serialize a silentpayments_public_data object into a 33-byte sequence.
196+ *
197+ * Returns: 1 always.
198+ *
199+ * Args: ctx: pointer to a context object.
200+ * Out: output33: pointer to a 33-byte array to place the serialized `silentpayments_public_data` in.
201+ * In: public_data: pointer to an initialized silentpayments_public_data object.
202+ */
203+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_public_data_serialize (
204+ const secp256k1_context * ctx ,
205+ unsigned char * output33 ,
206+ const secp256k1_silentpayments_public_data * public_data
207+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
208+
209+ /** Parse a 33-byte sequence into a silent_payments_public_data object.
210+ *
211+ * Returns: 1 if the data was able to be parsed.
212+ * 0 if the sequence is invalid (e.g. does not represent a valid public key).
213+ *
214+ * Args: ctx: pointer to a context object.
215+ * Out: public_data: pointer to a silentpayments_public_data object. If 1 is returned, it is set to a
216+ * parsed version of input33.
217+ * In: input33: pointer to a serialized silentpayments_public_data.
218+ */
219+
220+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_public_data_parse (
221+ const secp256k1_context * ctx ,
222+ secp256k1_silentpayments_public_data * public_data ,
223+ const unsigned char * input33
224+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 );
225+
226+ /** Scan for Silent Payment transaction outputs.
227+ *
228+ * Given a input public sum, an input_hash, a recipient's spend public key B_spend, and the relevant transaction
229+ * outputs, scan for outputs belong to the recipient and return the tweak(s) needed for spending
230+ * the output(s). An optional label_lookup callback function and label_context can be passed if the
231+ * recipient uses labels. This allows for checking if a label exists in the recipients label cache
232+ * and retrieving the label tweak during scanning.
233+ *
234+ * Returns: 1 if output scanning was successful. 0 if an error occured.
235+ * Args: ctx: pointer to a context object
236+ * Out: found_outputs: pointer to an array of pointers to found output objects. The found outputs
237+ * array MUST be initialized to be the same length as the tx_outputs array
238+ * n_found_outputs: pointer to an integer indicating the final size of the found outputs array.
239+ * This number represents the number of outputs found while scanning (0 if
240+ * none are found)
241+ * In: tx_outputs: pointer to the tx's x-only public key outputs
242+ * n_tx_outputs: the number of tx_outputs being scanned
243+ * scan_key: pointer to the recipient's scan key
244+ * public_data: pointer to the input public key sum (optionaly, with the `input_hash`
245+ * multiplied in, see `_recipient_compute_public_data`).
246+ * recipient_spend_pubkey: pointer to the receiver's spend pubkey
247+ * label_lookup: pointer to a callback function for looking up a label value. This fucntion
248+ * takes a label pubkey as an argument and returns a pointer to the label tweak
249+ * if the label exists, otherwise returns a nullptr (NULL if labels are not used)
250+ * label_context: pointer to a label context object (NULL if labels are not used)
251+ */
252+
253+ typedef const unsigned char * (* secp256k1_silentpayments_label_lookup )(const secp256k1_pubkey * , const void * );
254+ typedef struct {
255+ secp256k1_xonly_pubkey output ;
256+ unsigned char tweak [32 ];
257+ int found_with_label ;
258+ secp256k1_pubkey label ;
259+ } secp256k1_silentpayments_found_output ;
260+
261+ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs (
262+ const secp256k1_context * ctx ,
263+ secp256k1_silentpayments_found_output * * found_outputs ,
264+ size_t * n_found_outputs ,
265+ const secp256k1_xonly_pubkey * const * tx_outputs ,
266+ size_t n_tx_outputs ,
267+ const unsigned char * scan_key ,
268+ const secp256k1_silentpayments_public_data * public_data ,
269+ const secp256k1_pubkey * receiver_spend_pubkey ,
270+ const secp256k1_silentpayments_label_lookup label_lookup ,
271+ const void * label_context
272+ ) SECP256K1_ARG_NONNULL (1 ) SECP256K1_ARG_NONNULL (2 ) SECP256K1_ARG_NONNULL (3 ) SECP256K1_ARG_NONNULL (4 )
273+ SECP256K1_ARG_NONNULL (6 ) SECP256K1_ARG_NONNULL (7 ) SECP256K1_ARG_NONNULL (8 );
274+
142275#ifdef __cplusplus
143276}
144277#endif
0 commit comments