Skip to content

Commit

Permalink
Merge pull request #9
Browse files Browse the repository at this point in the history
add support for OpenSSL 1.1.x
  • Loading branch information
sikenekis committed Jan 24, 2019
2 parents aa91df1 + 96c24fe commit b33cf2b
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 14 deletions.
18 changes: 18 additions & 0 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,31 @@ bool EnsureLowS(std::vector<unsigned char>& vchSig) {
if (sig == NULL)
return false;

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const BIGNUM *sig_r, *sig_s;
ECDSA_SIG_get0(sig, &sig_r, &sig_s);
#endif

BIGNUM *order = BN_bin2bn(vchOrder, sizeof(vchOrder), NULL);
BIGNUM *halforder = BN_bin2bn(vchHalfOrder, sizeof(vchHalfOrder), NULL);

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
if (BN_cmp(sig_s, halforder) > 0) {
BIGNUM *r, *s;
r = BN_dup(sig_r);
s = BN_new();

// enforce low S values, by negating the value (modulo the order) if above order/2.
BN_sub(s, order, sig_s);

ECDSA_SIG_set0(sig, r, s);
}
#else
if (BN_cmp(sig->s, halforder) > 0) {
// enforce low S values, by negating the value (modulo the order) if above order/2.
BN_sub(sig->s, order, sig->s);
}
#endif

BN_free(halforder);
BN_free(order);
Expand Down
66 changes: 52 additions & 14 deletions src/opensslkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY *ecKey, ECDSA_SIG *ecsig, const unsigned ch
int n = 0;
int i = recid / 2;

const BIGNUM *ecsig_r, *ecsig_s;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
ECDSA_SIG_get0(ecsig, &ecsig_r, &ecsig_s);
#else
ecsig_r = ecsig->r;
ecsig_s = ecsig->s;
#endif

const EC_GROUP *group = EC_KEY_get0_group(ecKey);
if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
BN_CTX_start(ctx);
Expand All @@ -82,7 +90,7 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY *ecKey, ECDSA_SIG *ecsig, const unsigned ch
x = BN_CTX_get(ctx);
if (!BN_copy(x, order)) { ret=-1; goto err; }
if (!BN_mul_word(x, i)) { ret=-1; goto err; }
if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
if (!BN_add(x, x, ecsig_r)) { ret=-1; goto err; }
field = BN_CTX_get(ctx);
if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
Expand All @@ -103,9 +111,9 @@ int ECDSA_SIG_recover_key_GFp(EC_KEY *ecKey, ECDSA_SIG *ecsig, const unsigned ch
if (!BN_zero(zero)) { ret=-1; goto err; }
if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
rr = BN_CTX_get(ctx);
if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
if (!BN_mod_inverse(rr, ecsig_r, order, ctx)) { ret=-1; goto err; }
sor = BN_CTX_get(ctx);
if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
if (!BN_mod_mul(sor, ecsig_s, rr, order, ctx)) { ret=-1; goto err; }
eor = BN_CTX_get(ctx);
if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
Expand Down Expand Up @@ -150,13 +158,12 @@ class CECKey {

void SetSecretBytes(const unsigned char vch[32]) {
bool ret;
BIGNUM bn;
BN_init(&bn);
ret = BN_bin2bn(vch, 32, &bn);
BIGNUM* bn = BN_new();
ret = BN_bin2bn(vch, 32, bn);
assert(ret);
ret = EC_KEY_regenerate_key(pkey, &bn);
ret = EC_KEY_regenerate_key(pkey, bn);
assert(ret);
BN_clear_free(&bn);
BN_clear_free(bn);
}

void GetPrivKey(COpenPrivKey &privkey, bool fCompressed) {
Expand Down Expand Up @@ -205,17 +212,32 @@ class CECKey {
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
if (sig == NULL)
return false;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
const BIGNUM *sig_r, *sig_s;
ECDSA_SIG_get0(sig, &sig_r, &sig_s);
#endif
BN_CTX *ctx = BN_CTX_new();
BN_CTX_start(ctx);
const EC_GROUP *group = EC_KEY_get0_group(pkey);
BIGNUM *order = BN_CTX_get(ctx);
BIGNUM *halforder = BN_CTX_get(ctx);
EC_GROUP_get_order(group, order, ctx);
BN_rshift1(halforder, order);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
if (BN_cmp(sig_s, halforder) > 0) {
BIGNUM *r, *s;
r = BN_dup(sig_r);
s = BN_new();
// enforce low S values, by negating the value (modulo the order) if above order/2.
BN_sub(s, order, sig_s);
ECDSA_SIG_set0(sig, r, s);
}
#else
if (BN_cmp(sig->s, halforder) > 0) {
// enforce low S values, by negating the value (modulo the order) if above order/2.
BN_sub(sig->s, order, sig->s);
}
#endif
BN_CTX_end(ctx);
BN_CTX_free(ctx);
unsigned int nSize = ECDSA_size(pkey);
Expand Down Expand Up @@ -263,9 +285,16 @@ class CECKey {
ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&hash, sizeof(hash), pkey);
if (sig==NULL)
return false;
const BIGNUM *sig_r, *sig_s;
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
ECDSA_SIG_get0(sig, &sig_r, &sig_s);
#else
sig_r = sig->r;
sig_s = sig->s;
#endif
memset(p64, 0, 64);
int nBitsR = BN_num_bits(sig->r);
int nBitsS = BN_num_bits(sig->s);
int nBitsR = BN_num_bits(sig_r);
int nBitsS = BN_num_bits(sig_s);
if (nBitsR <= 256 && nBitsS <= 256) {
COpenPubKey pubkey;
GetPubKey(pubkey, true);
Expand All @@ -282,8 +311,8 @@ class CECKey {
}
}
assert(fOk);
BN_bn2bin(sig->r,&p64[32-(nBitsR+7)/8]);
BN_bn2bin(sig->s,&p64[64-(nBitsS+7)/8]);
BN_bn2bin(sig_r,&p64[32-(nBitsR+7)/8]);
BN_bn2bin(sig_s,&p64[64-(nBitsS+7)/8]);
}
ECDSA_SIG_free(sig);
return fOk;
Expand All @@ -298,8 +327,17 @@ class CECKey {
if (rec<0 || rec>=3)
return false;
ECDSA_SIG *sig = ECDSA_SIG_new();
BN_bin2bn(&p64[0], 32, sig->r);
BN_bin2bn(&p64[32], 32, sig->s);
BIGNUM *sig_r, *sig_s;
sig_r = BN_new();
sig_s = BN_new();
BN_bin2bn(&p64[0], 32, sig_r);
BN_bin2bn(&p64[32], 32, sig_s);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
ECDSA_SIG_set0(sig, sig_r, sig_s);
#else
BN_copy(sig->r, sig_r);
BN_copy(sig->s, sig_s);
#endif
bool ret = ECDSA_SIG_recover_key_GFp(pkey, sig, (unsigned char*)&hash, sizeof(hash), rec, 0) == 1;
ECDSA_SIG_free(sig);
return ret;
Expand Down

0 comments on commit b33cf2b

Please sign in to comment.