Merge pull request #60
c259a7c
Set precomputation table late and unset early. (Pieter Wuille)04e34d1
Split up signing and verification initialization (Pieter Wuille)
This commit is contained in:
commit
b00982fdbd
|
@ -5,12 +5,16 @@
|
|||
extern "C" {
|
||||
#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.
|
||||
*/
|
||||
void secp256k1_start(void);
|
||||
void secp256k1_start(unsigned int flags);
|
||||
|
||||
/** Free all memory associated with this library. After this, no
|
||||
* functions can be called anymore, except secp256k1_start()
|
||||
|
@ -22,6 +26,7 @@ void secp256k1_stop(void);
|
|||
* 0: incorrect signature
|
||||
* -1: invalid public key
|
||||
* -2: invalid signature
|
||||
* Requires starting using SECP256K1_START_VERIFY.
|
||||
*/
|
||||
int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen,
|
||||
const unsigned char *sig, int siglen,
|
||||
|
@ -36,6 +41,7 @@ int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen,
|
|||
* nonce: pointer to a 32-byte nonce (generated with a cryptographic PRNG)
|
||||
* Out: sig: pointer to a 72-byte array where the signature will be placed.
|
||||
* siglen: pointer to an int, which will be updated to the signature length (<=72).
|
||||
* Requires starting using SECP256K1_START_SIGN.
|
||||
*/
|
||||
int secp256k1_ecdsa_sign(const unsigned char *msg, int msglen,
|
||||
unsigned char *sig, int *siglen,
|
||||
|
@ -51,6 +57,7 @@ int secp256k1_ecdsa_sign(const unsigned char *msg, int msglen,
|
|||
* nonce: pointer to a 32-byte nonce (generated with a cryptographic PRNG)
|
||||
* Out: sig: pointer to a 64-byte array where the signature will be placed.
|
||||
* recid: pointer to an int, which will be updated to contain the recovery id.
|
||||
* Requires starting using SECP256K1_START_SIGN.
|
||||
*/
|
||||
int secp256k1_ecdsa_sign_compact(const unsigned char *msg, int msglen,
|
||||
unsigned char *sig64,
|
||||
|
@ -68,8 +75,8 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *msg, int msglen,
|
|||
* recid: the recovery id (as returned by ecdsa_sign_compact)
|
||||
* Out: pubkey: pointer to a 33 or 65 byte array to put the pubkey.
|
||||
* pubkeylen: pointer to an int that will contain the pubkey length.
|
||||
* Requires starting using SECP256K1_START_VERIFY.
|
||||
*/
|
||||
|
||||
int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen,
|
||||
const unsigned char *sig64,
|
||||
unsigned char *pubkey, int *pubkeylen,
|
||||
|
@ -97,6 +104,7 @@ int secp256k1_ecdsa_pubkey_verify(const unsigned char *pubkey, int pubkeylen);
|
|||
* length.
|
||||
* Returns: 1: secret was valid, public key stores
|
||||
* 0: secret was invalid, try again.
|
||||
* Requires starting using SECP256K1_START_SIGN.
|
||||
*/
|
||||
int secp256k1_ecdsa_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed);
|
||||
|
||||
|
|
|
@ -69,7 +69,9 @@ typedef struct {
|
|||
// For accelerating the computation of a*P + b*G:
|
||||
secp256k1_ge_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; // odd multiples of the generator
|
||||
secp256k1_ge_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; // odd multiples of 2^128*generator
|
||||
} secp256k1_ecmult_consts_t;
|
||||
|
||||
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.
|
||||
|
@ -83,16 +85,17 @@ typedef struct {
|
|||
// the intermediate sums while computing a*G.
|
||||
// To make memory access uniform, the bytes of prec(i, n_i) are sliced per value of n_i.
|
||||
unsigned char prec[64][sizeof(secp256k1_ge_t)][16]; // prec[j][k][i] = k'th byte of (16^j * i * G + U_i)
|
||||
} secp256k1_ecmult_consts_t;
|
||||
} secp256k1_ecmult_gen_consts_t;
|
||||
|
||||
static const secp256k1_ecmult_consts_t *secp256k1_ecmult_consts = NULL;
|
||||
static const secp256k1_ecmult_gen_consts_t *secp256k1_ecmult_gen_consts = NULL;
|
||||
|
||||
static void secp256k1_ecmult_start(void) {
|
||||
if (secp256k1_ecmult_consts != NULL)
|
||||
return;
|
||||
|
||||
// Allocate the precomputation table.
|
||||
secp256k1_ecmult_consts_t *ret = (secp256k1_ecmult_consts_t*)malloc(sizeof(secp256k1_ecmult_consts_t));
|
||||
secp256k1_ecmult_consts = ret;
|
||||
|
||||
// get the generator
|
||||
const secp256k1_ge_t *g = &secp256k1_ge_consts->g;
|
||||
|
@ -107,6 +110,21 @@ static void secp256k1_ecmult_start(void) {
|
|||
secp256k1_ecmult_table_precomp_ge(ret->pre_g, &gj, WINDOW_G);
|
||||
secp256k1_ecmult_table_precomp_ge(ret->pre_g_128, &g_128j, WINDOW_G);
|
||||
|
||||
// Set the global pointer to the precomputation table.
|
||||
secp256k1_ecmult_consts = ret;
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_gen_start(void) {
|
||||
if (secp256k1_ecmult_gen_consts != NULL)
|
||||
return;
|
||||
|
||||
// Allocate the precomputation table.
|
||||
secp256k1_ecmult_gen_consts_t *ret = (secp256k1_ecmult_gen_consts_t*)malloc(sizeof(secp256k1_ecmult_gen_consts_t));
|
||||
|
||||
// get the generator
|
||||
const secp256k1_ge_t *g = &secp256k1_ge_consts->g;
|
||||
secp256k1_gej_t gj; secp256k1_gej_set_ge(&gj, g);
|
||||
|
||||
// Construct a group element with no known corresponding scalar (nothing up my sleeve).
|
||||
secp256k1_gej_t nums_gej;
|
||||
{
|
||||
|
@ -154,6 +172,9 @@ static void secp256k1_ecmult_start(void) {
|
|||
ret->prec[j][k][i] = raw[k];
|
||||
}
|
||||
}
|
||||
|
||||
// Set the global pointer to the precomputation table.
|
||||
secp256k1_ecmult_gen_consts = ret;
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_stop(void) {
|
||||
|
@ -161,8 +182,17 @@ static void secp256k1_ecmult_stop(void) {
|
|||
return;
|
||||
|
||||
secp256k1_ecmult_consts_t *c = (secp256k1_ecmult_consts_t*)secp256k1_ecmult_consts;
|
||||
free(c);
|
||||
secp256k1_ecmult_consts = NULL;
|
||||
free(c);
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_gen_stop(void) {
|
||||
if (secp256k1_ecmult_gen_consts == NULL)
|
||||
return;
|
||||
|
||||
secp256k1_ecmult_gen_consts_t *c = (secp256k1_ecmult_gen_consts_t*)secp256k1_ecmult_gen_consts;
|
||||
secp256k1_ecmult_gen_consts = NULL;
|
||||
free(c);
|
||||
}
|
||||
|
||||
/** Convert a number to WNAF notation. The number becomes represented by sum(2^i * wnaf[i], i=0..bits),
|
||||
|
@ -209,7 +239,7 @@ void static secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_num_t *gn)
|
|||
secp256k1_num_t n;
|
||||
secp256k1_num_init(&n);
|
||||
secp256k1_num_copy(&n, gn);
|
||||
const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
|
||||
const secp256k1_ecmult_gen_consts_t *c = secp256k1_ecmult_gen_consts;
|
||||
secp256k1_gej_set_infinity(r);
|
||||
secp256k1_ge_t add;
|
||||
int bits;
|
||||
|
|
|
@ -15,7 +15,7 @@ static void __javasecp256k1_attach(void) __attribute__((constructor));
|
|||
static void __javasecp256k1_detach(void) __attribute__((destructor));
|
||||
|
||||
static void __javasecp256k1_attach(void) {
|
||||
secp256k1_start();
|
||||
secp256k1_start(SECP256K1_START_VERIFY);
|
||||
}
|
||||
|
||||
static void __javasecp256k1_detach(void) {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "include/secp256k1.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "util.h"
|
||||
#include "num_impl.h"
|
||||
|
@ -10,19 +12,26 @@
|
|||
#include "ecmult_impl.h"
|
||||
#include "ecdsa_impl.h"
|
||||
|
||||
void secp256k1_start(void) {
|
||||
void secp256k1_start(unsigned int flags) {
|
||||
secp256k1_fe_start();
|
||||
secp256k1_ge_start();
|
||||
secp256k1_ecmult_start();
|
||||
if (flags & SECP256K1_START_SIGN) {
|
||||
secp256k1_ecmult_gen_start();
|
||||
}
|
||||
if (flags & SECP256K1_START_VERIFY) {
|
||||
secp256k1_ecmult_start();
|
||||
}
|
||||
}
|
||||
|
||||
void secp256k1_stop(void) {
|
||||
secp256k1_ecmult_stop();
|
||||
secp256k1_ecmult_gen_stop();
|
||||
secp256k1_ge_stop();
|
||||
secp256k1_fe_stop();
|
||||
}
|
||||
|
||||
int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) {
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(msg != NULL);
|
||||
DEBUG_CHECK(msglen <= 32);
|
||||
DEBUG_CHECK(sig != NULL);
|
||||
|
@ -56,6 +65,7 @@ end:
|
|||
}
|
||||
|
||||
int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned char *signature, int *signaturelen, const unsigned char *seckey, const unsigned char *nonce) {
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
|
||||
DEBUG_CHECK(message != NULL);
|
||||
DEBUG_CHECK(messagelen <= 32);
|
||||
DEBUG_CHECK(signature != NULL);
|
||||
|
@ -91,6 +101,7 @@ int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned
|
|||
}
|
||||
|
||||
int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, unsigned char *sig64, const unsigned char *seckey, const unsigned char *nonce, int *recid) {
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
|
||||
DEBUG_CHECK(message != NULL);
|
||||
DEBUG_CHECK(messagelen <= 32);
|
||||
DEBUG_CHECK(sig64 != NULL);
|
||||
|
@ -126,6 +137,7 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u
|
|||
}
|
||||
|
||||
int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) {
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(msg != NULL);
|
||||
DEBUG_CHECK(msglen <= 32);
|
||||
DEBUG_CHECK(sig64 != NULL);
|
||||
|
@ -173,6 +185,7 @@ int secp256k1_ecdsa_pubkey_verify(const unsigned char *pubkey, int pubkeylen) {
|
|||
}
|
||||
|
||||
int secp256k1_ecdsa_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsigned char *seckey, int compressed) {
|
||||
DEBUG_CHECK(secp256k1_ecmult_gen_consts != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(pubkeylen != NULL);
|
||||
DEBUG_CHECK(seckey != NULL);
|
||||
|
@ -230,6 +243,7 @@ int secp256k1_ecdsa_privkey_tweak_add(unsigned char *seckey, const unsigned char
|
|||
}
|
||||
|
||||
int secp256k1_ecdsa_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
|
||||
|
@ -246,8 +260,12 @@ int secp256k1_ecdsa_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const
|
|||
}
|
||||
if (ret) {
|
||||
secp256k1_gej_t pt;
|
||||
secp256k1_ecmult_gen(&pt, &term);
|
||||
secp256k1_gej_add_ge(&pt, &pt, &p);
|
||||
secp256k1_gej_set_ge(&pt, &p);
|
||||
secp256k1_num_t one;
|
||||
secp256k1_num_init(&one);
|
||||
secp256k1_num_set_int(&one, 1);
|
||||
secp256k1_ecmult(&pt, &pt, &one, &term);
|
||||
secp256k1_num_free(&one);
|
||||
if (secp256k1_gej_is_infinity(&pt))
|
||||
ret = 0;
|
||||
secp256k1_ge_set_gej(&p, &pt);
|
||||
|
@ -285,6 +303,7 @@ int secp256k1_ecdsa_privkey_tweak_mul(unsigned char *seckey, const unsigned char
|
|||
}
|
||||
|
||||
int secp256k1_ecdsa_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
|
||||
DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
|
||||
|
|
|
@ -704,7 +704,7 @@ int main(int argc, char **argv) {
|
|||
printf("test count = %i\n", count);
|
||||
|
||||
// initialize
|
||||
secp256k1_start();
|
||||
secp256k1_start(SECP256K1_START_SIGN | SECP256K1_START_VERIFY);
|
||||
|
||||
// num tests
|
||||
run_num_smalltests();
|
||||
|
|
Loading…
Reference in New Issue