mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-27 11:43:26 -03:00
Switch all EC/ECDSA logic from num to scalar
This commit is contained in:
parent
6794be6080
commit
f24041d6aa
15 changed files with 285 additions and 192 deletions
14
src/ecdsa.h
14
src/ecdsa.h
|
@ -7,17 +7,21 @@
|
|||
#ifndef _SECP256K1_ECDSA_
|
||||
#define _SECP256K1_ECDSA_
|
||||
|
||||
#include "num.h"
|
||||
#include "scalar.h"
|
||||
#include "group.h"
|
||||
|
||||
static void secp256k1_ecsda_start(void);
|
||||
static void secp256k1_ecdsa_stop(void);
|
||||
|
||||
typedef struct {
|
||||
secp256k1_num_t r, s;
|
||||
secp256k1_scalar_t r, s;
|
||||
} secp256k1_ecdsa_sig_t;
|
||||
|
||||
static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size);
|
||||
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a);
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message);
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message);
|
||||
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);
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid);
|
||||
static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s);
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid);
|
||||
static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s);
|
||||
|
||||
#endif
|
||||
|
|
178
src/ecdsa_impl.h
178
src/ecdsa_impl.h
|
@ -8,13 +8,47 @@
|
|||
#ifndef _SECP256K1_ECDSA_IMPL_H_
|
||||
#define _SECP256K1_ECDSA_IMPL_H_
|
||||
|
||||
#include "num.h"
|
||||
#include "scalar.h"
|
||||
#include "field.h"
|
||||
#include "group.h"
|
||||
#include "ecmult.h"
|
||||
#include "ecmult_gen.h"
|
||||
#include "ecdsa.h"
|
||||
|
||||
typedef struct {
|
||||
secp256k1_fe_t order_as_fe;
|
||||
secp256k1_fe_t p_minus_order;
|
||||
} secp256k1_ecdsa_consts_t;
|
||||
|
||||
static const secp256k1_ecdsa_consts_t *secp256k1_ecdsa_consts = NULL;
|
||||
|
||||
static void secp256k1_ecdsa_start(void) {
|
||||
if (secp256k1_ecdsa_consts != NULL)
|
||||
return;
|
||||
|
||||
/* Allocate. */
|
||||
secp256k1_ecdsa_consts_t *ret = (secp256k1_ecdsa_consts_t*)malloc(sizeof(secp256k1_ecdsa_consts_t));
|
||||
|
||||
unsigned char p[32];
|
||||
secp256k1_num_get_bin(p, 32, &secp256k1_ge_consts->order);
|
||||
secp256k1_fe_set_b32(&ret->order_as_fe, p);
|
||||
|
||||
secp256k1_fe_negate(&ret->p_minus_order, &ret->order_as_fe, 1);
|
||||
secp256k1_fe_normalize(&ret->p_minus_order);
|
||||
|
||||
/* Set the global pointer. */
|
||||
secp256k1_ecdsa_consts = ret;
|
||||
}
|
||||
|
||||
static void secp256k1_ecdsa_stop(void) {
|
||||
if (secp256k1_ecdsa_consts == NULL)
|
||||
return;
|
||||
|
||||
secp256k1_ecdsa_consts_t *c = (secp256k1_ecdsa_consts_t*)secp256k1_ecmult_consts;
|
||||
secp256k1_ecdsa_consts = NULL;
|
||||
free(c);
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned char *sig, int size) {
|
||||
if (sig[0] != 0x30) return 0;
|
||||
int lenr = sig[3];
|
||||
|
@ -26,18 +60,37 @@ static int secp256k1_ecdsa_sig_parse(secp256k1_ecdsa_sig_t *r, const unsigned ch
|
|||
if (lenr == 0) return 0;
|
||||
if (sig[lenr+4] != 0x02) return 0;
|
||||
if (lens == 0) return 0;
|
||||
secp256k1_num_set_bin(&r->r, sig+4, lenr);
|
||||
secp256k1_num_set_bin(&r->s, sig+6+lenr, lens);
|
||||
const unsigned char *sp = sig + 6 + lenr;
|
||||
while (lens > 0 && sp[0] == 0) {
|
||||
lens--;
|
||||
sp++;
|
||||
}
|
||||
if (lens > 32) return 0;
|
||||
const unsigned char *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;
|
||||
secp256k1_scalar_set_b32(&r->r, ra, &overflow);
|
||||
if (overflow) return 0;
|
||||
secp256k1_scalar_set_b32(&r->s, sa, &overflow);
|
||||
if (overflow) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const secp256k1_ecdsa_sig_t *a) {
|
||||
int lenR = (secp256k1_num_bits(&a->r) + 7)/8;
|
||||
if (lenR == 0 || secp256k1_num_get_bit(&a->r, lenR*8-1))
|
||||
lenR++;
|
||||
int lenS = (secp256k1_num_bits(&a->s) + 7)/8;
|
||||
if (lenS == 0 || secp256k1_num_get_bit(&a->s, lenS*8-1))
|
||||
lenS++;
|
||||
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;
|
||||
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)
|
||||
return 0;
|
||||
*size = 6 + lenS + lenR;
|
||||
|
@ -45,98 +98,67 @@ static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, int *size, const se
|
|||
sig[1] = 4 + lenS + lenR;
|
||||
sig[2] = 0x02;
|
||||
sig[3] = lenR;
|
||||
secp256k1_num_get_bin(sig+4, lenR, &a->r);
|
||||
memcpy(sig+4, rp, lenR);
|
||||
sig[4+lenR] = 0x02;
|
||||
sig[5+lenR] = lenS;
|
||||
secp256k1_num_get_bin(sig+lenR+6, lenS, &a->s);
|
||||
memcpy(sig+lenR+6, sp, lenS);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_recompute(secp256k1_num_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) {
|
||||
const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
|
||||
|
||||
if (secp256k1_num_is_neg(&sig->r) || secp256k1_num_is_neg(&sig->s))
|
||||
return 0;
|
||||
if (secp256k1_num_is_zero(&sig->r) || secp256k1_num_is_zero(&sig->s))
|
||||
return 0;
|
||||
if (secp256k1_num_cmp(&sig->r, &c->order) >= 0 || secp256k1_num_cmp(&sig->s, &c->order) >= 0)
|
||||
static int secp256k1_ecdsa_sig_recompute(secp256k1_scalar_t *r2, const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
|
||||
if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s))
|
||||
return 0;
|
||||
|
||||
int ret = 0;
|
||||
secp256k1_num_t sn, u1, u2;
|
||||
secp256k1_num_init(&sn);
|
||||
secp256k1_num_init(&u1);
|
||||
secp256k1_num_init(&u2);
|
||||
secp256k1_num_mod_inverse(&sn, &sig->s, &c->order);
|
||||
secp256k1_num_mod_mul(&u1, &sn, message, &c->order);
|
||||
secp256k1_num_mod_mul(&u2, &sn, &sig->r, &c->order);
|
||||
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);
|
||||
if (!secp256k1_gej_is_infinity(&pr)) {
|
||||
secp256k1_fe_t xr; secp256k1_gej_get_x_var(&xr, &pr);
|
||||
secp256k1_fe_normalize(&xr);
|
||||
unsigned char xrb[32]; secp256k1_fe_get_b32(xrb, &xr);
|
||||
secp256k1_num_set_bin(r2, xrb, 32);
|
||||
secp256k1_num_mod(r2, &c->order);
|
||||
secp256k1_scalar_set_b32(r2, xrb, NULL);
|
||||
ret = 1;
|
||||
}
|
||||
secp256k1_num_free(&sn);
|
||||
secp256k1_num_free(&u1);
|
||||
secp256k1_num_free(&u2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_num_t *message, int recid) {
|
||||
const secp256k1_ge_consts_t *c = secp256k1_ge_consts;
|
||||
|
||||
if (secp256k1_num_is_neg(&sig->r) || secp256k1_num_is_neg(&sig->s))
|
||||
return 0;
|
||||
if (secp256k1_num_is_zero(&sig->r) || secp256k1_num_is_zero(&sig->s))
|
||||
return 0;
|
||||
if (secp256k1_num_cmp(&sig->r, &c->order) >= 0 || secp256k1_num_cmp(&sig->s, &c->order) >= 0)
|
||||
static int secp256k1_ecdsa_sig_recover(const secp256k1_ecdsa_sig_t *sig, secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message, int recid) {
|
||||
if (secp256k1_scalar_is_zero(&sig->r) || secp256k1_scalar_is_zero(&sig->s))
|
||||
return 0;
|
||||
|
||||
secp256k1_num_t rx;
|
||||
secp256k1_num_init(&rx);
|
||||
secp256k1_num_copy(&rx, &sig->r);
|
||||
if (recid & 2) {
|
||||
secp256k1_num_add(&rx, &rx, &c->order);
|
||||
if (secp256k1_num_cmp(&rx, &secp256k1_fe_consts->p) >= 0)
|
||||
return 0;
|
||||
}
|
||||
unsigned char brx[32];
|
||||
secp256k1_num_get_bin(brx, 32, &rx);
|
||||
secp256k1_num_free(&rx);
|
||||
secp256k1_scalar_get_b32(brx, &sig->r);
|
||||
secp256k1_fe_t fx;
|
||||
VERIFY_CHECK(secp256k1_fe_set_b32(&fx, brx)); /* Either rx < n (and n < p), or rx + n < p (checked above). */
|
||||
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_consts->p_minus_order) >= 0)
|
||||
return 0;
|
||||
secp256k1_fe_add(&fx, &secp256k1_ecdsa_consts->order_as_fe);
|
||||
}
|
||||
secp256k1_ge_t x;
|
||||
if (!secp256k1_ge_set_xo(&x, &fx, recid & 1))
|
||||
return 0;
|
||||
secp256k1_gej_t xj;
|
||||
secp256k1_gej_set_ge(&xj, &x);
|
||||
secp256k1_num_t rn, u1, u2;
|
||||
secp256k1_num_init(&rn);
|
||||
secp256k1_num_init(&u1);
|
||||
secp256k1_num_init(&u2);
|
||||
secp256k1_num_mod_inverse(&rn, &sig->r, &c->order);
|
||||
secp256k1_num_mod_mul(&u1, &rn, message, &c->order);
|
||||
secp256k1_num_sub(&u1, &c->order, &u1);
|
||||
secp256k1_num_mod_mul(&u2, &rn, &sig->s, &c->order);
|
||||
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);
|
||||
secp256k1_num_free(&rn);
|
||||
secp256k1_num_free(&u1);
|
||||
secp256k1_num_free(&u2);
|
||||
return !secp256k1_gej_is_infinity(&qj);
|
||||
}
|
||||
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_num_t *message) {
|
||||
secp256k1_num_t r2;
|
||||
secp256k1_num_init(&r2);
|
||||
static int secp256k1_ecdsa_sig_verify(const secp256k1_ecdsa_sig_t *sig, const secp256k1_ge_t *pubkey, const secp256k1_scalar_t *message) {
|
||||
secp256k1_scalar_t r2;
|
||||
int ret = 0;
|
||||
ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_num_cmp(&sig->r, &r2) == 0;
|
||||
secp256k1_num_free(&r2);
|
||||
ret = secp256k1_ecdsa_sig_recompute(&r2, sig, pubkey, message) && secp256k1_scalar_eq(&sig->r, &r2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -150,34 +172,30 @@ static int secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_
|
|||
secp256k1_fe_normalize(&r.y);
|
||||
secp256k1_fe_get_b32(b, &r.x);
|
||||
int overflow = 0;
|
||||
secp256k1_scalar_t sigr;
|
||||
secp256k1_scalar_set_b32(&sigr, b, &overflow);
|
||||
secp256k1_scalar_set_b32(&sig->r, b, &overflow);
|
||||
if (recid)
|
||||
*recid = (overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0);
|
||||
secp256k1_scalar_t n;
|
||||
secp256k1_scalar_mul(&n, &sigr, seckey);
|
||||
secp256k1_scalar_mul(&n, &sig->r, seckey);
|
||||
secp256k1_scalar_add(&n, &n, message);
|
||||
secp256k1_scalar_t sigs;
|
||||
secp256k1_scalar_inverse(&sigs, nonce);
|
||||
secp256k1_scalar_mul(&sigs, &sigs, &n);
|
||||
secp256k1_scalar_inverse(&sig->s, nonce);
|
||||
secp256k1_scalar_mul(&sig->s, &sig->s, &n);
|
||||
secp256k1_scalar_clear(&n);
|
||||
secp256k1_gej_clear(&rp);
|
||||
secp256k1_ge_clear(&r);
|
||||
if (secp256k1_scalar_is_zero(&sigs))
|
||||
if (secp256k1_scalar_is_zero(&sig->s))
|
||||
return 0;
|
||||
if (secp256k1_scalar_is_high(&sigs)) {
|
||||
secp256k1_scalar_negate(&sigs, &sigs);
|
||||
if (secp256k1_scalar_is_high(&sig->s)) {
|
||||
secp256k1_scalar_negate(&sig->s, &sig->s);
|
||||
if (recid)
|
||||
*recid ^= 1;
|
||||
}
|
||||
secp256k1_scalar_get_num(&sig->s, &sigs);
|
||||
secp256k1_scalar_get_num(&sig->r, &sigr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_num_t *r, const secp256k1_num_t *s) {
|
||||
secp256k1_num_copy(&sig->r, r);
|
||||
secp256k1_num_copy(&sig->s, s);
|
||||
static void secp256k1_ecdsa_sig_set_rs(secp256k1_ecdsa_sig_t *sig, const secp256k1_scalar_t *r, const secp256k1_scalar_t *s) {
|
||||
sig->r = *r;
|
||||
sig->s = *s;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include "group.h"
|
||||
#include "scalar.h"
|
||||
#include "num.h"
|
||||
|
||||
static int secp256k1_eckey_pubkey_parse(secp256k1_ge_t *elem, const unsigned char *pub, int size);
|
||||
static int secp256k1_eckey_pubkey_serialize(secp256k1_ge_t *elem, unsigned char *pub, int *size, int compressed);
|
||||
|
@ -18,8 +17,8 @@ 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);
|
||||
|
||||
static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_num_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp256k1_scalar_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_num_t *tweak);
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include "eckey.h"
|
||||
|
||||
#include "num.h"
|
||||
#include "scalar.h"
|
||||
#include "field.h"
|
||||
#include "group.h"
|
||||
#include "ecmult_gen.h"
|
||||
|
@ -154,17 +154,12 @@ static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar_t *key, const secp
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_pubkey_tweak_add(secp256k1_ge_t *key, const secp256k1_num_t *tweak) {
|
||||
if (secp256k1_num_cmp(tweak, &secp256k1_ge_consts->order) >= 0)
|
||||
return 0;
|
||||
|
||||
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_num_t one;
|
||||
secp256k1_num_init(&one);
|
||||
secp256k1_num_set_int(&one, 1);
|
||||
secp256k1_scalar_t one;
|
||||
secp256k1_scalar_set_int(&one, 1);
|
||||
secp256k1_ecmult(&pt, &pt, &one, tweak);
|
||||
secp256k1_num_free(&one);
|
||||
|
||||
if (secp256k1_gej_is_infinity(&pt))
|
||||
return 0;
|
||||
|
@ -180,19 +175,15 @@ static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar_t *key, const secp
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_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)
|
||||
static int secp256k1_eckey_pubkey_tweak_mul(secp256k1_ge_t *key, const secp256k1_scalar_t *tweak) {
|
||||
if (secp256k1_scalar_is_zero(tweak))
|
||||
return 0;
|
||||
|
||||
secp256k1_num_t zero;
|
||||
secp256k1_num_init(&zero);
|
||||
secp256k1_num_set_int(&zero, 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_num_free(&zero);
|
||||
secp256k1_ge_set_gej(key, &pt);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -14,6 +14,6 @@ static void secp256k1_ecmult_start(void);
|
|||
static void secp256k1_ecmult_stop(void);
|
||||
|
||||
/** Double multiply: R = na*A + ng*G */
|
||||
static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng);
|
||||
static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#ifndef _SECP256K1_ECMULT_IMPL_H_
|
||||
#define _SECP256K1_ECMULT_IMPL_H_
|
||||
|
||||
#include "num.h"
|
||||
#include "group.h"
|
||||
#include "scalar.h"
|
||||
#include "ecmult.h"
|
||||
|
@ -125,22 +124,13 @@ static void secp256k1_ecmult_stop(void) {
|
|||
* - the number of set values in wnaf is returned. This number is at most 256, and at most one more
|
||||
* - than the number of bits in the (absolute value) of the input.
|
||||
*/
|
||||
static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_num_t *a, int w) {
|
||||
secp256k1_num_t x;
|
||||
secp256k1_num_copy(&x, a);
|
||||
int sign = 1;
|
||||
if (secp256k1_num_is_neg(&x)) {
|
||||
sign = -1;
|
||||
secp256k1_num_negate(&x);
|
||||
}
|
||||
unsigned char cr[32];
|
||||
secp256k1_num_get_bin(cr, 32, &x);
|
||||
secp256k1_scalar_t s;
|
||||
secp256k1_scalar_set_b32(&s, cr, NULL);
|
||||
static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_scalar_t *a, int w) {
|
||||
secp256k1_scalar_t s = *a;
|
||||
|
||||
int sign = 1;
|
||||
if (secp256k1_scalar_get_bits(&s, 255, 1)) {
|
||||
secp256k1_scalar_negate(&s, &s);
|
||||
sign *= -1;
|
||||
sign = -1;
|
||||
}
|
||||
|
||||
int set_bits = 0;
|
||||
|
@ -169,13 +159,13 @@ static int secp256k1_ecmult_wnaf(int *wnaf, const secp256k1_num_t *a, int w) {
|
|||
return set_bits;
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_num_t *na, const secp256k1_num_t *ng) {
|
||||
static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const secp256k1_scalar_t *na, const secp256k1_scalar_t *ng) {
|
||||
const secp256k1_ecmult_consts_t *c = secp256k1_ecmult_consts;
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_num_t na_1, na_lam;
|
||||
secp256k1_scalar_t na_1, na_lam;
|
||||
/* split na into na_1 and na_lam (where na = na_1 + na_lam*lambda, and na_1 and na_lam are ~128 bit) */
|
||||
secp256k1_gej_split_exp_var(&na_1, &na_lam, na);
|
||||
secp256k1_scalar_split_lambda_var(&na_1, &na_lam, na);
|
||||
|
||||
/* build wnaf representation for na_1 and na_lam. */
|
||||
int wnaf_na_1[129]; int bits_na_1 = secp256k1_ecmult_wnaf(wnaf_na_1, &na_1, WINDOW_A);
|
||||
|
@ -198,10 +188,10 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
|
|||
secp256k1_gej_mul_lambda(&pre_a_lam[i], &pre_a[i]);
|
||||
|
||||
/* Splitted G factors. */
|
||||
secp256k1_num_t ng_1, ng_128;
|
||||
secp256k1_scalar_t ng_1, ng_128;
|
||||
|
||||
/* split ng into ng_1 and ng_128 (where gn = gn_1 + gn_128*2^128, and gn_1 and gn_128 are ~128 bit) */
|
||||
secp256k1_num_split(&ng_1, &ng_128, ng, 128);
|
||||
secp256k1_scalar_split_128(&ng_1, &ng_128, ng);
|
||||
|
||||
/* Build wnaf representation for ng_1 and ng_128 */
|
||||
int wnaf_ng_1[129]; int bits_ng_1 = secp256k1_ecmult_wnaf(wnaf_ng_1, &ng_1, WINDOW_G);
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
typedef struct {
|
||||
secp256k1_num_t p;
|
||||
secp256k1_fe_t order;
|
||||
} secp256k1_fe_consts_t;
|
||||
|
||||
static const secp256k1_fe_consts_t *secp256k1_fe_consts = NULL;
|
||||
|
@ -59,6 +60,9 @@ static int secp256k1_fe_is_odd(const secp256k1_fe_t *a);
|
|||
/** Compare two field elements. Requires both inputs to be normalized */
|
||||
static int secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
|
||||
|
||||
/** Compare two field elements. Requires both inputs to be normalized */
|
||||
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b);
|
||||
|
||||
/** Set a field element equal to 32-byte big endian value. If succesful, the resulting field element is normalized. */
|
||||
static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a);
|
||||
|
||||
|
|
|
@ -152,6 +152,20 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const se
|
|||
| (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0;
|
||||
}
|
||||
|
||||
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
#ifdef VERIFY
|
||||
VERIFY_CHECK(a->normalized);
|
||||
VERIFY_CHECK(b->normalized);
|
||||
secp256k1_fe_verify(a);
|
||||
secp256k1_fe_verify(b);
|
||||
#endif
|
||||
for (int i = 9; i >= 0; i--) {
|
||||
if (a->n[i] > b->n[i]) return 1;
|
||||
if (a->n[i] < b->n[i]) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
|
||||
r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
|
||||
r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
|
||||
|
|
|
@ -150,6 +150,20 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const se
|
|||
return ((t[0]^u[0]) | (t[1]^u[1]) | (t[2]^u[2]) | (t[3]^u[3]) | (t[4]^u[4])) == 0;
|
||||
}
|
||||
|
||||
static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
#ifdef VERIFY
|
||||
VERIFY_CHECK(a->normalized);
|
||||
VERIFY_CHECK(b->normalized);
|
||||
secp256k1_fe_verify(a);
|
||||
secp256k1_fe_verify(b);
|
||||
#endif
|
||||
for (int i = 4; i >= 0; i--) {
|
||||
if (a->n[i] > b->n[i]) return 1;
|
||||
if (a->n[i] < b->n[i]) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
|
||||
r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
|
||||
for (int i=0; i<32; i++) {
|
||||
|
|
|
@ -75,6 +75,14 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const se
|
|||
return ret;
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
|
||||
for (int i=FIELD_LIMBS; i>=0; i--) {
|
||||
if (a->n[i] > b->n[i]) return 1;
|
||||
if (a->n[i] < b->n[i]) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
|
||||
for (int i=0; i<FIELD_LIMBS+1; i++)
|
||||
r->n[i] = 0;
|
||||
|
|
|
@ -72,6 +72,9 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar_t *a);
|
|||
/** Convert a scalar to a number. */
|
||||
static void secp256k1_scalar_get_num(secp256k1_num_t *r, const secp256k1_scalar_t *a);
|
||||
|
||||
/** Compare two scalars. */
|
||||
static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b);
|
||||
|
||||
static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_t *r2, const secp256k1_scalar_t *a);
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
|
|
|
@ -401,4 +401,8 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_
|
|||
r2->d[3] = 0;
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
|
||||
return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3])) == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -634,4 +634,8 @@ static void secp256k1_scalar_split_128(secp256k1_scalar_t *r1, secp256k1_scalar_
|
|||
r2->d[7] = 0;
|
||||
}
|
||||
|
||||
SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar_t *a, const secp256k1_scalar_t *b) {
|
||||
return ((a->d[0] ^ b->d[0]) | (a->d[1] ^ b->d[1]) | (a->d[2] ^ b->d[2]) | (a->d[3] ^ b->d[3]) | (a->d[4] ^ b->d[4]) | (a->d[5] ^ b->d[5]) | (a->d[6] ^ b->d[6]) | (a->d[7] ^ b->d[7])) == 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
void secp256k1_start(unsigned int flags) {
|
||||
secp256k1_fe_start();
|
||||
secp256k1_ge_start();
|
||||
secp256k1_ecdsa_start();
|
||||
if (flags & SECP256K1_START_SIGN) {
|
||||
secp256k1_ecmult_gen_start();
|
||||
}
|
||||
|
@ -32,6 +33,7 @@ void secp256k1_start(unsigned int flags) {
|
|||
void secp256k1_stop(void) {
|
||||
secp256k1_ecmult_stop();
|
||||
secp256k1_ecmult_gen_stop();
|
||||
secp256k1_ecdsa_stop();
|
||||
secp256k1_ge_stop();
|
||||
secp256k1_fe_stop();
|
||||
}
|
||||
|
@ -43,11 +45,13 @@ int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned
|
|||
DEBUG_CHECK(sig != NULL);
|
||||
DEBUG_CHECK(pubkey != NULL);
|
||||
|
||||
unsigned char msg32[32] = {0};
|
||||
memcpy(msg32 + 32 - msglen, msg, msglen);
|
||||
int ret = -3;
|
||||
secp256k1_num_t m;
|
||||
secp256k1_scalar_t m;
|
||||
secp256k1_ecdsa_sig_t s;
|
||||
secp256k1_ge_t q;
|
||||
secp256k1_num_set_bin(&m, msg, msglen);
|
||||
secp256k1_scalar_set_b32(&m, msg32, NULL);
|
||||
|
||||
if (!secp256k1_eckey_pubkey_parse(&q, pubkey, pubkeylen)) {
|
||||
ret = -1;
|
||||
|
@ -123,8 +127,8 @@ int secp256k1_ecdsa_sign_compact(const unsigned char *message, int messagelen, u
|
|||
ret = secp256k1_ecdsa_sig_sign(&sig, &sec, &msg, &non, recid);
|
||||
}
|
||||
if (ret) {
|
||||
secp256k1_num_get_bin(sig64, 32, &sig.r);
|
||||
secp256k1_num_get_bin(sig64 + 32, 32, &sig.s);
|
||||
secp256k1_scalar_get_b32(sig64, &sig.r);
|
||||
secp256k1_scalar_get_b32(sig64 + 32, &sig.s);
|
||||
}
|
||||
secp256k1_scalar_clear(&msg);
|
||||
secp256k1_scalar_clear(&non);
|
||||
|
@ -142,11 +146,20 @@ int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const
|
|||
DEBUG_CHECK(recid >= 0 && recid <= 3);
|
||||
|
||||
int ret = 0;
|
||||
secp256k1_num_t m;
|
||||
unsigned char msg32[32] = {0};
|
||||
memcpy(msg32 + 32 - msglen, msg, msglen);
|
||||
secp256k1_scalar_t m;
|
||||
secp256k1_ecdsa_sig_t sig;
|
||||
secp256k1_num_set_bin(&sig.r, sig64, 32);
|
||||
secp256k1_num_set_bin(&sig.s, sig64 + 32, 32);
|
||||
secp256k1_num_set_bin(&m, msg, msglen);
|
||||
int overflow = 0;
|
||||
secp256k1_scalar_set_b32(&sig.r, sig64, &overflow);
|
||||
if (overflow) {
|
||||
return 0;
|
||||
}
|
||||
secp256k1_scalar_set_b32(&sig.s, sig64 + 32, &overflow);
|
||||
if (overflow) {
|
||||
return 0;
|
||||
}
|
||||
secp256k1_scalar_set_b32(&m, msg32, NULL);
|
||||
|
||||
secp256k1_ge_t q;
|
||||
if (secp256k1_ecdsa_sig_recover(&sig, &q, &m, recid)) {
|
||||
|
@ -224,8 +237,12 @@ int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const un
|
|||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
|
||||
secp256k1_num_t term;
|
||||
secp256k1_num_set_bin(&term, tweak, 32);
|
||||
secp256k1_scalar_t term;
|
||||
int overflow = 0;
|
||||
secp256k1_scalar_set_b32(&term, tweak, &overflow);
|
||||
if (overflow) {
|
||||
return 0;
|
||||
}
|
||||
secp256k1_ge_t p;
|
||||
int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
|
||||
if (ret) {
|
||||
|
@ -264,8 +281,12 @@ int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const un
|
|||
DEBUG_CHECK(pubkey != NULL);
|
||||
DEBUG_CHECK(tweak != NULL);
|
||||
|
||||
secp256k1_num_t factor;
|
||||
secp256k1_num_set_bin(&factor, tweak, 32);
|
||||
secp256k1_scalar_t factor;
|
||||
int overflow = 0;
|
||||
secp256k1_scalar_set_b32(&factor, tweak, &overflow);
|
||||
if (overflow) {
|
||||
return 0;
|
||||
}
|
||||
secp256k1_ge_t p;
|
||||
int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen);
|
||||
if (ret) {
|
||||
|
|
129
src/tests.c
129
src/tests.c
|
@ -100,6 +100,18 @@ void random_scalar_order_test(secp256k1_scalar_t *num) {
|
|||
} while(1);
|
||||
}
|
||||
|
||||
void random_scalar_order(secp256k1_scalar_t *num) {
|
||||
do {
|
||||
unsigned char b32[32];
|
||||
secp256k1_rand256(b32);
|
||||
int overflow = 0;
|
||||
secp256k1_scalar_set_b32(num, b32, &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];
|
||||
|
@ -240,14 +252,6 @@ void run_num_smalltests(void) {
|
|||
|
||||
/***** SCALAR TESTS *****/
|
||||
|
||||
int secp256k1_scalar_eq(const secp256k1_scalar_t *s1, const secp256k1_scalar_t *s2) {
|
||||
secp256k1_scalar_t t;
|
||||
secp256k1_scalar_negate(&t, s2);
|
||||
secp256k1_scalar_add(&t, &t, s1);
|
||||
int ret = secp256k1_scalar_is_zero(&t);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void scalar_test(void) {
|
||||
unsigned char c[32];
|
||||
|
||||
|
@ -746,35 +750,47 @@ void run_ecmult_chain(void) {
|
|||
secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64));
|
||||
secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay);
|
||||
/* two random initial factors xn and gn */
|
||||
secp256k1_num_t xn;
|
||||
secp256k1_num_set_hex(&xn, "84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407", 64);
|
||||
secp256k1_num_t gn;
|
||||
secp256k1_num_set_hex(&gn, "a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de", 64);
|
||||
static const unsigned char xni[32] = {
|
||||
0x84, 0xcc, 0x54, 0x52, 0xf7, 0xfd, 0xe1, 0xed,
|
||||
0xb4, 0xd3, 0x8a, 0x8c, 0xe9, 0xb1, 0xb8, 0x4c,
|
||||
0xce, 0xf3, 0x1f, 0x14, 0x6e, 0x56, 0x9b, 0xe9,
|
||||
0x70, 0x5d, 0x35, 0x7a, 0x42, 0x98, 0x54, 0x07
|
||||
};
|
||||
secp256k1_scalar_t xn;
|
||||
secp256k1_scalar_set_b32(&xn, xni, NULL);
|
||||
static const unsigned char gni[32] = {
|
||||
0xa1, 0xe5, 0x8d, 0x22, 0x55, 0x3d, 0xcd, 0x42,
|
||||
0xb2, 0x39, 0x80, 0x62, 0x5d, 0x4c, 0x57, 0xa9,
|
||||
0x6e, 0x93, 0x23, 0xd4, 0x2b, 0x31, 0x52, 0xe5,
|
||||
0xca, 0x2c, 0x39, 0x90, 0xed, 0xc7, 0xc9, 0xde
|
||||
};
|
||||
secp256k1_scalar_t gn;
|
||||
secp256k1_scalar_set_b32(&gn, gni, NULL);
|
||||
/* two small multipliers to be applied to xn and gn in every iteration: */
|
||||
secp256k1_num_t xf;
|
||||
secp256k1_num_set_hex(&xf, "1337", 4);
|
||||
secp256k1_num_t gf;
|
||||
secp256k1_num_set_hex(&gf, "7113", 4);
|
||||
static const unsigned char xfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x13,0x37};
|
||||
secp256k1_scalar_t xf;
|
||||
secp256k1_scalar_set_b32(&xf, xfi, NULL);
|
||||
static const unsigned char gfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x71,0x13};
|
||||
secp256k1_scalar_t gf;
|
||||
secp256k1_scalar_set_b32(&gf, gfi, NULL);
|
||||
/* accumulators with the resulting coefficients to A and G */
|
||||
secp256k1_num_t ae;
|
||||
secp256k1_num_set_int(&ae, 1);
|
||||
secp256k1_num_t ge;
|
||||
secp256k1_num_set_int(&ge, 0);
|
||||
secp256k1_scalar_t ae;
|
||||
secp256k1_scalar_set_int(&ae, 1);
|
||||
secp256k1_scalar_t ge;
|
||||
secp256k1_scalar_set_int(&ge, 0);
|
||||
/* the point being computed */
|
||||
secp256k1_gej_t x = a;
|
||||
const secp256k1_num_t *order = &secp256k1_ge_consts->order;
|
||||
for (int i=0; i<200*count; i++) {
|
||||
/* in each iteration, compute X = xn*X + gn*G; */
|
||||
secp256k1_ecmult(&x, &x, &xn, &gn);
|
||||
/* also compute ae and ge: the actual accumulated factors for A and G */
|
||||
/* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
|
||||
secp256k1_num_mod_mul(&ae, &ae, &xn, order);
|
||||
secp256k1_num_mod_mul(&ge, &ge, &xn, order);
|
||||
secp256k1_num_add(&ge, &ge, &gn);
|
||||
secp256k1_num_mod(&ge, order);
|
||||
secp256k1_scalar_mul(&ae, &ae, &xn);
|
||||
secp256k1_scalar_mul(&ge, &ge, &xn);
|
||||
secp256k1_scalar_add(&ge, &ge, &gn);
|
||||
/* modify xn and gn */
|
||||
secp256k1_num_mod_mul(&xn, &xn, &xf, order);
|
||||
secp256k1_num_mod_mul(&gn, &gn, &gf, order);
|
||||
secp256k1_scalar_mul(&xn, &xn, &xf);
|
||||
secp256k1_scalar_mul(&gn, &gn, &gf);
|
||||
|
||||
/* verify */
|
||||
if (i == 19999) {
|
||||
|
@ -795,10 +811,10 @@ void run_ecmult_chain(void) {
|
|||
|
||||
void test_point_times_order(const secp256k1_gej_t *point) {
|
||||
/* X * (point + G) + (order-X) * (pointer + G) = 0 */
|
||||
secp256k1_num_t x;
|
||||
random_num_order_test(&x);
|
||||
secp256k1_num_t nx;
|
||||
secp256k1_num_sub(&nx, &secp256k1_ge_consts->order, &x);
|
||||
secp256k1_scalar_t x;
|
||||
random_scalar_order_test(&x);
|
||||
secp256k1_scalar_t nx;
|
||||
secp256k1_scalar_negate(&nx, &x);
|
||||
secp256k1_gej_t res1, res2;
|
||||
secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */
|
||||
secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
|
||||
|
@ -824,16 +840,16 @@ void run_point_times_order(void) {
|
|||
CHECK(strcmp(c, "7603CB59B0EF6C63FE6084792A0C378CDB3233A80F8A9A09A877DEAD31B38C45") == 0);
|
||||
}
|
||||
|
||||
void test_wnaf(const secp256k1_num_t *number, int w) {
|
||||
secp256k1_num_t x, two, t;
|
||||
secp256k1_num_set_int(&x, 0);
|
||||
secp256k1_num_set_int(&two, 2);
|
||||
void test_wnaf(const secp256k1_scalar_t *number, int w) {
|
||||
secp256k1_scalar_t x, two, t;
|
||||
secp256k1_scalar_set_int(&x, 0);
|
||||
secp256k1_scalar_set_int(&two, 2);
|
||||
int wnaf[256];
|
||||
int bits = secp256k1_ecmult_wnaf(wnaf, number, w);
|
||||
CHECK(bits <= 256);
|
||||
int zeroes = -1;
|
||||
for (int i=bits-1; i>=0; i--) {
|
||||
secp256k1_num_mul(&x, &x, &two);
|
||||
secp256k1_scalar_mul(&x, &x, &two);
|
||||
int v = wnaf[i];
|
||||
if (v) {
|
||||
CHECK(zeroes == -1 || zeroes >= w-1); /* check that distance between non-zero elements is at least w-1 */
|
||||
|
@ -845,21 +861,23 @@ void test_wnaf(const secp256k1_num_t *number, int w) {
|
|||
CHECK(zeroes != -1); /* check that no unnecessary zero padding exists */
|
||||
zeroes++;
|
||||
}
|
||||
secp256k1_num_set_int(&t, v);
|
||||
secp256k1_num_add(&x, &x, &t);
|
||||
if (v >= 0) {
|
||||
secp256k1_scalar_set_int(&t, v);
|
||||
} else {
|
||||
secp256k1_scalar_set_int(&t, -v);
|
||||
secp256k1_scalar_negate(&t, &t);
|
||||
}
|
||||
secp256k1_scalar_add(&x, &x, &t);
|
||||
}
|
||||
secp256k1_num_t xcopy = x, ncopy = *number;
|
||||
secp256k1_num_mod(&xcopy, &secp256k1_ge_consts->order);
|
||||
secp256k1_num_mod(&ncopy, &secp256k1_ge_consts->order);
|
||||
CHECK(secp256k1_num_eq(&xcopy, &ncopy)); /* check that wnaf represents number */
|
||||
CHECK(secp256k1_scalar_eq(&x, number)); /* check that wnaf represents number */
|
||||
}
|
||||
|
||||
void run_wnaf(void) {
|
||||
secp256k1_num_t n;
|
||||
secp256k1_scalar_t n;
|
||||
for (int i=0; i<count; i++) {
|
||||
random_num_order(&n);
|
||||
random_scalar_order(&n);
|
||||
if (i % 1)
|
||||
secp256k1_num_negate(&n);
|
||||
secp256k1_scalar_negate(&n, &n);
|
||||
test_wnaf(&n, 4+(i%10));
|
||||
}
|
||||
}
|
||||
|
@ -879,11 +897,11 @@ void test_ecdsa_sign_verify(void) {
|
|||
secp256k1_ge_t pub; secp256k1_ge_set_gej(&pub, &pubj);
|
||||
secp256k1_ecdsa_sig_t sig;
|
||||
random_sign(&sig, &key, &msg, NULL);
|
||||
secp256k1_num_t 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));
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
|
||||
secp256k1_scalar_t one;
|
||||
secp256k1_scalar_set_int(&one, 1);
|
||||
secp256k1_scalar_add(&msg, &msg, &one);
|
||||
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &pub, &msg));
|
||||
}
|
||||
|
||||
void run_ecdsa_sign_verify(void) {
|
||||
|
@ -1071,11 +1089,12 @@ void test_ecdsa_openssl(void) {
|
|||
CHECK(ECDSA_sign(0, message, sizeof(message), signature, &sigsize, ec_key));
|
||||
secp256k1_ecdsa_sig_t sig;
|
||||
CHECK(secp256k1_ecdsa_sig_parse(&sig, signature, sigsize));
|
||||
secp256k1_num_t 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_num));
|
||||
CHECK(secp256k1_ecdsa_sig_verify(&sig, &q, &msg));
|
||||
secp256k1_scalar_t one;
|
||||
secp256k1_scalar_set_int(&one, 1);
|
||||
secp256k1_scalar_t msg2;
|
||||
secp256k1_scalar_add(&msg2, &msg, &one);
|
||||
CHECK(!secp256k1_ecdsa_sig_verify(&sig, &q, &msg2));
|
||||
|
||||
random_sign(&sig, &key, &msg, NULL);
|
||||
int secp_sigsize = 80;
|
||||
|
|
Loading…
Add table
Reference in a new issue