Skip to content

Commit

Permalink
silentpayments: implement output spending privkey creation (for recei…
Browse files Browse the repository at this point in the history
…ver)
  • Loading branch information
theStack committed Feb 12, 2024
1 parent 77da028 commit e340dfc
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 0 deletions.
29 changes: 29 additions & 0 deletions include/secp256k1_silentpayments.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,35 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_create_s
const secp256k1_xonly_pubkey *tx_output
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);

/** Create Silent Payment output private key (for spending receiver's funds).
*
* Given a shared_secret, a recipient's spend private key b_spend, an output
* counter k, and an optional label_tweak, calculate the corresponding
* output private key d:
*
* b_m = b_spend + label_tweak
* (if no label tweak is used, them b_m = b_spend)
* d = (b_m + hash(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 counter (usually set to 0, should be increased for
* every additional output to the same recipient)
* label_tweak32: an optional 32-byte label tweak (NULL if no label is used)
*/
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
31 changes: 31 additions & 0 deletions src/modules/silentpayments/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,4 +345,35 @@ int secp256k1_silentpayments_create_scan_labels(const secp256k1_context *ctx, se
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) {
secp256k1_scalar t_k_scalar;
secp256k1_scalar final_seckey;
int ret;

/* 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);

/* Apply label tweak if provided */
ret = secp256k1_scalar_set_b32_seckey(&final_seckey, receiver_spend_seckey);
VERIFY_CHECK(ret);
(void)ret;
if (label_tweak32 != NULL) {
secp256k1_scalar tweak_scalar;
secp256k1_scalar_set_b32(&tweak_scalar, label_tweak32, NULL);
secp256k1_eckey_privkey_tweak_add(&final_seckey, &tweak_scalar);
}

/* Compute and return d = (b_m + t_k) mod n */
secp256k1_silentpayments_create_t_k(&t_k_scalar, shared_secret33, k);
secp256k1_eckey_privkey_tweak_add(&final_seckey, &t_k_scalar);
secp256k1_scalar_get_b32(output_seckey, &final_seckey);
secp256k1_scalar_clear(&final_seckey);

return 1;
}

#endif

0 comments on commit e340dfc

Please sign in to comment.