Skip to content

Commit

Permalink
fixup! split In/Out arg in musig_adapt into two args
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasnick committed Dec 16, 2021
1 parent 5f772dd commit b498180
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 33 deletions.
18 changes: 10 additions & 8 deletions include/secp256k1_musig.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,26 +462,28 @@ SECP256K1_API int secp256k1_musig_nonce_parity(
const secp256k1_musig_session *session
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);

/** Converts a pre-signature that misses the adaptor into a full signature
/** Creates a signature from a pre-signature and an adaptor.
*
* If the sec_adaptor32 argument is incorrect, the adapted signature will be
* invalid. This function does not verify the adapted signature.
* If the sec_adaptor32 argument is incorrect, the output signature will be
* invalid. This function does not verify the signature.
*
* Returns: 0 if the arguments are invalid, or sig64 or sec_adaptor32 contain
* Returns: 0 if the arguments are invalid, or pre_sig64 or sec_adaptor32 contain
* invalid (overflowing) values. 1 otherwise (which does NOT mean the
* signature or the adaptor are valid!)
* Args: ctx: pointer to a context object
* In/Out: sig64: 64-byte pre-signature that is adapted to a complete signature
* In: sec_adaptor32: 32-byte secret adaptor to add to the partial signature
* Out: sig64: 64-byte signature
* In: pre_sig64: 64-byte pre-signature
* sec_adaptor32: 32-byte secret adaptor to add to the pre-signature
* nonce_parity: the output of `musig_nonce_parity` called with the
* session used for producing sig64
* session used for producing the pre-signature
*/
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_musig_adapt(
const secp256k1_context* ctx,
unsigned char *sig64,
const unsigned char *pre_sig64,
const unsigned char *sec_adaptor32,
int nonce_parity
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);

/** Extracts a secret adaptor from a MuSig pre-signature and corresponding
* signature
Expand Down
10 changes: 7 additions & 3 deletions src/modules/musig/adaptor_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#ifndef SECP256K1_MODULE_MUSIG_ADAPTOR_IMPL_H
#define SECP256K1_MODULE_MUSIG_ADAPTOR_IMPL_H

#include <string.h>

#include "../../../include/secp256k1.h"
#include "../../../include/secp256k1_musig.h"

Expand All @@ -26,18 +28,19 @@ int secp256k1_musig_nonce_parity(const secp256k1_context* ctx, int *nonce_parity
return 1;
}

int secp256k1_musig_adapt(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *sec_adaptor32, int nonce_parity) {
int secp256k1_musig_adapt(const secp256k1_context* ctx, unsigned char *sig64, const unsigned char *pre_sig64, const unsigned char *sec_adaptor32, int nonce_parity) {
secp256k1_scalar s;
secp256k1_scalar t;
int overflow;
int ret = 1;

VERIFY_CHECK(ctx != NULL);
ARG_CHECK(sig64 != NULL);
ARG_CHECK(pre_sig64 != NULL);
ARG_CHECK(sec_adaptor32 != NULL);
ARG_CHECK(nonce_parity == 0 || nonce_parity == 1);

secp256k1_scalar_set_b32(&s, &sig64[32], &overflow);
secp256k1_scalar_set_b32(&s, &pre_sig64[32], &overflow);
if (overflow) {
return 0;
}
Expand All @@ -52,14 +55,15 @@ int secp256k1_musig_adapt(const secp256k1_context* ctx, unsigned char *sig64, co
* Since a BIP340 signature requires an x-only public nonce, in the case where
* (r + t)*G has odd Y-coordinate (i.e. nonce_parity == 1), the x-only public nonce
* corresponding to the signature is actually (-r - t)*G. Thus adapting a
* presignature requires negating t in this case.
* pre-signature requires negating t in this case.
*/
if (nonce_parity) {
secp256k1_scalar_negate(&t, &t);
}

secp256k1_scalar_add(&s, &s, &t);
secp256k1_scalar_get_b32(&sig64[32], &s);
memmove(sig64, pre_sig64, 32);
secp256k1_scalar_clear(&t);
return ret;
}
Expand Down
42 changes: 22 additions & 20 deletions src/modules/musig/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -539,23 +539,25 @@ void musig_api_tests(secp256k1_scratch_space *scratch) {
CHECK(ecount == 3);

ecount = 0;
{
unsigned char tmp_sig[64];
memcpy(tmp_sig, pre_sig, sizeof(tmp_sig));
CHECK(secp256k1_musig_adapt(none, tmp_sig, sec_adaptor, nonce_parity) == 1);
CHECK(secp256k1_musig_adapt(none, NULL, sec_adaptor, 0) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_musig_adapt(none, max64, sec_adaptor, 0) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_musig_adapt(none, tmp_sig, NULL, 0) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_musig_adapt(none, tmp_sig, max64, nonce_parity) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_musig_adapt(none, tmp_sig, sec_adaptor, 2) == 0);
CHECK(ecount == 3);
}
CHECK(secp256k1_musig_adapt(none, final_sig, pre_sig, sec_adaptor, nonce_parity) == 1);
CHECK(secp256k1_musig_adapt(none, NULL, pre_sig, sec_adaptor, 0) == 0);
CHECK(ecount == 1);
CHECK(secp256k1_musig_adapt(none, final_sig, NULL, sec_adaptor, 0) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_musig_adapt(none, final_sig, max64, sec_adaptor, 0) == 0);
CHECK(ecount == 2);
CHECK(secp256k1_musig_adapt(none, final_sig, pre_sig, NULL, 0) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_musig_adapt(none, final_sig, pre_sig, max64, 0) == 0);
CHECK(ecount == 3);
CHECK(secp256k1_musig_adapt(none, final_sig, pre_sig, sec_adaptor, 2) == 0);
CHECK(ecount == 4);
/* sig and pre_sig argument point to the same location */
memcpy(final_sig, pre_sig, sizeof(final_sig));
CHECK(secp256k1_musig_adapt(none, final_sig, sec_adaptor, nonce_parity) == 1);
CHECK(secp256k1_musig_adapt(none, final_sig, final_sig, sec_adaptor, nonce_parity) == 1);
CHECK(secp256k1_schnorrsig_verify(vrfy, final_sig, msg, sizeof(msg), &agg_pk) == 1);

CHECK(secp256k1_musig_adapt(none, final_sig, pre_sig, sec_adaptor, nonce_parity) == 1);
CHECK(secp256k1_schnorrsig_verify(vrfy, final_sig, msg, sizeof(msg), &agg_pk) == 1);

/** Secret adaptor can be extracted from signature */
Expand Down Expand Up @@ -647,6 +649,7 @@ void scriptless_atomic_swap(secp256k1_scratch_space *scratch) {
* while the indices 0 and 1 refer to the two signers. Here signer 0 is
* sending a-coins to signer 1, while signer 1 is sending b-coins to signer
* 0. Signer 0 produces the adaptor signatures. */
unsigned char pre_sig_a[64];
unsigned char final_sig_a[64];
unsigned char pre_sig_b[64];
unsigned char final_sig_b[64];
Expand Down Expand Up @@ -733,17 +736,16 @@ void scriptless_atomic_swap(secp256k1_scratch_space *scratch) {
* signature from signer 1 and adapts it. This results in a complete
* signature which is broadcasted by signer 0 to take B-coins. */
CHECK(secp256k1_musig_partial_sig_agg(ctx, pre_sig_b, &session_b, partial_sig_b_ptr, 2) == 1);
memcpy(final_sig_b, pre_sig_b, sizeof(final_sig_b));
CHECK(secp256k1_musig_adapt(ctx, final_sig_b, sec_adaptor, nonce_parity_b) == 1);
CHECK(secp256k1_musig_adapt(ctx, final_sig_b, pre_sig_b, sec_adaptor, nonce_parity_b) == 1);
CHECK(secp256k1_schnorrsig_verify(ctx, final_sig_b, msg32_b, sizeof(msg32_b), &agg_pk_b) == 1);

/* Step 6: Signer 1 signs, extracts adaptor from the published signature,
* and adapts the signature to take A-coins. */
CHECK(secp256k1_musig_partial_sign(ctx, &partial_sig_a[1], &secnonce_a[1], &keypair_a[1], &keyagg_cache_a, &session_a) == 1);
CHECK(secp256k1_musig_partial_sig_agg(ctx, final_sig_a, &session_a, partial_sig_a_ptr, 2) == 1);
CHECK(secp256k1_musig_partial_sig_agg(ctx, pre_sig_a, &session_a, partial_sig_a_ptr, 2) == 1);
CHECK(secp256k1_musig_extract_adaptor(ctx, sec_adaptor_extracted, final_sig_b, pre_sig_b, nonce_parity_b) == 1);
CHECK(memcmp(sec_adaptor_extracted, sec_adaptor, sizeof(sec_adaptor)) == 0); /* in real life we couldn't check this, of course */
CHECK(secp256k1_musig_adapt(ctx, final_sig_a, sec_adaptor_extracted, nonce_parity_a) == 1);
CHECK(secp256k1_musig_adapt(ctx, final_sig_a, pre_sig_a, sec_adaptor_extracted, nonce_parity_a) == 1);
CHECK(secp256k1_schnorrsig_verify(ctx, final_sig_a, msg32_a, sizeof(msg32_a), &agg_pk_a) == 1);
}

Expand Down
3 changes: 1 addition & 2 deletions src/valgrind_ctime_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,7 @@ void run_tests(secp256k1_context *ctx, unsigned char *key) {
VALGRIND_MAKE_MEM_DEFINED(pre_sig, sizeof(pre_sig));

CHECK(secp256k1_musig_nonce_parity(ctx, &nonce_parity, &session));
memcpy(sig, pre_sig, sizeof(pre_sig));
ret = secp256k1_musig_adapt(ctx, sig, sec_adaptor, nonce_parity);
ret = secp256k1_musig_adapt(ctx, sig, pre_sig, sec_adaptor, nonce_parity);
VALGRIND_MAKE_MEM_DEFINED(&ret, sizeof(ret));
CHECK(ret == 1);
ret = secp256k1_musig_extract_adaptor(ctx, sec_adaptor, sig, pre_sig, nonce_parity);
Expand Down

0 comments on commit b498180

Please sign in to comment.