From d0b33489f282ae3675cb4fc5ae4c2c9381df4103 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Sep 2013 00:58:42 +0200 Subject: [PATCH] Break malleability by producing S <= order/2 --- src/group.h | 1 + src/impl/ecdsa.h | 2 +- src/impl/group.h | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/group.h b/src/group.h index dd601fa0b05..ae291c6caa4 100644 --- a/src/group.h +++ b/src/group.h @@ -26,6 +26,7 @@ typedef struct { /** Global constants related to the group */ typedef struct { secp256k1_num_t order; // the order of the curve (= order of its generator) + secp256k1_num_t half_order; // half the order of the curve (= order of its generator) secp256k1_ge_t g; // the generator point // constants related to secp256k1's efficiently computable endomorphism diff --git a/src/impl/ecdsa.h b/src/impl/ecdsa.h index 1d45e211584..3b7ffe2ee92 100644 --- a/src/impl/ecdsa.h +++ b/src/impl/ecdsa.h @@ -187,7 +187,7 @@ int static secp256k1_ecdsa_sig_sign(secp256k1_ecdsa_sig_t *sig, const secp256k1_ secp256k1_num_free(&n); if (secp256k1_num_is_zero(&sig->s)) return 0; - if (secp256k1_num_is_odd(&sig->s)) { + if (secp256k1_num_cmp(&sig->s, &c->half_order) > 0) { secp256k1_num_sub(&sig->s, &c->order, &sig->s); if (recid) *recid ^= 1; diff --git a/src/impl/group.h b/src/impl/group.h index 37c509a4748..ce8d7b2043b 100644 --- a/src/impl/group.h +++ b/src/impl/group.h @@ -359,6 +359,7 @@ void static secp256k1_ge_start(void) { if (secp256k1_ge_consts == NULL) { secp256k1_ge_consts_t *ret = (secp256k1_ge_consts_t*)malloc(sizeof(secp256k1_ge_consts_t)); secp256k1_num_init(&ret->order); + secp256k1_num_init(&ret->half_order); secp256k1_num_init(&ret->lambda); secp256k1_num_init(&ret->a1b2); secp256k1_num_init(&ret->a2); @@ -368,6 +369,8 @@ void static secp256k1_ge_start(void) { secp256k1_num_set_bin(&ret->a1b2, secp256k1_ge_consts_a1b2, sizeof(secp256k1_ge_consts_a1b2)); secp256k1_num_set_bin(&ret->a2, secp256k1_ge_consts_a2, sizeof(secp256k1_ge_consts_a2)); secp256k1_num_set_bin(&ret->b1, secp256k1_ge_consts_b1, sizeof(secp256k1_ge_consts_b1)); + secp256k1_num_copy(&ret->half_order, &ret->order); + secp256k1_num_shift(&ret->half_order, 1); secp256k1_fe_set_b32(&ret->beta, secp256k1_ge_consts_beta); secp256k1_fe_t g_x, g_y; secp256k1_fe_set_b32(&g_x, secp256k1_ge_consts_g_x); @@ -381,6 +384,7 @@ void static secp256k1_ge_stop(void) { if (secp256k1_ge_consts != NULL) { secp256k1_ge_consts_t *c = (secp256k1_ge_consts_t*)secp256k1_ge_consts; secp256k1_num_free(&c->order); + secp256k1_num_free(&c->half_order); secp256k1_num_free(&c->lambda); secp256k1_num_free(&c->a1b2); secp256k1_num_free(&c->a2);