Introduce secp256k1_scalar_t for future constant-time mod order operations

This commit is contained in:
Pieter Wuille 2014-10-28 04:08:15 -07:00
parent b2bfdabdeb
commit a9f5c8b875
14 changed files with 319 additions and 149 deletions

View File

@ -4,6 +4,8 @@ lib_LTLIBRARIES = libsecp256k1.la
noinst_LTLIBRARIES = libsecp256k1_common.la
include_HEADERS = include/secp256k1.h
noinst_HEADERS =
noinst_HEADERS += src/scalar.h
noinst_HEADERS += src/scalar_impl.h
noinst_HEADERS += src/group.h
noinst_HEADERS += src/group_impl.h
noinst_HEADERS += src/num_openssl.h

View File

@ -17,7 +17,7 @@ void static secp256k1_ecdsa_sig_free(secp256k1_ecdsa_sig_t *r);
int static secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size);
int static secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a);
int static secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message);
int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *seckey, const secp256k1_num_t *message, const secp256k1_num_t *nonce, int *recid);
int static 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);
int static secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid);
void static secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s);

View File

@ -147,9 +147,7 @@ int static secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const se
return ret;
}
int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *seckey, const secp256k1_num_t *message, const secp256k1_num_t *nonce, int *recid) {
const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
int static 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) {
secp256k1_gej_t rp;
secp256k1_ecmult_gen(&rp, nonce);
secp256k1_ge_t r;
@ -158,28 +156,35 @@ int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_
secp256k1_fe_normalize(&r.x);
secp256k1_fe_normalize(&r.y);
secp256k1_fe_get_b32(b, &r.x);
secp256k1_num_set_bin(&sig->r, b, 32);
int overflow = 0;
secp256k1_scalar_t sigr;
secp256k1_scalar_init(&sigr);
secp256k1_scalar_set_bin(&sigr, b, 32, &overflow);
if (recid)
*recid = (secp256k1_num_cmp(&sig->r, &c->order) >= 0 ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
secp256k1_num_mod(&sig->r, &c->order);
secp256k1_num_t n;
secp256k1_num_init(&n);
secp256k1_num_mod_mul(&n, &sig->r, seckey, &c->order);
secp256k1_num_add(&n, &n, message);
secp256k1_num_mod(&n, &c->order);
secp256k1_num_mod_inverse(&sig->s, nonce, &c->order);
secp256k1_num_mod_mul(&sig->s, &sig->s, &n, &c->order);
secp256k1_num_clear(&n);
secp256k1_num_free(&n);
*recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
secp256k1_scalar_t n;
secp256k1_scalar_init(&n);
secp256k1_scalar_mul(&n, &sigr, seckey);
secp256k1_scalar_add(&n, &n, message);
secp256k1_scalar_t sigs;
secp256k1_scalar_init(&sigs);
secp256k1_scalar_inverse(&sigs, nonce);
secp256k1_scalar_mul(&sigs, &sigs, &n);
secp256k1_scalar_clear(&n);
secp256k1_scalar_free(&n);
secp256k1_gej_clear(&rp);
secp256k1_ge_clear(&r);
if (secp256k1_num_is_zero(&sig->s))
if (secp256k1_scalar_is_zero(&sigs))
return 0;
if (secp256k1_num_cmp(&sig->s, &c->half_order) > 0) {
secp256k1_num_sub(&sig->s, &c->order, &sig->s);
if (secp256k1_scalar_is_high(&sigs)) {
secp256k1_scalar_negate(&sigs, &sigs);
if (recid)
*recid ^= 1;
}
secp256k1_scalar_get_num(&sig->s, &sigs);
secp256k1_scalar_get_num(&sig->r, &sigr);
secp256k1_scalar_free(&sigs);
secp256k1_scalar_free(&sigr);
return 1;
}

View File

@ -6,17 +6,18 @@
#define _SECP256K1_ECKEY_
#include "group.h"
#include "scalar.h"
#include "num.h"
int static secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size);
void static secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed);
int static secp256k1_eckey_privkey_parse(secp256k1_num_t *key, const unsigned char *privkey, int privkeylen);
int static secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_num_t *key, int compressed);
int static secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen);
int static secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed);
int static secp256k1_eckey_privkey_tweak_add(secp256k1_num_t *key, const secp256k1_num_t *tweak);
int static secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
int static secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_num_t *tweak);
int static secp256k1_eckey_privkey_tweak_mul(secp256k1_num_t *key, const secp256k1_num_t *tweak);
int static secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
int static secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_num_t *tweak);
#endif

View File

@ -44,7 +44,7 @@ void static secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char
}
}
int static secp256k1_eckey_privkey_parse(secp256k1_num_t *key, const unsigned char *privkey, int privkeylen) {
int static secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) {
const unsigned char *end = privkey + privkeylen;
// sequence header
if (end < privkey+1 || *privkey != 0x30)
@ -72,11 +72,12 @@ int static secp256k1_eckey_privkey_parse(secp256k1_num_t *key, const unsigned ch
// sequence element 1: octet string, up to 32 bytes
if (end < privkey+2 || privkey[0] != 0x04 || privkey[1] > 0x20 || end < privkey+2+privkey[1])
return 0;
secp256k1_num_set_bin(key, privkey+2, privkey[1]);
return 1;
int overflow = 0;
secp256k1_scalar_set_bin(key, privkey+2, privkey[1], &overflow);
return !overflow;
}
int static secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_num_t *key, int compressed) {
int static secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privkeylen, const secp256k1_scalar_t *key, int compressed) {
secp256k1_gej_t rp;
secp256k1_ecmult_gen(&rp, key);
secp256k1_ge_t r;
@ -98,7 +99,7 @@ int static secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke
};
unsigned char *ptr = privkey;
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
secp256k1_num_get_bin(ptr, 32, key); ptr += 32;
secp256k1_scalar_get_bin(ptr, 32, key); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
int pubkeylen = 0;
secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 1); ptr += pubkeylen;
@ -122,7 +123,7 @@ int static secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke
};
unsigned char *ptr = privkey;
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
secp256k1_num_get_bin(ptr, 32, key); ptr += 32;
secp256k1_scalar_get_bin(ptr, 32, key); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
int pubkeylen = 0;
secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 0); ptr += pubkeylen;
@ -131,12 +132,9 @@ int static secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke
return 1;
}
int static secp256k1_eckey_privkey_tweak_add(secp256k1_num_t *key, const secp256k1_num_t *tweak) {
if (secp256k1_num_cmp(tweak, &secp256k1_ge_consts->order) >= 0)
return 0;
secp256k1_num_add(key, key, tweak);
secp256k1_num_mod(key, &secp256k1_ge_consts->order);
if (secp256k1_num_is_zero(key))
int static secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) {
secp256k1_scalar_add(key, key, tweak);
if (secp256k1_scalar_is_zero(key))
return 0;
return 1;
}
@ -159,13 +157,11 @@ int static secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1
return 1;
}
int static secp256k1_eckey_privkey_tweak_mul(secp256k1_num_t *key, const secp256k1_num_t *tweak) {
if (secp256k1_num_is_zero(tweak))
return 0;
if (secp256k1_num_cmp(tweak, &secp256k1_ge_consts->order) >= 0)
int static secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak) {
if (secp256k1_scalar_is_zero(tweak))
return 0;
secp256k1_num_mod_mul(key, key, tweak, &secp256k1_ge_consts->order);
secp256k1_scalar_mul(key, key, tweak);
return 1;
}

View File

@ -5,13 +5,13 @@
#ifndef _SECP256K1_ECMULT_GEN_
#define _SECP256K1_ECMULT_GEN_
#include "num.h"
#include "scalar.h"
#include "group.h"
static void secp256k1_ecmult_gen_start(void);
static void secp256k1_ecmult_gen_stop(void);
/** Multiply with the generator: R = a*G */
static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_num_t *a);
static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *a);
#endif

View File

@ -6,7 +6,7 @@
#define _SECP256K1_ECMULT_GEN_IMPL_H_
#include <assert.h>
#include "num.h"
#include "scalar.h"
#include "group.h"
#include "ecmult_gen.h"
@ -100,24 +100,19 @@ static void secp256k1_ecmult_gen_stop(void) {
free(c);
}
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);
void static secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *gn) {
const secp256k1_ecmult_gen_consts_t *c = secp256k1_ecmult_gen_consts;
secp256k1_gej_set_infinity(r);
secp256k1_ge_t add;
int bits;
for (int j=0; j<64; j++) {
bits = secp256k1_num_shift(&n, 4);
bits = secp256k1_scalar_get_bits(gn, j * 4, 4);
for (int k=0; k<sizeof(secp256k1_ge_t); k++)
((unsigned char*)(&add))[k] = c->prec[j][k][bits];
secp256k1_gej_add_ge(r, r, &add);
}
bits = 0;
secp256k1_ge_clear(&add);
secp256k1_num_clear(&n);
secp256k1_num_free(&n);
}
#endif

View File

@ -100,4 +100,7 @@ void static secp256k1_num_split(secp256k1_num_t *rl, secp256k1_num_t *rh, const
/** Change a number's sign. */
void static secp256k1_num_negate(secp256k1_num_t *r);
/** Get a bunch of bits from a number. */
int static secp256k1_num_get_bits(const secp256k1_num_t *a, int offset, int count);
#endif

View File

@ -362,4 +362,12 @@ void static secp256k1_num_negate(secp256k1_num_t *r) {
r->neg ^= 1;
}
int static secp256k1_num_get_bits(const secp256k1_num_t *a, int offset, int count) {
int ret = 0;
for (int i = 0; i < count; i++) {
ret |= ((a->data[(offset + i) / GMP_NUMB_BITS] >> ((offset + i) % GMP_NUMB_BITS)) & 1) << i;
}
return ret;
}
#endif

View File

@ -252,4 +252,12 @@ void static secp256k1_num_negate(secp256k1_num_t *r) {
BN_set_negative(&r->bn, !BN_is_negative(&r->bn));
}
int static secp256k1_num_get_bits(const secp256k1_num_t *a, int offset, int count) {
int ret = 0;
for (int i = 0; i < count; i++) {
ret |= BN_is_bit_set(&a->bn, offset + i) << i;
}
return ret;
}
#endif

54
src/scalar.h Normal file
View File

@ -0,0 +1,54 @@
// Copyright (c) 2014 Pieter Wuille
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _SECP256K1_SCALAR_
#define _SECP256K1_SCALAR_
#include "num.h"
/** A scalar modulo the group order of the secp256k1 curve. */
typedef struct {
secp256k1_num_t n;
} secp256k1_scalar_t;
/** Initialize a scalar. */
void static secp256k1_scalar_init(secp256k1_scalar_t *r);
/** Clear a scalar to prevent the leak of sensitive data. */
void static secp256k1_scalar_clear(secp256k1_scalar_t *r);
/** Free a scalar. */
void static secp256k1_scalar_free(secp256k1_scalar_t *r);
/** Access bits from a scalar. */
int static secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, int offset, int count);
/** Set a scalar from a big endian byte array. */
void static secp256k1_scalar_set_bin(secp256k1_scalar_t *r, const unsigned char *bin, int len, int *overflow);
/** Convert a scalar to a byte array. */
void static secp256k1_scalar_get_bin(unsigned char *bin, int len, const secp256k1_scalar_t* a);
/** Add two scalars together (modulo the group order). */
void static secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
/** Multiply two scalars (modulo the group order). */
void static secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
/** Compute the inverse of a scalar (modulo the group order). */
void static secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
/** Compute the complement of a scalar (modulo the group order). */
void static secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a);
/** Check whether a scalar equals zero. */
int static secp256k1_scalar_is_zero(const secp256k1_scalar_t *a);
/** Check whether a scalar is higher than the group order divided by 2. */
int static secp256k1_scalar_is_high(const secp256k1_scalar_t *a);
/** Convert a scalar to a number. */
void static secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a);
#endif

73
src/scalar_impl.h Normal file
View File

@ -0,0 +1,73 @@
// Copyright (c) 2014 Pieter Wuille
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef _SECP256K1_SCALAR_IMPL_H_
#define _SECP256K1_SCALAR_IMPL_H_
#include <string.h>
#include "scalar.h"
#include "group.h"
void static secp256k1_scalar_init(secp256k1_scalar_t *r) {
secp256k1_num_init(&r->n);
}
void static secp256k1_scalar_clear(secp256k1_scalar_t *r) {
secp256k1_num_clear(&r->n);
}
void static secp256k1_scalar_free(secp256k1_scalar_t *r) {
secp256k1_num_free(&r->n);
}
int static secp256k1_scalar_get_bits(const secp256k1_scalar_t *a, int offset, int count) {
return secp256k1_num_get_bits(&a->n, offset, count);
}
void static secp256k1_scalar_set_bin(secp256k1_scalar_t *r, const unsigned char *bin, int len, int *overflow) {
secp256k1_num_set_bin(&r->n, bin, len);
if (overflow) {
*overflow = secp256k1_num_cmp(&r->n, &secp256k1_ge_consts->order) >= 0;
}
secp256k1_num_mod(&r->n, &secp256k1_ge_consts->order);
}
void static secp256k1_scalar_get_bin(unsigned char *bin, int len, const secp256k1_scalar_t* a) {
secp256k1_num_get_bin(bin, len, &a->n);
}
void static secp256k1_scalar_add(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
secp256k1_num_add(&r->n, &a->n, &b->n);
secp256k1_num_mod(&r->n, &secp256k1_ge_consts->order);
}
void static secp256k1_scalar_mul(secp256k1_scalar_t *r, const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
secp256k1_num_mod_mul(&r->n, &a->n, &b->n, &secp256k1_ge_consts->order);
}
void static secp256k1_scalar_inverse(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
secp256k1_num_mod_inverse(&r->n, &a->n, &secp256k1_ge_consts->order);
}
void static secp256k1_scalar_negate(secp256k1_scalar_t *r, const secp256k1_scalar_t *a) {
secp256k1_num_sub(&r->n, &secp256k1_ge_consts->order, &a->n);
}
int static secp256k1_scalar_is_zero(const secp256k1_scalar_t *a) {
return secp256k1_num_is_zero(&a->n);
}
int static secp256k1_scalar_is_high(const secp256k1_scalar_t *a) {
return secp256k1_num_cmp(&a->n, &secp256k1_ge_consts->half_order) > 0;
}
void static secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a) {
unsigned char c[32];
secp256k1_num_get_bin(c, 32, &a->n);
secp256k1_num_set_bin(r, c, 32);
}
#endif

View File

@ -8,6 +8,7 @@
#include "util.h"
#include "num_impl.h"
#include "field_impl.h"
#include "scalar_impl.h"
#include "group_impl.h"
#include "ecmult_impl.h"
#include "ecmult_gen_impl.h"
@ -75,15 +76,15 @@ int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(nonce != NULL);
secp256k1_num_t sec, non, msg;
secp256k1_num_init(&sec);
secp256k1_num_init(&non);
secp256k1_num_init(&msg);
secp256k1_num_set_bin(&sec, seckey, 32);
secp256k1_num_set_bin(&non, nonce, 32);
secp256k1_num_set_bin(&msg, message, messagelen);
int ret = !secp256k1_num_is_zero(&non) &&
(secp256k1_num_cmp(&non, &secp256k1_ge_consts->order) < 0);
secp256k1_scalar_t sec, non, msg;
secp256k1_scalar_init(&sec);
secp256k1_scalar_init(&non);
secp256k1_scalar_init(&msg);
secp256k1_scalar_set_bin(&sec, seckey, 32, NULL);
int overflow = 0;
secp256k1_scalar_set_bin(&non, nonce, 32, &overflow);
secp256k1_scalar_set_bin(&msg, message, messagelen, NULL);
int ret = !secp256k1_scalar_is_zero(&non) && !overflow;
secp256k1_ecdsa_sig_t sig;
secp256k1_ecdsa_sig_init(&sig);
if (ret) {
@ -93,12 +94,12 @@ int secp256k1_ecdsa_sign(const unsigned char *message, int messagelen, unsigned
secp256k1_ecdsa_sig_serialize(signature, signaturelen, &sig);
}
secp256k1_ecdsa_sig_free(&sig);
secp256k1_num_clear(&msg);
secp256k1_num_clear(&non);
secp256k1_num_clear(&sec);
secp256k1_num_free(&msg);
secp256k1_num_free(&non);
secp256k1_num_free(&sec);
secp256k1_scalar_clear(&msg);
secp256k1_scalar_clear(&non);
secp256k1_scalar_clear(&sec);
secp256k1_scalar_free(&msg);
secp256k1_scalar_free(&non);
secp256k1_scalar_free(&sec);
return ret;
}
@ -110,15 +111,15 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(nonce != NULL);
secp256k1_num_t sec, non, msg;
secp256k1_num_init(&sec);
secp256k1_num_init(&non);
secp256k1_num_init(&msg);
secp256k1_num_set_bin(&sec, seckey, 32);
secp256k1_num_set_bin(&non, nonce, 32);
secp256k1_num_set_bin(&msg, message, messagelen);
int ret = !secp256k1_num_is_zero(&non) &&
(secp256k1_num_cmp(&non, &secp256k1_ge_consts->order) < 0);
secp256k1_scalar_t sec, non, msg;
secp256k1_scalar_init(&sec);
secp256k1_scalar_init(&non);
secp256k1_scalar_init(&msg);
secp256k1_scalar_set_bin(&sec, seckey, 32, NULL);
int overflow = 0;
secp256k1_scalar_set_bin(&non, nonce, 32, &overflow);
secp256k1_scalar_set_bin(&msg, message, messagelen, NULL);
int ret = !secp256k1_scalar_is_zero(&non) && !overflow;
secp256k1_ecdsa_sig_t sig;
secp256k1_ecdsa_sig_init(&sig);
if (ret) {
@ -129,12 +130,12 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u
secp256k1_num_get_bin(sig64 + 32, 32, &sig.s);
}
secp256k1_ecdsa_sig_free(&sig);
secp256k1_num_clear(&msg);
secp256k1_num_clear(&non);
secp256k1_num_clear(&sec);
secp256k1_num_free(&msg);
secp256k1_num_free(&non);
secp256k1_num_free(&sec);
secp256k1_scalar_clear(&msg);
secp256k1_scalar_clear(&non);
secp256k1_scalar_clear(&sec);
secp256k1_scalar_free(&msg);
secp256k1_scalar_free(&non);
secp256k1_scalar_free(&sec);
return ret;
}
@ -169,13 +170,13 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const
int secp256k1_ec_seckey_verify(const unsigned char *seckey) {
DEBUG_CHECK(seckey != NULL);
secp256k1_num_t sec;
secp256k1_num_init(&sec);
secp256k1_num_set_bin(&sec, seckey, 32);
int ret = !secp256k1_num_is_zero(&sec) &&
(secp256k1_num_cmp(&sec, &secp256k1_ge_consts->order) < 0);
secp256k1_num_clear(&sec);
secp256k1_num_free(&sec);
secp256k1_scalar_t sec;
secp256k1_scalar_init(&sec);
int overflow;
secp256k1_scalar_set_bin(&sec, seckey, 32, &overflow);
int ret = !secp256k1_scalar_is_zero(&sec) && !overflow;
secp256k1_scalar_clear(&sec);
secp256k1_scalar_free(&sec);
return ret;
}
@ -192,13 +193,13 @@ int secp256k1_ec_pubkey_create(unsigned char *pubkey, int *pubkeylen, const unsi
DEBUG_CHECK(pubkeylen != NULL);
DEBUG_CHECK(seckey != NULL);
secp256k1_num_t sec;
secp256k1_num_init(&sec);
secp256k1_num_set_bin(&sec, seckey, 32);
secp256k1_scalar_t sec;
secp256k1_scalar_init(&sec);
secp256k1_scalar_set_bin(&sec, seckey, 32, NULL);
secp256k1_gej_t pj;
secp256k1_ecmult_gen(&pj, &sec);
secp256k1_num_clear(&sec);
secp256k1_num_free(&sec);
secp256k1_scalar_clear(&sec);
secp256k1_scalar_free(&sec);
secp256k1_ge_t p;
secp256k1_ge_set_gej(&p, &pj);
secp256k1_eckey_pubkey_serialize(&p, pubkey, pubkeylen, compressed);
@ -220,22 +221,23 @@ int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *t
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(tweak != NULL);
secp256k1_num_t term;
secp256k1_num_init(&term);
secp256k1_num_set_bin(&term, tweak, 32);
secp256k1_num_t sec;
secp256k1_num_init(&sec);
secp256k1_num_set_bin(&sec, seckey, 32);
secp256k1_scalar_t term;
secp256k1_scalar_init(&term);
int overflow = 0;
secp256k1_scalar_set_bin(&term, tweak, 32, &overflow);
secp256k1_scalar_t sec;
secp256k1_scalar_init(&sec);
secp256k1_scalar_set_bin(&sec, seckey, 32, NULL);
int ret = secp256k1_eckey_privkey_tweak_add(&sec, &term);
int ret = secp256k1_eckey_privkey_tweak_add(&sec, &term) && !overflow;
if (ret) {
secp256k1_num_get_bin(seckey, 32, &sec);
secp256k1_scalar_get_bin(seckey, 32, &sec);
}
secp256k1_num_clear(&sec);
secp256k1_num_clear(&term);
secp256k1_num_free(&sec);
secp256k1_num_free(&term);
secp256k1_scalar_clear(&sec);
secp256k1_scalar_clear(&term);
secp256k1_scalar_free(&sec);
secp256k1_scalar_free(&term);
return ret;
}
@ -266,21 +268,22 @@ int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *t
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(tweak != NULL);
secp256k1_num_t factor;
secp256k1_num_init(&factor);
secp256k1_num_set_bin(&factor, tweak, 32);
secp256k1_num_t sec;
secp256k1_num_init(&sec);
secp256k1_num_set_bin(&sec, seckey, 32);
int ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor);
secp256k1_scalar_t factor;
secp256k1_scalar_init(&factor);
int overflow = 0;
secp256k1_scalar_set_bin(&factor, tweak, 32, &overflow);
secp256k1_scalar_t sec;
secp256k1_scalar_init(&sec);
secp256k1_scalar_set_bin(&sec, seckey, 32, NULL);
int ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor) && !overflow;
if (ret) {
secp256k1_num_get_bin(seckey, 32, &sec);
secp256k1_scalar_get_bin(seckey, 32, &sec);
}
secp256k1_num_clear(&sec);
secp256k1_num_clear(&factor);
secp256k1_num_free(&sec);
secp256k1_num_free(&factor);
secp256k1_scalar_clear(&sec);
secp256k1_scalar_clear(&factor);
secp256k1_scalar_free(&sec);
secp256k1_scalar_free(&factor);
return ret;
}
@ -312,11 +315,12 @@ int secp256k1_ec_privkey_export(const unsigned char *seckey, unsigned char *priv
DEBUG_CHECK(privkey != NULL);
DEBUG_CHECK(privkeylen != NULL);
secp256k1_num_t key;
secp256k1_num_init(&key);
secp256k1_num_set_bin(&key, seckey, 32);
secp256k1_scalar_t key;
secp256k1_scalar_init(&key);
secp256k1_scalar_set_bin(&key, seckey, 32, NULL);
int ret = secp256k1_eckey_privkey_serialize(privkey, privkeylen, &key, compressed);
secp256k1_num_free(&key);
secp256k1_scalar_clear(&key);
secp256k1_scalar_free(&key);
return ret;
}
@ -324,11 +328,12 @@ int secp256k1_ec_privkey_import(unsigned char *seckey, const unsigned char *priv
DEBUG_CHECK(seckey != NULL);
DEBUG_CHECK(privkey != NULL);
secp256k1_num_t key;
secp256k1_num_init(&key);
secp256k1_scalar_t key;
secp256k1_scalar_init(&key);
int ret = secp256k1_eckey_privkey_parse(&key, privkey, privkeylen);
if (ret)
secp256k1_num_get_bin(seckey, 32, &key);
secp256k1_num_free(&key);
secp256k1_scalar_get_bin(seckey, 32, &key);
secp256k1_scalar_clear(&key);
secp256k1_scalar_free(&key);
return ret;
}

View File

@ -41,6 +41,18 @@ void random_num_order_test(secp256k1_num_t *num) {
} while(1);
}
void random_scalar_order_test(secp256k1_scalar_t *num) {
do {
unsigned char b32[32];
secp256k1_rand256_test(b32);
int overflow = 0;
secp256k1_scalar_set_bin(num, b32, 32, &overflow);
if (overflow || secp256k1_scalar_is_zero(num))
continue;
break;
} while(1);
}
void random_num_order(secp256k1_num_t *num) {
do {
unsigned char b32[32];
@ -507,33 +519,37 @@ void run_wnaf() {
secp256k1_num_free(&n);
}
void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *key, const secp256k1_num_t *msg, int *recid) {
secp256k1_num_t nonce;
secp256k1_num_init(&nonce);
void random_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *key, const secp256k1_scalar_t *msg, int *recid) {
secp256k1_scalar_t nonce;
secp256k1_scalar_init(&nonce);
do {
random_num_order_test(&nonce);
random_scalar_order_test(&nonce);
} while(!secp256k1_ecdsa_sig_sign(sig, key, msg, &nonce, recid));
secp256k1_num_free(&nonce);
secp256k1_scalar_free(&nonce);
}
void test_ecdsa_sign_verify() {
const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
secp256k1_num_t msg, key;
secp256k1_num_init(&msg);
random_num_order_test(&msg);
secp256k1_num_init(&key);
random_num_order_test(&key);
secp256k1_scalar_t msg, key;
secp256k1_scalar_init(&msg);
random_scalar_order_test(&msg);
secp256k1_scalar_init(&key);
random_scalar_order_test(&key);
secp256k1_gej_t pubj; secp256k1_ecmult_gen(&pubj, &key);
secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj);
secp256k1_ecdsa_sig_t sig;
secp256k1_ecdsa_sig_init(&sig);
random_sign(&sig, &key, &msg, NULL);
CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
secp256k1_num_inc(&msg);
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
secp256k1_num_t msg_num;
secp256k1_num_init(&msg_num);
secp256k1_scalar_get_num(&msg_num, &msg);
CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg_num));
secp256k1_num_inc(&msg_num);
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg_num));
secp256k1_ecdsa_sig_free(&sig);
secp256k1_num_free(&msg);
secp256k1_num_free(&key);
secp256k1_num_free(&msg_num);
secp256k1_scalar_free(&msg);
secp256k1_scalar_free(&key);
}
void run_ecdsa_sign_verify() {
@ -643,7 +659,7 @@ void run_ecdsa_end_to_end() {
#ifdef ENABLE_OPENSSL_TESTS
EC_KEY *get_openssl_key(const secp256k1_num_t *key) {
EC_KEY *get_openssl_key(const secp256k1_scalar_t *key) {
unsigned char privkey[300];
int privkeylen;
int compr = secp256k1_rand32() & 1;
@ -657,13 +673,13 @@ EC_KEY *get_openssl_key(const secp256k1_num_t *key) {
void test_ecdsa_openssl() {
const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
secp256k1_num_t key, msg;
secp256k1_num_init(&msg);
secp256k1_scalar_t key, msg;
secp256k1_scalar_init(&msg);
unsigned char message[32];
secp256k1_rand256_test(message);
secp256k1_num_set_bin(&msg, message, 32);
secp256k1_num_init(&key);
random_num_order_test(&key);
secp256k1_scalar_set_bin(&msg, message, 32, NULL);
secp256k1_scalar_init(&key);
random_scalar_order_test(&key);
secp256k1_gej_t qj;
secp256k1_ecmult_gen(&qj, &key);
secp256k1_ge_t q;
@ -676,9 +692,13 @@ void test_ecdsa_openssl() {
secp256k1_ecdsa_sig_t sig;
secp256k1_ecdsa_sig_init(&sig);
CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize));
CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg));
secp256k1_num_t msg_num;
secp256k1_num_init(&msg_num);
secp256k1_scalar_get_num(&msg_num, &msg);
CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg_num));
secp256k1_num_inc(&sig.r);
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg));
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg_num));
secp256k1_num_free(&msg_num);
random_sign(&sig, &key, &msg, NULL);
sigsize = 80;
@ -687,8 +707,8 @@ void test_ecdsa_openssl() {
secp256k1_ecdsa_sig_free(&sig);
EC_KEY_free(ec_key);
secp256k1_num_free(&key);
secp256k1_num_free(&msg);
secp256k1_scalar_free(&key);
secp256k1_scalar_free(&msg);
}
void run_ecdsa_openssl() {