Skip to content

Commit

Permalink
silentpayments: implement output privkey creation (for receiver)
Browse files Browse the repository at this point in the history
Labels are not supported yet, the corresponding parameter
label_tweak32 must be set to NULL right now.
  • Loading branch information
theStack committed Dec 20, 2023
1 parent a626eff commit b86e153
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 9 deletions.
26 changes: 26 additions & 0 deletions include/secp256k1_silentpayments.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,32 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_create_o
const unsigned char *label_tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

/** Create Silent Payment output private key (for spending receiver's funds).
*
* Given a shared_secret, a recipient's spend private key b_spend, and an
* output group counter k, calculate the corresponding output private key d:
*
* d = (b_spend + sha256(shared_secret || ser_32(k))) mod n
*
* Returns: 1 if private key creation was successful. 0 if an error occured.
* Args: ctx: pointer to a context object
* Out: output_seckey: pointer to the resulting spending private key
* In: shared_secret33: shared secret, derived from either sender's
* or receiver's perspective with routines from above
* receiver_spend_seckey: pointer to the receiver's spend private key
* k: output group counter
* label_tweak32: an optional 32-byte label tweak
* (not supported yet, must be set to NULL right now)
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_create_output_seckey(
const secp256k1_context *ctx,
unsigned char *output_seckey,
const unsigned char *shared_secret33,
const unsigned char *receiver_spend_seckey,
unsigned int k,
const unsigned char *label_tweak32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

#ifdef __cplusplus
}
#endif
Expand Down
43 changes: 34 additions & 9 deletions src/modules/silentpayments/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,20 @@ int secp256k1_silentpayments_receive_create_shared_secret(const secp256k1_contex
return 1;
}

int secp256k1_silentpayments_create_output(const secp256k1_context *ctx, secp256k1_xonly_pubkey *output_xonly_pubkey, const unsigned char *shared_secret33, const secp256k1_pubkey *receiver_spend_pubkey, unsigned int k, const unsigned char *label_tweak32) {
secp256k1_pubkey P_output;
static void secp256k1_silentpayments_create_t_k(unsigned char *t_k, const unsigned char *shared_secret33, unsigned int k) {
secp256k1_sha256 sha;
unsigned char shared_secret_and_k[33+4];

/* Compute t_k = sha256(shared_secret || ser_32(k)) */
memcpy(shared_secret_and_k, shared_secret33, 33);
secp256k1_write_be32(shared_secret_and_k+33, k);
secp256k1_sha256_initialize(&sha);
secp256k1_sha256_write(&sha, shared_secret_and_k, sizeof(shared_secret_and_k));
secp256k1_sha256_finalize(&sha, t_k);
}

int secp256k1_silentpayments_create_output(const secp256k1_context *ctx, secp256k1_xonly_pubkey *output_xonly_pubkey, const unsigned char *shared_secret33, const secp256k1_pubkey *receiver_spend_pubkey, unsigned int k, const unsigned char *label_tweak32) {
secp256k1_pubkey P_output;
unsigned char t_k[32];

/* Sanity check inputs */
Expand All @@ -198,14 +208,8 @@ int secp256k1_silentpayments_create_output(const secp256k1_context *ctx, secp256
ARG_CHECK(receiver_spend_pubkey != NULL);
ARG_CHECK(label_tweak32 == NULL); /* label tweaks are not supported yet */

/* Compute t_k = sha256(shared_secret || ser_32(k)) */
memcpy(shared_secret_and_k, shared_secret33, 33);
secp256k1_write_be32(shared_secret_and_k+33, k);
secp256k1_sha256_initialize(&sha);
secp256k1_sha256_write(&sha, shared_secret_and_k, sizeof(shared_secret_and_k));
secp256k1_sha256_finalize(&sha, t_k);

/* Compute and return P_output = B_spend + t_k * G */
secp256k1_silentpayments_create_t_k(t_k, shared_secret33, k);
P_output = *receiver_spend_pubkey;
if (!secp256k1_ec_pubkey_tweak_add(ctx, &P_output, t_k)) {
return 0;
Expand All @@ -217,4 +221,25 @@ int secp256k1_silentpayments_create_output(const secp256k1_context *ctx, secp256
return 1;
}

int secp256k1_silentpayments_create_output_seckey(const secp256k1_context *ctx, unsigned char *output_seckey, const unsigned char *shared_secret33, const unsigned char *receiver_spend_seckey, unsigned int k, const unsigned char *label_tweak32) {
unsigned char t_k[32];

/* Sanity check inputs */
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(output_seckey != NULL);
memset(output_seckey, 0, 32);
ARG_CHECK(shared_secret33 != NULL);
ARG_CHECK(receiver_spend_seckey != NULL);
ARG_CHECK(label_tweak32 == NULL); /* label tweaks are not supported yet */

/* Compute and return d = (b_spend + t_k) mod n */
memcpy(output_seckey, receiver_spend_seckey, 32);
secp256k1_silentpayments_create_t_k(t_k, shared_secret33, k);
if (!secp256k1_ec_seckey_tweak_add(ctx, output_seckey, t_k)) {
return 0;
}

return 1;
}

#endif

0 comments on commit b86e153

Please sign in to comment.