|
19 | 19 | #include <secp256k1_musig.h>
|
20 | 20 |
|
21 | 21 | #include "random.h"
|
| 22 | +#include <string.h> |
22 | 23 |
|
23 | 24 | struct signer_secrets {
|
24 | 25 | secp256k1_keypair keypair;
|
@@ -98,6 +99,19 @@ int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, st
|
98 | 99 | /* The same for all signers */
|
99 | 100 | secp256k1_musig_session session;
|
100 | 101 |
|
| 102 | + /* For adapter signature, committing to random scalar */ |
| 103 | + unsigned char presig[64]; |
| 104 | + int nonce_parity; |
| 105 | + unsigned char adaptor_key[32]; |
| 106 | + unsigned char extracted_adaptor[32]; |
| 107 | + secp256k1_pubkey adaptor; |
| 108 | + if (!fill_random(adaptor_key, sizeof(adaptor_key))) { |
| 109 | + return 0; |
| 110 | + } |
| 111 | + if (!secp256k1_ec_pubkey_create(ctx, &adaptor, adaptor_key)) { |
| 112 | + return 0; |
| 113 | + } |
| 114 | + |
101 | 115 | for (i = 0; i < N_SIGNERS; i++) {
|
102 | 116 | unsigned char seckey[32];
|
103 | 117 | unsigned char session_id[32];
|
@@ -126,7 +140,7 @@ int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, st
|
126 | 140 | if (!secp256k1_musig_nonce_agg(ctx, &agg_pubnonce, pubnonces, N_SIGNERS)) {
|
127 | 141 | return 0;
|
128 | 142 | }
|
129 |
| - if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache, NULL)) { |
| 143 | + if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache, &adaptor)) { |
130 | 144 | return 0;
|
131 | 145 | }
|
132 | 146 | /* partial_sign will clear the secnonce by setting it to 0. That's because
|
@@ -156,7 +170,25 @@ int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, st
|
156 | 170 | return 0;
|
157 | 171 | }
|
158 | 172 | }
|
159 |
| - return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS); |
| 173 | + |
| 174 | + /* Since we are doing adaptor sig, complete pre-signature */ |
| 175 | + if (!secp256k1_musig_nonce_parity(ctx, &nonce_parity, &session)) { |
| 176 | + return 0; |
| 177 | + } |
| 178 | + if (!secp256k1_musig_partial_sig_agg(ctx, presig, &session, partial_sigs, N_SIGNERS)){ |
| 179 | + return 0; |
| 180 | + } |
| 181 | + if (!secp256k1_musig_adapt(ctx, sig64, presig, adaptor_key, nonce_parity)) { |
| 182 | + return 0; |
| 183 | + } |
| 184 | + /* With sig64 "on-chain" now, other party can grab the revealed adaptor secret */ |
| 185 | + if (!secp256k1_musig_extract_adaptor(ctx, extracted_adaptor, sig64, presig, nonce_parity)) { |
| 186 | + return 0; |
| 187 | + } |
| 188 | + if (memcmp(extracted_adaptor, adaptor_key, sizeof(adaptor_key)) != 0) { |
| 189 | + return 0; |
| 190 | + } |
| 191 | + return 1; |
160 | 192 | }
|
161 | 193 |
|
162 | 194 | int main(void) {
|
@@ -201,7 +233,7 @@ int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secrets, st
|
201 | 233 | return 1;
|
202 | 234 | }
|
203 | 235 | printf("ok\n");
|
204 |
| - printf("Verifying signature....."); |
| 236 | + printf("Verifying signature and revealed adaptor....."); |
205 | 237 | if (!secp256k1_schnorrsig_verify(ctx, sig, msg, 32, &agg_pk)) {
|
206 | 238 | printf("FAILED\n");
|
207 | 239 | return 1;
|
|
0 commit comments