6#ifndef SECP256K1_MODULE_SILENTPAYMENTS_MAIN_H
7#define SECP256K1_MODULE_SILENTPAYMENTS_MAIN_H
44 #if defined(_MSC_VER) && (_MSC_VER < 1933)
46 #pragma warning(disable: 4090)
51 #if defined(_MSC_VER) && (_MSC_VER < 1933)
58 static const uint32_t midstate[8] = {
59 0xd4143ffcul, 0x012ea4b5ul, 0x36e21c8ful, 0xf7ec7b54ul,
60 0x4dd4e2acul, 0x9bcaa0a4ul, 0xe244899bul, 0xcd06903eul
68 unsigned char pubkey_sum_ser[33];
69 unsigned char input_hash[32];
84 secp256k1_scalar_set_b32(input_hash_scalar, input_hash, &overflow);
85 return (!secp256k1_scalar_is_zero(input_hash_scalar)) & (!overflow);
92 VERIFY_CHECK(!secp256k1_ge_is_infinity(public_component));
93 VERIFY_CHECK(!secp256k1_scalar_is_zero(secret_component));
95 secp256k1_ecmult_const(&ss_j, public_component, secret_component);
96 secp256k1_ge_set_gej(&
ss, &ss_j);
105 secp256k1_ge_clear(&
ss);
106 secp256k1_gej_clear(&ss_j);
111 static const uint32_t midstate[8] = {
112 0x88831537ul, 0x5127079bul, 0x69c2137bul, 0xab0303e6ul,
113 0x98fa21faul, 0x4a888523ul, 0xbd99daabul, 0xf25e5e0aul
121 unsigned char hash_ser[32];
122 unsigned char k_serialized[4];
135 secp256k1_declassify(ctx, hash_ser,
sizeof(hash_ser));
144 secp256k1_scalar_set_b32(t_k_scalar, hash_ser, &overflow);
148 return (!secp256k1_scalar_is_zero(t_k_scalar)) & (!overflow);
161 secp256k1_scalar_clear(&t_k_scalar);
165 if (!secp256k1_pubkey_load(ctx, &output_ge, spend_pubkey)) {
166 secp256k1_scalar_clear(&t_k_scalar);
175 secp256k1_scalar_clear(&t_k_scalar);
183 secp256k1_scalar_clear(&t_k_scalar);
192 const unsigned char *outpoint_smallest36,
195 const unsigned char *
const *seckeys,
202 unsigned char shared_secret[33];
204 int ret, sum_is_zero;
213 ARG_CHECK((n_seckeys > 0) || (n_keypairs > 0));
214 if (n_keypairs > 0) {
216 for (i = 0; i < n_keypairs; i++) {
222 for (i = 0; i < n_seckeys; i++) {
226 for (i = 0; i < n_recipients; i++) {
232 seckey_sum_scalar = secp256k1_scalar_zero;
233 for (i = 0; i < n_seckeys; i++) {
234 ret = secp256k1_scalar_set_b32_seckey(&addend, seckeys[i]);
235 secp256k1_declassify(ctx, &
ret,
sizeof(
ret));
237 secp256k1_scalar_clear(&addend);
238 secp256k1_scalar_clear(&seckey_sum_scalar);
241 secp256k1_scalar_add(&seckey_sum_scalar, &seckey_sum_scalar, &addend);
245 for (i = 0; i < n_keypairs; i++) {
248 secp256k1_declassify(ctx, &
ret,
sizeof(
ret));
250 secp256k1_scalar_clear(&addend);
251 secp256k1_scalar_clear(&seckey_sum_scalar);
255 secp256k1_scalar_negate(&addend, &addend);
257 secp256k1_scalar_add(&seckey_sum_scalar, &seckey_sum_scalar, &addend);
260 sum_is_zero = secp256k1_scalar_is_zero(&seckey_sum_scalar);
261 secp256k1_declassify(ctx, &sum_is_zero,
sizeof(sum_is_zero));
262 secp256k1_scalar_clear(&addend);
264 secp256k1_scalar_clear(&seckey_sum_scalar);
267 secp256k1_ecmult_gen_ge(&ctx->
ecmult_gen_ctx, &prevouts_pubkey_sum_ge, &seckey_sum_scalar);
271 secp256k1_declassify(ctx, &prevouts_pubkey_sum_ge,
sizeof(prevouts_pubkey_sum_ge));
281 secp256k1_scalar_clear(&seckey_sum_scalar);
284 secp256k1_scalar_mul(&seckey_sum_scalar, &seckey_sum_scalar, &input_hash_scalar);
294 for (i = 0; i < n_recipients; i++) {
302 if (!secp256k1_pubkey_load(ctx, &pk, &recipients[i]->scan_pubkey)) {
303 secp256k1_scalar_clear(&seckey_sum_scalar);
317 secp256k1_scalar_clear(&seckey_sum_scalar);
322 secp256k1_scalar_clear(&seckey_sum_scalar);
329 secp256k1_scalar_clear(&seckey_sum_scalar);
336 static const uint32_t midstate[8] = {
337 0x26b95d63ul, 0x8bf1b740ul, 0x10a5986ful, 0x06a387a5ul,
338 0x2d1c1c30ul, 0xd035951aul, 0x2d7f0f96ul, 0x29e3e0dbul
363 memset(label, 0,
sizeof(*label));
379 memset(out33, 0, 33);
391 unsigned char m_serialized[4];
399 memset(label, 0,
sizeof(*label));
414 ret &= secp256k1_ec_pubkey_create_helper(&ctx->
ecmult_gen_ctx, &label_tweak_scalar, &label_ge, label_tweak32);
419 secp256k1_scalar_clear(&label_tweak_scalar);
435 memset(labeled_spend_pubkey, 0,
sizeof(*labeled_spend_pubkey));
436 ARG_CHECK(unlabeled_spend_pubkey != NULL);
442 ret = secp256k1_pubkey_load(ctx, &labeled_spend_pubkey_ge, unlabeled_spend_pubkey);
447 secp256k1_gej_set_ge(&result_gej, &labeled_spend_pubkey_ge);
448 secp256k1_gej_add_ge_var(&result_gej, &result_gej, &label_addend, NULL);
449 if (secp256k1_gej_is_infinity(&result_gej)) {
453 secp256k1_ge_set_gej_var(&result_ge, &result_gej);
454 secp256k1_pubkey_save(labeled_spend_pubkey, &result_ge);
487 const unsigned char *outpoint_smallest36,
489 size_t n_xonly_pubkeys,
501 memset(prevouts_summary, 0,
sizeof(*prevouts_summary));
503 ARG_CHECK((n_pubkeys > 0) || (n_xonly_pubkeys > 0));
504 if (n_xonly_pubkeys > 0) {
506 for (i = 0; i < n_xonly_pubkeys; i++) {
512 for (i = 0; i < n_pubkeys; i++) {
524 secp256k1_gej_set_infinity(&prevouts_pubkey_sum_gej);
525 for (i = 0; i < n_pubkeys; i++) {
526 if (!secp256k1_pubkey_load(ctx, &addend, pubkeys[i])) {
529 secp256k1_gej_add_ge_var(&prevouts_pubkey_sum_gej, &prevouts_pubkey_sum_gej, &addend, NULL);
531 for (i = 0; i < n_xonly_pubkeys; i++) {
535 secp256k1_gej_add_ge_var(&prevouts_pubkey_sum_gej, &prevouts_pubkey_sum_gej, &addend, NULL);
537 if (secp256k1_gej_is_infinity(&prevouts_pubkey_sum_gej)) {
540 secp256k1_ge_set_gej_var(&prevouts_pubkey_sum_ge, &prevouts_pubkey_sum_gej);
551 prevouts_summary->
data[4] = 0;
553 secp256k1_scalar_get_b32(&prevouts_summary->
data[5 + 64], &input_hash_scalar);
569 const unsigned char **label_tweak,
574 const void *label_context
577 unsigned char label33[33];
581 secp256k1_ge_set_all_gej_var(label_candidates_ge, label_candidates_gej, 2 * n_batch);
582 for (i = 0; i < 2 * n_batch; i++) {
587 VERIFY_CHECK(!secp256k1_ge_is_infinity(&label_candidates_ge[i]));
590 if (*label_tweak != NULL) {
591 *label_ge = label_candidates_ge[i];
592 return (
int)(j_start + i / 2);
602 const unsigned char *scan_key32,
606 const void *label_context
609 secp256k1_ge unlabeled_spend_pubkey_ge, prevouts_pubkey_sum_ge, tx_output_ge;
610 unsigned char shared_secret[33];
613 int found_idx, combined, valid_scan_key,
ret;
619 *n_found_outputs = 0;
622 for (i = 0; i < n_tx_outputs; i++) {
633 ARG_CHECK(unlabeled_spend_pubkey != NULL);
635 if (label_context != NULL) {
638 valid_scan_key = secp256k1_scalar_set_b32_seckey(&scan_key_scalar, scan_key32);
639 secp256k1_declassify(ctx, &valid_scan_key,
sizeof(valid_scan_key));
640 if (!valid_scan_key) {
641 secp256k1_scalar_clear(&scan_key_scalar);
645 combined = (int)prevouts_summary->
data[4];
650 secp256k1_scalar_set_b32(&input_hash_scalar, &prevouts_summary->
data[5 + 64], NULL);
651 secp256k1_scalar_mul(&scan_key_scalar, &scan_key_scalar, &input_hash_scalar);
653 ret = secp256k1_pubkey_load(ctx, &unlabeled_spend_pubkey_ge, unlabeled_spend_pubkey);
655 secp256k1_scalar_clear(&scan_key_scalar);
664 secp256k1_scalar_clear(&scan_key_scalar);
670 for (
k = 0;
k < k_max;
k++) {
673 secp256k1_ge unlabeled_output_ge = unlabeled_spend_pubkey_ge;
676 size_t label_batch_idx = 0;
677 const unsigned char *label_tweak = NULL;
688 secp256k1_scalar_clear(&t_k_scalar);
698 secp256k1_scalar_clear(&t_k_scalar);
703 secp256k1_ge_neg(&unlabeled_output_negated_ge, &unlabeled_output_ge);
709 for (j = 0; j < n_tx_outputs; j++) {
714 if (label_batch_idx > 0) {
716 &label_ge, &label_tweak, label_candidates_gej, label_batch_idx,
718 if (label_found_idx != -1) {
719 found_idx = label_found_idx;
728 secp256k1_gej *label_candidate1 = &label_candidates_gej[2 * label_batch_idx];
729 secp256k1_gej *label_candidate2 = &label_candidates_gej[2 * label_batch_idx + 1];
736 secp256k1_gej_set_ge(&tx_output_gej, &tx_output_ge);
737 secp256k1_gej_add_ge_var(label_candidate1, &tx_output_gej, &unlabeled_output_negated_ge, NULL);
738 secp256k1_gej_neg(&tx_output_gej, &tx_output_gej);
739 secp256k1_gej_add_ge_var(label_candidate2, &tx_output_gej, &unlabeled_output_negated_ge, NULL);
745 &label_ge, &label_tweak, label_candidates_gej, label_batch_idx,
749 if (found_idx != -1) {
754 if (found_idx != -1) {
755 found_outputs[
k]->
output = *tx_outputs[found_idx];
756 secp256k1_scalar_get_b32(found_outputs[
k]->
tweak, &t_k_scalar);
759 secp256k1_scalar_clear(&t_k_scalar);
760 if (label_tweak != NULL) {
775 memset(found_outputs[
k]->
tweak, 0, 32);
781 memset(&found_outputs[
k]->label, 0,
sizeof(found_outputs[
k]->label));
786 secp256k1_scalar_clear(&t_k_scalar);
790 *n_found_outputs =
k;
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge *key, const secp256k1_scalar *tweak)
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context *ecmult_gen_ctx)
static int secp256k1_keypair_load(const secp256k1_context *ctx, secp256k1_scalar *sk, secp256k1_ge *pk, const secp256k1_keypair *keypair)
static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge)
static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_xonly_pubkey *pubkey)
static int secp256k1_extrakeys_ge_even_y(secp256k1_ge *r)
Keeps a group element as is if it has an even Y and otherwise negates it.
#define secp256k1_fe_is_odd
#define secp256k1_fe_normalize_var
#define secp256k1_fe_get_b32
#define secp256k1_fe_normalize
static void secp256k1_ge_serialize33(secp256k1_ge *elem, unsigned char *pub33)
Serialize a group element (that is not allowed to be infinity) to a compressed public key (33 bytes).
static int secp256k1_ge_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size)
Parse a group element from a 33-byte compressed or 65-byte uncompressed public key.
static void secp256k1_ge_to_bytes(unsigned char *buf, const secp256k1_ge *a)
Convert a group element that is not infinity to a 64-byte array.
static void secp256k1_ge_from_bytes(secp256k1_ge *r, const unsigned char *buf)
Convert a 64-byte array into group element.
static void secp256k1_hsort(void *ptr, size_t count, size_t size, int(*cmp)(const void *, const void *, void *), void *cmp_data)
struct secp256k1_context_struct secp256k1_context
Unless explicitly stated all pointer arguments must not be NULL.
static int tweak(const secp256k1_context *ctx, secp256k1_xonly_pubkey *agg_pk, secp256k1_musig_keyagg_cache *cache)
static void secp256k1_sha256_finalize(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, unsigned char *out32)
static void secp256k1_sha256_initialize_midstate(secp256k1_sha256 *hash, uint64_t bytes, const uint32_t state[8])
static void secp256k1_sha256_write(const secp256k1_hash_ctx *hash_ctx, secp256k1_sha256 *hash, const unsigned char *data, size_t size)
static void secp256k1_sha256_clear(secp256k1_sha256 *hash)
static SECP256K1_INLINE void secp256k1_memclear_explicit(void *ptr, size_t len)
static SECP256K1_INLINE int secp256k1_memcmp_var(const void *s1, const void *s2, size_t n)
Semantics like memcmp.
static SECP256K1_INLINE void secp256k1_write_be32(unsigned char *p, uint32_t x)
#define VERIFY_CHECK(cond)
static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag)
#define SECP256K1_TAG_PUBKEY_EVEN
Prefix byte used to tag various encoded curvepoints for specific purposes.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_cmp(const secp256k1_context *ctx, const secp256k1_pubkey *pubkey1, const secp256k1_pubkey *pubkey2) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compare two public keys using lexicographic (of compressed serialization) order.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const secp256k1_context *ctx, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Verify an elliptic curve secret key.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_tweak_add(const secp256k1_context *ctx, unsigned char *seckey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a secret key by adding tweak to it.
SECP256K1_API int secp256k1_silentpayments_recipient_label_serialize(const secp256k1_context *ctx, unsigned char *out33, const secp256k1_silentpayments_label *label) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Serialize a Silent Payments label.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_prevouts_summary_create(const secp256k1_context *ctx, secp256k1_silentpayments_prevouts_summary *prevouts_summary, const unsigned char *outpoint_smallest36, const secp256k1_xonly_pubkey *const *xonly_pubkeys, size_t n_xonly_pubkeys, const secp256k1_pubkey *const *pubkeys, size_t n_pubkeys) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute Silent Payments prevouts summary from prevout public keys and transaction inputs.
const unsigned char *(*) secp256k1_silentpayments_label_lookup(const unsigned char *label33, const void *label_context)
Type of callback function for label lookups.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_parse(const secp256k1_context *ctx, secp256k1_silentpayments_label *label, const unsigned char *in33) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a Silent Payments label.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_sender_create_outputs(const secp256k1_context *ctx, secp256k1_xonly_pubkey **generated_outputs, const secp256k1_silentpayments_recipient **recipients, size_t n_recipients, const unsigned char *outpoint_smallest36, const secp256k1_keypair *const *keypairs, size_t n_keypairs, const unsigned char *const *seckeys, size_t n_seckeys) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5)
Create Silent Payments outputs for recipient(s).
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_create_labeled_spend_pubkey(const secp256k1_context *ctx, secp256k1_pubkey *labeled_spend_pubkey, const secp256k1_pubkey *unlabeled_spend_pubkey, const secp256k1_silentpayments_label *label) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create Silent Payments labeled spend public key.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_scan_outputs(const secp256k1_context *ctx, secp256k1_silentpayments_found_output **found_outputs, uint32_t *n_found_outputs, const secp256k1_xonly_pubkey *const *tx_outputs, size_t n_tx_outputs, const unsigned char *scan_key32, const secp256k1_silentpayments_prevouts_summary *prevouts_summary, const secp256k1_pubkey *unlabeled_spend_pubkey, secp256k1_silentpayments_label_lookup label_lookup, const void *label_context) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7) SECP256K1_ARG_NONNULL(8)
Scan for Silent Payments transaction outputs.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipient_label_create(const secp256k1_context *ctx, secp256k1_silentpayments_label *label, unsigned char *label_tweak32, const unsigned char *scan_key32, uint32_t m) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create Silent Payments label tweak and label.
#define SECP256K1_SILENTPAYMENTS_RECIPIENT_GROUP_LIMIT
This module provides an implementation for Silent Payments, as specified in BIP352.
static void secp256k1_silentpayments_recipient_sort(const secp256k1_context *ctx, const secp256k1_silentpayments_recipient **recipients, size_t n_recipients)
static void secp256k1_silentpayments_sha256_init_sharedsecret(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "BIP0352/SharedSecret".
static void secp256k1_silentpayments_sha256_init_inputs(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "BIP0352/Inputs".
static int secp256k1_silentpayments_recipient_sort_cmp(const void *pk1, const void *pk2, void *ctx)
Sort an array of Silent Payments recipients.
static void secp256k1_silentpayments_sha256_init_label(secp256k1_sha256 *hash)
Set hash state to the BIP340 tagged hash midstate for "BIP0352/Label".
static int secp256k1_silentpayments_create_output_tweak(const secp256k1_context *ctx, secp256k1_scalar *t_k_scalar, const unsigned char *shared_secret33, uint32_t k)
static void secp256k1_silentpayments_label_save(secp256k1_silentpayments_label *label, const secp256k1_ge *ge)
static int secp256k1_silentpayments_calculate_input_hash_scalar(const secp256k1_hash_ctx *hash_ctx, secp256k1_scalar *input_hash_scalar, const unsigned char *outpoint_smallest36, secp256k1_ge *pubkey_sum)
Callers must ensure that pubkey_sum is not the point at infinity before calling this function.
static void secp256k1_silentpayments_create_shared_secret(unsigned char *shared_secret33, const secp256k1_ge *public_component, const secp256k1_scalar *secret_component)
static const unsigned char secp256k1_silentpayments_label_magic[4]
static int secp256k1_silentpayments_check_label_batch(secp256k1_ge *label_ge, const unsigned char **label_tweak, const secp256k1_gej *label_candidates_gej, size_t n_batch, size_t j_start, secp256k1_silentpayments_label_lookup label_lookup, const void *label_context)
static int secp256k1_silentpayments_create_output_pubkey(const secp256k1_context *ctx, secp256k1_xonly_pubkey *output_xonly, const unsigned char *shared_secret33, const secp256k1_pubkey *spend_pubkey, uint32_t k)
static const unsigned char secp256k1_silentpayments_prevouts_summary_magic[4]
magic bytes for ensuring prevouts_summary objects were initialized correctly.
static int secp256k1_silentpayments_label_load(const secp256k1_context *ctx, secp256k1_ge *ge, const secp256k1_silentpayments_label *label)
const unsigned char * label_lookup(const unsigned char *label33, const void *cache_ptr)
secp256k1_ecmult_gen_context ecmult_gen_ctx
secp256k1_hash_ctx hash_ctx
A group element in affine coordinates on the secp256k1 curve, or occasionally on an isomorphic curve ...
A group element of the secp256k1 curve, in jacobian coordinates.
Opaque data structure that holds a keypair consisting of a secret and a public key.
Opaque data structure that holds a parsed and valid public key.
A scalar modulo the group order of the secp256k1 curve.
secp256k1_xonly_pubkey output
Opaque data structure that holds a Silent Payments label.
Opaque data structure that holds Silent Payments prevouts summary data.
The data from a single recipient address.
secp256k1_pubkey scan_pubkey
Opaque data structure that holds a parsed and valid "x-only" public key.