-
Notifications
You must be signed in to change notification settings - Fork 1.1k
schnorrsig API overhaul #844
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
99e8614
README: mention schnorrsig module
jonasnick df3bfa1
schnorrsig: clarify result of calling nonce_function_bip340 without data
jonasnick 442cee5
schnorrsig: add algolen argument to nonce_function_hardened
jonasnick b6c0b72
schnorrsig: remove noncefp args from sign; add sign_custom function
jonasnick 5a8e499
Add secp256k1_tagged_sha256 as defined in BIP-340
jonasnick a0c3fc1
schnorrsig: allow signing and verification of variable length msgs
jonasnick d8d806a
schnorrsig: add extra parameter struct for sign_custom
jonasnick fdd06b7
schnorrsig: add tests for sign_custom and varlen msg verification
jonasnick 5f6ceaf
schnorrsig: allow setting MSGLEN != 32 in benchmark
jonasnick File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,24 +23,29 @@ extern "C" { | |
* | ||
* 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 (will not be NULL) | ||
* key32: pointer to a 32-byte secret key (will not be NULL) | ||
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32 | ||
* (will not be NULL) | ||
* algo16: pointer to a 16-byte array describing the signature | ||
* algorithm (will not be NULL). | ||
* data: Arbitrary data pointer that is passed through. | ||
* Out: nonce32: pointer to a 32-byte array to be filled by the function | ||
* In: msg: the message being verified. Is NULL if and only if msglen | ||
* is 0. | ||
* msglen: the length of the message | ||
* key32: pointer to a 32-byte secret key (will not be NULL) | ||
* xonly_pk32: the 32-byte serialized xonly pubkey corresponding to key32 | ||
* (will not be NULL) | ||
jonasnick marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* algo: pointer to an array describing the signature | ||
* algorithm (will not be NULL) | ||
* 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)( | ||
unsigned char *nonce32, | ||
const unsigned char *msg32, | ||
const unsigned char *msg, | ||
size_t msglen, | ||
const unsigned char *key32, | ||
const unsigned char *xonly_pk32, | ||
const unsigned char *algo16, | ||
const unsigned char *algo, | ||
size_t algolen, | ||
void *data | ||
); | ||
|
||
|
@@ -50,59 +55,113 @@ typedef int (*secp256k1_nonce_function_hardened)( | |
* | ||
* 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. If the data pointer is NULL, | ||
* schnorrsig_sign does not produce BIP-340 compliant signatures. The algo16 | ||
* argument must be non-NULL, otherwise the function will fail and return 0. | ||
* The hash will be tagged with algo16 after removing all terminating null | ||
* bytes. Therefore, to create BIP-340 compliant signatures, algo16 must be set | ||
* to "BIP0340/nonce\0\0\0" | ||
* the nonce derivation procedure follows BIP-340 by setting the auxiliary | ||
* random data to zero. The algo argument must be non-NULL, otherwise the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was about to suggest that maybe we could allow |
||
* function will fail and return 0. The hash will be tagged with algo. | ||
* Therefore, to create BIP-340 compliant signatures, algo must be set to | ||
* "BIP0340/nonce" and algolen to 13. | ||
*/ | ||
SECP256K1_API extern const secp256k1_nonce_function_hardened secp256k1_nonce_function_bip340; | ||
|
||
/** Data structure that contains additional arguments for schnorrsig_sign_custom. | ||
* | ||
* A schnorrsig_extraparams structure object can be initialized correctly by | ||
* setting it to SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT. | ||
* | ||
* Members: | ||
* magic: set to SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC at initialization | ||
* and has no other function than making sure the object is | ||
* initialized. | ||
* noncefp: pointer to a nonce generation function. If NULL, | ||
* secp256k1_nonce_function_bip340 is used | ||
* ndata: pointer to arbitrary data used by the nonce generation function | ||
* (can be NULL). If it is non-NULL and | ||
* secp256k1_nonce_function_bip340 is used, then ndata must be a | ||
* pointer to 32-byte auxiliary randomness as per BIP-340. | ||
*/ | ||
typedef struct { | ||
unsigned char magic[4]; | ||
secp256k1_nonce_function_hardened noncefp; | ||
void* ndata; | ||
} secp256k1_schnorrsig_extraparams; | ||
|
||
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC "\xda\x6f\xb3\x8c" | ||
#define SECP256K1_SCHNORRSIG_EXTRAPARAMS_INIT {\ | ||
SECP256K1_SCHNORRSIG_EXTRAPARAMS_MAGIC,\ | ||
NULL,\ | ||
NULL\ | ||
} | ||
|
||
/** Create a Schnorr signature. | ||
* | ||
* Does _not_ strictly follow BIP-340 because it does not verify the resulting | ||
* signature. Instead, you can manually use secp256k1_schnorrsig_verify and | ||
* abort if it fails. | ||
* | ||
* Otherwise BIP-340 compliant if the noncefp argument is NULL or | ||
* secp256k1_nonce_function_bip340 and the ndata argument is 32-byte auxiliary | ||
* randomness. | ||
* This function only signs 32-byte messages. If you have messages of a | ||
* different size (or the same size but without a context-specific tag | ||
* prefix), it is recommended to create a 32-byte message hash with | ||
* secp256k1_tagged_sha256 and then sign the hash. Tagged hashing allows | ||
* providing an context-specific tag for domain separation. This prevents | ||
* signatures from being valid in multiple contexts by accident. | ||
* | ||
* Returns 1 on success, 0 on failure. | ||
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) | ||
* Out: sig64: pointer to a 64-byte array to store the serialized signature (cannot be NULL) | ||
* In: msg32: the 32-byte message being signed (cannot be NULL) | ||
* keypair: pointer to an initialized keypair (cannot be NULL) | ||
* noncefp: pointer to a nonce generation function. If NULL, secp256k1_nonce_function_bip340 is used | ||
* ndata: pointer to arbitrary data used by the nonce generation | ||
* function (can be NULL). If it is non-NULL and | ||
* secp256k1_nonce_function_bip340 is used, then ndata must be a | ||
* pointer to 32-byte auxiliary randomness as per BIP-340. | ||
* aux_rand32: 32 bytes of fresh randomness. While recommended to provide | ||
* this, it is only supplemental to security and can be NULL. See | ||
jonasnick marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* BIP-340 "Default Signing" for a full explanation of this | ||
* argument and for guidance if randomness is expensive. | ||
*/ | ||
SECP256K1_API int secp256k1_schnorrsig_sign( | ||
const secp256k1_context* ctx, | ||
unsigned char *sig64, | ||
const unsigned char *msg32, | ||
const secp256k1_keypair *keypair, | ||
secp256k1_nonce_function_hardened noncefp, | ||
void *ndata | ||
unsigned char *aux_rand32 | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); | ||
|
||
/** Create a Schnorr signature with a more flexible API. | ||
* | ||
* Same arguments as secp256k1_schnorrsig_sign except that it allows signing | ||
* variable length messages and accepts a pointer to an extraparams object that | ||
* allows customizing signing by passing additional arguments. | ||
* | ||
* Creates the same signatures as schnorrsig_sign if msglen is 32 and the | ||
* extraparams.ndata is the same as aux_rand32. | ||
* | ||
* In: msg: the message being signed. Can only be NULL if msglen is 0. | ||
* msglen: length of the message | ||
* extraparams: pointer to a extraparams object (can be NULL) | ||
*/ | ||
jonasnick marked this conversation as resolved.
Show resolved
Hide resolved
|
||
SECP256K1_API int secp256k1_schnorrsig_sign_custom( | ||
const secp256k1_context* ctx, | ||
unsigned char *sig64, | ||
const unsigned char *msg, | ||
size_t msglen, | ||
const secp256k1_keypair *keypair, | ||
secp256k1_schnorrsig_extraparams *extraparams | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5); | ||
|
||
/** Verify a Schnorr signature. | ||
* | ||
* Returns: 1: correct signature | ||
* 0: incorrect signature | ||
* Args: ctx: a secp256k1 context object, initialized for verification. | ||
* In: sig64: pointer to the 64-byte signature to verify (cannot be NULL) | ||
* msg32: the 32-byte message being verified (cannot be NULL) | ||
* msg: the message being verified. Can only be NULL if msglen is 0. | ||
* msglen: length of the message | ||
* pubkey: pointer to an x-only public key to verify with (cannot be NULL) | ||
*/ | ||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify( | ||
const secp256k1_context* ctx, | ||
const unsigned char *sig64, | ||
const unsigned char *msg32, | ||
const unsigned char *msg, | ||
size_t msglen, | ||
const secp256k1_xonly_pubkey *pubkey | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(5); | ||
|
||
#ifdef __cplusplus | ||
} | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.