ecdsa_adaptor: add nonce function and tags
This commit adds a nonce function that will be used by default for ECDSA adaptor signatures. This nonce function is similar to secp256k1_nonce_function_hardened except it uses the compressed 33-byte encoding for the pubkey argument. We need 33 bytes instead of 32 because, unlike with BIP-340, an ECDSA X-coordinate alone is not sufficient to disambiguate the Y-coordinate.
This commit is contained in:
parent
654cd633f5
commit
d8f336564f
@ -12,6 +12,40 @@ extern "C" {
|
||||
* and https://github.com/LLFourn/one-time-VES/blob/master/main.pdf).
|
||||
*/
|
||||
|
||||
/** A pointer to a function to deterministically generate a nonce.
|
||||
*
|
||||
* Same as secp256k1_nonce_function_hardened with the exception of using the
|
||||
* compressed 33-byte encoding for the pubkey argument.
|
||||
*
|
||||
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to
|
||||
* return an error.
|
||||
* Out: nonce32: pointer to a 32-byte array to be filled by the function
|
||||
* In: msg32: the 32-byte message hash being verified
|
||||
* key32: pointer to a 32-byte secret key
|
||||
* pk33: the 33-byte serialized pubkey corresponding to key32
|
||||
* algo: pointer to an array describing the signature algorithm
|
||||
* algolen: the length of the algo array
|
||||
* data: arbitrary data pointer that is passed through
|
||||
*
|
||||
* Except for test cases, this function should compute some cryptographic hash of
|
||||
* the message, the key, the pubkey, the algorithm description, and data.
|
||||
*/
|
||||
typedef int (*secp256k1_nonce_function_hardened_ecdsa_adaptor)(
|
||||
unsigned char *nonce32,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *key32,
|
||||
const unsigned char *pk33,
|
||||
const unsigned char *algo,
|
||||
size_t algolen,
|
||||
void *data
|
||||
);
|
||||
|
||||
/** A modified BIP-340 nonce generation function. If a data pointer is passed, it is
|
||||
* assumed to be a pointer to 32 bytes of auxiliary random data as defined in BIP-340.
|
||||
* The hash will be tagged with algo after removing all terminating null bytes.
|
||||
*/
|
||||
SECP256K1_API extern const secp256k1_nonce_function_hardened_ecdsa_adaptor secp256k1_nonce_function_ecdsa_adaptor;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1 +1,2 @@
|
||||
include_HEADERS += include/secp256k1_ecdsa_adaptor.h
|
||||
noinst_HEADERS += src/modules/ecdsa_adaptor/main_impl.h
|
||||
|
@ -9,4 +9,82 @@
|
||||
|
||||
#include "include/secp256k1_ecdsa_adaptor.h"
|
||||
|
||||
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
|
||||
* SHA256 to SHA256("ECDSAadaptor/non")||SHA256("ECDSAadaptor/non"). */
|
||||
static void secp256k1_nonce_function_ecdsa_adaptor_sha256_tagged(secp256k1_sha256 *sha) {
|
||||
secp256k1_sha256_initialize(sha);
|
||||
sha->s[0] = 0x791dae43ul;
|
||||
sha->s[1] = 0xe52d3b44ul;
|
||||
sha->s[2] = 0x37f9edeaul;
|
||||
sha->s[3] = 0x9bfd2ab1ul;
|
||||
sha->s[4] = 0xcfb0f44dul;
|
||||
sha->s[5] = 0xccf1d880ul;
|
||||
sha->s[6] = 0xd18f2c13ul;
|
||||
sha->s[7] = 0xa37b9024ul;
|
||||
|
||||
sha->bytes = 64;
|
||||
}
|
||||
|
||||
/* Initializes SHA256 with fixed midstate. This midstate was computed by applying
|
||||
* SHA256 to SHA256("ECDSAadaptor/aux")||SHA256("ECDSAadaptor/aux"). */
|
||||
static void secp256k1_nonce_function_ecdsa_adaptor_sha256_tagged_aux(secp256k1_sha256 *sha) {
|
||||
secp256k1_sha256_initialize(sha);
|
||||
sha->s[0] = 0xd14c7bd9ul;
|
||||
sha->s[1] = 0x095d35e6ul;
|
||||
sha->s[2] = 0xb8490a88ul;
|
||||
sha->s[3] = 0xfb00ef74ul;
|
||||
sha->s[4] = 0x0baa488ful;
|
||||
sha->s[5] = 0x69366693ul;
|
||||
sha->s[6] = 0x1c81c5baul;
|
||||
sha->s[7] = 0xc33b296aul;
|
||||
|
||||
sha->bytes = 64;
|
||||
}
|
||||
|
||||
/* algo argument for nonce_function_ecdsa_adaptor to derive the nonce using a tagged hash function. */
|
||||
static const unsigned char ecdsa_adaptor_algo[16] = "ECDSAadaptor/non";
|
||||
|
||||
/* Modified BIP-340 nonce function */
|
||||
static int nonce_function_ecdsa_adaptor(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *pk33, const unsigned char *algo, size_t algolen, void *data) {
|
||||
secp256k1_sha256 sha;
|
||||
unsigned char masked_key[32];
|
||||
int i;
|
||||
|
||||
if (algo == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data != NULL) {
|
||||
secp256k1_nonce_function_ecdsa_adaptor_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];
|
||||
}
|
||||
}
|
||||
|
||||
/* Tag the hash with algo which is important to avoid nonce reuse across
|
||||
* algorithims. An optimized tagging implementation is used if the default
|
||||
* tag is provided. */
|
||||
if (algolen == sizeof(ecdsa_adaptor_algo)
|
||||
&& secp256k1_memcmp_var(algo, ecdsa_adaptor_algo, algolen) == 0) {
|
||||
secp256k1_nonce_function_ecdsa_adaptor_sha256_tagged(&sha);
|
||||
} else {
|
||||
secp256k1_sha256_initialize_tagged(&sha, algo, algolen);
|
||||
}
|
||||
|
||||
/* Hash (masked-)key||pk||msg using the tagged hash as per BIP-340 */
|
||||
if (data != NULL) {
|
||||
secp256k1_sha256_write(&sha, masked_key, 32);
|
||||
} else {
|
||||
secp256k1_sha256_write(&sha, key32, 32);
|
||||
}
|
||||
secp256k1_sha256_write(&sha, pk33, 33);
|
||||
secp256k1_sha256_write(&sha, msg32, 32);
|
||||
secp256k1_sha256_finalize(&sha, nonce32);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const secp256k1_nonce_function_hardened_ecdsa_adaptor secp256k1_nonce_function_ecdsa_adaptor = nonce_function_ecdsa_adaptor;
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user