mirror of
https://github.com/status-im/secp256k1.git
synced 2025-02-23 11:18:15 +00:00
Add secp256k1_tagged_sha256 as defined in BIP-340
Gives users the ability to hash messages to 32 byte before they are signed while allowing efficient domain separation through the tag.
This commit is contained in:
parent
b6c0b72fb0
commit
5a8e4991ad
@ -793,6 +793,31 @@ SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
|
||||
size_t n
|
||||
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Compute a tagged hash as defined in BIP-340.
|
||||
*
|
||||
* This is useful for creating a message hash and achieving domain separation
|
||||
* through an application-specific tag. This function returns
|
||||
* SHA256(SHA256(tag)||SHA256(tag)||msg). Therefore, tagged hash
|
||||
* implementations optimized for a specific tag can precompute the SHA256 state
|
||||
* after hashing the tag hashes.
|
||||
*
|
||||
* Returns 0 if the arguments are invalid and 1 otherwise.
|
||||
* Args: ctx: pointer to a context object
|
||||
* Out: hash32: pointer to a 32-byte array to store the resulting hash
|
||||
* In: tag: pointer to an array containing the tag
|
||||
* taglen: length of the tag array
|
||||
* msg: pointer to an array containing the message
|
||||
* msglen: length of the message array
|
||||
*/
|
||||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_tagged_sha256(
|
||||
const secp256k1_context* ctx,
|
||||
unsigned char *hash32,
|
||||
const unsigned char *tag,
|
||||
size_t taglen,
|
||||
const unsigned char *msg,
|
||||
size_t msglen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -790,6 +790,19 @@ int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *
|
||||
return 1;
|
||||
}
|
||||
|
||||
int secp256k1_tagged_sha256(const secp256k1_context* ctx, unsigned char *hash32, const unsigned char *tag, size_t taglen, const unsigned char *msg, size_t msglen) {
|
||||
secp256k1_sha256 sha;
|
||||
VERIFY_CHECK(ctx != NULL);
|
||||
ARG_CHECK(hash32 != NULL);
|
||||
ARG_CHECK(tag != NULL);
|
||||
ARG_CHECK(msg != NULL);
|
||||
|
||||
secp256k1_sha256_initialize_tagged(&sha, tag, taglen);
|
||||
secp256k1_sha256_write(&sha, msg, msglen);
|
||||
secp256k1_sha256_finalize(&sha, hash32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_MODULE_ECDH
|
||||
# include "modules/ecdh/main_impl.h"
|
||||
#endif
|
||||
|
33
src/tests.c
33
src/tests.c
@ -564,6 +564,38 @@ void run_rfc6979_hmac_sha256_tests(void) {
|
||||
secp256k1_rfc6979_hmac_sha256_finalize(&rng);
|
||||
}
|
||||
|
||||
void run_tagged_sha256_tests(void) {
|
||||
int ecount = 0;
|
||||
secp256k1_context *none = secp256k1_context_create(SECP256K1_CONTEXT_NONE);
|
||||
unsigned char tag[32] = { 0 };
|
||||
unsigned char msg[32] = { 0 };
|
||||
unsigned char hash32[32];
|
||||
unsigned char hash_expected[32] = {
|
||||
0x04, 0x7A, 0x5E, 0x17, 0xB5, 0x86, 0x47, 0xC1,
|
||||
0x3C, 0xC6, 0xEB, 0xC0, 0xAA, 0x58, 0x3B, 0x62,
|
||||
0xFB, 0x16, 0x43, 0x32, 0x68, 0x77, 0x40, 0x6C,
|
||||
0xE2, 0x76, 0x55, 0x9A, 0x3B, 0xDE, 0x55, 0xB3
|
||||
};
|
||||
|
||||
secp256k1_context_set_illegal_callback(none, counting_illegal_callback_fn, &ecount);
|
||||
|
||||
/* API test */
|
||||
CHECK(secp256k1_tagged_sha256(none, hash32, tag, sizeof(tag), msg, sizeof(msg)) == 1);
|
||||
CHECK(secp256k1_tagged_sha256(none, NULL, tag, sizeof(tag), msg, sizeof(msg)) == 0);
|
||||
CHECK(ecount == 1);
|
||||
CHECK(secp256k1_tagged_sha256(none, hash32, NULL, 0, msg, sizeof(msg)) == 0);
|
||||
CHECK(ecount == 2);
|
||||
CHECK(secp256k1_tagged_sha256(none, hash32, tag, sizeof(tag), NULL, 0) == 0);
|
||||
CHECK(ecount == 3);
|
||||
|
||||
/* Static test vector */
|
||||
memcpy(tag, "tag", 3);
|
||||
memcpy(msg, "msg", 3);
|
||||
CHECK(secp256k1_tagged_sha256(none, hash32, tag, 3, msg, 3) == 1);
|
||||
CHECK(secp256k1_memcmp_var(hash32, hash_expected, sizeof(hash32)) == 0);
|
||||
secp256k1_context_destroy(none);
|
||||
}
|
||||
|
||||
/***** RANDOM TESTS *****/
|
||||
|
||||
void test_rand_bits(int rand32, int bits) {
|
||||
@ -6505,6 +6537,7 @@ int main(int argc, char **argv) {
|
||||
run_sha256_tests();
|
||||
run_hmac_sha256_tests();
|
||||
run_rfc6979_hmac_sha256_tests();
|
||||
run_tagged_sha256_tests();
|
||||
|
||||
/* scalar tests */
|
||||
run_scalar_tests();
|
||||
|
Loading…
x
Reference in New Issue
Block a user