Skip to content

Commit

Permalink
added new hash tags specifically for schnorr adaptor
Browse files Browse the repository at this point in the history
  • Loading branch information
ZhePang committed Oct 24, 2023
1 parent 9c60058 commit d268b56
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
60 changes: 47 additions & 13 deletions src/modules/schnorr_adaptor/main_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,42 @@
#include "../../../include/secp256k1_schnorr_adaptor.h"
#include "../../hash.h"

/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
* SHA256 to SHA256("SchnorrAdaptor/nonce")||SHA256("SchnorrAdaptor/nonce"). */
static void secp256k1_adaptor_nonce_function_bip340_sha256_tagged(secp256k1_sha256 *sha) {
secp256k1_sha256_initialize(sha);
sha->s[0] = 0xe268ac2aul;
sha->s[1] = 0x3a221b84ul;
sha->s[2] = 0x69612afdul;
sha->s[3] = 0x92ce3040ul;
sha->s[4] = 0xc83ca35ful;
sha->s[5] = 0xec2ee152ul;
sha->s[6] = 0xba136ab7ul;
sha->s[7] = 0x3bf6ec7ful;

sha->bytes = 64;
}

/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
* SHA256 to SHA256("SchnorrAdaptor/aux")||SHA256("SchnorrAdaptor/aux"). */
static void secp256k1_adaptor_nonce_function_bip340_sha256_tagged_aux(secp256k1_sha256 *sha) {
secp256k1_sha256_initialize(sha);
sha->s[0] = 0x60c4ec6dul;
sha->s[1] = 0x2fc91363ul;
sha->s[2] = 0xce54f4a5ul;
sha->s[3] = 0x962e1565ul;
sha->s[4] = 0x2b5da649ul;
sha->s[5] = 0x6ba94748ul;
sha->s[6] = 0x456c70adul;
sha->s[7] = 0x842cbaddul;

sha->bytes = 64;
}

/* algo argument for adaptor_nonce_function_bip340 to derive the nonce of Schnorr adaptor signature
* by using the correct tagged hash function. */
static const unsigned char adaptor_bip340_algo[20] = "SchnorrAdaptor/nonce";

static int adaptor_nonce_function_bip340(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *t33, const unsigned char *xonly_pk32, const unsigned char *algo, size_t algolen, void *data) {
secp256k1_sha256 sha;
unsigned char masked_key[32];
Expand All @@ -21,19 +57,19 @@ static int adaptor_nonce_function_bip340(unsigned char *nonce32, const unsigned
}

if (data != NULL) {
secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha);
secp256k1_adaptor_nonce_function_bip340_sha256_tagged_aux(&sha);
secp256k1_sha256_write(&sha, data, 32);
secp256k1_sha256_finalize(&sha, masked_key);
for (i = 0; i < 32; i++) {
masked_key[i] ^= key32[i];
}
} else {
/* Precomputed TaggedHash("BIP0340/aux", 0x0000...00); */
/* Precomputed TaggedHash("SchnorrAdaptor/aux", 0x0000...00); */
static const unsigned char ZERO_MASK[32] = {
84, 241, 105, 207, 201, 226, 229, 114,
116, 128, 68, 31, 144, 186, 37, 196,
136, 244, 97, 199, 11, 94, 165, 220,
170, 247, 175, 105, 39, 10, 165, 20
65, 206, 231, 5, 44, 99, 30, 162,
119, 101, 143, 108, 176, 134, 217, 23,
54, 150, 157, 221, 198, 161, 164, 85,
235, 82, 28, 56, 164, 220, 113, 53
};
for (i = 0; i < 32; i++) {
masked_key[i] = key32[i] ^ ZERO_MASK[i];
Expand All @@ -43,9 +79,9 @@ static int adaptor_nonce_function_bip340(unsigned char *nonce32, const unsigned
/* Tag the hash with algo which is important to avoid nonce reuse across
* algorithms. If this nonce function is used in BIP-340 signing as defined
* in the spec, an optimized tagging implementation is used. */
if (algolen == sizeof(bip340_algo)
&& secp256k1_memcmp_var(algo, bip340_algo, algolen) == 0) {
secp256k1_nonce_function_bip340_sha256_tagged(&sha);
if (algolen == sizeof(adaptor_bip340_algo)
&& secp256k1_memcmp_var(algo, adaptor_bip340_algo, algolen) == 0) {
secp256k1_adaptor_nonce_function_bip340_sha256_tagged(&sha);
} else {
secp256k1_sha256_initialize_tagged(&sha, algo, algolen);
}
Expand Down Expand Up @@ -221,6 +257,7 @@ int secp256k1_schnorr_adaptor_adapt(const secp256k1_context *ctx, unsigned char
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(sig64 != NULL);
ARG_CHECK(sig65 != NULL);
ARG_CHECK(sig65[0] == SECP256K1_TAG_PUBKEY_EVEN || sig65[0] == SECP256K1_TAG_PUBKEY_ODD);
ARG_CHECK(t32 != NULL);

/* s0 */
Expand All @@ -236,8 +273,6 @@ int secp256k1_schnorr_adaptor_adapt(const secp256k1_context *ctx, unsigned char
} else if (sig65[0] == SECP256K1_TAG_PUBKEY_ODD) {
secp256k1_scalar_negate(&t, &t);
secp256k1_scalar_add(&s, &s0, &t);
} else {
ret = 0;
}

memcpy(sig64, &sig65[1], 32);
Expand All @@ -259,6 +294,7 @@ int secp256k1_schnorr_adaptor_extract_adaptor(const secp256k1_context *ctx, unsi
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(t32 != NULL);
ARG_CHECK(sig65 != NULL);
ARG_CHECK(sig65[0] == SECP256K1_TAG_PUBKEY_EVEN || sig65[0] == SECP256K1_TAG_PUBKEY_ODD);
ARG_CHECK(sig64 != NULL);

/* s0 */
Expand All @@ -275,8 +311,6 @@ int secp256k1_schnorr_adaptor_extract_adaptor(const secp256k1_context *ctx, unsi
} else if (sig65[0] == SECP256K1_TAG_PUBKEY_ODD) {
secp256k1_scalar_negate(&s, &s);
secp256k1_scalar_add(&t, &s0, &s);
} else {
ret = 0;
}

secp256k1_scalar_get_b32(t32, &t);
Expand Down
12 changes: 6 additions & 6 deletions src/modules/schnorr_adaptor/tests_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ void adaptor_nonce_function_bip340_bitflip(unsigned char **args, size_t n_flip,
}

void run_adaptor_nonce_function_bip340_tests(void) {
unsigned char tag[13] = "BIP0340/nonce";
unsigned char aux_tag[11] = "BIP0340/aux";
unsigned char algo[13] = "BIP0340/nonce";
unsigned char tag[20] = "SchnorrAdaptor/nonce";
unsigned char aux_tag[18] = "SchnorrAdaptor/aux";
unsigned char algo[20] = "SchnorrAdaptor/nonce";
size_t algolen = sizeof(algo);
secp256k1_sha256 sha;
secp256k1_sha256 sha_optimized;
Expand All @@ -45,14 +45,14 @@ void run_adaptor_nonce_function_bip340_tests(void) {
* secp256k1_nonce_function_bip340_sha256_tagged has the expected
* state. */
secp256k1_sha256_initialize_tagged(&sha, tag, sizeof(tag));
secp256k1_nonce_function_bip340_sha256_tagged(&sha_optimized);
secp256k1_adaptor_nonce_function_bip340_sha256_tagged(&sha_optimized);
test_sha256_eq(&sha, &sha_optimized);

/* Check that hash initialized by
* secp256k1_nonce_function_bip340_sha256_tagged_aux has the expected
* state. */
secp256k1_sha256_initialize_tagged(&sha, aux_tag, sizeof(aux_tag));
secp256k1_nonce_function_bip340_sha256_tagged_aux(&sha_optimized);
secp256k1_adaptor_nonce_function_bip340_sha256_tagged_aux(&sha_optimized);
test_sha256_eq(&sha, &sha_optimized);

secp256k1_testrand256(msg);
Expand All @@ -78,7 +78,7 @@ void run_adaptor_nonce_function_bip340_tests(void) {
adaptor_nonce_function_bip340_bitflip(args, 1, 32, algolen);
adaptor_nonce_function_bip340_bitflip(args, 2, 32, algolen);
adaptor_nonce_function_bip340_bitflip(args, 3, 32, algolen);
/* Flip algo special case "BIP0340/nonce" */
/* Flip algo special case "SchnorrAdaptor/nonce" */
adaptor_nonce_function_bip340_bitflip(args, 4, algolen, algolen);
/* Flip algo again */
adaptor_nonce_function_bip340_bitflip(args, 4, algolen, algolen);
Expand Down

0 comments on commit d268b56

Please sign in to comment.