-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Allow sign-to-contract commitments in schnorrsigs #588
Closed
Closed
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
f4153a2
add chacha20 function
apoelstra d65adc8
Add schnorrsig module which implements BIP-schnorr [0] compatible sig…
apoelstra 39fe790
Add secp256k1_context argument to secp256k1_nonce_functions
jonasnick 741ddd5
Add ec_commitments which are essentially the pay-to-contract-style tw…
jonasnick 6ddb655
Add and expose sign-to-contract contexts and make nonce_function_bips…
jonasnick 8fa102c
Add verification of schnorrsig sign-to-contract commitments
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 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 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 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 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 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 |
---|---|---|
@@ -0,0 +1,141 @@ | ||
#ifndef SECP256K1_SCHNORRSIG_H | ||
#define SECP256K1_SCHNORRSIG_H | ||
|
||
/** This module implements a variant of Schnorr signatures compliant with | ||
* BIP-schnorr | ||
* (https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki). | ||
*/ | ||
|
||
/** Opaque data structure that holds a parsed Schnorr signature. | ||
* | ||
* The exact representation of data inside is implementation defined and not | ||
* guaranteed to be portable between different platforms or versions. It is | ||
* however guaranteed to be 64 bytes in size, and can be safely copied/moved. | ||
* If you need to convert to a format suitable for storage, transmission, or | ||
* comparison, use the `secp256k1_schnorrsig_serialize` and | ||
* `secp256k1_schnorrsig_parse` functions. | ||
*/ | ||
typedef struct { | ||
unsigned char data[64]; | ||
} secp256k1_schnorrsig; | ||
|
||
/** Serialize a Schnorr signature. | ||
* | ||
* Returns: 1 | ||
* Args: ctx: a secp256k1 context object | ||
* Out: out64: pointer to a 64-byte array to store the serialized signature | ||
* In: sig: pointer to the signature | ||
* | ||
* See secp256k1_schnorrsig_parse for details about the encoding. | ||
*/ | ||
SECP256K1_API int secp256k1_schnorrsig_serialize( | ||
const secp256k1_context* ctx, | ||
unsigned char *out64, | ||
const secp256k1_schnorrsig* sig | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); | ||
|
||
/** Parse a Schnorr signature. | ||
* | ||
* Returns: 1 when the signature could be parsed, 0 otherwise. | ||
* Args: ctx: a secp256k1 context object | ||
* Out: sig: pointer to a signature object | ||
* In: in64: pointer to the 64-byte signature to be parsed | ||
* | ||
* The signature is serialized in the form R||s, where R is a 32-byte public | ||
* key (x-coordinate only; the y-coordinate is considered to be the unique | ||
* y-coordinate satisfying the curve equation that is a quadratic residue) | ||
* and s is a 32-byte big-endian scalar. | ||
* | ||
* After the call, sig will always be initialized. If parsing failed or the | ||
* encoded numbers are out of range, signature validation with it is | ||
* guaranteed to fail for every message and public key. | ||
*/ | ||
SECP256K1_API int secp256k1_schnorrsig_parse( | ||
const secp256k1_context* ctx, | ||
secp256k1_schnorrsig* sig, | ||
const unsigned char *in64 | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); | ||
|
||
/** Create a Schnorr signature. | ||
* | ||
* Returns 1 on success, 0 on failure. | ||
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) | ||
* Out: sig: pointer to the returned signature (cannot be NULL) | ||
* nonce_is_negated: a pointer to an integer indicates if signing algorithm negated the | ||
* nonce (can be NULL) | ||
* In: msg32: the 32-byte message hash being signed (cannot be NULL) | ||
* seckey: pointer to a 32-byte secret key (cannot be NULL) | ||
* noncefp: pointer to a nonce generation function. If NULL, | ||
* secp256k1_nonce_function_bipschnorr is used | ||
* ndata: pointer to arbitrary data used by the nonce generation function. If non-NULL must | ||
* be a pointer to an s2c_context object when using the default nonce function | ||
* secp256k1_nonce_function_bipschnorr. s2c_context must be initialized with | ||
* secp256k1_s2c_commit_context_create. (can be NULL) | ||
*/ | ||
SECP256K1_API int secp256k1_schnorrsig_sign( | ||
const secp256k1_context* ctx, | ||
secp256k1_schnorrsig *sig, | ||
int *nonce_is_negated, | ||
const unsigned char *msg32, | ||
const unsigned char *seckey, | ||
secp256k1_nonce_function noncefp, | ||
void *ndata | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5); | ||
|
||
/** Verify a Schnorr signature. | ||
* | ||
* Returns: 1: correct signature | ||
* 0: incorrect or unparseable signature | ||
* Args: ctx: a secp256k1 context object, initialized for verification. | ||
* In: sig: the signature being verified (cannot be NULL) | ||
* msg32: the 32-byte message hash being verified (cannot be NULL) | ||
* pubkey: pointer to a public key to verify with (cannot be NULL) | ||
*/ | ||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify( | ||
const secp256k1_context* ctx, | ||
const secp256k1_schnorrsig *sig, | ||
const unsigned char *msg32, | ||
const secp256k1_pubkey *pubkey | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); | ||
|
||
/** Verifies a set of Schnorr signatures. | ||
* | ||
* Returns 1 if all succeeded, 0 otherwise. In particular, returns 1 if n_sigs is 0. | ||
* | ||
* Args: ctx: a secp256k1 context object, initialized for verification. | ||
* scratch: scratch space used for the multiexponentiation | ||
* In: sig: array of signatures, or NULL if there are no signatures | ||
* msg32: array of messages, or NULL if there are no signatures | ||
* pk: array of public keys, or NULL if there are no signatures | ||
* n_sigs: number of signatures in above arrays. Must be smaller than | ||
* 2^31 and smaller than half the maximum size_t value. Must be 0 | ||
* if above arrays are NULL. | ||
*/ | ||
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify_batch( | ||
const secp256k1_context* ctx, | ||
secp256k1_scratch_space *scratch, | ||
const secp256k1_schnorrsig *const *sig, | ||
const unsigned char *const *msg32, | ||
const secp256k1_pubkey *const *pk, | ||
size_t n_sigs | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2); | ||
|
||
/** Verify a sign-to-contract commitment. | ||
* | ||
* Returns: 1: the signature contains a commitment to data32 | ||
* 0: incorrect opening | ||
* Args: ctx: a secp256k1 context object, initialized for verification. | ||
* In: sig: the signature containing the sign-to-contract commitment (cannot be NULL) | ||
* data32: the 32-byte data that was committed to (cannot be NULL) | ||
* original_nonce: pointer to the original_nonce created when signing (cannot be NULL) | ||
* negated_nonce: integer indicating if signing algorithm negated the nonce | ||
*/ | ||
SECP256K1_API int secp256k1_schnorrsig_verify_s2c_commit( | ||
const secp256k1_context* ctx, | ||
const secp256k1_schnorrsig *sig, | ||
const unsigned char *data32, | ||
const secp256k1_pubkey *original_nonce, | ||
int negated_nonce | ||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); | ||
|
||
#endif |
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the "public nonce" really be represented as
pubkey
? for mege
orgej
would be more readable, but they're probably not exported....(I got confused while diving into
secp256k1_ec_commit_seckey
andsecp256k1_ec_commit_tweak
about the whole public key thing)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ge
orgej
are not exported. But, hm, perhaps this should be a pubnonce type if it already confuses people.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, yes. A public key is a public key, and a nonce is a different thing. (I mean we can't enforce anything in C but maybe it's helpful to use different names for the two public types at least.)
Do we have the same problem in other places too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a second thought... if we really want to optimize for a simple API, then #589 is the way to go. There the entire problem is eliminated by hiding from the user that a signature contains a "nonce".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nonce is represented as a pubkey also there https://github.com/bitcoin-core/secp256k1/pull/589/files#diff-222d6d707e263c79c462fb223b0e3ddcR98
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, yes, but that struct is not really public:
https://github.com/bitcoin-core/secp256k1/pull/589/files#diff-222d6d707e263c79c462fb223b0e3ddcR87
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair