diff --git a/src/eckey.h b/src/eckey.h index 76e3da4..2396d97 100644 --- a/src/eckey.h +++ b/src/eckey.h @@ -10,7 +10,13 @@ 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_tweak_add(secp256k1_num_t *key, const secp256k1_num_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_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 9fa3fa4..70d7616 100644 --- a/src/eckey_impl.h +++ b/src/eckey_impl.h @@ -131,4 +131,59 @@ 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)) + return 0; + return 1; +} + +int static 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; + + 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_ecmult(&pt, &pt, &one, tweak); + secp256k1_num_free(&one); + + if (secp256k1_gej_is_infinity(&pt)) + return 0; + secp256k1_ge_set_gej(key, &pt); + 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) + return 0; + + secp256k1_num_mod_mul(key, key, tweak, &secp256k1_ge_consts->order); + return 1; +} + +int static 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) + return 0; + + secp256k1_num_t zero; + secp256k1_num_init(&zero); + secp256k1_num_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; +} + #endif diff --git a/src/secp256k1.c b/src/secp256k1.c index 8ad02a3..94026dd 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -220,23 +220,18 @@ int secp256k1_ec_privkey_tweak_add(unsigned char *seckey, const unsigned char *t DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(tweak != NULL); - int ret = 1; secp256k1_num_t term; secp256k1_num_init(&term); secp256k1_num_set_bin(&term, tweak, 32); - if (secp256k1_num_cmp(&term, &secp256k1_ge_consts->order) >= 0) - ret = 0; secp256k1_num_t sec; secp256k1_num_init(&sec); + secp256k1_num_set_bin(&sec, seckey, 32); + + int ret = secp256k1_eckey_privkey_tweak_add(&sec, &term); if (ret) { - secp256k1_num_set_bin(&sec, seckey, 32); - secp256k1_num_add(&sec, &sec, &term); - secp256k1_num_mod(&sec, &secp256k1_ge_consts->order); - if (secp256k1_num_is_zero(&sec)) - ret = 0; - } - if (ret) secp256k1_num_get_bin(seckey, 32, &sec); + } + secp256k1_num_clear(&sec); secp256k1_num_clear(&term); secp256k1_num_free(&sec); @@ -249,32 +244,20 @@ int secp256k1_ec_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const un DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); - int ret = 1; secp256k1_num_t term; secp256k1_num_init(&term); secp256k1_num_set_bin(&term, tweak, 32); - if (secp256k1_num_cmp(&term, &secp256k1_ge_consts->order) >= 0) - ret = 0; secp256k1_ge_t p; + int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); if (ret) { - if (!secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen)) - ret = 0; + ret = secp256k1_eckey_pubkey_tweak_add(&p, &term); } if (ret) { - secp256k1_gej_t pt; - secp256k1_gej_set_ge(&pt, &p); - secp256k1_num_t one; - secp256k1_num_init(&one); - secp256k1_num_set_int(&one, 1); - secp256k1_ecmult(&pt, &pt, &one, &term); - secp256k1_num_free(&one); - if (secp256k1_gej_is_infinity(&pt)) - ret = 0; - secp256k1_ge_set_gej(&p, &pt); int oldlen = pubkeylen; secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); VERIFY_CHECK(pubkeylen == oldlen); } + secp256k1_num_free(&term); return ret; } @@ -283,22 +266,19 @@ int secp256k1_ec_privkey_tweak_mul(unsigned char *seckey, const unsigned char *t DEBUG_CHECK(seckey != NULL); DEBUG_CHECK(tweak != NULL); - int ret = 1; secp256k1_num_t factor; secp256k1_num_init(&factor); secp256k1_num_set_bin(&factor, tweak, 32); - if (secp256k1_num_is_zero(&factor)) - ret = 0; - if (secp256k1_num_cmp(&factor, &secp256k1_ge_consts->order) >= 0) - ret = 0; secp256k1_num_t sec; secp256k1_num_init(&sec); + secp256k1_num_set_bin(&sec, seckey, 32); + int ret = secp256k1_eckey_privkey_tweak_mul(&sec, &factor); if (ret) { - secp256k1_num_set_bin(&sec, seckey, 32); - secp256k1_num_mod_mul(&sec, &sec, &factor, &secp256k1_ge_consts->order); - } - if (ret) secp256k1_num_get_bin(seckey, 32, &sec); + } + + secp256k1_num_clear(&sec); + secp256k1_num_clear(&factor); secp256k1_num_free(&sec); secp256k1_num_free(&factor); return ret; @@ -309,32 +289,20 @@ int secp256k1_ec_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const un DEBUG_CHECK(pubkey != NULL); DEBUG_CHECK(tweak != NULL); - int ret = 1; secp256k1_num_t factor; secp256k1_num_init(&factor); secp256k1_num_set_bin(&factor, tweak, 32); - if (secp256k1_num_is_zero(&factor)) - ret = 0; - if (secp256k1_num_cmp(&factor, &secp256k1_ge_consts->order) >= 0) - ret = 0; secp256k1_ge_t p; + int ret = secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen); if (ret) { - if (!secp256k1_eckey_pubkey_parse(&p, pubkey, pubkeylen)) - ret = 0; + ret = secp256k1_eckey_pubkey_tweak_mul(&p, &factor); } if (ret) { - secp256k1_num_t zero; - secp256k1_num_init(&zero); - secp256k1_num_set_int(&zero, 0); - secp256k1_gej_t pt; - secp256k1_gej_set_ge(&pt, &p); - secp256k1_ecmult(&pt, &pt, &factor, &zero); - secp256k1_num_free(&zero); - secp256k1_ge_set_gej(&p, &pt); int oldlen = pubkeylen; secp256k1_eckey_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33); VERIFY_CHECK(pubkeylen == oldlen); } + secp256k1_num_free(&factor); return ret; }