Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions src/ecdsa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,32 +25,37 @@ static const secp256k1_fe_t secp256k1_ecdsa_const_p_minus_order = SECP256K1_FE_C
);

static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) {
unsigned char ra[32] = {0}, sa[32] = {0};
const unsigned char *rp;
const unsigned char *sp;
int lenr;
int lens;
int overflow;
if (sig[0] != 0x30) return 0;
int lenr = sig[3];
lenr = sig[3];
if (5+lenr >= size) return 0;
int lens = sig[lenr+5];
lens = sig[lenr+5];
if (sig[1] != lenr+lens+4) return 0;
if (lenr+lens+6 > size) return 0;
if (sig[2] != 0x02) return 0;
if (lenr == 0) return 0;
if (sig[lenr+4] != 0x02) return 0;
if (lens == 0) return 0;
const unsigned char *sp = sig + 6 + lenr;
sp = sig + 6 + lenr;
while (lens > 0 && sp[0] == 0) {
lens--;
sp++;
}
if (lens > 32) return 0;
const unsigned char *rp = sig + 4;
rp = sig + 4;
while (lenr > 0 && rp[0] == 0) {
lenr--;
rp++;
}
if (lenr > 32) return 0;
unsigned char ra[32] = {0}, sa[32] = {0};
memcpy(ra + 32 - lenr, rp, lenr);
memcpy(sa + 32 - lens, sp, lens);
int overflow = 0;
overflow = 0;
secp256k1_scalar_set_b32(&r->r, ra, &overflow);
if (overflow) return 0;
secp256k1_scalar_set_b32(&r->s, sa, &overflow);
Expand All @@ -60,10 +65,10 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned ch

static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) {
unsigned char r[33] = {0}, s[33] = {0};
secp256k1_scalar_get_b32(&r[1], &a->r);
secp256k1_scalar_get_b32(&s[1], &a->s);
unsigned char *rp = r, *sp = s;
int lenR = 33, lenS = 33;
secp256k1_scalar_get_b32(&r[1], &a->r);
secp256k1_scalar_get_b32(&s[1], &a->s);
while (lenR > 1 && rp[0] == 0 && rp[1] < 0x80) { lenR--; rp++; }
while (lenS > 1 && sp[0] == 0 && sp[1] < 0x80) { lenS--; sp++; }
if (*size < 6+lenS+lenR)
Expand All @@ -81,21 +86,24 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se
}

static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
unsigned char c[32];
secp256k1_scalar_t sn, u1, u2;
secp256k1_fe_t xr;
secp256k1_gej_t pubkeyj;
secp256k1_gej_t pr;

if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s))
return 0;

secp256k1_scalar_t sn, u1, u2;
secp256k1_scalar_inverse_var(&sn, &sig->s);
secp256k1_scalar_mul(&u1, &sn, message);
secp256k1_scalar_mul(&u2, &sn, &sig->r);
secp256k1_gej_t pubkeyj; secp256k1_gej_set_ge(&pubkeyj, pubkey);
secp256k1_gej_t pr; secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
secp256k1_gej_set_ge(&pubkeyj, pubkey);
secp256k1_ecmult(&pr, &pubkeyj, &u2, &u1);
if (secp256k1_gej_is_infinity(&pr)) {
return 0;
}
unsigned char c[32];
secp256k1_scalar_get_b32(c, &sig->r);
secp256k1_fe_t xr;
secp256k1_fe_set_b32(&xr, c);

/** We now have the recomputed R point in pr, and its claimed x coordinate (modulo n)
Expand Down Expand Up @@ -131,44 +139,47 @@ static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const se
}

static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
unsigned char brx[32];
secp256k1_fe_t fx;
secp256k1_ge_t x;
secp256k1_gej_t xj;
secp256k1_scalar_t rn, u1, u2;
secp256k1_gej_t qj;

if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s))
return 0;

unsigned char brx[32];
secp256k1_scalar_get_b32(brx, &sig->r);
secp256k1_fe_t fx;
VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* brx comes from a scalar, so is less than the order; certainly less than p */
if (recid & 2) {
if (secp256k1_fe_cmp_var(&fx, &secp256k1_ecdsa_const_p_minus_order) >= 0)
return 0;
secp256k1_fe_add(&fx, &secp256k1_ecdsa_const_order_as_fe);
}
secp256k1_ge_t x;
if (!secp256k1_ge_set_xo_var(&x, &fx, recid & 1))
return 0;
secp256k1_gej_t xj;
secp256k1_gej_set_ge(&xj, &x);
secp256k1_scalar_t rn, u1, u2;
secp256k1_scalar_inverse_var(&rn, &sig->r);
secp256k1_scalar_mul(&u1, &rn, message);
secp256k1_scalar_negate(&u1, &u1);
secp256k1_scalar_mul(&u2, &rn, &sig->s);
secp256k1_gej_t qj;
secp256k1_ecmult(&qj, &xj, &u2, &u1);
secp256k1_ge_set_gej_var(pubkey, &qj);
return !secp256k1_gej_is_infinity(&qj);
}

static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *seckey, const secp256k1_scalar_t *message, const secp256k1_scalar_t *nonce, int *recid) {
unsigned char b[32];
secp256k1_gej_t rp;
secp256k1_ecmult_gen(&rp, nonce);
secp256k1_ge_t r;
secp256k1_scalar_t n;
int overflow = 0;

secp256k1_ecmult_gen(&rp, nonce);
secp256k1_ge_set_gej(&r, &rp);
unsigned char b[32];
secp256k1_fe_normalize(&r.x);
secp256k1_fe_normalize(&r.y);
secp256k1_fe_get_b32(b, &r.x);
int overflow = 0;
secp256k1_scalar_set_b32(&sig->r, b, &overflow);
if (secp256k1_scalar_is_zero(&sig->r)) {
/* P.x = order is on the curve, so technically sig->r could end up zero, which would be an invalid signature. */
Expand All @@ -178,7 +189,6 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_
}
if (recid)
*recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
secp256k1_scalar_t n;
secp256k1_scalar_mul(&n, &sig->r, seckey);
secp256k1_scalar_add(&n, &n, message);
secp256k1_scalar_inverse(&sig->s, nonce);
Expand Down
19 changes: 9 additions & 10 deletions src/eckey_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,16 @@ static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char
}

static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned char *privkey, int privkeylen) {
unsigned char c[32] = {0};
const unsigned char *end = privkey + privkeylen;
int lenb = 0;
int len = 0;
int overflow = 0;
/* sequence header */
if (end < privkey+1 || *privkey != 0x30)
return 0;
privkey++;
/* sequence length constructor */
int lenb = 0;
if (end < privkey+1 || !(*privkey & 0x80))
return 0;
lenb = *privkey & ~0x80; privkey++;
Expand All @@ -66,7 +69,6 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned
if (end < privkey+lenb)
return 0;
/* sequence length */
int len = 0;
len = privkey[lenb-1] | (lenb > 1 ? privkey[lenb-2] << 8 : 0);
privkey += lenb;
if (end < privkey+len)
Expand All @@ -78,8 +80,6 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned
/* 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;
int overflow = 0;
unsigned char c[32] = {0};
memcpy(c + 32 - privkey[1], privkey + 2, privkey[1]);
secp256k1_scalar_set_b32(key, c, &overflow);
memset(c, 0, 32);
Expand All @@ -88,8 +88,9 @@ static int secp256k1_eckey_privkey_parse(secp256k1_scalar_t *key, const unsigned

static int 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;
int pubkeylen = 0;
secp256k1_ecmult_gen(&rp, key);
secp256k1_ge_set_gej(&r, &rp);
if (compressed) {
static const unsigned char begin[] = {
Expand All @@ -110,7 +111,6 @@ static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
secp256k1_scalar_get_b32(ptr, key); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
int pubkeylen = 0;
if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 1)) {
return 0;
}
Expand All @@ -137,7 +137,6 @@ static int secp256k1_eckey_privkey_serialize(unsigned char *privkey, int *privke
memcpy(ptr, begin, sizeof(begin)); ptr += sizeof(begin);
secp256k1_scalar_get_b32(ptr, key); ptr += 32;
memcpy(ptr, middle, sizeof(middle)); ptr += sizeof(middle);
int pubkeylen = 0;
if (!secp256k1_eckey_pubkey_serialize(&r, ptr, &pubkeylen, 0)) {
return 0;
}
Expand All @@ -156,8 +155,8 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp

static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
secp256k1_gej_t pt;
secp256k1_gej_set_ge(&pt, key);
secp256k1_scalar_t one;
secp256k1_gej_set_ge(&pt, key);
secp256k1_scalar_set_int(&one, 1);
secp256k1_ecmult(&pt, &pt, &one, tweak);

Expand All @@ -176,12 +175,12 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp
}

static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
secp256k1_scalar_t zero;
secp256k1_gej_t pt;
if (secp256k1_scalar_is_zero(tweak))
return 0;

secp256k1_scalar_t zero;
secp256k1_scalar_set_int(&zero, 0);
secp256k1_gej_t pt;
secp256k1_gej_set_ge(&pt, key);
secp256k1_ecmult(&pt, &pt, tweak, &zero);
secp256k1_ge_set_gej(key, &pt);
Expand Down
9 changes: 5 additions & 4 deletions src/hash_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ static void secp256k1_sha256_finalize(secp256k1_sha256_t *hash, unsigned char *o
}

static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, const unsigned char *key, size_t keylen) {
int n;
unsigned char rkey[64];
if (keylen <= 64) {
memcpy(rkey, key, keylen);
Expand All @@ -187,12 +188,12 @@ static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256_t *hash, cons
}

secp256k1_sha256_initialize(&hash->outer);
for (int n = 0; n < 64; n++)
for (n = 0; n < 64; n++)
rkey[n] ^= 0x5c;
secp256k1_sha256_write(&hash->outer, rkey, 64);

secp256k1_sha256_initialize(&hash->inner);
for (int n = 0; n < 64; n++)
for (n = 0; n < 64; n++)
rkey[n] ^= 0x5c ^ 0x36;
secp256k1_sha256_write(&hash->inner, rkey, 64);
memset(rkey, 0, 64);
Expand All @@ -212,13 +213,13 @@ static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256_t *hash, unsign


static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256_t *rng, const unsigned char *key, size_t keylen, const unsigned char *msg, size_t msglen) {
secp256k1_hmac_sha256_t hmac;
static const unsigned char zero[1] = {0x00};
static const unsigned char one[1] = {0x01};

memset(rng->v, 0x01, 32);
memset(rng->k, 0x00, 32);

secp256k1_hmac_sha256_t hmac;
secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
secp256k1_hmac_sha256_write(&hmac, zero, 1);
Expand Down Expand Up @@ -256,10 +257,10 @@ static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256

while (outlen > 0) {
secp256k1_hmac_sha256_t hmac;
int now = outlen;
secp256k1_hmac_sha256_initialize(&hmac, rng->k, 32);
secp256k1_hmac_sha256_write(&hmac, rng->v, 32);
secp256k1_hmac_sha256_finalize(&hmac, rng->v);
int now = outlen;
if (now > 32) {
now = 32;
}
Expand Down
29 changes: 17 additions & 12 deletions src/num_gmp_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ static void secp256k1_num_copy(secp256k1_num_t *r, const secp256k1_num_t *a) {
static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num_t *a) {
unsigned char tmp[65];
int len = 0;
int shift = 0;
if (a->limbs>1 || a->data[0] != 0) {
len = mpn_get_str(tmp, 256, (mp_limb_t*)a->data, a->limbs);
}
int shift = 0;
while (shift < len && tmp[shift] == 0) shift++;
VERIFY_CHECK(len-shift <= (int)rlen);
memset(r, 0, rlen - len + shift);
Expand All @@ -43,9 +43,10 @@ static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const sec
}

static void secp256k1_num_set_bin(secp256k1_num_t *r, const unsigned char *a, unsigned int alen) {
int len;
VERIFY_CHECK(alen > 0);
VERIFY_CHECK(alen <= 64);
int len = mpn_set_str(r->data, a, alen, 256);
len = mpn_set_str(r->data, a, alen, 256);
if (len == 0) {
r->data[0] = 0;
len = 1;
Expand Down Expand Up @@ -91,6 +92,12 @@ static void secp256k1_num_mod(secp256k1_num_t *r, const secp256k1_num_t *m) {
}

static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *m) {
int i;
mp_limb_t g[NUM_LIMBS+1];
mp_limb_t u[NUM_LIMBS+1];
mp_limb_t v[NUM_LIMBS+1];
mp_size_t sn;
mp_size_t gn;
secp256k1_num_sanity(a);
secp256k1_num_sanity(m);

Expand All @@ -106,15 +113,12 @@ static void secp256k1_num_mod_inverse(secp256k1_num_t *r, const secp256k1_num_t
*/
VERIFY_CHECK(m->limbs <= NUM_LIMBS);
VERIFY_CHECK(m->data[m->limbs-1] != 0);
mp_limb_t g[NUM_LIMBS+1];
mp_limb_t u[NUM_LIMBS+1];
mp_limb_t v[NUM_LIMBS+1];
for (int i=0; i < m->limbs; i++) {
for (i = 0; i < m->limbs; i++) {
u[i] = (i < a->limbs) ? a->data[i] : 0;
v[i] = m->data[i];
}
mp_size_t sn = NUM_LIMBS+1;
mp_size_t gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs);
sn = NUM_LIMBS+1;
gn = mpn_gcdext(g, r->data, &sn, u, m->limbs, v, m->limbs);
VERIFY_CHECK(gn == 1);
VERIFY_CHECK(g[0] == 1);
r->neg = a->neg ^ m->neg;
Expand Down Expand Up @@ -183,10 +187,10 @@ static void secp256k1_num_sub(secp256k1_num_t *r, const secp256k1_num_t *a, cons
}

static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, const secp256k1_num_t *b) {
mp_limb_t tmp[2*NUM_LIMBS+1];
secp256k1_num_sanity(a);
secp256k1_num_sanity(b);

mp_limb_t tmp[2*NUM_LIMBS+1];
VERIFY_CHECK(a->limbs + b->limbs <= 2*NUM_LIMBS+1);
if ((a->limbs==1 && a->data[0]==0) || (b->limbs==1 && b->data[0]==0)) {
r->limbs = 1;
Expand All @@ -207,13 +211,14 @@ static void secp256k1_num_mul(secp256k1_num_t *r, const secp256k1_num_t *a, cons
}

static void secp256k1_num_shift(secp256k1_num_t *r, int bits) {
int i;
if (bits % GMP_NUMB_BITS) {
// Shift within limbs.
/* Shift within limbs. */
mpn_rshift(r->data, r->data, r->limbs, bits % GMP_NUMB_BITS);
}
if (bits >= GMP_NUMB_BITS) {
// Shift full limbs.
for (int i = 0; i < r->limbs; i++) {
/* Shift full limbs. */
for (i = 0; i < r->limbs; i++) {
int index = i + (bits / GMP_NUMB_BITS);
if (index < r->limbs && index < 2*NUM_LIMBS) {
r->data[i] = r->data[index];
Expand Down
3 changes: 2 additions & 1 deletion src/testrand_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ SECP256K1_INLINE static uint32_t secp256k1_rand32(void) {
}

static void secp256k1_rand256(unsigned char *b32) {
for (int i=0; i<8; i++) {
int i;
for (i = 0; i < 8; i++) {
uint32_t r = secp256k1_rand32();
b32[i*4 + 0] = (r >> 0) & 0xFF;
b32[i*4 + 1] = (r >> 8) & 0xFF;
Expand Down