From a9f5c8b8753fbe9d3faf19a7f90985d103c2b648 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Tue, 28 Oct 2014 04:08:15 -0700 Subject: [PATCH] Introduce secp256k1_scalar_t for future constant-time mod order operations --- Makefile.am | 2 + src/ecdsa.h | 2 +- src/ecdsa_impl.h | 41 ++++++----- src/eckey.h | 9 +-- src/eckey_impl.h | 30 ++++---- src/ecmult_gen.h | 4 +- src/ecmult_gen_impl.h | 11 +-- src/num.h | 3 + src/num_gmp_impl.h | 8 +++ src/num_openssl_impl.h | 8 +++ src/scalar.h | 54 +++++++++++++++ src/scalar_impl.h | 73 ++++++++++++++++++++ src/secp256k1.c | 153 +++++++++++++++++++++-------------------- src/tests.c | 70 ++++++++++++------- 14 files changed, 319 insertions(+), 149 deletions(-) create mode 100644 src/scalar.h create mode 100644 src/scalar_impl.h diff --git a/Makefile.am b/Makefile.am index 2cb6b8b..c6612d8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/src/ecdsa.h b/src/ecdsa.h index ff47f9b..a5e65dc 100644 --- a/src/ecdsa.h +++ b/src/ecdsa.h @@ -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); diff --git a/src/ecdsa_impl.h b/src/ecdsa_impl.h index ee605ac..eef3b7d 100644 --- a/src/ecdsa_impl.h +++ b/src/ecdsa_impl.h @@ -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; } diff --git a/src/eckey.h b/src/eckey.h index 2396d97..c5e828f 100644 --- a/src/eckey.h +++ b/src/eckey.h @@ -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 diff --git a/src/eckey_impl.h b/src/eckey_impl.h index 70d7616..792b741 100644 --- a/src/eckey_impl.h +++ b/src/eckey_impl.h @@ -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; } diff --git a/src/ecmult_gen.h b/src/ecmult_gen.h index b71b6a9..79aa4bf 100644 --- a/src/ecmult_gen.h +++ b/src/ecmult_gen.h @@ -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 diff --git a/src/ecmult_gen_impl.h b/src/ecmult_gen_impl.h index 9fa3dc4..a81c494 100644 --- a/src/ecmult_gen_impl.h +++ b/src/ecmult_gen_impl.h @@ -6,7 +6,7 @@ #define _SECP256K1_ECMULT_GEN_IMPL_H_ #include -#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; kprec[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 diff --git a/src/num.h b/src/num.h index d24288c..4bc2e16 100644 --- a/src/num.h +++ b/src/num.h @@ -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 diff --git a/src/num_gmp_impl.h b/src/num_gmp_impl.h index b6b3b84..2b65aa8 100644 --- a/src/num_gmp_impl.h +++ b/src/num_gmp_impl.h @@ -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 diff --git a/src/num_openssl_impl.h b/src/num_openssl_impl.h index 74e743c..0c0049e 100644 --- a/src/num_openssl_impl.h +++ b/src/num_openssl_impl.h @@ -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 diff --git a/src/scalar.h b/src/scalar.h new file mode 100644 index 0000000..880bbea --- /dev/null +++ b/src/scalar.h @@ -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 diff --git a/src/scalar_impl.h b/src/scalar_impl.h new file mode 100644 index 0000000..9cc1657 --- /dev/null +++ b/src/scalar_impl.h @@ -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 + +#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 diff --git a/src/secp256k1.c b/src/secp256k1.c index 94026dd..a7ba14f 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -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; } diff --git a/src/tests.c b/src/tests.c index 12a218f..76a20fb 100644 --- a/src/tests.c +++ b/src/tests.c @@ -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() {