Introduce secp256k1_scalar_t for future constant-time mod order operations
This commit is contained in:
parent
b2bfdabdeb
commit
a9f5c8b875
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
153
src/secp256k1.c
153
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;
|
||||
}
|
||||
|
|
70
src/tests.c
70
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() {
|
||||
|
|
Loading…
Reference in New Issue