Skip to content

Commit 9039d6b

Browse files
committed
silentpayments: implement output spending privkey creation (for receiver)
1 parent e8cb4e7 commit 9039d6b

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

include/secp256k1_silentpayments.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,35 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_create_o
221221
const unsigned char *label_tweak32
222222
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
223223

224+
/** Create Silent Payment output private key (for spending receiver's funds).
225+
*
226+
* Given a shared_secret, a recipient's spend private key b_spend, an output
227+
* counter k, and an optional label_tweak, calculate the corresponding
228+
* output private key d:
229+
*
230+
* b_m = b_spend + label_tweak
231+
* (if no label tweak is used, them b_m = b_spend)
232+
* d = (b_m + hash(shared_secret || ser_32(k))) mod n
233+
*
234+
* Returns: 1 if private key creation was successful. 0 if an error occured.
235+
* Args: ctx: pointer to a context object
236+
* Out: output_seckey: pointer to the resulting spending private key
237+
* In: shared_secret33: shared secret, derived from either sender's
238+
* or receiver's perspective with routines from above
239+
* receiver_spend_seckey: pointer to the receiver's spend private key
240+
* k: output counter (usually set to 0, should be increased for
241+
* every additional output to the same recipient)
242+
* label_tweak32: an optional 32-byte label tweak (NULL if no label is used)
243+
*/
244+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_create_output_seckey(
245+
const secp256k1_context *ctx,
246+
unsigned char *output_seckey,
247+
const unsigned char *shared_secret33,
248+
const unsigned char *receiver_spend_seckey,
249+
unsigned int k,
250+
const unsigned char *label_tweak32
251+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
252+
224253
#ifdef __cplusplus
225254
}
226255
#endif

src/modules/silentpayments/main_impl.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,4 +320,35 @@ int secp256k1_silentpayments_create_output_pubkey(const secp256k1_context *ctx,
320320
return 1;
321321
}
322322

323+
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) {
324+
secp256k1_scalar t_k_scalar;
325+
secp256k1_scalar final_seckey;
326+
int ret;
327+
328+
/* Sanity check inputs */
329+
VERIFY_CHECK(ctx != NULL);
330+
ARG_CHECK(output_seckey != NULL);
331+
memset(output_seckey, 0, 32);
332+
ARG_CHECK(shared_secret33 != NULL);
333+
ARG_CHECK(receiver_spend_seckey != NULL);
334+
335+
/* Apply label tweak if provided */
336+
ret = secp256k1_scalar_set_b32_seckey(&final_seckey, receiver_spend_seckey);
337+
VERIFY_CHECK(ret);
338+
(void)ret;
339+
if (label_tweak32 != NULL) {
340+
secp256k1_scalar tweak_scalar;
341+
secp256k1_scalar_set_b32(&tweak_scalar, label_tweak32, NULL);
342+
secp256k1_eckey_privkey_tweak_add(&final_seckey, &tweak_scalar);
343+
}
344+
345+
/* Compute and return d = (b_m + t_k) mod n */
346+
secp256k1_silentpayments_create_t_k(&t_k_scalar, shared_secret33, k);
347+
secp256k1_eckey_privkey_tweak_add(&final_seckey, &t_k_scalar);
348+
secp256k1_scalar_get_b32(output_seckey, &final_seckey);
349+
secp256k1_scalar_clear(&final_seckey);
350+
351+
return 1;
352+
}
353+
323354
#endif

0 commit comments

Comments
 (0)