10 #include <openssl/bn.h>
11 #include <openssl/ecdsa.h>
12 #include <openssl/obj_mac.h>
21 int ECDSA_SIG_recover_key_GFp(EC_KEY* eckey, ECDSA_SIG* ecsig,
const unsigned char* msg,
int msglen,
int recid,
int check)
42 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
43 const BIGNUM *sig_r, *sig_s;
44 ECDSA_SIG_get0(ecsig, &sig_r, &sig_s);
47 const EC_GROUP* group = EC_KEY_get0_group(eckey);
48 if ((ctx = BN_CTX_new()) == NULL) {
53 order = BN_CTX_get(ctx);
54 if (!EC_GROUP_get_order(group, order, ctx)) {
59 if (!BN_copy(x, order)) {
63 if (!BN_mul_word(x, i)) {
67 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
68 if (!BN_add(x, x, sig_r)) {
70 if (!BN_add(x, x, ecsig->r)) {
75 field = BN_CTX_get(ctx);
76 if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) {
80 if (BN_cmp(x, field) >= 0) {
84 if ((
R = EC_POINT_new(group)) == NULL) {
88 if (!EC_POINT_set_compressed_coordinates_GFp(group,
R, x, recid % 2, ctx)) {
93 if ((O = EC_POINT_new(group)) == NULL) {
97 if (!EC_POINT_mul(group, O, NULL,
R, order, ctx)) {
101 if (!EC_POINT_is_at_infinity(group, O)) {
106 if ((Q = EC_POINT_new(group)) == NULL) {
110 n = EC_GROUP_get_degree(group);
112 if (!BN_bin2bn(msg, msglen, e)) {
116 if (8 * msglen > n) BN_rshift(e, e, 8 - (n & 7));
117 zero = BN_CTX_get(ctx);
118 if (!BN_zero(zero)) {
122 if (!BN_mod_sub(e, zero, e, order, ctx)) {
126 rr = BN_CTX_get(ctx);
127 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
128 if (!BN_mod_inverse(rr, sig_r, order, ctx)) {
130 if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) {
135 sor = BN_CTX_get(ctx);
136 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
137 if (!BN_mod_mul(sor, sig_s, rr, order, ctx)) {
139 if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) {
144 eor = BN_CTX_get(ctx);
145 if (!BN_mod_mul(eor, e, rr, order, ctx)) {
149 if (!EC_POINT_mul(group, Q, eor,
R, sor, ctx)) {
153 if (!EC_KEY_set_public_key(eckey, Q)) {
165 if (
R != NULL) EC_POINT_free(
R);
166 if (O != NULL) EC_POINT_free(O);
167 if (Q != NULL) EC_POINT_free(Q);
175 pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
176 assert(
pkey != NULL);
186 EC_KEY_set_conv_form(
pkey, fCompressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED);
187 int nSize = i2o_ECPublicKey(
pkey, NULL);
191 pubkey.resize(nSize);
192 unsigned char* pbegin(pubkey.data());
193 int nSize2 = i2o_ECPublicKey(
pkey, &pbegin);
194 assert(nSize == nSize2);
199 return o2i_ECPublicKey(&
pkey, &pubkey, size) != NULL;
208 unsigned char* norm_der = NULL;
209 ECDSA_SIG* norm_sig = ECDSA_SIG_new();
210 const unsigned char* sigptr = &vchSig[0];
212 if (d2i_ECDSA_SIG(&norm_sig, &sigptr, vchSig.size()) == NULL) {
219 ECDSA_SIG_free(norm_sig);
222 int derlen = i2d_ECDSA_SIG(norm_sig, &norm_der);
223 ECDSA_SIG_free(norm_sig);
228 bool ret = ECDSA_verify(0, (
unsigned char*)&hash,
sizeof(hash), norm_der, derlen,
pkey) == 1;
229 OPENSSL_free(norm_der);
235 if (rec < 0 || rec >= 3)
237 ECDSA_SIG* sig = ECDSA_SIG_new();
238 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
239 BIGNUM *sig_r = NULL;
240 BIGNUM *sig_s = NULL;
241 if (!(sig_r = BN_bin2bn(&p64[0], 32,
nullptr)) ||
242 !(sig_s = BN_bin2bn(&p64[32], 32,
nullptr)) ||
243 !ECDSA_SIG_set0(sig, sig_r, sig_s)) {
249 BN_bin2bn(&p64[0], 32, sig->r);
250 BN_bin2bn(&p64[32], 32, sig->s);
252 bool ret = ECDSA_SIG_recover_key_GFp(
pkey, sig, (
unsigned char*)&hash,
sizeof(hash), rec, 0) == 1;
260 BN_CTX* ctx = BN_CTX_new();
262 BIGNUM* bnTweak = BN_CTX_get(ctx);
263 BIGNUM* bnOrder = BN_CTX_get(ctx);
264 BIGNUM* bnOne = BN_CTX_get(ctx);
265 const EC_GROUP* group = EC_KEY_get0_group(
pkey);
266 EC_GROUP_get_order(group, bnOrder, ctx);
267 BN_bin2bn(vchTweak, 32, bnTweak);
268 if (BN_cmp(bnTweak, bnOrder) >= 0)
270 EC_POINT* point = EC_POINT_dup(EC_KEY_get0_public_key(
pkey), group);
272 EC_POINT_mul(group, point, bnTweak, point, bnOne, ctx);
273 if (EC_POINT_is_at_infinity(group, point))
275 EC_KEY_set_public_key(
pkey, point);
276 EC_POINT_free(point);
284 EC_KEY*
pkey = EC_KEY_new_by_curve_name(NID_secp256k1);