Browse Source

[API BREAK] Change argument order to out/outin/in

master
Pieter Wuille 7 years ago
parent
commit
dc0ce9fc41
  1. 167
      include/secp256k1.h
  2. 6
      include/secp256k1_ecdh.h
  3. 36
      include/secp256k1_recovery.h
  4. 70
      include/secp256k1_schnorr.h
  5. 2
      src/bench_recover.c
  6. 4
      src/bench_schnorr_verify.c
  7. 2
      src/bench_sign.c
  8. 4
      src/bench_verify.c
  9. 6
      src/modules/recovery/main_impl.h
  10. 58
      src/modules/recovery/tests_impl.h
  11. 16
      src/modules/schnorr/main_impl.h
  12. 22
      src/modules/schnorr/tests_impl.h
  13. 12
      src/secp256k1.c
  14. 64
      src/tests.c

167
include/secp256k1.h

@ -5,6 +5,21 @@ @@ -5,6 +5,21 @@
extern "C" {
# endif
/* These rules specify the order of arguments in API calls:
*
* 1. Context pointers go first, followed by output arguments, combined
* output/input arguments, and finally input-only arguments.
* 2. Array lengths always immediately the follow the argument whose length
* they describe, even if this violates rule 1.
* 3. Within the OUT/OUTIN/IN groups, pointers to data that is typically generated
* later go first. This means: signatures, public nonces, private nonces,
* messages, public keys, secret keys, tweaks.
* 4. Arguments that are not data pointers go last, from more complex to less
* complex: function pointers, algorithm names, messages, void pointers,
* counts, flags, booleans.
* 5. Opaque data pointers follow the function pointer they are to be passed to.
*/
/** Opaque data structure that holds context information (precomputed tables etc.).
*
* The purpose of context structures is to cache large precomputed data tables
@ -59,15 +74,15 @@ typedef struct { @@ -59,15 +74,15 @@ typedef struct {
/** A pointer to a function to deterministically generate a nonce.
*
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
* 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)
* algo16: pointer to a 16-byte array describing the signature
* algorithm (will be NULL for ECDSA for compatibility).
* data: Arbitrary data pointer that is passed through.
* attempt: how many iterations we have tried to find a nonce.
* This will almost always be 0, but different attempt values
* are required to result in a different nonce.
* data: Arbitrary data pointer that is passed through.
* Out: nonce32: pointer to a 32-byte array to be filled by the function.
*
* Except for test cases, this function should compute some cryptographic hash of
* the message, the algorithm, the key and the attempt.
@ -77,8 +92,8 @@ typedef int (*secp256k1_nonce_function_t)( @@ -77,8 +92,8 @@ typedef int (*secp256k1_nonce_function_t)(
const unsigned char *msg32,
const unsigned char *key32,
const unsigned char *algo16,
unsigned int attempt,
const void *data
const void *data,
unsigned int attempt
);
# if !defined(SECP256K1_GNUC_PREREQ)
@ -132,7 +147,7 @@ secp256k1_context_t* secp256k1_context_create( @@ -132,7 +147,7 @@ secp256k1_context_t* secp256k1_context_create(
/** Copies a secp256k1 context object.
*
* Returns: a newly created context object.
* In: ctx: an existing context to copy (cannot be NULL)
* Args: ctx: an existing context to copy (cannot be NULL)
*/
secp256k1_context_t* secp256k1_context_clone(
const secp256k1_context_t* ctx
@ -141,7 +156,7 @@ secp256k1_context_t* secp256k1_context_clone( @@ -141,7 +156,7 @@ secp256k1_context_t* secp256k1_context_clone(
/** Destroy a secp256k1 context object.
*
* The context pointer may not be used afterwards.
* In: ctx: an existing context to destroy (cannot be NULL)
* Args: ctx: an existing context to destroy (cannot be NULL)
*/
void secp256k1_context_destroy(
secp256k1_context_t* ctx
@ -161,10 +176,10 @@ void secp256k1_context_destroy( @@ -161,10 +176,10 @@ void secp256k1_context_destroy(
* to cause a crash, though its return value and output arguments are
* undefined.
*
* In: ctx: an existing context object (cannot be NULL)
* fun: a pointer to a function to call when an illegal argument is
* passed to the API, taking a message and an opaque pointer
* (cannot be NULL).
* Args: ctx: an existing context object (cannot be NULL)
* In: fun: a pointer to a function to call when an illegal argument is
* passed to the API, taking a message and an opaque pointer
* (cannot be NULL).
* data: the opaque pointer to pass to fun above.
*/
void secp256k1_context_set_illegal_callback(
@ -183,9 +198,9 @@ void secp256k1_context_set_illegal_callback( @@ -183,9 +198,9 @@ void secp256k1_context_set_illegal_callback(
* for that). After this callback returns, anything may happen, including
* crashing.
*
* In: ctx: an existing context object (cannot be NULL)
* fun: a pointer to a function to call when an interal error occurs,
* taking a message and an opaque pointer (cannot be NULL).
* Args: ctx: an existing context object (cannot be NULL)
* In: fun: a pointer to a function to call when an interal error occurs,
* taking a message and an opaque pointer (cannot be NULL).
* data: the opaque pointer to pass to fun above.
*/
void secp256k1_context_set_error_callback(
@ -198,11 +213,11 @@ void secp256k1_context_set_error_callback( @@ -198,11 +213,11 @@ void secp256k1_context_set_error_callback(
*
* Returns: 1 if the public key was fully valid.
* 0 if the public key could not be parsed or is invalid.
* In: ctx: a secp256k1 context object.
* input: pointer to a serialized public key
* inputlen: length of the array pointed to by input
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
* parsed version of input. If not, its value is undefined.
* Args: ctx: a secp256k1 context object.
* Out: pubkey: pointer to a pubkey object. If 1 is returned, it is set to a
* parsed version of input. If not, its value is undefined.
* In: input: pointer to a serialized public key
* inputlen: length of the array pointed to by input
*
* This function supports parsing compressed (33 bytes, header byte 0x02 or
* 0x03), uncompressed (65 bytes, header byte 0x04), or hybrid (65 bytes, header
@ -218,14 +233,14 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse( @@ -218,14 +233,14 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(
/** Serialize a pubkey object into a serialized byte sequence.
*
* Returns: 1 always.
* In: ctx: a secp256k1 context object.
* pubkey: a pointer to a secp256k1_pubkey_t containing an initialized
* public key.
* compressed: whether to serialize in compressed format.
* Args: ctx: a secp256k1 context object.
* Out: output: a pointer to a 65-byte (if compressed==0) or 33-byte (if
* compressed==1) byte array to place the serialized key in.
* outputlen: a pointer to an integer which will contain the serialized
* size.
* In: pubkey: a pointer to a secp256k1_pubkey_t containing an initialized
* public key.
* compressed: whether to serialize in compressed format.
*/
int secp256k1_ec_pubkey_serialize(
const secp256k1_context_t* ctx,
@ -238,10 +253,10 @@ int secp256k1_ec_pubkey_serialize( @@ -238,10 +253,10 @@ int secp256k1_ec_pubkey_serialize(
/** Parse a DER ECDSA signature.
*
* Returns: 1 when the signature could be parsed, 0 otherwise.
* In: ctx: a secp256k1 context object
* input: a pointer to the signature to be parsed
* inputlen: the length of the array pointed to be input
* Out: sig: a pointer to a signature object
* Args: ctx: a secp256k1 context object
* Out: sig: a pointer to a signature object
* In: input: a pointer to the signature to be parsed
* inputlen: the length of the array pointed to be input
*
* Note that this function also supports some violations of DER and even BER.
*/
@ -255,13 +270,13 @@ int secp256k1_ecdsa_signature_parse_der( @@ -255,13 +270,13 @@ int secp256k1_ecdsa_signature_parse_der(
/** Serialize an ECDSA signature in DER format.
*
* Returns: 1 if enough space was available to serialize, 0 otherwise
* In: ctx: a secp256k1 context object
* sig: a pointer to an initialized signature object
* Args: ctx: a secp256k1 context object
* Out: output: a pointer to an array to store the DER serialization
* In/Out: outputlen: a pointer to a length integer. Initially, this integer
* should be set to the length of output. After the call
* it will be set to the length of the serialization (even
* if 0 was returned).
* In: sig: a pointer to an initialized signature object
*/
int secp256k1_ecdsa_signature_serialize_der(
const secp256k1_context_t* ctx,
@ -274,15 +289,15 @@ int secp256k1_ecdsa_signature_serialize_der( @@ -274,15 +289,15 @@ int secp256k1_ecdsa_signature_serialize_der(
*
* Returns: 1: correct signature
* 0: incorrect or unparseable signature
* In: ctx: a secp256k1 context object, initialized for verification.
* 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)
* sig: the signature being verified (cannot be NULL)
* pubkey: pointer to an initialized public key to verify with (cannot be NULL)
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
const secp256k1_ecdsa_signature_t *sig,
const unsigned char *msg32,
const secp256k1_pubkey_t *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
@ -299,12 +314,12 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; @@ -299,12 +314,12 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the private key was invalid.
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* msg32: the 32-byte message hash being signed (cannot be NULL)
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot 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_default is used
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
*
* The sig always has an s value in the lower half of the range (From 0x1
* to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
@ -335,8 +350,8 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default; @@ -335,8 +350,8 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
*/
int secp256k1_ecdsa_sign(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
secp256k1_ecdsa_signature_t *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function_t noncefp,
const void *ndata
@ -346,8 +361,8 @@ int secp256k1_ecdsa_sign( @@ -346,8 +361,8 @@ int secp256k1_ecdsa_sign(
*
* Returns: 1: secret key is valid
* 0: secret key is invalid
* In: ctx: pointer to a context object (cannot be NULL)
* seckey: pointer to a 32-byte secret key (cannot be NULL)
* Args: ctx: pointer to a context object (cannot be NULL)
* In: seckey: pointer to a 32-byte secret key (cannot be NULL)
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
const secp256k1_context_t* ctx,
@ -356,11 +371,11 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify( @@ -356,11 +371,11 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
/** Compute the public key for a secret key.
*
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* seckey: pointer to a 32-byte private key (cannot be NULL)
* Out: pubkey: pointer to the created public key (cannot be NULL)
* Returns: 1: secret was valid, public key stores
* 0: secret was invalid, try again
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: pubkey: pointer to the created public key (cannot be NULL)
* In: seckey: pointer to a 32-byte private key (cannot be NULL)
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
const secp256k1_context_t* ctx,
@ -370,15 +385,15 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( @@ -370,15 +385,15 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
/** Export a private key in BER format.
*
* In: ctx: pointer to a context object, initialized for signing (cannot
* be NULL)
* seckey: pointer to a 32-byte secret key to export.
* compressed: whether the key should be exported in compressed format.
* Out: privkey: pointer to an array for storing the private key in BER.
* Should have space for 279 bytes, and cannot be NULL.
* privkeylen: Pointer to an int where the length of the private key in
* privkey will be stored.
* Returns: 1 if the private key was valid.
* Args: ctx: pointer to a context object, initialized for signing (cannot
* be NULL)
* Out: privkey: pointer to an array for storing the private key in BER.
* Should have space for 279 bytes, and cannot be NULL.
* privkeylen: Pointer to an int where the length of the private key in
* privkey will be stored.
* In: seckey: pointer to a 32-byte secret key to export.
* compressed: whether the key should be exported in compressed format.
*
* This function is purely meant for compatibility with applications that
* require BER encoded keys. When working with secp256k1-specific code, the
@ -389,19 +404,19 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create( @@ -389,19 +404,19 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export(
const secp256k1_context_t* ctx,
const unsigned char *seckey,
unsigned char *privkey,
int *privkeylen,
const unsigned char *seckey,
int compressed
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Import a private key in DER format.
* Returns: 1 if a private key was extracted.
* In: ctx: pointer to a context object (cannot be NULL).
* privkey: pointer to a private key in DER format (cannot be NULL).
* privkeylen: length of the DER private key pointed to be privkey.
* Out: seckey: pointer to a 32-byte array for storing the private key.
* (cannot be NULL).
* Args: ctx: pointer to a context object (cannot be NULL).
* Out: seckey: pointer to a 32-byte array for storing the private key.
* (cannot be NULL).
* In: privkey: pointer to a private key in DER format (cannot be NULL).
* privkeylen: length of the DER private key pointed to be privkey.
*
* This function will accept more than just strict DER, and even allow some BER
* violations. The public key stored inside the DER-encoded private key is not
@ -417,13 +432,13 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import( @@ -417,13 +432,13 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import(
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Tweak a private key by adding tweak to it.
* In: ctx: pointer to a context object (cannot be NULL).
* tweak: pointer to a 32-byte tweak.
* In/Out: seckey: pointer to a 32-byte private key.
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
* uniformly random 32-byte arrays, or if the resulting private key
* would be invalid (only when the tweak is the complement of the
* private key). 1 otherwise.
* Args: ctx: pointer to a context object (cannot be NULL).
* In/Out: seckey: pointer to a 32-byte private key.
* In: tweak: pointer to a 32-byte tweak.
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
const secp256k1_context_t* ctx,
@ -432,14 +447,14 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add( @@ -432,14 +447,14 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Tweak a public key by adding tweak times the generator to it.
* In: ctx: pointer to a context object initialized for validation
* (cannot be NULL).
* tweak: pointer to a 32-byte tweak.
* In/Out: pubkey: pointer to a public key object.
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
* uniformly random 32-byte arrays, or if the resulting public key
* would be invalid (only when the tweak is the complement of the
* corresponding private key). 1 otherwise.
* Args: ctx: pointer to a context object initialized for validation
* (cannot be NULL).
* In/Out: pubkey: pointer to a public key object.
* In: tweak: pointer to a 32-byte tweak.
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
const secp256k1_context_t* ctx,
@ -448,11 +463,11 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add( @@ -448,11 +463,11 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Tweak a private key by multiplying it by a tweak.
* In: ctx: pointer to a context object (cannot be NULL).
* tweak: pointer to a 32-byte tweak.
* In/Out: seckey: pointer to a 32-byte private key.
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
* uniformly random 32-byte arrays, or equal to zero. 1 otherwise.
* Args: ctx: pointer to a context object (cannot be NULL).
* In/Out: seckey: pointer to a 32-byte private key.
* In: tweak: pointer to a 32-byte tweak.
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
const secp256k1_context_t* ctx,
@ -461,12 +476,12 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul( @@ -461,12 +476,12 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
/** Tweak a public key by multiplying it by a tweak value.
* In: ctx: pointer to a context object initialized for validation
* (cannot be NULL).
* tweak: pointer to a 32-byte tweak.
* In/Out: pubkey: pointer to a public key obkect.
* Returns: 0 if the tweak was out of range (chance of around 1 in 2^128 for
* uniformly random 32-byte arrays, or equal to zero. 1 otherwise.
* Args: ctx: pointer to a context object initialized for validation
* (cannot be NULL).
* In/Out: pubkey: pointer to a public key obkect.
* In: tweak: pointer to a 32-byte tweak.
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
const secp256k1_context_t* ctx,
@ -477,8 +492,8 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul( @@ -477,8 +492,8 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
/** Updates the context randomization.
* Returns: 1: randomization successfully updated
* 0: error
* In: ctx: pointer to a context object (cannot be NULL)
* seed32: pointer to a 32-byte random seed (NULL resets to initial state)
* Args: ctx: pointer to a context object (cannot be NULL)
* In: seed32: pointer to a 32-byte random seed (NULL resets to initial state)
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
secp256k1_context_t* ctx,
@ -488,20 +503,20 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize( @@ -488,20 +503,20 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_context_randomize(
/** Add a number of public keys together.
* Returns: 1: the sum of the public keys is valid.
* 0: the sum of the public keys is not valid.
* In: ctx: pointer to a context object
* out: pointer to pubkey for placing the resulting public key
* Args: ctx: pointer to a context object
* Out: out: pointer to pubkey for placing the resulting public key
* (cannot be NULL)
* In: ins: pointer to array of pointers to public keys (cannot be NULL)
* n: the number of public keys to add together (must be at least 1)
* ins: pointer to array of pointers to public keys (cannot be NULL)
* Use secp256k1_ec_pubkey_compress and secp256k1_ec_pubkey_decompress if the
* uncompressed format is needed.
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_combine(
const secp256k1_context_t* ctx,
secp256k1_pubkey_t *out,
int n,
const secp256k1_pubkey_t * const * ins
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
const secp256k1_pubkey_t * const * ins,
int n
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
# ifdef __cplusplus
}

6
include/secp256k1_ecdh.h

@ -10,11 +10,11 @@ extern "C" { @@ -10,11 +10,11 @@ extern "C" {
/** Compute an EC Diffie-Hellman secret in constant time
* Returns: 1: exponentiation was successful
* 0: scalar was invalid (zero or overflow)
* In: ctx: pointer to a context object (cannot be NULL)
* point: pointer to a public point
* scalar: a 32-byte scalar with which to multiply the point
* Args: ctx: pointer to a context object (cannot be NULL)
* Out: result: a 32-byte array which will be populated by an ECDH
* secret computed from the point and scalar
* In: point: pointer to a public point
* scalar: a 32-byte scalar with which to multiply the point
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(
const secp256k1_context_t* ctx,

36
include/secp256k1_recovery.h

@ -28,10 +28,10 @@ typedef struct { @@ -28,10 +28,10 @@ typedef struct {
/** Parse a compact ECDSA signature (64 bytes + recovery id).
*
* Returns: 1 when the signature could be parsed, 0 otherwise
* In: ctx: a secp256k1 context object
* input64: a pointer to a 64-byte compact signature
* recid: the recovery id (0, 1, 2 or 3)
* Out: sig: a pointer to a signature object
* Args: ctx: a secp256k1 context object
* Out: sig: a pointer to a signature object
* In: input64: a pointer to a 64-byte compact signature
* recid: the recovery id (0, 1, 2 or 3)
*/
int secp256k1_ecdsa_recoverable_signature_parse_compact(
const secp256k1_context_t* ctx,
@ -43,8 +43,8 @@ int secp256k1_ecdsa_recoverable_signature_parse_compact( @@ -43,8 +43,8 @@ int secp256k1_ecdsa_recoverable_signature_parse_compact(
/** Convert a recoverable signature into a normal signature.
*
* Returns: 1
* In: sigin: a pointer to a recoverable signature (cannot be NULL).
* Out: sig: a pointer to a normal signature (cannot be NULL).
* In: sigin: a pointer to a recoverable signature (cannot be NULL).
*/
int secp256k1_ecdsa_recoverable_signature_convert(
const secp256k1_context_t* ctx,
@ -55,10 +55,10 @@ int secp256k1_ecdsa_recoverable_signature_convert( @@ -55,10 +55,10 @@ int secp256k1_ecdsa_recoverable_signature_convert(
/** Serialize an ECDSA signature in compact format (64 bytes + recovery id).
*
* Returns: 1
* In: ctx: a secp256k1 context object
* sig: a pointer to an initialized signature object (cannot be NULL)
* Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
* recid: a pointer to an integer to hold the recovery id (can be NULL).
* Args: ctx: a secp256k1 context object
* Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL)
* recid: a pointer to an integer to hold the recovery id (can be NULL).
* In: sig: a pointer to an initialized signature object (cannot be NULL)
*/
int secp256k1_ecdsa_recoverable_signature_serialize_compact(
const secp256k1_context_t* ctx,
@ -71,17 +71,17 @@ int secp256k1_ecdsa_recoverable_signature_serialize_compact( @@ -71,17 +71,17 @@ int secp256k1_ecdsa_recoverable_signature_serialize_compact(
*
* Returns: 1: signature created
* 0: the nonce generation function failed, or the private key was invalid.
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* msg32: the 32-byte message hash being signed (cannot be NULL)
* Args: ctx: pointer to a context object, initialized for signing (cannot be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot 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_default is used
* ndata: pointer to arbitrary data used by the nonce generation function (can be NULL)
* Out: sig: pointer to an array where the signature will be placed (cannot be NULL)
*/
int secp256k1_ecdsa_sign_recoverable(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
secp256k1_ecdsa_recoverable_signature_t *sig,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function_t noncefp,
const void *ndata
@ -91,16 +91,16 @@ int secp256k1_ecdsa_sign_recoverable( @@ -91,16 +91,16 @@ int secp256k1_ecdsa_sign_recoverable(
*
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
* 0: otherwise.
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
* sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL)
* Args: ctx: pointer to a context object, initialized for verification (cannot be NULL)
* Out: pubkey: pointer to the recoved public key (cannot be NULL)
* In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL)
* msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
secp256k1_pubkey_t *pubkey,
const secp256k1_ecdsa_recoverable_signature_t *sig,
secp256k1_pubkey_t *pubkey
const unsigned char *msg32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
# ifdef __cplusplus

70
include/secp256k1_schnorr.h

@ -13,21 +13,21 @@ extern "C" { @@ -13,21 +13,21 @@ extern "C" {
* Returns: 1: signature created
* 0: the nonce generation function failed, or the private key was
* invalid.
* In: ctx: pointer to a context object, initialized for signing
* Args: ctx: pointer to a context object, initialized for signing
* (cannot be NULL)
* msg32: the 32-byte message hash being signed (cannot be NULL)
* Out: sig64: pointer to a 64-byte array where the signature will be
* placed (cannot 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_default is used
* ndata: pointer to arbitrary data used by the nonce generation
* function (can be NULL)
* Out: sig64: pointer to a 64-byte array where the signature will be
* placed (cannot be NULL)
*/
int secp256k1_schnorr_sign(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
unsigned char *sig64,
const unsigned char *msg32,
const unsigned char *seckey,
secp256k1_nonce_function_t noncefp,
const void *ndata
@ -36,15 +36,15 @@ int secp256k1_schnorr_sign( @@ -36,15 +36,15 @@ int secp256k1_schnorr_sign(
/** Verify a signature created by secp256k1_schnorr_sign.
* Returns: 1: correct signature
* 0: incorrect signature
* In: ctx: a secp256k1 context object, initialized for verification.
* Args: ctx: a secp256k1 context object, initialized for verification.
* In: sig64: the 64-byte signature being verified (cannot be NULL)
* msg32: the 32-byte message hash being verified (cannot be NULL)
* sig64: the 64-byte signature being verified (cannot be NULL)
* pubkey: the public key to verify with (cannot be NULL)
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
const unsigned char *sig64,
const unsigned char *msg32,
const secp256k1_pubkey_t *pubkey
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
@ -53,47 +53,47 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify( @@ -53,47 +53,47 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_verify(
* Returns: 1: public key successfully recovered (which guarantees a correct
* signature).
* 0: otherwise.
* In: ctx: pointer to a context object, initialized for
* Args: ctx: pointer to a context object, initialized for
* verification (cannot be NULL)
* msg32: the 32-byte message hash assumed to be signed (cannot
* be NULL)
* sig64: signature as 64 byte array (cannot be NULL)
* Out: pubkey: pointer to a pubkey to set to the recovered public key
* (cannot be NULL).
* In: sig64: signature as 64 byte array (cannot be NULL)
* msg32: the 32-byte message hash assumed to be signed (cannot
* be NULL)
*/
int secp256k1_schnorr_recover(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
secp256k1_pubkey_t *pubkey,
const unsigned char *sig64,
secp256k1_pubkey_t *pubkey
const unsigned char *msg32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
/** Generate a nonce pair deterministically for use with
* secp256k1_schnorr_partial_sign.
* Returns: 1: valid nonce pair was generated.
* 0: otherwise (nonce generation function failed)
* In: ctx: pointer to a context object, initialized for signing
* Args: ctx: pointer to a context object, initialized for signing
* (cannot be NULL)
* msg32: the 32-byte message hash assumed to be signed (cannot
* Out: pubnonce: public side of the nonce (cannot be NULL)
* privnonce32: private side of the nonce (32 byte) (cannot be NULL)
* In: msg32: the 32-byte message hash assumed to be signed (cannot
* be NULL)
* sec32: the 32-byte private key (cannot be NULL)
* noncefp: pointer to a nonce generation function. If NULL,
* secp256k1_nonce_function_default is used
* noncedata: pointer to arbitrary data used by the nonce generation
* function (can be NULL)
* Out: pubnonce: public side of the nonce (cannot be NULL)
* privnonce32: private side of the nonce (32 byte) (cannot be NULL)
*
* Do not use the output as a private/public key pair for signing/validation.
*/
int secp256k1_schnorr_generate_nonce_pair(
const secp256k1_context_t* ctx,
secp256k1_pubkey_t *pubnonce,
unsigned char *privnonce32,
const unsigned char *msg32,
const unsigned char *sec32,
secp256k1_nonce_function_t noncefp,
const void* noncedata,
secp256k1_pubkey_t *pubnonce,
unsigned char *privnonce32
const void* noncedata
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(6) SECP256K1_ARG_NONNULL(7);
/** Produce a partial Schnorr signature, which can be combined using
@ -103,14 +103,14 @@ int secp256k1_schnorr_generate_nonce_pair( @@ -103,14 +103,14 @@ int secp256k1_schnorr_generate_nonce_pair(
* 0: no valid signature exists with this combination of keys, nonces
* and message (chance around 1 in 2^128)
* -1: invalid private key, nonce, or public nonces.
* In: ctx: pointer to context object, initialized for signing (cannot
* Args: ctx: pointer to context object, initialized for signing (cannot
* be NULL)
* msg32: pointer to 32-byte message to sign
* Out: sig64: pointer to 64-byte array to put partial signature in
* In: msg32: pointer to 32-byte message to sign
* sec32: pointer to 32-byte private key
* secnonce32: pointer to 32-byte array containing our nonce
* pubnonce_others: pointer to pubkey containing the sum of the other's
* nonces (see secp256k1_ec_pubkey_combine)
* Out: sig64: pointer to 64-byte array to put partial signature in
* secnonce32: pointer to 32-byte array containing our nonce
*
* The intended procedure for creating a multiparty signature is:
* - Each signer S[i] with private key x[i] and public key Q[i] runs
@ -140,11 +140,11 @@ int secp256k1_schnorr_generate_nonce_pair( @@ -140,11 +140,11 @@ int secp256k1_schnorr_generate_nonce_pair(
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign(
const secp256k1_context_t* ctx,
const unsigned char *msg32,
unsigned char *sig64,
const unsigned char *msg32,
const unsigned char *sec32,
const unsigned char *secnonce32,
const secp256k1_pubkey_t *pubnonce_others
const secp256k1_pubkey_t *pubnonce_others,
const unsigned char *secnonce32
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5) SECP256K1_ARG_NONNULL(6);
/** Combine multiple Schnorr partial signatures.
@ -152,19 +152,19 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign( @@ -152,19 +152,19 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_sign(
* 0: the resulting signature is not valid (chance of 1 in 2^256)
* -1: some inputs were invalid, or the signatures were not created
* using the same set of nonces
* In: ctx: pointer to a context object
* sig64: pointer to a 64-byte array to place the combined signature
* Args: ctx: pointer to a context object
* Out: sig64: pointer to a 64-byte array to place the combined signature
* (cannot be NULL)
* n: the number of signatures to combine (at least 1)
* Out: sig64sin: pointer to an array of n pointers to 64-byte input
* In: sig64sin: pointer to an array of n pointers to 64-byte input
* signatures
* n: the number of signatures to combine (at least 1)
*/
SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorr_partial_combine(
const secp256k1_context_t* ctx,
unsigned char *sig64,
int n,
const unsigned char * const * sig64sin
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
const unsigned char * const * sig64sin,
int n
) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
# ifdef __cplusplus
}

2
src/bench_recover.c

@ -26,7 +26,7 @@ void bench_recover(void* arg) { @@ -26,7 +26,7 @@ void bench_recover(void* arg) {
int pubkeylen = 33;
secp256k1_ecdsa_recoverable_signature_t sig;
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(data->ctx, &sig, data->sig, i % 2));
CHECK(secp256k1_ecdsa_recover(data->ctx, data->msg, &sig, &pubkey));
CHECK(secp256k1_ecdsa_recover(data->ctx, &pubkey, &sig, data->msg));
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, pubkeyc, &pubkeylen, &pubkey, 1));
for (j = 0; j < 32; j++) {
data->sig[j + 32] = data->msg[j]; /* Move former message to S. */

4
src/bench_schnorr_verify.c

@ -34,7 +34,7 @@ static void benchmark_schnorr_init(void* arg) { @@ -34,7 +34,7 @@ static void benchmark_schnorr_init(void* arg) {
for (k = 0; k < data->numsigs; k++) {
secp256k1_pubkey_t pubkey;
for (i = 0; i < 32; i++) data->sigs[k].key[i] = 33 + i + k;
secp256k1_schnorr_sign(data->ctx, data->msg, data->sigs[k].sig, data->sigs[k].key, NULL, NULL);
secp256k1_schnorr_sign(data->ctx, data->sigs[k].sig, data->msg, data->sigs[k].key, NULL, NULL);
data->sigs[k].pubkeylen = 33;
CHECK(secp256k1_ec_pubkey_create(data->ctx, &pubkey, data->sigs[k].key));
CHECK(secp256k1_ec_pubkey_serialize(data->ctx, data->sigs[k].pubkey, &data->sigs[k].pubkeylen, &pubkey, 1));
@ -49,7 +49,7 @@ static void benchmark_schnorr_verify(void* arg) { @@ -49,7 +49,7 @@ static void benchmark_schnorr_verify(void* arg) {
secp256k1_pubkey_t pubkey;
data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF);
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->sigs[0].pubkey, data->sigs[0].pubkeylen));
CHECK(secp256k1_schnorr_verify(data->ctx, data->msg, data->sigs[0].sig, &pubkey) == ((i & 0xFF) == 0));
CHECK(secp256k1_schnorr_verify(data->ctx, data->sigs[0].sig, data->msg, &pubkey) == ((i & 0xFF) == 0));
data->sigs[0].sig[(i >> 8) % 64] ^= (i & 0xFF);
}
}

2
src/bench_sign.c

@ -31,7 +31,7 @@ static void bench_sign(void* arg) { @@ -31,7 +31,7 @@ static void bench_sign(void* arg) {
int siglen = 74;
int j;
secp256k1_ecdsa_signature_t signature;
CHECK(secp256k1_ecdsa_sign(data->ctx, data->msg, &signature, data->key, NULL, NULL));
CHECK(secp256k1_ecdsa_sign(data->ctx, &signature, data->msg, data->key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data->ctx, sig, &siglen, &signature));
for (j = 0; j < 32; j++) {
data->msg[j] = sig[j];

4
src/bench_verify.c

@ -33,7 +33,7 @@ static void benchmark_verify(void* arg) { @@ -33,7 +33,7 @@ static void benchmark_verify(void* arg) {
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
CHECK(secp256k1_ec_pubkey_parse(data->ctx, &pubkey, data->pubkey, data->pubkeylen) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(data->ctx, &sig, data->sig, data->siglen) == 1);
CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, &sig, &pubkey) == (i == 0));
CHECK(secp256k1_ecdsa_verify(data->ctx, &sig, data->msg, &pubkey) == (i == 0));
data->sig[data->siglen - 1] ^= (i & 0xFF);
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
@ -51,7 +51,7 @@ int main(void) { @@ -51,7 +51,7 @@ int main(void) {
for (i = 0; i < 32; i++) data.msg[i] = 1 + i;
for (i = 0; i < 32; i++) data.key[i] = 33 + i;
data.siglen = 72;
CHECK(secp256k1_ecdsa_sign(data.ctx, data.msg, &sig, data.key, NULL, NULL));
CHECK(secp256k1_ecdsa_sign(data.ctx, &sig, data.msg, data.key, NULL, NULL));
CHECK(secp256k1_ecdsa_signature_serialize_der(data.ctx, data.sig, &data.siglen, &sig));
CHECK(secp256k1_ec_pubkey_create(data.ctx, &pubkey, data.key));
CHECK(secp256k1_ec_pubkey_serialize(data.ctx, data.pubkey, &data.pubkeylen, &pubkey, 1) == 1);

6
src/modules/recovery/main_impl.h

@ -83,7 +83,7 @@ int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context_t* ctx @@ -83,7 +83,7 @@ int secp256k1_ecdsa_recoverable_signature_convert(const secp256k1_context_t* ctx
return 1;
}
int secp256k1_ecdsa_sign_recoverable(const secp256k1_context_t* ctx, const unsigned char *msg32, secp256k1_ecdsa_recoverable_signature_t *signature, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
int secp256k1_ecdsa_sign_recoverable(const secp256k1_context_t* ctx, secp256k1_ecdsa_recoverable_signature_t *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
secp256k1_scalar_t r, s;
secp256k1_scalar_t sec, non, msg;
int recid;
@ -105,7 +105,7 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context_t* ctx, const unsig @@ -105,7 +105,7 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context_t* ctx, const unsig
secp256k1_scalar_set_b32(&msg, msg32, NULL);
while (1) {
unsigned char nonce32[32];
ret = noncefp(nonce32, msg32, seckey, NULL, count, noncedata);
ret = noncefp(nonce32, seckey, msg32, NULL, noncedata, count);
if (!ret) {
break;
}
@ -130,7 +130,7 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context_t* ctx, const unsig @@ -130,7 +130,7 @@ int secp256k1_ecdsa_sign_recoverable(const secp256k1_context_t* ctx, const unsig
return ret;
}
int secp256k1_ecdsa_recover(const secp256k1_context_t* ctx, const unsigned char *msg32, const secp256k1_ecdsa_recoverable_signature_t *signature, secp256k1_pubkey_t *pubkey) {
int secp256k1_ecdsa_recover(const secp256k1_context_t* ctx, secp256k1_pubkey_t *pubkey, const secp256k1_ecdsa_recoverable_signature_t *signature, const unsigned char *msg32) {
secp256k1_ge_t q;
secp256k1_scalar_t r, s;
secp256k1_scalar_t m;

58
src/modules/recovery/tests_impl.h

@ -33,33 +33,33 @@ void test_ecdsa_recovery_end_to_end(void) { @@ -33,33 +33,33 @@ void test_ecdsa_recovery_end_to_end(void) {
/* Serialize/parse compact and verify/recover. */
extra[0] = 0;
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, message, &rsignature[0], privkey, NULL, NULL) == 1);
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, message, &rsignature[4], privkey, NULL, NULL) == 1);
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, message, &rsignature[1], privkey, NULL, extra) == 1);
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[0], message, privkey, NULL, NULL) == 1);
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[4], message, privkey, NULL, NULL) == 1);
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[1], message, privkey, NULL, extra) == 1);
extra[31] = 1;
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, message, &rsignature[2], privkey, NULL, extra) == 1);
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[2], message, privkey, NULL, extra) == 1);
extra[31] = 0;
extra[0] = 1;
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, message, &rsignature[3], privkey, NULL, extra) == 1);
CHECK(secp256k1_ecdsa_sign_recoverable(ctx, &rsignature[3], message, privkey, NULL, extra) == 1);
CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, message, &signature[4], &pubkey) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1);
memset(&rsignature[4], 0, sizeof(rsignature[4]));
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, message, &signature[4], &pubkey) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 1);
/* Parse compact (with recovery id) and recover. */
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, message, &rsignature[4], &recpubkey) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 1);
CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
/* Serialize/destroy/parse signature and verify again. */
CHECK(secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig, &recid, &rsignature[4]) == 1);
sig[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsignature[4], sig, recid) == 1);
CHECK(secp256k1_ecdsa_recoverable_signature_convert(ctx, &signature[4], &rsignature[4]) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, message, &signature[4], &pubkey) == 0);
CHECK(secp256k1_ecdsa_verify(ctx, &signature[4], message, &pubkey) == 0);
/* Recover again */
CHECK(secp256k1_ecdsa_recover(ctx, message, &rsignature[4], &recpubkey) == 0 ||
CHECK(secp256k1_ecdsa_recover(ctx, &recpubkey, &rsignature[4], message) == 0 ||
memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
}
@ -101,13 +101,13 @@ void test_ecdsa_recovery_edge_cases(void) { @@ -101,13 +101,13 @@ void test_ecdsa_recovery_edge_cases(void) {
int recid;
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 0));
CHECK(!secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkey));
CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 1));
CHECK(secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkey));
CHECK(secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 2));
CHECK(!secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkey));
CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sig64, 3));
CHECK(!secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkey));
CHECK(!secp256k1_ecdsa_recover(ctx, &pubkey, &rsig, msg32));
for (recid = 0; recid < 4; recid++) {
int i;
@ -153,13 +153,13 @@ void test_ecdsa_recovery_edge_cases(void) { @@ -153,13 +153,13 @@ void test_ecdsa_recovery_edge_cases(void) {
0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
};
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
for (recid2 = 0; recid2 < 4; recid2++) {
secp256k1_pubkey_t pubkey2b;
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigb64, recid2) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkey2b) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, &pubkey2b, &rsig, msg32) == 1);
/* Verifying with (order + r,4) should always fail. */
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderlong, sizeof(sigbderlong)) == 0);
}
@ -169,13 +169,13 @@ void test_ecdsa_recovery_edge_cases(void) { @@ -169,13 +169,13 @@ void test_ecdsa_recovery_edge_cases(void) {
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder_zs, sizeof(sigcder_zs)) == 0);
/* Leading zeros. */
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt1, sizeof(sigbderalt1)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt2, sizeof(sigbderalt2)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt4, sizeof(sigbderalt4)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyb) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 1);
sigbderalt3[4] = 1;
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbderalt3, sizeof(sigbderalt3)) == 0);
sigbderalt4[7] = 1;
@ -183,7 +183,7 @@ void test_ecdsa_recovery_edge_cases(void) { @@ -183,7 +183,7 @@ void test_ecdsa_recovery_edge_cases(void) {
/* Damage signature. */
sigbder[7]++;
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyb) == 0);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
sigbder[7]--;
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, 6) == 0);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder) - 1) == 0);
@ -196,7 +196,7 @@ void test_ecdsa_recovery_edge_cases(void) { @@ -196,7 +196,7 @@ void test_ecdsa_recovery_edge_cases(void) {
continue;
}
sigbder[i] = c;
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyb) == 0);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigbder, sizeof(sigbder)) == 0 || secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyb) == 0);
}
sigbder[i] = orig;
}
@ -218,23 +218,23 @@ void test_ecdsa_recovery_edge_cases(void) { @@ -218,23 +218,23 @@ void test_ecdsa_recovery_edge_cases(void) {
};
secp256k1_pubkey_t pubkeyc;
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkeyc) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyc, &rsig, msg32) == 1);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyc) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 1);
sigcder[4] = 0;
sigc64[31] = 0;
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkeyb) == 0);
CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyc) == 0);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0);
sigcder[4] = 1;
sigcder[7] = 0;
sigc64[31] = 1;
sigc64[63] = 0;
CHECK(secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rsig, sigc64, 0) == 1);
CHECK(secp256k1_ecdsa_recover(ctx, msg32, &rsig, &pubkeyb) == 0);
CHECK(secp256k1_ecdsa_recover(ctx, &pubkeyb, &rsig, msg32) == 0);
CHECK(secp256k1_ecdsa_signature_parse_der(ctx, &sig, sigcder, sizeof(sigcder)) == 1);
CHECK(secp256k1_ecdsa_verify(ctx, msg32, &sig, &pubkeyc) == 0);
CHECK(secp256k1_ecdsa_verify(ctx, &sig, msg32, &pubkeyc) == 0);
}
}

16
src/modules/schnorr/main_impl.h

@ -19,7 +19,7 @@ static void secp256k1_schnorr_msghash_sha256(unsigned char *h32, const unsigned @@ -19,7 +19,7 @@ static void secp256k1_schnorr_msghash_sha256(unsigned char *h32, const unsigned
static const unsigned char secp256k1_schnorr_algo16[16] = "Schnorr+SHA256 ";
int secp256k1_schnorr_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
int secp256k1_schnorr_sign(const secp256k1_context_t* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
secp256k1_scalar_t sec, non;
int ret = 0;
int overflow = 0;
@ -36,7 +36,7 @@ int secp256k1_schnorr_sign(const secp256k1_context_t* ctx, const unsigned char * @@ -36,7 +36,7 @@ int secp256k1_schnorr_sign(const secp256k1_context_t* ctx, const unsigned char *
secp256k1_scalar_set_b32(&sec, seckey, NULL);
while (1) {
unsigned char nonce32[32];
ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, count, noncedata);
ret = noncefp(nonce32, msg32, seckey, secp256k1_schnorr_algo16, noncedata, count);
if (!ret) {
break;
}
@ -57,7 +57,7 @@ int secp256k1_schnorr_sign(const secp256k1_context_t* ctx, const unsigned char * @@ -57,7 +57,7 @@ int secp256k1_schnorr_sign(const secp256k1_context_t* ctx, const unsigned char *
return ret;
}
int secp256k1_schnorr_verify(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, const secp256k1_pubkey_t *pubkey) {
int secp256k1_schnorr_verify(const secp256k1_context_t* ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_pubkey_t *pubkey) {
secp256k1_ge_t q;
VERIFY_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
@ -69,7 +69,7 @@ int secp256k1_schnorr_verify(const secp256k1_context_t* ctx, const unsigned char @@ -69,7 +69,7 @@ int secp256k1_schnorr_verify(const secp256k1_context_t* ctx, const unsigned char
return secp256k1_schnorr_sig_verify(&ctx->ecmult_ctx, sig64, &q, secp256k1_schnorr_msghash_sha256, msg32);
}
int secp256k1_schnorr_recover(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, secp256k1_pubkey_t *pubkey) {
int secp256k1_schnorr_recover(const secp256k1_context_t* ctx, secp256k1_pubkey_t *pubkey, const unsigned char *sig64, const unsigned char *msg32) {
secp256k1_ge_t q;
VERIFY_CHECK(ctx != NULL);
@ -87,7 +87,7 @@ int secp256k1_schnorr_recover(const secp256k1_context_t* ctx, const unsigned cha @@ -87,7 +87,7 @@ int secp256k1_schnorr_recover(const secp256k1_context_t* ctx, const unsigned cha
}
}
int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sec32, secp256k1_nonce_function_t noncefp, const void* noncedata, secp256k1_pubkey_t *pubnonce, unsigned char *privnonce32) {
int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context_t* ctx, secp256k1_pubkey_t *pubnonce, unsigned char *privnonce32, const unsigned char *sec32, const unsigned char *msg32, secp256k1_nonce_function_t noncefp, const void* noncedata) {
int count = 0;
int ret = 1;
secp256k1_gej_t Qj;
@ -107,7 +107,7 @@ int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context_t* ctx, const @@ -107,7 +107,7 @@ int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context_t* ctx, const
do {
int overflow;
ret = noncefp(privnonce32, msg32, sec32, secp256k1_schnorr_algo16, count++, noncedata);
ret = noncefp(privnonce32, sec32, msg32, secp256k1_schnorr_algo16, noncedata, count++);
if (!ret) {
break;
}
@ -129,7 +129,7 @@ int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context_t* ctx, const @@ -129,7 +129,7 @@ int secp256k1_schnorr_generate_nonce_pair(const secp256k1_context_t* ctx, const
return ret;
}
int secp256k1_schnorr_partial_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *sig64, const unsigned char *sec32, const unsigned char *secnonce32, const secp256k1_pubkey_t *pubnonce_others) {
int secp256k1_schnorr_partial_sign(const secp256k1_context_t* ctx, unsigned char *sig64, const unsigned char *msg32, const unsigned char *sec32, const secp256k1_pubkey_t *pubnonce_others, const unsigned char *secnonce32) {
int overflow = 0;
secp256k1_scalar_t sec, non;
secp256k1_ge_t pubnon;
@ -153,7 +153,7 @@ int secp256k1_schnorr_partial_sign(const secp256k1_context_t* ctx, const unsigne @@ -153,7 +153,7 @@ int secp256k1_schnorr_partial_sign(const secp256k1_context_t* ctx, const unsigne
return secp256k1_schnorr_sig_sign(&ctx->ecmult_gen_ctx, sig64, &sec, &non, &pubnon, secp256k1_schnorr_msghash_sha256, msg32);
}
int secp256k1_schnorr_partial_combine(const secp256k1_context_t* ctx, unsigned char *sig64, int n, const unsigned char * const *sig64sin) {
int secp256k1_schnorr_partial_combine(const secp256k1_context_t* ctx, unsigned char *sig64, const unsigned char * const *sig64sin, int n) {
ARG_CHECK(sig64 != NULL);
ARG_CHECK(n >= 1);
ARG_CHECK(sig64sin != NULL);

22
src/modules/schnorr/tests_impl.h

@ -26,14 +26,14 @@ void test_schnorr_end_to_end(void) { @@ -26,14 +26,14 @@ void test_schnorr_end_to_end(void) {
CHECK(secp256k1_ec_pubkey_create(ctx, &pubkey, privkey) == 1);
/* Schnorr sign. */
CHECK(secp256k1_schnorr_sign(ctx, message, schnorr_signature, privkey, NULL, NULL) == 1);
CHECK(secp256k1_schnorr_verify(ctx, message, schnorr_signature, &pubkey) == 1);
CHECK(secp256k1_schnorr_recover(ctx, message, schnorr_signature, &recpubkey) == 1);
CHECK(secp256k1_schnorr_sign(ctx, schnorr_signature, message, privkey, NULL, NULL) == 1);
CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 1);
CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) == 1);
CHECK(memcmp(&pubkey, &recpubkey, sizeof(pubkey)) == 0);
/* Destroy signature and verify again. */
schnorr_signature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
CHECK(secp256k1_schnorr_verify(ctx, message, schnorr_signature, &pubkey) == 0);
CHECK(secp256k1_schnorr_recover(ctx, message, schnorr_signature, &recpubkey) != 1 ||
CHECK(secp256k1_schnorr_verify(ctx, schnorr_signature, message, &pubkey) == 0);
CHECK(secp256k1_schnorr_recover(ctx, &recpubkey, schnorr_signature, message) != 1 ||
memcmp(&pubkey, &recpubkey, sizeof(pubkey)) != 0);
}
@ -103,7 +103,7 @@ void test_schnorr_threshold(void) { @@ -103,7 +103,7 @@ void test_schnorr_threshold(void) {
secp256k1_rand256_test(sec[i]);
} while (!secp256k1_ec_seckey_verify(ctx, sec[i]));
CHECK(secp256k1_ec_pubkey_create(ctx, &pub[i], sec[i]));
CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, msg, sec[i], NULL, NULL, &pubnonce[i], nonce[i]));
CHECK(secp256k1_schnorr_generate_nonce_pair(ctx, &pubnonce[i], nonce[i], msg, sec[i], NULL, NULL));
pubs[i] = &pub[i];
}
if (damage == 1) {
@ -121,22 +121,22 @@ void test_schnorr_threshold(void) { @@ -121,22 +121,22 @@ void test_schnorr_threshold(void) {
for (j = i + 1; j < n; j++) {
pubnonces[j - 1] = &pubnonce[j];
}
CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, n - 1, pubnonces));
ret |= (secp256k1_schnorr_partial_sign(ctx, msg, sig[i], sec[i], nonce[i], &allpubnonce) != 1) * 1;
CHECK(secp256k1_ec_pubkey_combine(ctx, &allpubnonce, pubnonces, n - 1));
ret |= (secp256k1_schnorr_partial_sign(ctx, sig[i], msg, sec[i], &allpubnonce, nonce[i]) != 1) * 1;
sigs[i] = sig[i];
}
if (damage == 3) {
sig[secp256k1_rand32() % n][secp256k1_rand32() % 64] ^= 1 + (secp256k1_rand32() % 255);
}
ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, n, pubs) != 1) * 2;
ret |= (secp256k1_ec_pubkey_combine(ctx, &allpub, pubs, n) != 1) * 2;
if ((ret & 1) == 0) {
ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, n, sigs) != 1) * 4;
ret |= (secp256k1_schnorr_partial_combine(ctx, allsig, sigs, n) != 1) * 4;
}
if (damage == 4) {
allsig[secp256k1_rand32() % 32] ^= 1 + (secp256k1_rand32() % 255);
}
if ((ret & 7) == 0) {
ret |= (secp256k1_schnorr_verify(ctx, msg, allsig, &allpub) != 1) * 8;
ret |= (secp256k1_schnorr_verify(ctx, allsig, msg, &allpub) != 1) * 8;
}
CHECK((ret == 0) == (damage == 0));
}

12
src/secp256k1.c

@ -207,7 +207,7 @@ int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context_t* ctx, unsi @@ -207,7 +207,7 @@ int secp256k1_ecdsa_signature_serialize_der(const secp256k1_context_t* ctx, unsi
return secp256k1_ecdsa_sig_serialize(output, outputlen, &r, &s);
}
int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *msg32, const secp256k1_ecdsa_signature_t *sig, const secp256k1_pubkey_t *pubkey) {
int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const secp256k1_ecdsa_signature_t *sig, const unsigned char *msg32, const secp256k1_pubkey_t *pubkey) {
secp256k1_ge_t q;
secp256k1_scalar_t r, s;
secp256k1_scalar_t m;
@ -223,7 +223,7 @@ int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char * @@ -223,7 +223,7 @@ int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *
secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &r, &s, &q, &m));
}
static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, unsigned int counter, const void *data) {
static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *msg32, const unsigned char *key32, const unsigned char *algo16, const void *data, unsigned int counter) {
unsigned char keydata[112];
int keylen = 64;
secp256k1_rfc6979_hmac_sha256_t rng;
@ -257,7 +257,7 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m @@ -257,7 +257,7 @@ static int nonce_function_rfc6979(unsigned char *nonce32, const unsigned char *m
const secp256k1_nonce_function_t secp256k1_nonce_function_rfc6979 = nonce_function_rfc6979;
const secp256k1_nonce_function_t secp256k1_nonce_function_default = nonce_function_rfc6979;
int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, secp256k1_ecdsa_signature_t *signature, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, secp256k1_ecdsa_signature_t *signature, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
secp256k1_scalar_t r, s;
secp256k1_scalar_t sec, non, msg;
int ret = 0;
@ -278,7 +278,7 @@ int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *ms @@ -278,7 +278,7 @@ int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *ms
secp256k1_scalar_set_b32(&msg, msg32, NULL);
while (1) {
unsigned char nonce32[32];
ret = noncefp(nonce32, msg32, seckey, NULL, count, noncedata);
ret = noncefp(nonce32, msg32, seckey, NULL, noncedata, count);
if (!ret) {
break;
}
@ -431,7 +431,7 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, secp256k1_pubk @@ -431,7 +431,7 @@ int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, secp256k1_pubk
return ret;
}
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) {
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, unsigned char *privkey, int *privkeylen, const unsigned char *seckey, int compressed) {
secp256k1_scalar_t key;
int ret = 0;
VERIFY_CHECK(ctx != NULL);
@ -468,7 +468,7 @@ int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *s @@ -468,7 +468,7 @@ int secp256k1_context_randomize(secp256k1_context_t* ctx, const unsigned char *s
return 1;
}
int secp256k1_ec_pubkey_combine(const secp256k1_context_t* ctx, secp256k1_pubkey_t *pubnonce, int n, const secp256k1_pubkey_t * const *pubnonces) {
int secp256k1_ec_pubkey_combine(const secp256k1_context_t* ctx, secp256k1_pubkey_t *pubnonce, const secp256k1_pubkey_t * const *pubnonces, int n) {
int i;