Skip to content

Commit eb2e695

Browse files
committed
silentpayments: sending
Add a routine for the entire sending flow which takes a set of private keys, the smallest outpoint, and list of recipients and returns a list of x-only public keys by performing the following steps: 1. Sum up the private keys 2. Calculate the input_hash 3. For each recipient group: 3a. Calculate a shared secret 3b. Create the requested number of outputs This function assumes a single sender context in that it requires the sender to have access to all of the private keys. In the future, this API may be expanded to allow for a multiple senders or for a single sender who does not have access to all private keys at any given time, but for now these modes are considered out of scope / unsafe. Internal to the library, add: 1. A function for creating shared secrets (i.e., a*B or b*A) 2. A function for generating the "SharedSecret" tagged hash 3. A function for creating a single output public key
1 parent 8f69297 commit eb2e695

File tree

4 files changed

+631
-2
lines changed

4 files changed

+631
-2
lines changed

include/secp256k1_silentpayments.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define SECP256K1_SILENTPAYMENTS_H
33

44
#include "secp256k1.h"
5+
#include "secp256k1_extrakeys.h"
56

67
#ifdef __cplusplus
78
extern "C" {
@@ -25,6 +26,93 @@ extern "C" {
2526
* any further elliptic-curve operations from the wallet.
2627
*/
2728

29+
/** This struct serves as an input parameter for passing the silent payment
30+
* address data to `silentpayments_sender_create_outputs`.
31+
*
32+
* The index field is for when more than one address is being sent to in
33+
* a transaction. Index is set to the position of this recipient in the
34+
* `recipients` array passed to `silentpayments_sender_create_outputs`
35+
* and used to return the generated outputs matching the original ordering.
36+
*
37+
* The spend public key field is named `labeled_spend_pubkey` to indicate this
38+
* spend public key may be tweaked with an optional label. This is not relevant
39+
* for the sender and is purely a documentation convention to differentiate
40+
* between other uses of `spend_pubkey` in this API, where it is meant to refer
41+
* to the unlabeled spend public key.
42+
*/
43+
typedef struct {
44+
secp256k1_pubkey scan_pubkey;
45+
secp256k1_pubkey labeled_spend_pubkey;
46+
size_t index;
47+
} secp256k1_silentpayments_recipient;
48+
49+
/** Create Silent Payment outputs for recipient(s).
50+
*
51+
* Given a list of n secret keys a_1...a_n (one for each silent payment
52+
* eligible input to spend), a serialized outpoint, and a list of recipients,
53+
* create the taproot outputs.
54+
*
55+
* `outpoint_smallest` refers to the smallest outpoint lexicographically
56+
* from the transaction inputs (both silent payments eligible and non-eligible
57+
* inputs). This value MUST be the smallest outpoint out of all of the
58+
* transaction inputs, otherwise the recipient will be unable to find the
59+
* payment. Determining the smallest outpoint from the list of transaction
60+
* inputs is the responsibility of the caller. It is strongly recommended
61+
* that implementations ensure they are doing this correctly by using the
62+
* test vectors from BIP352.
63+
*
64+
* If necessary, the secret keys are negated to enforce the right y-parity.
65+
* For that reason, the secret keys have to be passed in via two different
66+
* parameter pairs, depending on whether the seckeys correspond to x-only
67+
* outputs or not.
68+
*
69+
* Returns: 1 if creation of outputs was successful. 0 if an error occurred.
70+
* Args: ctx: pointer to a context object
71+
* Out: generated_outputs: pointer to an array of pointers to xonly pubkeys,
72+
* one per recipient.
73+
* The outputs here are sorted by the index value
74+
* provided in the recipient objects.
75+
* In: recipients: pointer to an array of pointers to silent payment
76+
* recipients, where each recipient is a scan public
77+
* key, a spend public key, and an index indicating
78+
* its position in the original ordering. The
79+
* recipient array will be sorted in place, but
80+
* generated outputs are saved in the
81+
* `generated_outputs` array to match the ordering
82+
* from the index field. This ensures the caller is
83+
* able to match the generated outputs to the
84+
* correct silent payment addresses. The same
85+
* recipient can be passed multiple times to create
86+
* multiple outputs for the same recipient.
87+
* n_recipients: the number of recipients. This is equal to the
88+
* total number of outputs to be generated as each
89+
* recipient may passed multiple times to generate
90+
* multiple outputs for the same recipient
91+
* outpoint_smallest: serialized (36-byte) smallest outpoint
92+
* (lexicographically) from the transaction inputs
93+
* taproot_seckeys: pointer to an array of pointers to taproot
94+
* keypair inputs (can be NULL if no secret keys
95+
* of taproot inputs are used)
96+
* n_taproot_seckeys: the number of sender's taproot input secret keys
97+
* plain_seckeys: pointer to an array of pointers to 32-byte
98+
* secret keys of non-taproot inputs (can be NULL
99+
* if no secret keys of non-taproot inputs are
100+
* used)
101+
* n_plain_seckeys: the number of sender's non-taproot input secret
102+
* keys
103+
*/
104+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs(
105+
const secp256k1_context *ctx,
106+
secp256k1_xonly_pubkey **generated_outputs,
107+
const secp256k1_silentpayments_recipient **recipients,
108+
size_t n_recipients,
109+
const unsigned char *outpoint_smallest36,
110+
const secp256k1_keypair * const *taproot_seckeys,
111+
size_t n_taproot_seckeys,
112+
const unsigned char * const *plain_seckeys,
113+
size_t n_plain_seckeys
114+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
115+
28116
#ifdef __cplusplus
29117
}
30118
#endif

0 commit comments

Comments
 (0)