|
7 | 7 | #define SECP256K1_MODULE_SILENTPAYMENTS_MAIN_H
|
8 | 8 |
|
9 | 9 | #include "../../../include/secp256k1.h"
|
| 10 | +#include "../../../include/secp256k1_ecdh.h" |
| 11 | +#include "../../../include/secp256k1_extrakeys.h" |
10 | 12 | #include "../../../include/secp256k1_silentpayments.h"
|
11 | 13 |
|
12 | 14 | /** Set hash state to the BIP340 tagged hash midstate for "BIP0352/Inputs". */
|
@@ -102,6 +104,46 @@ int secp256k1_silentpayments_create_private_tweak_data(const secp256k1_context *
|
102 | 104 | return 1;
|
103 | 105 | }
|
104 | 106 |
|
| 107 | +/* secp256k1_ecdh expects a hash function to be passed in or uses its default |
| 108 | + * hashing function. We don't want to hash the ECDH result, so we define a |
| 109 | + * custom function which simply returns the pubkey without hashing. |
| 110 | + */ |
| 111 | +static int secp256k1_silentpayments_ecdh_return_pubkey(unsigned char *output, const unsigned char *x32, const unsigned char *y32, void *data) { |
| 112 | + secp256k1_ge point; |
| 113 | + secp256k1_fe x, y; |
| 114 | + size_t ser_size; |
| 115 | + int ser_ret; |
| 116 | + |
| 117 | + (void)data; |
| 118 | + /* Parse point as group element */ |
| 119 | + if (!secp256k1_fe_set_b32_limit(&x, x32) || !secp256k1_fe_set_b32_limit(&y, y32)) { |
| 120 | + return 0; |
| 121 | + } |
| 122 | + secp256k1_ge_set_xy(&point, &x, &y); |
| 123 | + |
| 124 | + /* Serialize as compressed pubkey */ |
| 125 | + ser_ret = secp256k1_eckey_pubkey_serialize(&point, output, &ser_size, 1); |
| 126 | + VERIFY_CHECK(ser_ret && ser_size == 33); |
| 127 | + (void)ser_ret; |
| 128 | + |
| 129 | + return 1; |
| 130 | +} |
| 131 | + |
| 132 | +int secp256k1_silentpayments_send_create_shared_secret(const secp256k1_context *ctx, unsigned char *shared_secret33, const unsigned char *private_tweak_data32, const secp256k1_pubkey *receiver_scan_pubkey) { |
| 133 | + /* Sanity check inputs */ |
| 134 | + ARG_CHECK(shared_secret33 != NULL); |
| 135 | + memset(shared_secret33, 0, 33); |
| 136 | + ARG_CHECK(private_tweak_data32 != NULL); |
| 137 | + ARG_CHECK(receiver_scan_pubkey != NULL); |
| 138 | + |
| 139 | + /* Compute shared_secret = a_tweaked * B_scan */ |
| 140 | + if (!secp256k1_ecdh(ctx, shared_secret33, receiver_scan_pubkey, private_tweak_data32, secp256k1_silentpayments_ecdh_return_pubkey, NULL)) { |
| 141 | + return 0; |
| 142 | + } |
| 143 | + |
| 144 | + return 1; |
| 145 | +} |
| 146 | + |
105 | 147 | /* TODO: implement functions for receiver side. */
|
106 | 148 |
|
107 | 149 | #endif
|
0 commit comments