mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 10:38:42 +01:00
Merge pull request #208
a9b6595
[API BREAK] Introduce explicit contexts (Pieter Wuille)
This commit is contained in:
commit
3608c7f2f6
@ -40,42 +40,52 @@ extern "C" {
|
||||
# define SECP256K1_ARG_NONNULL(_x)
|
||||
# endif
|
||||
|
||||
|
||||
/** Flags to pass to secp256k1_start. */
|
||||
# define SECP256K1_START_VERIFY (1 << 0)
|
||||
# define SECP256K1_START_SIGN (1 << 1)
|
||||
|
||||
/** Initialize the library. This may take some time (10-100 ms).
|
||||
* You need to call this before calling any other function.
|
||||
* It cannot run in parallel with any other functions, but once
|
||||
* secp256k1_start() returns, all other functions are thread-safe.
|
||||
/** Opaque data structure that holds context information (precomputed tables etc.).
|
||||
* Only functions that take a pointer to a non-const context require exclusive
|
||||
* access to it. Multiple functions that take a pointer to a const context may
|
||||
* run simultaneously.
|
||||
*/
|
||||
void secp256k1_start(unsigned int flags);
|
||||
typedef struct secp256k1_context_struct secp256k1_context_t;
|
||||
|
||||
/** Free all memory associated with this library. After this, no
|
||||
* functions can be called anymore, except secp256k1_start()
|
||||
/** Flags to pass to secp256k1_context_create. */
|
||||
# define SECP256K1_CONTEXT_VERIFY (1 << 0)
|
||||
# define SECP256K1_CONTEXT_SIGN (1 << 1)
|
||||
|
||||
/** Create a secp256k1 context object.
|
||||
* Returns: a newly created context object.
|
||||
* In: flags: which parts of the context to initialize.
|
||||
*/
|
||||
void secp256k1_stop(void);
|
||||
secp256k1_context_t* secp256k1_context_create(
|
||||
int flags
|
||||
) SECP256K1_WARN_UNUSED_RESULT;
|
||||
|
||||
/** Destroy a secp256k1 context object.
|
||||
* The context pointer may not be used afterwards.
|
||||
*/
|
||||
void secp256k1_context_destroy(
|
||||
secp256k1_context_t* ctx
|
||||
) SECP256K1_ARG_NONNULL(1);
|
||||
|
||||
/** Verify an ECDSA signature.
|
||||
* Returns: 1: correct signature
|
||||
* 0: incorrect signature
|
||||
* -1: invalid public key
|
||||
* -2: invalid signature
|
||||
* In: msg32: the 32-byte message hash being verified (cannot be NULL)
|
||||
* In: ctx: a secp256k1 context object, initialized for verification.
|
||||
* msg32: the 32-byte message hash being verified (cannot be NULL)
|
||||
* sig: the signature being verified (cannot be NULL)
|
||||
* siglen: the length of the signature
|
||||
* pubkey: the public key to verify with (cannot be NULL)
|
||||
* pubkeylen: the length of pubkey
|
||||
* Requires starting using SECP256K1_START_VERIFY.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *sig,
|
||||
int siglen,
|
||||
const unsigned char *pubkey,
|
||||
int pubkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** A pointer to a function to deterministically generate a nonce.
|
||||
* Returns: 1 if a nonce was successfully generated. 0 will cause signing to fail.
|
||||
@ -111,15 +121,14 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, the private key was invalid, or there is not
|
||||
* enough space in the signature (as indicated by siglen).
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* 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)
|
||||
* In/Out: siglen: pointer to an int with the length of sig, which will be updated
|
||||
* to contain the actual signature length (<=72). If 0 is returned, this will be
|
||||
* set to zero.
|
||||
* Requires starting using SECP256K1_START_SIGN.
|
||||
* to contain the actual signature length (<=72).
|
||||
*
|
||||
* The sig always has an s value in the lower half of the range (From 0x1
|
||||
* to 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
|
||||
@ -148,72 +157,85 @@ extern const secp256k1_nonce_function_t secp256k1_nonce_function_default;
|
||||
* be taken when this property is required for an application.
|
||||
*/
|
||||
int secp256k1_ecdsa_sign(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
unsigned char *sig,
|
||||
int *siglen,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function_t noncefp,
|
||||
const void *ndata
|
||||
) 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(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Create a compact ECDSA signature (64 byte + recovery id).
|
||||
* Returns: 1: signature created
|
||||
* 0: the nonce generation function failed, or the secret key was invalid.
|
||||
* In: msg32: the 32-byte message hash being signed (cannot be NULL)
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* 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 a 64-byte array where the signature will be placed (cannot be NULL)
|
||||
* In case 0 is returned, the returned signature length will be zero.
|
||||
* recid: pointer to an int, which will be updated to contain the recovery id (can be NULL)
|
||||
* Requires starting using SECP256K1_START_SIGN.
|
||||
*/
|
||||
int secp256k1_ecdsa_sign_compact(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
unsigned char *sig64,
|
||||
const unsigned char *seckey,
|
||||
secp256k1_nonce_function_t noncefp,
|
||||
const void *ndata,
|
||||
int *recid
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Recover an ECDSA public key from a compact signature.
|
||||
* Returns: 1: public key successfully recovered (which guarantees a correct signature).
|
||||
* 0: otherwise.
|
||||
* In: msg32: the 32-byte message hash assumed to be signed (cannot be NULL)
|
||||
* 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)
|
||||
* sig64: signature as 64 byte array (cannot be NULL)
|
||||
* compressed: whether to recover a compressed or uncompressed pubkey
|
||||
* recid: the recovery id (0-3, as returned by ecdsa_sign_compact)
|
||||
* Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey (cannot be NULL)
|
||||
* pubkeylen: pointer to an int that will contain the pubkey length (cannot be NULL)
|
||||
* Requires starting using SECP256K1_START_VERIFY.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *msg32,
|
||||
const unsigned char *sig64,
|
||||
unsigned char *pubkey,
|
||||
int *pubkeylen,
|
||||
int compressed,
|
||||
int recid
|
||||
) 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(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5);
|
||||
|
||||
/** Verify an ECDSA secret key.
|
||||
* Returns: 1: secret key is valid
|
||||
* 0: secret key is invalid
|
||||
* In: seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* seckey: pointer to a 32-byte secret key (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const unsigned char *seckey) SECP256K1_ARG_NONNULL(1);
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *seckey
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Verify an ECDSA public key.
|
||||
/** Just validate a public key.
|
||||
* Returns: 1: public key is valid
|
||||
* 0: public key is invalid
|
||||
* In: pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL).
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* pubkey: pointer to a 33-byte or 65-byte public key (cannot be NULL).
|
||||
* pubkeylen: length of pubkey
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) SECP256K1_ARG_NONNULL(1);
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *pubkey,
|
||||
int pubkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
|
||||
/** Compute the public key for a secret key.
|
||||
* In: compressed: whether the computed public key should be compressed
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
* compressed: whether the computed public key should be compressed
|
||||
* seckey: pointer to a 32-byte private key (cannot be NULL)
|
||||
* Out: pubkey: pointer to a 33-byte (if compressed) or 65-byte (if uncompressed)
|
||||
* area to store the public key (cannot be NULL)
|
||||
@ -221,16 +243,17 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_verify(const unsigned char
|
||||
* length (cannot be NULL)
|
||||
* Returns: 1: secret was valid, public key stores
|
||||
* 0: secret was invalid, try again
|
||||
* Requires starting using SECP256K1_START_SIGN.
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int *pubkeylen,
|
||||
const unsigned char *seckey,
|
||||
int compressed
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Decompress a public key.
|
||||
* In: ctx: pointer to a context object (cannot be NULL)
|
||||
* In/Out: pubkey: pointer to a 65-byte array to put the decompressed public key.
|
||||
* It must contain a 33-byte or 65-byte public key already (cannot be NULL)
|
||||
* pubkeylen: pointer to the size of the public key pointed to by pubkey (cannot be NULL)
|
||||
@ -239,54 +262,63 @@ SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(
|
||||
* 1: pubkey was valid, and was replaced with its decompressed version
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_decompress(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int *pubkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Export a private key in DER format. */
|
||||
/** Export a private key in DER format.
|
||||
* In: ctx: pointer to a context object, initialized for signing (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_export(
|
||||
const secp256k1_context_t* ctx,
|
||||
const unsigned char *seckey,
|
||||
unsigned char *privkey,
|
||||
int *privkeylen,
|
||||
int compressed
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Import a private key in DER format. */
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_import(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *privkey,
|
||||
int privkeylen
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a private key by adding tweak to it. */
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_add(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a public key by adding tweak times the generator to it.
|
||||
* Requires starting with SECP256K1_START_VERIFY.
|
||||
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int pubkeylen,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
/** Tweak a private key by multiplying it with tweak. */
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_privkey_tweak_mul(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *seckey,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3);
|
||||
|
||||
/** Tweak a public key by multiplying it with tweak.
|
||||
* Requires starting with SECP256K1_START_VERIFY.
|
||||
* In: ctx: pointer to a context object, initialized for verification (cannot be NULL)
|
||||
*/
|
||||
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(
|
||||
const secp256k1_context_t* ctx,
|
||||
unsigned char *pubkey,
|
||||
int pubkeylen,
|
||||
const unsigned char *tweak
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3);
|
||||
) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4);
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "bench.h"
|
||||
|
||||
typedef struct {
|
||||
secp256k1_context_t *ctx;
|
||||
unsigned char msg[32];
|
||||
unsigned char sig[64];
|
||||
} bench_recover_t;
|
||||
@ -21,7 +22,7 @@ void bench_recover(void* arg) {
|
||||
for (i = 0; i < 20000; i++) {
|
||||
int j;
|
||||
int pubkeylen = 33;
|
||||
CHECK(secp256k1_ecdsa_recover_compact(data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2));
|
||||
CHECK(secp256k1_ecdsa_recover_compact(data->ctx, data->msg, data->sig, pubkey, &pubkeylen, 1, i % 2));
|
||||
for (j = 0; j < 32; j++) {
|
||||
data->sig[j + 32] = data->msg[j]; /* Move former message to S. */
|
||||
data->msg[j] = data->sig[j]; /* Move former R to message. */
|
||||
@ -40,10 +41,11 @@ void bench_recover_setup(void* arg) {
|
||||
|
||||
int main(void) {
|
||||
bench_recover_t data;
|
||||
secp256k1_start(SECP256K1_START_VERIFY);
|
||||
|
||||
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
|
||||
run_benchmark("ecdsa_recover", bench_recover, bench_recover_setup, NULL, &data, 10, 20000);
|
||||
|
||||
secp256k1_stop();
|
||||
secp256k1_context_destroy(data.ctx);
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "bench.h"
|
||||
|
||||
typedef struct {
|
||||
secp256k1_context_t* ctx;
|
||||
unsigned char msg[32];
|
||||
unsigned char key[32];
|
||||
} bench_sign_t;
|
||||
@ -29,7 +30,7 @@ static void bench_sign(void* arg) {
|
||||
for (i = 0; i < 20000; i++) {
|
||||
int j;
|
||||
int recid = 0;
|
||||
CHECK(secp256k1_ecdsa_sign_compact(data->msg, sig, data->key, NULL, NULL, &recid));
|
||||
CHECK(secp256k1_ecdsa_sign_compact(data->ctx, data->msg, sig, data->key, NULL, NULL, &recid));
|
||||
for (j = 0; j < 32; j++) {
|
||||
data->msg[j] = sig[j]; /* Move former R to message. */
|
||||
data->key[j] = sig[j + 32]; /* Move former S to key. */
|
||||
@ -39,10 +40,11 @@ static void bench_sign(void* arg) {
|
||||
|
||||
int main(void) {
|
||||
bench_sign_t data;
|
||||
secp256k1_start(SECP256K1_START_SIGN);
|
||||
|
||||
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
|
||||
|
||||
run_benchmark("ecdsa_sign", bench_sign, bench_sign_setup, NULL, &data, 10, 20000);
|
||||
|
||||
secp256k1_stop();
|
||||
secp256k1_context_destroy(data.ctx);
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "bench.h"
|
||||
|
||||
typedef struct {
|
||||
secp256k1_context_t *ctx;
|
||||
unsigned char msg[32];
|
||||
unsigned char key[32];
|
||||
unsigned char sig[72];
|
||||
@ -28,7 +29,7 @@ static void benchmark_verify(void* arg) {
|
||||
data->sig[data->siglen - 1] ^= (i & 0xFF);
|
||||
data->sig[data->siglen - 2] ^= ((i >> 8) & 0xFF);
|
||||
data->sig[data->siglen - 3] ^= ((i >> 16) & 0xFF);
|
||||
CHECK(secp256k1_ecdsa_verify(data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (i == 0));
|
||||
CHECK(secp256k1_ecdsa_verify(data->ctx, data->msg, data->sig, data->siglen, data->pubkey, data->pubkeylen) == (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);
|
||||
@ -39,17 +40,17 @@ int main(void) {
|
||||
int i;
|
||||
benchmark_verify_t data;
|
||||
|
||||
secp256k1_start(SECP256K1_START_VERIFY | SECP256K1_START_SIGN);
|
||||
data.ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
|
||||
|
||||
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;
|
||||
secp256k1_ecdsa_sign(data.msg, data.sig, &data.siglen, data.key, NULL, NULL);
|
||||
secp256k1_ecdsa_sign(data.ctx, data.msg, data.sig, &data.siglen, data.key, NULL, NULL);
|
||||
data.pubkeylen = 33;
|
||||
CHECK(secp256k1_ec_pubkey_create(data.pubkey, &data.pubkeylen, data.key, 1));
|
||||
CHECK(secp256k1_ec_pubkey_create(data.ctx, data.pubkey, &data.pubkeylen, data.key, 1));
|
||||
|
||||
run_benchmark("ecdsa_verify", benchmark_verify, NULL, NULL, &data, 10, 20000);
|
||||
|
||||
secp256k1_stop();
|
||||
secp256k1_context_destroy(data.ctx);
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "scalar.h"
|
||||
#include "group.h"
|
||||
#include "ecmult.h"
|
||||
|
||||
typedef struct {
|
||||
secp256k1_scalar_t r, s;
|
||||
@ -16,8 +17,8 @@ typedef struct {
|
||||
|
||||
static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size);
|
||||
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a);
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
|
||||
static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid);
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
|
||||
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid);
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
|
||||
|
||||
#endif
|
||||
|
@ -132,7 +132,7 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
|
||||
unsigned char c[32];
|
||||
secp256k1_scalar_t sn, u1, u2;
|
||||
secp256k1_fe_t xr;
|
||||
@ -147,7 +147,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const se
|
||||
secp256k1_scalar_mul(&u1, &sn, message);
|
||||
secp256k1_scalar_mul(&u2, &sn, &sig->r);
|
||||
secp256k1_gej_set_ge(&pubkeyj, pubkey);
|
||||
secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
|
||||
secp256k1_ecmult(ctx, &pr, &pubkeyj, &u2, &u1);
|
||||
if (secp256k1_gej_is_infinity(&pr)) {
|
||||
return 0;
|
||||
}
|
||||
@ -186,7 +186,7 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const se
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecmult_context_t *ctx, const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
|
||||
unsigned char brx[32];
|
||||
secp256k1_fe_t fx;
|
||||
secp256k1_ge_t x;
|
||||
@ -214,19 +214,19 @@ static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256
|
||||
secp256k1_scalar_mul(&u1, &rn, message);
|
||||
secp256k1_scalar_negate(&u1, &u1);
|
||||
secp256k1_scalar_mul(&u2, &rn, &sig->s);
|
||||
secp256k1_ecmult(&qj, &xj, &u2, &u1);
|
||||
secp256k1_ecmult(ctx, &qj, &xj, &u2, &u1);
|
||||
secp256k1_ge_set_gej_var(pubkey, &qj);
|
||||
return !secp256k1_gej_is_infinity(&qj);
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
|
||||
static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
|
||||
unsigned char b[32];
|
||||
secp256k1_gej_t rp;
|
||||
secp256k1_ge_t r;
|
||||
secp256k1_scalar_t n;
|
||||
int overflow = 0;
|
||||
|
||||
secp256k1_ecmult_gen(&rp, nonce);
|
||||
secp256k1_ecmult_gen(ctx, &rp, nonce);
|
||||
secp256k1_ge_set_gej(&r, &rp);
|
||||
secp256k1_fe_normalize(&r.x);
|
||||
secp256k1_fe_normalize(&r.y);
|
||||
|
@ -9,16 +9,18 @@
|
||||
|
||||
#include "group.h"
|
||||
#include "scalar.h"
|
||||
#include "ecmult.h"
|
||||
#include "ecmult_gen.h"
|
||||
|
||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size);
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed);
|
||||
|
||||
static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen);
|
||||
static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed);
|
||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed);
|
||||
|
||||
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||
|
||||
#endif
|
||||
|
@ -94,11 +94,11 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned
|
||||
return !overflow;
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) {
|
||||
static int secp256k1_eckey_privkey_serialize(const secp256k1_ecmult_gen_context_t *ctx, unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) {
|
||||
secp256k1_gej_t rp;
|
||||
secp256k1_ge_t r;
|
||||
int pubkeylen = 0;
|
||||
secp256k1_ecmult_gen(&rp, key);
|
||||
secp256k1_ecmult_gen(ctx, &rp, key);
|
||||
secp256k1_ge_set_gej(&r, &rp);
|
||||
if (compressed) {
|
||||
static const unsigned char begin[] = {
|
||||
@ -162,12 +162,12 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
|
||||
static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
|
||||
secp256k1_gej_t pt;
|
||||
secp256k1_scalar_t one;
|
||||
secp256k1_gej_set_ge(&pt, key);
|
||||
secp256k1_scalar_set_int(&one, 1);
|
||||
secp256k1_ecmult(&pt, &pt, &one, tweak);
|
||||
secp256k1_ecmult(ctx, &pt, &pt, &one, tweak);
|
||||
|
||||
if (secp256k1_gej_is_infinity(&pt)) {
|
||||
return 0;
|
||||
@ -185,7 +185,7 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context_t *ctx, secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
|
||||
secp256k1_scalar_t zero;
|
||||
secp256k1_gej_t pt;
|
||||
if (secp256k1_scalar_is_zero(tweak)) {
|
||||
@ -194,7 +194,7 @@ static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1
|
||||
|
||||
secp256k1_scalar_set_int(&zero, 0);
|
||||
secp256k1_gej_set_ge(&pt, key);
|
||||
secp256k1_ecmult(&pt, &pt, tweak, &zero);
|
||||
secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero);
|
||||
secp256k1_ge_set_gej(key, &pt);
|
||||
return 1;
|
||||
}
|
||||
|
16
src/ecmult.h
16
src/ecmult.h
@ -10,10 +10,20 @@
|
||||
#include "num.h"
|
||||
#include "group.h"
|
||||
|
||||
static void secp256k1_ecmult_start(void);
|
||||
static void secp256k1_ecmult_stop(void);
|
||||
typedef struct {
|
||||
/* For accelerating the computation of a*P + b*G: */
|
||||
secp256k1_ge_storage_t (*pre_g)[]; /* odd multiples of the generator */
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_ge_storage_t (*pre_g_128)[]; /* odd multiples of 2^128*generator */
|
||||
#endif
|
||||
} secp256k1_ecmult_context_t;
|
||||
|
||||
static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx);
|
||||
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx);
|
||||
static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx);
|
||||
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx);
|
||||
|
||||
/** Double multiply: R = na*A + ng*G */
|
||||
static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng);
|
||||
static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng);
|
||||
|
||||
#endif
|
||||
|
@ -10,10 +10,28 @@
|
||||
#include "scalar.h"
|
||||
#include "group.h"
|
||||
|
||||
static void secp256k1_ecmult_gen_start(void);
|
||||
static void secp256k1_ecmult_gen_stop(void);
|
||||
typedef struct {
|
||||
/* For accelerating the computation of a*G:
|
||||
* To harden against timing attacks, use the following mechanism:
|
||||
* * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63.
|
||||
* * Compute sum(n_i * 16^i * G + U_i, i=0..63), where:
|
||||
* * U_i = U * 2^i (for i=0..62)
|
||||
* * U_i = U * (1-2^63) (for i=63)
|
||||
* where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0.
|
||||
* For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is
|
||||
* precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63).
|
||||
* None of the resulting prec group elements have a known scalar, and neither do any of
|
||||
* the intermediate sums while computing a*G.
|
||||
*/
|
||||
secp256k1_ge_storage_t (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */
|
||||
} secp256k1_ecmult_gen_context_t;
|
||||
|
||||
static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t* ctx);
|
||||
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t* ctx);
|
||||
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t* ctx);
|
||||
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx);
|
||||
|
||||
/** Multiply with the generator: R = a*G */
|
||||
static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *a);
|
||||
static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t* ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *a);
|
||||
|
||||
#endif
|
||||
|
@ -11,36 +11,21 @@
|
||||
#include "group.h"
|
||||
#include "ecmult_gen.h"
|
||||
|
||||
typedef struct {
|
||||
/* For accelerating the computation of a*G:
|
||||
* To harden against timing attacks, use the following mechanism:
|
||||
* * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63.
|
||||
* * Compute sum(n_i * 16^i * G + U_i, i=0..63), where:
|
||||
* * U_i = U * 2^i (for i=0..62)
|
||||
* * U_i = U * (1-2^63) (for i=63)
|
||||
* where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0.
|
||||
* For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is
|
||||
* precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63).
|
||||
* None of the resulting prec group elements have a known scalar, and neither do any of
|
||||
* the intermediate sums while computing a*G.
|
||||
*/
|
||||
secp256k1_ge_storage_t prec[64][16]; /* prec[j][i] = 16^j * i * G + U_i */
|
||||
} secp256k1_ecmult_gen_consts_t;
|
||||
static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context_t *ctx) {
|
||||
ctx->prec = NULL;
|
||||
}
|
||||
|
||||
static const secp256k1_ecmult_gen_consts_t *secp256k1_ecmult_gen_consts = NULL;
|
||||
|
||||
static void secp256k1_ecmult_gen_start(void) {
|
||||
static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context_t *ctx) {
|
||||
secp256k1_ge_t prec[1024];
|
||||
secp256k1_gej_t gj;
|
||||
secp256k1_gej_t nums_gej;
|
||||
secp256k1_ecmult_gen_consts_t *ret;
|
||||
int i, j;
|
||||
if (secp256k1_ecmult_gen_consts != NULL) {
|
||||
|
||||
if (ctx->prec != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate the precomputation table. */
|
||||
ret = (secp256k1_ecmult_gen_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_gen_consts_t));
|
||||
ctx->prec = (secp256k1_ge_storage_t (*)[64][16])checked_malloc(sizeof(*ctx->prec));
|
||||
|
||||
/* get the generator */
|
||||
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
|
||||
@ -86,27 +71,21 @@ static void secp256k1_ecmult_gen_start(void) {
|
||||
}
|
||||
for (j = 0; j < 64; j++) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
secp256k1_ge_to_storage(&ret->prec[j][i], &prec[j*16 + i]);
|
||||
secp256k1_ge_to_storage(&(*ctx->prec)[j][i], &prec[j*16 + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the global pointer to the precomputation table. */
|
||||
secp256k1_ecmult_gen_consts = ret;
|
||||
static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context_t* ctx) {
|
||||
return ctx->prec != NULL;
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_gen_stop(void) {
|
||||
secp256k1_ecmult_gen_consts_t *c;
|
||||
if (secp256k1_ecmult_gen_consts == NULL) {
|
||||
return;
|
||||
static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context_t *ctx) {
|
||||
free(ctx->prec);
|
||||
ctx->prec = NULL;
|
||||
}
|
||||
|
||||
c = (secp256k1_ecmult_gen_consts_t*)secp256k1_ecmult_gen_consts;
|
||||
secp256k1_ecmult_gen_consts = NULL;
|
||||
free(c);
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *gn) {
|
||||
const secp256k1_ecmult_gen_consts_t *c = secp256k1_ecmult_gen_consts;
|
||||
static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context_t *ctx, secp256k1_gej_t *r, const secp256k1_scalar_t *gn) {
|
||||
secp256k1_ge_t add;
|
||||
secp256k1_ge_storage_t adds;
|
||||
int bits;
|
||||
@ -127,7 +106,7 @@ static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *g
|
||||
* by Dag Arne Osvik, Adi Shamir, and Eran Tromer
|
||||
* (http://www.tau.ac.il/~tromer/papers/cache.pdf)
|
||||
*/
|
||||
secp256k1_ge_storage_cmov(&adds, &c->prec[j][i], i == bits);
|
||||
secp256k1_ge_storage_cmov(&adds, &(*ctx->prec)[j][i], i == bits);
|
||||
}
|
||||
secp256k1_ge_from_storage(&add, &adds);
|
||||
secp256k1_gej_add_ge(r, r, &add);
|
||||
|
@ -92,59 +92,55 @@ static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
typedef struct {
|
||||
/* For accelerating the computation of a*P + b*G: */
|
||||
secp256k1_ge_storage_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */
|
||||
static void secp256k1_ecmult_context_init(secp256k1_ecmult_context_t *ctx) {
|
||||
ctx->pre_g = NULL;
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_ge_storage_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */
|
||||
ctx->pre_g_128 = NULL;
|
||||
#endif
|
||||
} secp256k1_ecmult_consts_t;
|
||||
|
||||
static const secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL;
|
||||
|
||||
static void secp256k1_ecmult_start(void) {
|
||||
secp256k1_gej_t gj;
|
||||
secp256k1_ecmult_consts_t *ret;
|
||||
if (secp256k1_ecmult_consts != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate the precomputation table. */
|
||||
ret = (secp256k1_ecmult_consts_t*)checked_malloc(sizeof(secp256k1_ecmult_consts_t));
|
||||
static void secp256k1_ecmult_context_build(secp256k1_ecmult_context_t *ctx) {
|
||||
secp256k1_gej_t gj;
|
||||
|
||||
if (ctx->pre_g != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* get the generator */
|
||||
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g);
|
||||
|
||||
ctx->pre_g = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
|
||||
|
||||
/* precompute the tables with odd multiples */
|
||||
secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g, &gj, WINDOW_G);
|
||||
secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g, &gj, WINDOW_G);
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
{
|
||||
secp256k1_gej_t g_128j;
|
||||
int i;
|
||||
|
||||
ctx->pre_g_128 = (secp256k1_ge_storage_t (*)[])checked_malloc(sizeof((*ctx->pre_g_128)[0]) * ECMULT_TABLE_SIZE(WINDOW_G));
|
||||
|
||||
/* calculate 2^128*generator */
|
||||
g_128j = gj;
|
||||
for (i = 0; i < 128; i++) {
|
||||
secp256k1_gej_double_var(&g_128j, &g_128j);
|
||||
}
|
||||
secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g_128, &g_128j, WINDOW_G);
|
||||
secp256k1_ecmult_table_precomp_ge_storage_var(*ctx->pre_g_128, &g_128j, WINDOW_G);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the global pointer to the precomputation table. */
|
||||
secp256k1_ecmult_consts = ret;
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_stop(void) {
|
||||
secp256k1_ecmult_consts_t *c;
|
||||
if (secp256k1_ecmult_consts == NULL) {
|
||||
return;
|
||||
static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context_t *ctx) {
|
||||
return ctx->pre_g != NULL;
|
||||
}
|
||||
|
||||
c = (secp256k1_ecmult_consts_t*)secp256k1_ecmult_consts;
|
||||
secp256k1_ecmult_consts = NULL;
|
||||
free(c);
|
||||
static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context_t *ctx) {
|
||||
free(ctx->pre_g);
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
free(ctx->pre_g_128);
|
||||
#endif
|
||||
secp256k1_ecmult_context_init(ctx);
|
||||
}
|
||||
|
||||
/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits),
|
||||
@ -191,11 +187,10 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w)
|
||||
return set_bits;
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) {
|
||||
static void secp256k1_ecmult(const secp256k1_ecmult_context_t *ctx, secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) {
|
||||
secp256k1_gej_t tmpj;
|
||||
secp256k1_gej_t pre_a[ECMULT_TABLE_SIZE(WINDOW_A)];
|
||||
secp256k1_ge_t tmpa;
|
||||
const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_gej_t pre_a_lam[ECMULT_TABLE_SIZE(WINDOW_A)];
|
||||
secp256k1_scalar_t na_1, na_lam;
|
||||
@ -279,11 +274,11 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
|
||||
secp256k1_gej_add_var(r, r, &tmpj);
|
||||
}
|
||||
if (i < bits_ng_1 && (n = wnaf_ng_1[i])) {
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G);
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G);
|
||||
secp256k1_gej_add_ge_var(r, r, &tmpa);
|
||||
}
|
||||
if (i < bits_ng_128 && (n = wnaf_ng_128[i])) {
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g_128, n, WINDOW_G);
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g_128, n, WINDOW_G);
|
||||
secp256k1_gej_add_ge_var(r, r, &tmpa);
|
||||
}
|
||||
#else
|
||||
@ -292,7 +287,7 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
|
||||
secp256k1_gej_add_var(r, r, &tmpj);
|
||||
}
|
||||
if (i < bits_ng && (n = wnaf_ng[i])) {
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G);
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, *ctx->pre_g, n, WINDOW_G);
|
||||
secp256k1_gej_add_ge_var(r, r, &tmpa);
|
||||
}
|
||||
#endif
|
||||
|
106
src/secp256k1.c
106
src/secp256k1.c
@ -1,5 +1,5 @@
|
||||
/**********************************************************************
|
||||
* Copyright (c) 2013, 2014 Pieter Wuille *
|
||||
* Copyright (c) 2013-2015 Pieter Wuille *
|
||||
* Distributed under the MIT software license, see the accompanying *
|
||||
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
|
||||
**********************************************************************/
|
||||
@ -19,26 +19,39 @@
|
||||
#include "eckey_impl.h"
|
||||
#include "hash_impl.h"
|
||||
|
||||
void secp256k1_start(unsigned int flags) {
|
||||
if (flags & SECP256K1_START_SIGN) {
|
||||
secp256k1_ecmult_gen_start();
|
||||
}
|
||||
if (flags & SECP256K1_START_VERIFY) {
|
||||
secp256k1_ecmult_start();
|
||||
struct secp256k1_context_struct {
|
||||
secp256k1_ecmult_context_t ecmult_ctx;
|
||||
secp256k1_ecmult_gen_context_t ecmult_gen_ctx;
|
||||
};
|
||||
|
||||
secp256k1_context_t* secp256k1_context_create(int flags) {
|
||||
secp256k1_context_t* ret = (secp256k1_context_t*)checked_malloc(sizeof(secp256k1_context_t));
|
||||
|
||||
secp256k1_ecmult_context_init(&ret->ecmult_ctx);
|
||||
secp256k1_ecmult_gen_context_init(&ret->ecmult_gen_ctx);
|
||||
|
||||
if (flags & SECP256K1_CONTEXT_SIGN) {
|
||||
secp256k1_ecmult_gen_context_build(&ret->ecmult_gen_ctx);
|
||||
}
|
||||
if (flags & SECP256K1_CONTEXT_VERIFY) {
|
||||
secp256k1_ecmult_context_build(&ret->ecmult_ctx);
|
||||
}
|
||||
|
||||
void secp256k1_stop(void) {
|
||||
secp256k1_ecmult_stop();
|
||||
secp256k1_ecmult_gen_stop();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
|
||||
void secp256k1_context_destroy(secp256k1_context_t* ctx) {
|
||||
secp256k1_ecmult_context_clear(&ctx->ecmult_ctx);
|
||||
secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx);
|
||||
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_verify(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
|
||||
secp256k1_ge_t q;
|
||||
secp256k1_ecdsa_sig_t s;
|
||||
secp256k1_scalar_t m;
|
||||
int ret = -3;
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(msg32 != NULL);
|
||||
DEBUG_CHECK(sig != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
@ -47,7 +60,7 @@ int secp256k1_ecdsa_verify(const unsigned char *msg32, const unsigned char *sig,
|
||||
|
||||
if (secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) {
|
||||
if (secp256k1_ecdsa_sig_parse(&s, sig, siglen)) {
|
||||
if (secp256k1_ecdsa_sig_verify(&s, &q, &m)) {
|
||||
if (secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &s, &q, &m)) {
|
||||
/* success is 1, all other values are fail */
|
||||
ret = 1;
|
||||
} else {
|
||||
@ -77,13 +90,14 @@ 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 unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
|
||||
int secp256k1_ecdsa_sign(const secp256k1_context_t* ctx, const unsigned char *msg32, unsigned char *signature, int *signaturelen, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata) {
|
||||
secp256k1_ecdsa_sig_t sig;
|
||||
secp256k1_scalar_t sec, non, msg;
|
||||
int ret = 0;
|
||||
int overflow = 0;
|
||||
unsigned int count = 0;
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
||||
DEBUG_CHECK(msg32 != NULL);
|
||||
DEBUG_CHECK(signature != NULL);
|
||||
DEBUG_CHECK(signaturelen != NULL);
|
||||
@ -105,7 +119,7 @@ int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, i
|
||||
secp256k1_scalar_set_b32(&non, nonce32, &overflow);
|
||||
memset(nonce32, 0, 32);
|
||||
if (!secp256k1_scalar_is_zero(&non) && !overflow) {
|
||||
if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, NULL)) {
|
||||
if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, NULL)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -124,13 +138,14 @@ int secp256k1_ecdsa_sign(const unsigned char *msg32, unsigned char *signature, i
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig64, const unsigned char *seckey, secp256k1_nonce_function_t noncefp, const void* noncedata, int *recid) {
|
||||
int secp256k1_ecdsa_sign_compact(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 *recid) {
|
||||
secp256k1_ecdsa_sig_t sig;
|
||||
secp256k1_scalar_t sec, non, msg;
|
||||
int ret = 0;
|
||||
int overflow = 0;
|
||||
unsigned int count = 0;
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
||||
DEBUG_CHECK(msg32 != NULL);
|
||||
DEBUG_CHECK(sig64 != NULL);
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
@ -151,7 +166,7 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig6
|
||||
secp256k1_scalar_set_b32(&non, nonce32, &overflow);
|
||||
memset(nonce32, 0, 32);
|
||||
if (!secp256k1_scalar_is_zero(&non) && !overflow) {
|
||||
if (secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid)) {
|
||||
if (secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, &sig, &sec, &msg, &non, recid)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -171,13 +186,14 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *msg32, unsigned char *sig6
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) {
|
||||
int secp256k1_ecdsa_recover_compact(const secp256k1_context_t* ctx, const unsigned char *msg32, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) {
|
||||
secp256k1_ge_t q;
|
||||
secp256k1_ecdsa_sig_t sig;
|
||||
secp256k1_scalar_t m;
|
||||
int ret = 0;
|
||||
int overflow = 0;
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
|
||||
DEBUG_CHECK(msg32 != NULL);
|
||||
DEBUG_CHECK(sig64 != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
@ -190,7 +206,7 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned c
|
||||
if (!overflow) {
|
||||
secp256k1_scalar_set_b32(&m, msg32, NULL);
|
||||
|
||||
if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) {
|
||||
if (secp256k1_ecdsa_sig_recover(&ctx->ecmult_ctx, &sig, &q, &m, recid)) {
|
||||
ret = secp256k1_eckey_pubkey_serialize(&q, pubkey, pubkeylen, compressed);
|
||||
}
|
||||
}
|
||||
@ -198,11 +214,13 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg32, const unsigned c
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_seckey_verify(const unsigned char *seckey) {
|
||||
int secp256k1_ec_seckey_verify(const secp256k1_context_t* ctx, const unsigned char *seckey) {
|
||||
secp256k1_scalar_t sec;
|
||||
int ret;
|
||||
int overflow;
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
(void)ctx;
|
||||
|
||||
secp256k1_scalar_set_b32(&sec, seckey, &overflow);
|
||||
ret = !secp256k1_scalar_is_zero(&sec) && !overflow;
|
||||
@ -210,27 +228,28 @@ int secp256k1_ec_seckey_verify(const unsigned char *seckey) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_pubkey_verify(const unsigned char *pubkey, int pubkeylen) {
|
||||
int secp256k1_ec_pubkey_verify(const secp256k1_context_t* ctx, const unsigned char *pubkey, int pubkeylen) {
|
||||
secp256k1_ge_t q;
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
(void)ctx;
|
||||
|
||||
return secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen);
|
||||
}
|
||||
|
||||
int secp256k1_ec_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) {
|
||||
int secp256k1_ec_pubkey_create(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) {
|
||||
secp256k1_gej_t pj;
|
||||
secp256k1_ge_t p;
|
||||
secp256k1_scalar_t sec;
|
||||
int overflow;
|
||||
int ret = 0;
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(pubkeylen != NULL);
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
|
||||
secp256k1_scalar_set_b32(&sec, seckey, &overflow);
|
||||
if (!overflow) {
|
||||
secp256k1_ecmult_gen(&pj, &sec);
|
||||
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pj, &sec);
|
||||
secp256k1_scalar_clear(&sec);
|
||||
secp256k1_ge_set_gej(&p, &pj);
|
||||
ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed);
|
||||
@ -241,11 +260,12 @@ int secp256k1_ec_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsi
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) {
|
||||
int secp256k1_ec_pubkey_decompress(const secp256k1_context_t* ctx, unsigned char *pubkey, int *pubkeylen) {
|
||||
secp256k1_ge_t p;
|
||||
int ret = 0;
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(pubkeylen != NULL);
|
||||
(void)ctx;
|
||||
|
||||
if (secp256k1_eckey_pubkey_parse(&p, pubkey, *pubkeylen)) {
|
||||
ret = secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, 0);
|
||||
@ -253,13 +273,15 @@ int secp256k1_ec_pubkey_decompress(unsigned char *pubkey, int *pubkeylen) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *tweak) {
|
||||
int secp256k1_ec_privkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) {
|
||||
secp256k1_scalar_t term;
|
||||
secp256k1_scalar_t sec;
|
||||
int ret = 0;
|
||||
int overflow = 0;
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
(void)ctx;
|
||||
|
||||
secp256k1_scalar_set_b32(&term, tweak, &overflow);
|
||||
secp256k1_scalar_set_b32(&sec, seckey, NULL);
|
||||
@ -274,12 +296,13 @@ int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *t
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
|
||||
int secp256k1_ec_pubkey_tweak_add(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
|
||||
secp256k1_ge_t p;
|
||||
secp256k1_scalar_t term;
|
||||
int ret = 0;
|
||||
int overflow = 0;
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
|
||||
@ -287,7 +310,7 @@ int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const un
|
||||
if (!overflow) {
|
||||
ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
|
||||
if (ret) {
|
||||
ret = secp256k1_eckey_pubkey_tweak_add(&p, &term);
|
||||
ret = secp256k1_eckey_pubkey_tweak_add(&ctx->ecmult_ctx, &p, &term);
|
||||
}
|
||||
if (ret) {
|
||||
int oldlen = pubkeylen;
|
||||
@ -299,13 +322,15 @@ int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const un
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *tweak) {
|
||||
int secp256k1_ec_privkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *tweak) {
|
||||
secp256k1_scalar_t factor;
|
||||
secp256k1_scalar_t sec;
|
||||
int ret = 0;
|
||||
int overflow = 0;
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
(void)ctx;
|
||||
|
||||
secp256k1_scalar_set_b32(&factor, tweak, &overflow);
|
||||
secp256k1_scalar_set_b32(&sec, seckey, NULL);
|
||||
@ -319,12 +344,13 @@ int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *t
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
|
||||
int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context_t* ctx, unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
|
||||
secp256k1_ge_t p;
|
||||
secp256k1_scalar_t factor;
|
||||
int ret = 0;
|
||||
int overflow = 0;
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(ctx != NULL);
|
||||
DEBUG_CHECK(secp256k1_ecmult_context_is_built(&ctx->ecmult_ctx));
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
|
||||
@ -332,7 +358,7 @@ int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const un
|
||||
if (!overflow) {
|
||||
ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
|
||||
if (ret) {
|
||||
ret = secp256k1_eckey_pubkey_tweak_mul(&p, &factor);
|
||||
ret = secp256k1_eckey_pubkey_tweak_mul(&ctx->ecmult_ctx, &p, &factor);
|
||||
}
|
||||
if (ret) {
|
||||
int oldlen = pubkeylen;
|
||||
@ -344,24 +370,26 @@ int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const un
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_privkey_export(const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) {
|
||||
int secp256k1_ec_privkey_export(const secp256k1_context_t* ctx, const unsigned char *seckey, unsigned char *privkey, int *privkeylen, int compressed) {
|
||||
secp256k1_scalar_t key;
|
||||
int ret = 0;
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
DEBUG_CHECK(privkey != NULL);
|
||||
DEBUG_CHECK(privkeylen != NULL);
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_context_is_built(&ctx->ecmult_gen_ctx));
|
||||
|
||||
secp256k1_scalar_set_b32(&key, seckey, NULL);
|
||||
ret = secp256k1_eckey_privkey_serialize(privkey, privkeylen, &key, compressed);
|
||||
ret = secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, privkeylen, &key, compressed);
|
||||
secp256k1_scalar_clear(&key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int secp256k1_ec_privkey_import(unsigned char *seckey, const unsigned char *privkey, int privkeylen) {
|
||||
int secp256k1_ec_privkey_import(const secp256k1_context_t* ctx, unsigned char *seckey, const unsigned char *privkey, int privkeylen) {
|
||||
secp256k1_scalar_t key;
|
||||
int ret = 0;
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
DEBUG_CHECK(privkey != NULL);
|
||||
(void)ctx;
|
||||
|
||||
ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen);
|
||||
if (ret) {
|
||||
|
181
src/tests.c
181
src/tests.c
@ -24,6 +24,7 @@
|
||||
#endif
|
||||
|
||||
static int count = 64;
|
||||
static secp256k1_context_t *ctx = NULL;
|
||||
|
||||
void random_field_element_test(secp256k1_fe_t *fe) {
|
||||
do {
|
||||
@ -1035,7 +1036,7 @@ void run_ecmult_chain(void) {
|
||||
x = a;
|
||||
for (i = 0; i < 200*count; i++) {
|
||||
/* in each iteration, compute X = xn*X + gn*G; */
|
||||
secp256k1_ecmult(&x, &x, &xn, &gn);
|
||||
secp256k1_ecmult(&ctx->ecmult_ctx, &x, &x, &xn, &gn);
|
||||
/* also compute ae and ge: the actual accumulated factors for A and G */
|
||||
/* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
|
||||
secp256k1_scalar_mul(&ae, &ae, &xn);
|
||||
@ -1061,7 +1062,7 @@ void run_ecmult_chain(void) {
|
||||
}
|
||||
}
|
||||
/* redo the computation, but directly with the resulting ae and ge coefficients: */
|
||||
secp256k1_ecmult(&x2, &a, &ae, &ge);
|
||||
secp256k1_ecmult(&ctx->ecmult_ctx, &x2, &a, &ae, &ge);
|
||||
secp256k1_gej_neg(&x2, &x2);
|
||||
secp256k1_gej_add_var(&x2, &x2, &x);
|
||||
CHECK(secp256k1_gej_is_infinity(&x2));
|
||||
@ -1077,8 +1078,8 @@ void test_point_times_order(const secp256k1_gej_t *point) {
|
||||
int psize = 65;
|
||||
random_scalar_order_test(&x);
|
||||
secp256k1_scalar_negate(&nx, &x);
|
||||
secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */
|
||||
secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
|
||||
secp256k1_ecmult(&ctx->ecmult_ctx, &res1, point, &x, &x); /* calc res1 = x * point + x * G; */
|
||||
secp256k1_ecmult(&ctx->ecmult_ctx, &res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
|
||||
secp256k1_gej_add_var(&res1, &res1, &res2);
|
||||
CHECK(secp256k1_gej_is_infinity(&res1));
|
||||
CHECK(secp256k1_gej_is_valid_var(&res1) == 0);
|
||||
@ -1159,7 +1160,7 @@ void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, cons
|
||||
secp256k1_scalar_t nonce;
|
||||
do {
|
||||
random_scalar_order_test(&nonce);
|
||||
} while(!secp256k1_ecdsa_sig_sign(sig, key, msg, &nonce, recid));
|
||||
} while(!secp256k1_ecdsa_sig_sign(&ctx->ecmult_gen_ctx, sig, key, msg, &nonce, recid));
|
||||
}
|
||||
|
||||
void test_ecdsa_sign_verify(void) {
|
||||
@ -1172,17 +1173,17 @@ void test_ecdsa_sign_verify(void) {
|
||||
int getrec;
|
||||
random_scalar_order_test(&msg);
|
||||
random_scalar_order_test(&key);
|
||||
secp256k1_ecmult_gen(&pubj, &key);
|
||||
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &pubj, &key);
|
||||
secp256k1_ge_set_gej(&pub, &pubj);
|
||||
getrec = secp256k1_rand32()&1;
|
||||
random_sign(&sig, &key, &msg, getrec?&recid:NULL);
|
||||
if (getrec) {
|
||||
CHECK(recid >= 0 && recid < 4);
|
||||
}
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg));
|
||||
secp256k1_scalar_set_int(&one, 1);
|
||||
secp256k1_scalar_add(&msg, &msg, &one);
|
||||
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
|
||||
CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &pub, &msg));
|
||||
}
|
||||
|
||||
void run_ecdsa_sign_verify(void) {
|
||||
@ -1275,16 +1276,16 @@ void test_ecdsa_end_to_end(void) {
|
||||
}
|
||||
|
||||
/* Construct and verify corresponding public key. */
|
||||
CHECK(secp256k1_ec_seckey_verify(privkey) == 1);
|
||||
CHECK(secp256k1_ec_pubkey_create(pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1);
|
||||
CHECK(secp256k1_ec_seckey_verify(ctx, privkey) == 1);
|
||||
CHECK(secp256k1_ec_pubkey_create(ctx, pubkey, &pubkeylen, privkey, (secp256k1_rand32() & 3) != 0) == 1);
|
||||
if (secp256k1_rand32() & 1) {
|
||||
CHECK(secp256k1_ec_pubkey_decompress(pubkey, &pubkeylen));
|
||||
CHECK(secp256k1_ec_pubkey_decompress(ctx, pubkey, &pubkeylen));
|
||||
}
|
||||
CHECK(secp256k1_ec_pubkey_verify(pubkey, pubkeylen));
|
||||
CHECK(secp256k1_ec_pubkey_verify(ctx, pubkey, pubkeylen));
|
||||
|
||||
/* Verify private key import and export. */
|
||||
CHECK(secp256k1_ec_privkey_export(privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1);
|
||||
CHECK(secp256k1_ec_privkey_import(privkey2, seckey, seckeylen) == 1);
|
||||
CHECK(secp256k1_ec_privkey_export(ctx, privkey, seckey, &seckeylen, secp256k1_rand32() % 2) == 1);
|
||||
CHECK(secp256k1_ec_privkey_import(ctx, privkey2, seckey, seckeylen) == 1);
|
||||
CHECK(memcmp(privkey, privkey2, 32) == 0);
|
||||
|
||||
/* Optionally tweak the keys using addition. */
|
||||
@ -1295,13 +1296,13 @@ void test_ecdsa_end_to_end(void) {
|
||||
unsigned char pubkey2[65];
|
||||
int pubkeylen2 = 65;
|
||||
secp256k1_rand256_test(rnd);
|
||||
ret1 = secp256k1_ec_privkey_tweak_add(privkey, rnd);
|
||||
ret2 = secp256k1_ec_pubkey_tweak_add(pubkey, pubkeylen, rnd);
|
||||
ret1 = secp256k1_ec_privkey_tweak_add(ctx, privkey, rnd);
|
||||
ret2 = secp256k1_ec_pubkey_tweak_add(ctx, pubkey, pubkeylen, rnd);
|
||||
CHECK(ret1 == ret2);
|
||||
if (ret1 == 0) {
|
||||
return;
|
||||
}
|
||||
CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
|
||||
CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
|
||||
CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0);
|
||||
}
|
||||
|
||||
@ -1313,27 +1314,27 @@ void test_ecdsa_end_to_end(void) {
|
||||
unsigned char pubkey2[65];
|
||||
int pubkeylen2 = 65;
|
||||
secp256k1_rand256_test(rnd);
|
||||
ret1 = secp256k1_ec_privkey_tweak_mul(privkey, rnd);
|
||||
ret2 = secp256k1_ec_pubkey_tweak_mul(pubkey, pubkeylen, rnd);
|
||||
ret1 = secp256k1_ec_privkey_tweak_mul(ctx, privkey, rnd);
|
||||
ret2 = secp256k1_ec_pubkey_tweak_mul(ctx, pubkey, pubkeylen, rnd);
|
||||
CHECK(ret1 == ret2);
|
||||
if (ret1 == 0) {
|
||||
return;
|
||||
}
|
||||
CHECK(secp256k1_ec_pubkey_create(pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
|
||||
CHECK(secp256k1_ec_pubkey_create(ctx, pubkey2, &pubkeylen2, privkey, pubkeylen == 33) == 1);
|
||||
CHECK(memcmp(pubkey, pubkey2, pubkeylen) == 0);
|
||||
}
|
||||
|
||||
/* Sign. */
|
||||
CHECK(secp256k1_ecdsa_sign(message, signature, &signaturelen, privkey, NULL, NULL) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, message, signature, &signaturelen, privkey, NULL, NULL) == 1);
|
||||
CHECK(signaturelen > 0);
|
||||
CHECK(secp256k1_ecdsa_sign(message, signature2, &signaturelen2, privkey, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, message, signature2, &signaturelen2, privkey, NULL, extra) == 1);
|
||||
CHECK(signaturelen2 > 0);
|
||||
extra[31] = 1;
|
||||
CHECK(secp256k1_ecdsa_sign(message, signature3, &signaturelen3, privkey, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, message, signature3, &signaturelen3, privkey, NULL, extra) == 1);
|
||||
CHECK(signaturelen3 > 0);
|
||||
extra[31] = 0;
|
||||
extra[0] = 1;
|
||||
CHECK(secp256k1_ecdsa_sign(message, signature4, &signaturelen4, privkey, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, message, signature4, &signaturelen4, privkey, NULL, extra) == 1);
|
||||
CHECK(signaturelen3 > 0);
|
||||
CHECK((signaturelen != signaturelen2) || (memcmp(signature, signature2, signaturelen) != 0));
|
||||
CHECK((signaturelen != signaturelen3) || (memcmp(signature, signature3, signaturelen) != 0));
|
||||
@ -1342,24 +1343,24 @@ void test_ecdsa_end_to_end(void) {
|
||||
CHECK((signaturelen4 != signaturelen2) || (memcmp(signature4, signature2, signaturelen4) != 0));
|
||||
CHECK((signaturelen4 != signaturelen) || (memcmp(signature4, signature, signaturelen4) != 0));
|
||||
/* Verify. */
|
||||
CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(message, signature2, signaturelen2, pubkey, pubkeylen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(message, signature3, signaturelen3, pubkey, pubkeylen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(message, signature4, signaturelen4, pubkey, pubkeylen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, message, signature2, signaturelen2, pubkey, pubkeylen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, message, signature3, signaturelen3, pubkey, pubkeylen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, message, signature4, signaturelen4, pubkey, pubkeylen) == 1);
|
||||
/* Destroy signature and verify again. */
|
||||
signature[signaturelen - 1 - secp256k1_rand32() % 20] += 1 + (secp256k1_rand32() % 255);
|
||||
CHECK(secp256k1_ecdsa_verify(message, signature, signaturelen, pubkey, pubkeylen) != 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, message, signature, signaturelen, pubkey, pubkeylen) != 1);
|
||||
|
||||
/* Compact sign. */
|
||||
CHECK(secp256k1_ecdsa_sign_compact(message, csignature, privkey, NULL, NULL, &recid) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign_compact(ctx, message, csignature, privkey, NULL, NULL, &recid) == 1);
|
||||
CHECK(!is_empty_compact_signature(csignature));
|
||||
/* Recover. */
|
||||
CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1);
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) == 1);
|
||||
CHECK(recpubkeylen == pubkeylen);
|
||||
CHECK(memcmp(pubkey, recpubkey, pubkeylen) == 0);
|
||||
/* Destroy signature and verify again. */
|
||||
csignature[secp256k1_rand32() % 64] += 1 + (secp256k1_rand32() % 255);
|
||||
CHECK(secp256k1_ecdsa_recover_compact(message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 ||
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, message, csignature, recpubkey, &recpubkeylen, pubkeylen == 33, recid) != 1 ||
|
||||
memcmp(pubkey, recpubkey, pubkeylen) != 0);
|
||||
CHECK(recpubkeylen == pubkeylen);
|
||||
|
||||
@ -1482,10 +1483,10 @@ void test_ecdsa_edge_cases(void) {
|
||||
int pubkeyblen = 33;
|
||||
int recid;
|
||||
|
||||
CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 0));
|
||||
CHECK(secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 1));
|
||||
CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 2));
|
||||
CHECK(!secp256k1_ecdsa_recover_compact(msg32, sig64, pubkey, &pubkeylen, 0, 3));
|
||||
CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 0));
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 1));
|
||||
CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 2));
|
||||
CHECK(!secp256k1_ecdsa_recover_compact(ctx, msg32, sig64, pubkey, &pubkeylen, 0, 3));
|
||||
|
||||
for (recid = 0; recid < 4; recid++) {
|
||||
int i;
|
||||
@ -1530,34 +1531,34 @@ void test_ecdsa_edge_cases(void) {
|
||||
0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E,
|
||||
0x8C, 0xD0, 0x36, 0x41, 0x45, 0x02, 0x01, 0x04
|
||||
};
|
||||
CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid));
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkeyb, &pubkeyblen, 1, recid));
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 1);
|
||||
for (recid2 = 0; recid2 < 4; recid2++) {
|
||||
unsigned char pubkey2b[33];
|
||||
int pubkey2blen = 33;
|
||||
CHECK(secp256k1_ecdsa_recover_compact(msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2));
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigb64, pubkey2b, &pubkey2blen, 1, recid2));
|
||||
/* Verifying with (order + r,4) should always fail. */
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderlong, sizeof(sigbderlong), pubkey2b, pubkey2blen) != 1);
|
||||
}
|
||||
/* DER parsing tests. */
|
||||
/* Zero length r/s. */
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zr, sizeof(sigcder_zr), pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder_zs, sizeof(sigcder_zs), pubkeyb, pubkeyblen) == -2);
|
||||
/* Leading zeros. */
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt1, sizeof(sigbderalt1), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt2, sizeof(sigbderalt2), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == 1);
|
||||
sigbderalt3[4] = 1;
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt3, sizeof(sigbderalt3), pubkeyb, pubkeyblen) == -2);
|
||||
sigbderalt4[7] = 1;
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbderalt4, sizeof(sigbderalt4), pubkeyb, pubkeyblen) == -2);
|
||||
/* Damage signature. */
|
||||
sigbder[7]++;
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) == 0);
|
||||
sigbder[7]--;
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, 6, pubkeyb, pubkeyblen) == -2);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder)-1, pubkeyb, pubkeyblen) == -2);
|
||||
for(i = 0; i < 8; i++) {
|
||||
int c;
|
||||
unsigned char orig = sigbder[i];
|
||||
@ -1567,7 +1568,7 @@ void test_ecdsa_edge_cases(void) {
|
||||
continue;
|
||||
}
|
||||
sigbder[i] = c;
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) ==
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigbder, sizeof(sigbder), pubkeyb, pubkeyblen) ==
|
||||
(i==4 || i==7) ? 0 : -2 );
|
||||
}
|
||||
sigbder[i] = orig;
|
||||
@ -1584,10 +1585,10 @@ void test_ecdsa_edge_cases(void) {
|
||||
secp256k1_scalar_negate(&sig.s, &sig.s);
|
||||
secp256k1_scalar_inverse(&sig.s, &sig.s);
|
||||
secp256k1_scalar_set_int(&sig.r, 1);
|
||||
secp256k1_ecmult_gen(&keyj, &sig.r);
|
||||
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &keyj, &sig.r);
|
||||
secp256k1_ge_set_gej(&key, &keyj);
|
||||
msg = sig.s;
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&sig, &key, &msg) == 0);
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &key, &msg) == 0);
|
||||
}
|
||||
|
||||
/* Test r/s equal to zero */
|
||||
@ -1606,18 +1607,18 @@ void test_ecdsa_edge_cases(void) {
|
||||
};
|
||||
unsigned char pubkeyc[65];
|
||||
int pubkeyclen = 65;
|
||||
CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1);
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyc, &pubkeyclen, 0, 0) == 1);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 1);
|
||||
sigcder[4] = 0;
|
||||
sigc64[31] = 0;
|
||||
CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
|
||||
sigcder[4] = 1;
|
||||
sigcder[7] = 0;
|
||||
sigc64[31] = 1;
|
||||
sigc64[63] = 0;
|
||||
CHECK(secp256k1_ecdsa_recover_compact(msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
|
||||
CHECK(secp256k1_ecdsa_verify(msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
|
||||
CHECK(secp256k1_ecdsa_recover_compact(ctx, msg32, sigc64, pubkeyb, &pubkeyblen, 1, 0) == 0);
|
||||
CHECK(secp256k1_ecdsa_verify(ctx, msg32, sigcder, sizeof(sigcder), pubkeyc, pubkeyclen) == 0);
|
||||
}
|
||||
|
||||
/*Signature where s would be zero.*/
|
||||
@ -1648,18 +1649,18 @@ void test_ecdsa_edge_cases(void) {
|
||||
};
|
||||
unsigned char sig[72];
|
||||
int siglen = 72;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 0);
|
||||
CHECK(siglen == 0);
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 0);
|
||||
CHECK(siglen == 0);
|
||||
msg[31] = 0xaa;
|
||||
siglen = 72;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) == 1);
|
||||
CHECK(siglen > 0);
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce2) == 1);
|
||||
CHECK(siglen > 0);
|
||||
siglen = 10;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, precomputed_nonce_function, nonce) != 1);
|
||||
CHECK(siglen == 0);
|
||||
}
|
||||
|
||||
@ -1681,41 +1682,41 @@ void test_ecdsa_edge_cases(void) {
|
||||
msg[31] = 1;
|
||||
/* High key results in signature failure. */
|
||||
memset(key, 0xFF, 32);
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 0);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0);
|
||||
CHECK(siglen == 0);
|
||||
/* Zero key results in signature failure. */
|
||||
memset(key, 0, 32);
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 0);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 0);
|
||||
CHECK(siglen == 0);
|
||||
/* Nonce function failure results in signature failure. */
|
||||
key[31] = 1;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_fail, extra) == 0);
|
||||
CHECK(siglen == 0);
|
||||
CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_fail, extra, &recid) == 0);
|
||||
CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_fail, extra, &recid) == 0);
|
||||
CHECK(is_empty_compact_signature(sig));
|
||||
/* The retry loop successfully makes its way to the first good value. */
|
||||
siglen = 72;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, nonce_function_test_retry, extra) == 1);
|
||||
CHECK(siglen > 0);
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, nonce_function_rfc6979, extra) == 1);
|
||||
CHECK(siglen > 0);
|
||||
CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
|
||||
CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, nonce_function_test_retry, extra, &recid) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, nonce_function_test_retry, extra, &recid) == 1);
|
||||
CHECK(!is_empty_compact_signature(sig));
|
||||
CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, nonce_function_rfc6979, extra, &recid2) == 1);
|
||||
CHECK(!is_empty_compact_signature(sig2));
|
||||
CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
|
||||
/* The default nonce function is determinstic. */
|
||||
siglen = 72;
|
||||
siglen2 = 72;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig, &siglen, key, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig, &siglen, key, NULL, extra) == 1);
|
||||
CHECK(siglen > 0);
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1);
|
||||
CHECK(siglen2 > 0);
|
||||
CHECK((siglen == siglen2) && (memcmp(sig, sig2, siglen) == 0));
|
||||
CHECK(secp256k1_ecdsa_sign_compact(msg, sig, key, NULL, extra, &recid) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig, key, NULL, extra, &recid) == 1);
|
||||
CHECK(!is_empty_compact_signature(sig));
|
||||
CHECK(secp256k1_ecdsa_sign_compact(msg, sig2, key, NULL, extra, &recid2) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign_compact(ctx, msg, sig2, key, NULL, extra, &recid2) == 1);
|
||||
CHECK(!is_empty_compact_signature(sig));
|
||||
CHECK((recid == recid2) && (memcmp(sig, sig2, 64) == 0));
|
||||
/* The default nonce function changes output with different messages. */
|
||||
@ -1723,7 +1724,7 @@ void test_ecdsa_edge_cases(void) {
|
||||
int j;
|
||||
siglen2 = 72;
|
||||
msg[0] = i;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1);
|
||||
CHECK(!is_empty_compact_signature(sig));
|
||||
CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
|
||||
for (j = 0; j < i; j++) {
|
||||
@ -1737,7 +1738,7 @@ void test_ecdsa_edge_cases(void) {
|
||||
int j;
|
||||
siglen2 = 72;
|
||||
key[0] = i - 256;
|
||||
CHECK(secp256k1_ecdsa_sign(msg, sig2, &siglen2, key, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sign(ctx, msg, sig2, &siglen2, key, NULL, extra) == 1);
|
||||
CHECK(secp256k1_ecdsa_sig_parse(&s[i], sig2, siglen2));
|
||||
for (j = 0; j < i; j++) {
|
||||
CHECK(!secp256k1_scalar_eq(&s[i].r, &s[j].r));
|
||||
@ -1756,8 +1757,8 @@ void test_ecdsa_edge_cases(void) {
|
||||
0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41,
|
||||
};
|
||||
int outlen = 300;
|
||||
CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 0));
|
||||
CHECK(!secp256k1_ec_privkey_export(seckey, privkey, &outlen, 1));
|
||||
CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 0));
|
||||
CHECK(!secp256k1_ec_privkey_export(ctx, seckey, privkey, &outlen, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1772,7 +1773,7 @@ EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) {
|
||||
const unsigned char* pbegin = privkey;
|
||||
int compr = secp256k1_rand32() & 1;
|
||||
EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
CHECK(secp256k1_eckey_privkey_serialize(privkey, &privkeylen, key, compr));
|
||||
CHECK(secp256k1_eckey_privkey_serialize(&ctx->ecmult_gen_ctx, privkey, &privkeylen, key, compr));
|
||||
CHECK(d2i_ECPrivateKey(&ec_key, &pbegin, privkeylen));
|
||||
CHECK(EC_KEY_check_key(ec_key));
|
||||
return ec_key;
|
||||
@ -1793,16 +1794,16 @@ void test_ecdsa_openssl(void) {
|
||||
secp256k1_rand256_test(message);
|
||||
secp256k1_scalar_set_b32(&msg, message, NULL);
|
||||
random_scalar_order_test(&key);
|
||||
secp256k1_ecmult_gen(&qj, &key);
|
||||
secp256k1_ecmult_gen(&ctx->ecmult_gen_ctx, &qj, &key);
|
||||
secp256k1_ge_set_gej(&q, &qj);
|
||||
ec_key = get_openssl_key(&key);
|
||||
CHECK(ec_key);
|
||||
CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));
|
||||
CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize));
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg));
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg));
|
||||
secp256k1_scalar_set_int(&one, 1);
|
||||
secp256k1_scalar_add(&msg2, &msg, &one);
|
||||
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg2));
|
||||
CHECK(!secp256k1_ecdsa_sig_verify(&ctx->ecmult_ctx, &sig, &q, &msg2));
|
||||
|
||||
random_sign(&sig, &key, &msg, NULL);
|
||||
CHECK(secp256k1_ecdsa_sig_serialize(signature, &secp_sigsize, &sig));
|
||||
@ -1862,10 +1863,7 @@ int main(int argc, char **argv) {
|
||||
printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]);
|
||||
|
||||
/* initialize */
|
||||
secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY);
|
||||
|
||||
/* initializing a second time shouldn't cause any harm or memory leaks. */
|
||||
secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY);
|
||||
ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
|
||||
|
||||
run_sha256_tests();
|
||||
run_hmac_sha256_tests();
|
||||
@ -1909,9 +1907,6 @@ int main(int argc, char **argv) {
|
||||
printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]);
|
||||
|
||||
/* shutdown */
|
||||
secp256k1_stop();
|
||||
|
||||
/* shutting down twice shouldn't cause any double frees. */
|
||||
secp256k1_stop();
|
||||
secp256k1_context_destroy(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user