|
21 | 21 | #include <secp256k1_musig.h> |
22 | 22 |
|
23 | 23 | #include "examples_util.h" |
| 24 | +#include <string.h> |
24 | 25 |
|
25 | 26 | struct signer_secrets { |
26 | 27 | secp256k1_keypair keypair; |
@@ -100,6 +101,19 @@ static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secr |
100 | 101 | /* The same for all signers */ |
101 | 102 | secp256k1_musig_session session; |
102 | 103 |
|
| 104 | + /* For adapter signature, committing to random scalar */ |
| 105 | + unsigned char presig[64]; |
| 106 | + int nonce_parity; |
| 107 | + unsigned char adaptor_key[32]; |
| 108 | + unsigned char extracted_adaptor[32]; |
| 109 | + secp256k1_pubkey adaptor; |
| 110 | + if (!fill_random(adaptor_key, sizeof(adaptor_key))) { |
| 111 | + return 0; |
| 112 | + } |
| 113 | + if (!secp256k1_ec_pubkey_create(ctx, &adaptor, adaptor_key)) { |
| 114 | + return 0; |
| 115 | + } |
| 116 | + |
103 | 117 | for (i = 0; i < N_SIGNERS; i++) { |
104 | 118 | unsigned char seckey[32]; |
105 | 119 | unsigned char session_id[32]; |
@@ -128,7 +142,7 @@ static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secr |
128 | 142 | if (!secp256k1_musig_nonce_agg(ctx, &agg_pubnonce, pubnonces, N_SIGNERS)) { |
129 | 143 | return 0; |
130 | 144 | } |
131 | | - if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache, NULL)) { |
| 145 | + if (!secp256k1_musig_nonce_process(ctx, &session, &agg_pubnonce, msg32, cache, &adaptor)) { |
132 | 146 | return 0; |
133 | 147 | } |
134 | 148 | /* partial_sign will clear the secnonce by setting it to 0. That's because |
@@ -158,7 +172,23 @@ static int sign(const secp256k1_context* ctx, struct signer_secrets *signer_secr |
158 | 172 | return 0; |
159 | 173 | } |
160 | 174 | } |
161 | | - return secp256k1_musig_partial_sig_agg(ctx, sig64, &session, partial_sigs, N_SIGNERS); |
| 175 | + |
| 176 | + /* Since we are doing adaptor sig, complete pre-signature */ |
| 177 | + if (!secp256k1_musig_nonce_parity(ctx, &nonce_parity, &session)) { |
| 178 | + return 0; |
| 179 | + } |
| 180 | + if (!secp256k1_musig_partial_sig_agg(ctx, presig, &session, partial_sigs, N_SIGNERS)) { |
| 181 | + return 0; |
| 182 | + } |
| 183 | + if (!secp256k1_musig_adapt(ctx, sig64, presig, adaptor_key, nonce_parity)) { |
| 184 | + return 0; |
| 185 | + } |
| 186 | + /* With sig64 "on-chain" now, other party can grab the revealed adaptor secret */ |
| 187 | + if (!secp256k1_musig_extract_adaptor(ctx, extracted_adaptor, sig64, presig, nonce_parity)) { |
| 188 | + return 0; |
| 189 | + } |
| 190 | + assert(memcmp(extracted_adaptor, adaptor_key, sizeof(adaptor_key)) == 0); |
| 191 | + return 1; |
162 | 192 | } |
163 | 193 |
|
164 | 194 | int main(void) { |
|
0 commit comments