Skip to content

Commit 34b1649

Browse files
committed
add secp256k1_silentpayments_verify_proof
1 parent 22e4b40 commit 34b1649

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

include/secp256k1_silentpayments.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,29 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_recipien
442442
unsigned int k
443443
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
444444

445+
/** Verifies the Silent Payment proof. If the following algorithm succeeds, the points A and C were both generated from
446+
* the same scalar. The former from multiplying by G, and the latter from multiplying by B.
447+
*
448+
* Here, A refers to input public key sum (present in public_data)
449+
* B refers to recipient's scan pubkey
450+
* C refers to shared_secret point
451+
*
452+
* Returns: 1 if verification of proof was successful. 0 if an error occurred.
453+
* Args: ctx: pointer to a context object
454+
* In: shared_secret: 33 bytes shared secret
455+
* proof: 64 bytes DLEQ proof
456+
* recipient_scan_pubkey: pointer to the recipient's scan pubkey
457+
* public_data: pointer to the input public key sum (optionally, with the `input_hash` multiplied in,
458+
* see `_recipient_public_data_create`).
459+
*/
460+
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_silentpayments_verify_proof(
461+
const secp256k1_context *ctx,
462+
const unsigned char *shared_secret33,
463+
const unsigned char *proof64,
464+
const secp256k1_pubkey *recipient_scan_pubkey,
465+
const secp256k1_silentpayments_public_data *public_data
466+
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
467+
445468
/** Serialize a secp256k1_silentpayments_dleq_data object into a 101-byte sequence.
446469
* 101-byte sequence = 33 bytes shared secret + 64 bytes proof + 4 bytes index
447470
* where index is position in an array of pointers to silent payment recipients

src/modules/silentpayments/main_impl.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,40 @@ int secp256k1_silentpayments_recipient_create_output_pubkey(const secp256k1_cont
694694
return secp256k1_silentpayments_create_output_pubkey(ctx, P_output_xonly, shared_secret33, recipient_spend_pubkey, k);
695695
}
696696

697+
int secp256k1_silentpayments_verify_proof(const secp256k1_context *ctx, const unsigned char *shared_secret33, const unsigned char *proof64, const secp256k1_pubkey *recipient_scan_pubkey, const secp256k1_silentpayments_public_data *public_data)
698+
{
699+
secp256k1_scalar s;
700+
secp256k1_scalar e;
701+
secp256k1_pubkey pk;
702+
secp256k1_ge pubkey_sum;
703+
secp256k1_ge scan_pubkey;
704+
secp256k1_ge shared_secret;
705+
size_t pubkeylen = 33;
706+
unsigned char input_hash[32];
707+
int ret = 1;
708+
int combined;
709+
710+
VERIFY_CHECK(ctx != NULL);
711+
ARG_CHECK(shared_secret33 != NULL);
712+
ARG_CHECK(proof64 != NULL);
713+
ARG_CHECK(recipient_scan_pubkey != NULL);
714+
ARG_CHECK(public_data != NULL);
715+
716+
ret &= secp256k1_silentpayments_recipient_public_data_load_pubkey(ctx, &pk, public_data);
717+
combined = (int)public_data->data[0];
718+
if (!combined) {
719+
secp256k1_silentpayments_recipient_public_data_load_input_hash(input_hash, public_data);
720+
ret &= secp256k1_ec_pubkey_tweak_mul(ctx, &pk, input_hash);
721+
}
722+
ret &= secp256k1_pubkey_load(ctx, &pubkey_sum, &pk);
723+
ret &= secp256k1_pubkey_load(ctx, &scan_pubkey, recipient_scan_pubkey);
724+
ret &= secp256k1_ec_pubkey_parse(ctx, &pk, shared_secret33, pubkeylen);
725+
ret &= secp256k1_pubkey_load(ctx, &shared_secret, &pk);
726+
secp256k1_scalar_set_b32(&s, proof64, NULL);
727+
secp256k1_scalar_set_b32(&e, proof64 + 32, NULL);
728+
ret &= secp256k1_dleq_verify(&s, &e, &pubkey_sum, &scan_pubkey, &shared_secret, NULL);
729+
return ret;
730+
}
697731

698732
void secp256k1_silentpayments_dleq_data_serialize(unsigned char *output, const secp256k1_silentpayments_dleq_data *dleq_data) {
699733
memcpy(output, dleq_data->shared_secret, 33);

0 commit comments

Comments
 (0)