|
8 | 8 |
|
9 | 9 | #include "../../../include/secp256k1.h"
|
10 | 10 | #include "../../../include/secp256k1_ecdh.h"
|
| 11 | +#include "../../../include/secp256k1_extrakeys.h" |
11 | 12 | #include "../../../include/secp256k1_silentpayments.h"
|
12 | 13 |
|
13 | 14 | /** Sort an array of silent payment recipients. This is used to group recipients by scan pubkey to
|
@@ -118,4 +119,54 @@ int secp256k1_silentpayments_create_shared_secret(const secp256k1_context *ctx,
|
118 | 119 | return 1;
|
119 | 120 | }
|
120 | 121 |
|
| 122 | +/** Set hash state to the BIP340 tagged hash midstate for "BIP0352/SharedSecret". */ |
| 123 | +static void secp256k1_silentpayments_sha256_init_sharedsecret(secp256k1_sha256* hash) { |
| 124 | + secp256k1_sha256_initialize(hash); |
| 125 | + hash->s[0] = 0x88831537ul; |
| 126 | + hash->s[1] = 0x5127079bul; |
| 127 | + hash->s[2] = 0x69c2137bul; |
| 128 | + hash->s[3] = 0xab0303e6ul; |
| 129 | + hash->s[4] = 0x98fa21faul; |
| 130 | + hash->s[5] = 0x4a888523ul; |
| 131 | + hash->s[6] = 0xbd99daabul; |
| 132 | + hash->s[7] = 0xf25e5e0aul; |
| 133 | + |
| 134 | + hash->bytes = 64; |
| 135 | +} |
| 136 | + |
| 137 | +static void secp256k1_silentpayments_create_t_k(secp256k1_scalar *t_k_scalar, const unsigned char *shared_secret33, unsigned int k) { |
| 138 | + secp256k1_sha256 hash; |
| 139 | + unsigned char hash_ser[32]; |
| 140 | + unsigned char k_serialized[4]; |
| 141 | + |
| 142 | + /* Compute t_k = hash(shared_secret || ser_32(k)) [sha256 with tag "BIP0352/SharedSecret"] */ |
| 143 | + secp256k1_silentpayments_sha256_init_sharedsecret(&hash); |
| 144 | + secp256k1_sha256_write(&hash, shared_secret33, 33); |
| 145 | + secp256k1_write_be32(k_serialized, k); |
| 146 | + secp256k1_sha256_write(&hash, k_serialized, sizeof(k_serialized)); |
| 147 | + secp256k1_sha256_finalize(&hash, hash_ser); |
| 148 | + secp256k1_scalar_set_b32(t_k_scalar, hash_ser, NULL); |
| 149 | +} |
| 150 | + |
| 151 | +int secp256k1_silentpayments_create_output_pubkey(const secp256k1_context *ctx, secp256k1_xonly_pubkey *P_output_xonly, const unsigned char *shared_secret33, const secp256k1_pubkey *recipient_spend_pubkey, unsigned int k) { |
| 152 | + secp256k1_ge P_output_ge; |
| 153 | + secp256k1_scalar t_k_scalar; |
| 154 | + |
| 155 | + /* Sanity check inputs */ |
| 156 | + VERIFY_CHECK(ctx != NULL); |
| 157 | + ARG_CHECK(P_output_xonly != NULL); |
| 158 | + ARG_CHECK(shared_secret33 != NULL); |
| 159 | + ARG_CHECK(recipient_spend_pubkey != NULL); |
| 160 | + |
| 161 | + /* Calculate and return P_output_xonly = B_spend + t_k * G */ |
| 162 | + secp256k1_silentpayments_create_t_k(&t_k_scalar, shared_secret33, k); |
| 163 | + secp256k1_pubkey_load(ctx, &P_output_ge, recipient_spend_pubkey); |
| 164 | + if (!secp256k1_eckey_pubkey_tweak_add(&P_output_ge, &t_k_scalar)) { |
| 165 | + return 0; |
| 166 | + } |
| 167 | + secp256k1_xonly_pubkey_save(P_output_xonly, &P_output_ge); |
| 168 | + |
| 169 | + return 1; |
| 170 | +} |
| 171 | + |
121 | 172 | #endif
|
0 commit comments