Skip to content

Commit 5aaf3be

Browse files
josibaketheStack
authored andcommitted
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 0db22b9 commit 5aaf3be

File tree

4 files changed

+696
-2
lines changed

4 files changed

+696
-2
lines changed

include/secp256k1_silentpayments.h

Lines changed: 101 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,106 @@ extern "C" {
2526
* any further elliptic-curve operations from the wallet.
2627
*/
2728

29+
30+
/** The data from a single recipient address
31+
*
32+
* This struct serves as an input argument to `silentpayments_sender_create_outputs`.
33+
*
34+
* `index` must be set to the position (starting with 0) of this recipient in the
35+
* `recipients` array passed to `silentpayments_sender_create_outputs`. It is
36+
* used to map the returned generated outputs back to the original recipient.
37+
*
38+
* Note:
39+
* The spend public key named `spend_pubkey` may have been optionally tweaked with
40+
* a label by the recipient. Whether `spend_pubkey` has actually been tagged with
41+
* a label is irrelevant for the sender. As a documentation convention in this API,
42+
* `unlabeled_spend_pubkey` is used to indicate when the unlabeled spend public must
43+
* be used.
44+
*/
45+
typedef struct secp256k1_silentpayments_recipient {
46+
secp256k1_pubkey scan_pubkey;
47+
secp256k1_pubkey spend_pubkey;
48+
size_t index;
49+
} secp256k1_silentpayments_recipient;
50+
51+
/** Create Silent Payment outputs for recipient(s).
52+
*
53+
* Given a list of n secret keys a_1...a_n (one for each silent payment
54+
* eligible input to spend), a serialized outpoint, and a list of recipients,
55+
* create the taproot outputs. Inputs with conditional branches or multiple
56+
* public keys are excluded from silent payments eligible inputs; see BIP352
57+
* for more information.
58+
*
59+
* `outpoint_smallest36` refers to the smallest outpoint lexicographically
60+
* from the transaction inputs (both silent payments eligible and non-eligible
61+
* inputs). This value MUST be the smallest outpoint out of all of the
62+
* transaction inputs, otherwise the recipient will be unable to find the
63+
* payment. Determining the smallest outpoint from the list of transaction
64+
* inputs is the responsibility of the caller. It is strongly recommended
65+
* that implementations ensure they are doing this correctly by using the
66+
* test vectors from BIP352.
67+
*
68+
* When creating more than one generated output, all of the generated outputs
69+
* MUST be included in the final transaction. Dropping any of the generated
70+
* outputs from the final transaction may make all or some of the outputs
71+
* unfindable by the recipient.
72+
*
73+
* Returns: 1 if creation of outputs was successful.
74+
* 0 on failure. This is expected only with an adversarially chosen
75+
* recipient spend key. Specifically, failure occurs when:
76+
* - Input secret keys sum to 0 or the negation of a spend key
77+
* (negligible probability if at least one of the input secret
78+
* keys is uniformly random and independent of all other keys)
79+
* - A hash output is not a valid scalar (negligible probability
80+
* per hash evaluation)
81+
*
82+
* Args: ctx: pointer to a context object
83+
* (not secp256k1_context_static).
84+
* Out: generated_outputs: pointer to an array of pointers to xonly public keys,
85+
* one per recipient.
86+
* The outputs are ordered to match the original
87+
* ordering of the recipient objects, i.e.,
88+
* `generated_outputs[0]` is the generated output
89+
* for the `_silentpayments_recipient` object with
90+
* index = 0.
91+
* In: recipients: pointer to an array of pointers to silent payment
92+
* recipients, where each recipient is a scan public
93+
* key, a spend public key, and an index indicating
94+
* its position in the original ordering. The
95+
* recipient array will be grouped by scan public key
96+
* in place (as specified in BIP0352), but generated
97+
* outputs are saved in the `generated_outputs` array
98+
* to match the original ordering (using the index
99+
* field). This ensures the caller is able to match
100+
* the generated outputs to the correct silent
101+
* payment addresses. The same recipient can be
102+
* passed multiple times to create multiple outputs
103+
* for the same recipient.
104+
* n_recipients: the size of the recipients array.
105+
* outpoint_smallest36: serialized (36-byte) smallest outpoint
106+
* (lexicographically) from the transaction inputs
107+
* taproot_seckeys: pointer to an array of pointers to taproot
108+
* keypair inputs (can be NULL if no secret keys
109+
* of taproot inputs are used)
110+
* n_taproot_seckeys: the size of taproot_seckeys array.
111+
* plain_seckeys: pointer to an array of pointers to 32-byte
112+
* secret keys of non-taproot inputs (can be NULL
113+
* if no secret keys of non-taproot inputs are
114+
* used)
115+
* n_plain_seckeys: the size of the plain_seckeys array.
116+
*/
117+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs(
118+
const secp256k1_context *ctx,
119+
secp256k1_xonly_pubkey **generated_outputs,
120+
const secp256k1_silentpayments_recipient **recipients,
121+
size_t n_recipients,
122+
const unsigned char *outpoint_smallest36,
123+
const secp256k1_keypair * const *taproot_seckeys,
124+
size_t n_taproot_seckeys,
125+
const unsigned char * const *plain_seckeys,
126+
size_t n_plain_seckeys
127+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
128+
28129
#ifdef __cplusplus
29130
}
30131
#endif

0 commit comments

Comments
 (0)