7
7
#include " arith_uint256.h"
8
8
#include " crypto/common.h"
9
9
#include " crypto/hmac_sha512.h"
10
- #include " eccryptoverify.h"
11
10
#include " pubkey.h"
12
11
#include " random.h"
13
12
14
13
#include < secp256k1.h>
15
- #include " ecwrapper.h "
14
+ #include < secp256k1_recovery.h >
16
15
17
- static secp256k1_context_t * secp256k1_context = NULL ;
16
+ static secp256k1_context* secp256k1_context_sign = NULL ;
17
+
18
+ /* * These functions are taken from the libsecp256k1 distribution and are very ugly. */
19
+ static int ec_privkey_import_der (const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) {
20
+ const unsigned char *end = privkey + privkeylen;
21
+ int lenb = 0 ;
22
+ int len = 0 ;
23
+ memset (out32, 0 , 32 );
24
+ /* sequence header */
25
+ if (end < privkey+1 || *privkey != 0x30 ) {
26
+ return 0 ;
27
+ }
28
+ privkey++;
29
+ /* sequence length constructor */
30
+ if (end < privkey+1 || !(*privkey & 0x80 )) {
31
+ return 0 ;
32
+ }
33
+ lenb = *privkey & ~0x80 ; privkey++;
34
+ if (lenb < 1 || lenb > 2 ) {
35
+ return 0 ;
36
+ }
37
+ if (end < privkey+lenb) {
38
+ return 0 ;
39
+ }
40
+ /* sequence length */
41
+ len = privkey[lenb-1 ] | (lenb > 1 ? privkey[lenb-2 ] << 8 : 0 );
42
+ privkey += lenb;
43
+ if (end < privkey+len) {
44
+ return 0 ;
45
+ }
46
+ /* sequence element 0: version number (=1) */
47
+ if (end < privkey+3 || privkey[0 ] != 0x02 || privkey[1 ] != 0x01 || privkey[2 ] != 0x01 ) {
48
+ return 0 ;
49
+ }
50
+ privkey += 3 ;
51
+ /* sequence element 1: octet string, up to 32 bytes */
52
+ if (end < privkey+2 || privkey[0 ] != 0x04 || privkey[1 ] > 0x20 || end < privkey+2 +privkey[1 ]) {
53
+ return 0 ;
54
+ }
55
+ memcpy (out32 + 32 - privkey[1 ], privkey + 2 , privkey[1 ]);
56
+ if (!secp256k1_ec_seckey_verify (ctx, out32)) {
57
+ memset (out32, 0 , 32 );
58
+ return 0 ;
59
+ }
60
+ return 1 ;
61
+ }
62
+
63
+ static int ec_privkey_export_der (const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
64
+ secp256k1_pubkey pubkey;
65
+ size_t pubkeylen = 0 ;
66
+ if (!secp256k1_ec_pubkey_create (ctx, &pubkey, key32)) {
67
+ *privkeylen = 0 ;
68
+ return 0 ;
69
+ }
70
+ if (compressed) {
71
+ static const unsigned char begin[] = {
72
+ 0x30 ,0x81 ,0xD3 ,0x02 ,0x01 ,0x01 ,0x04 ,0x20
73
+ };
74
+ static const unsigned char middle[] = {
75
+ 0xA0 ,0x81 ,0x85 ,0x30 ,0x81 ,0x82 ,0x02 ,0x01 ,0x01 ,0x30 ,0x2C ,0x06 ,0x07 ,0x2A ,0x86 ,0x48 ,
76
+ 0xCE ,0x3D ,0x01 ,0x01 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
77
+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
78
+ 0xFF ,0xFF ,0xFE ,0xFF ,0xFF ,0xFC ,0x2F ,0x30 ,0x06 ,0x04 ,0x01 ,0x00 ,0x04 ,0x01 ,0x07 ,0x04 ,
79
+ 0x21 ,0x02 ,0x79 ,0xBE ,0x66 ,0x7E ,0xF9 ,0xDC ,0xBB ,0xAC ,0x55 ,0xA0 ,0x62 ,0x95 ,0xCE ,0x87 ,
80
+ 0x0B ,0x07 ,0x02 ,0x9B ,0xFC ,0xDB ,0x2D ,0xCE ,0x28 ,0xD9 ,0x59 ,0xF2 ,0x81 ,0x5B ,0x16 ,0xF8 ,
81
+ 0x17 ,0x98 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
82
+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFE ,0xBA ,0xAE ,0xDC ,0xE6 ,0xAF ,0x48 ,0xA0 ,0x3B ,0xBF ,0xD2 ,0x5E ,
83
+ 0x8C ,0xD0 ,0x36 ,0x41 ,0x41 ,0x02 ,0x01 ,0x01 ,0xA1 ,0x24 ,0x03 ,0x22 ,0x00
84
+ };
85
+ unsigned char *ptr = privkey;
86
+ memcpy (ptr, begin, sizeof (begin)); ptr += sizeof (begin);
87
+ memcpy (ptr, key32, 32 ); ptr += 32 ;
88
+ memcpy (ptr, middle, sizeof (middle)); ptr += sizeof (middle);
89
+ pubkeylen = 33 ;
90
+ secp256k1_ec_pubkey_serialize (ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED);
91
+ ptr += pubkeylen;
92
+ *privkeylen = ptr - privkey;
93
+ } else {
94
+ static const unsigned char begin[] = {
95
+ 0x30 ,0x82 ,0x01 ,0x13 ,0x02 ,0x01 ,0x01 ,0x04 ,0x20
96
+ };
97
+ static const unsigned char middle[] = {
98
+ 0xA0 ,0x81 ,0xA5 ,0x30 ,0x81 ,0xA2 ,0x02 ,0x01 ,0x01 ,0x30 ,0x2C ,0x06 ,0x07 ,0x2A ,0x86 ,0x48 ,
99
+ 0xCE ,0x3D ,0x01 ,0x01 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
100
+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
101
+ 0xFF ,0xFF ,0xFE ,0xFF ,0xFF ,0xFC ,0x2F ,0x30 ,0x06 ,0x04 ,0x01 ,0x00 ,0x04 ,0x01 ,0x07 ,0x04 ,
102
+ 0x41 ,0x04 ,0x79 ,0xBE ,0x66 ,0x7E ,0xF9 ,0xDC ,0xBB ,0xAC ,0x55 ,0xA0 ,0x62 ,0x95 ,0xCE ,0x87 ,
103
+ 0x0B ,0x07 ,0x02 ,0x9B ,0xFC ,0xDB ,0x2D ,0xCE ,0x28 ,0xD9 ,0x59 ,0xF2 ,0x81 ,0x5B ,0x16 ,0xF8 ,
104
+ 0x17 ,0x98 ,0x48 ,0x3A ,0xDA ,0x77 ,0x26 ,0xA3 ,0xC4 ,0x65 ,0x5D ,0xA4 ,0xFB ,0xFC ,0x0E ,0x11 ,
105
+ 0x08 ,0xA8 ,0xFD ,0x17 ,0xB4 ,0x48 ,0xA6 ,0x85 ,0x54 ,0x19 ,0x9C ,0x47 ,0xD0 ,0x8F ,0xFB ,0x10 ,
106
+ 0xD4 ,0xB8 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
107
+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFE ,0xBA ,0xAE ,0xDC ,0xE6 ,0xAF ,0x48 ,0xA0 ,0x3B ,0xBF ,0xD2 ,0x5E ,
108
+ 0x8C ,0xD0 ,0x36 ,0x41 ,0x41 ,0x02 ,0x01 ,0x01 ,0xA1 ,0x44 ,0x03 ,0x42 ,0x00
109
+ };
110
+ unsigned char *ptr = privkey;
111
+ memcpy (ptr, begin, sizeof (begin)); ptr += sizeof (begin);
112
+ memcpy (ptr, key32, 32 ); ptr += 32 ;
113
+ memcpy (ptr, middle, sizeof (middle)); ptr += sizeof (middle);
114
+ pubkeylen = 65 ;
115
+ secp256k1_ec_pubkey_serialize (ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
116
+ ptr += pubkeylen;
117
+ *privkeylen = ptr - privkey;
118
+ }
119
+ return 1 ;
120
+ }
18
121
19
122
bool CKey::Check (const unsigned char *vch) {
20
- return eccrypto::Check ( vch);
123
+ return secp256k1_ec_seckey_verify (secp256k1_context_sign, vch);
21
124
}
22
125
23
126
void CKey::MakeNewKey (bool fCompressedIn ) {
@@ -30,7 +133,7 @@ void CKey::MakeNewKey(bool fCompressedIn) {
30
133
}
31
134
32
135
bool CKey::SetPrivKey (const CPrivKey &privkey, bool fCompressedIn ) {
33
- if (!secp256k1_ec_privkey_import (secp256k1_context , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
136
+ if (!ec_privkey_import_der (secp256k1_context_sign , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
34
137
return false ;
35
138
fCompressed = fCompressedIn ;
36
139
fValid = true ;
@@ -40,22 +143,25 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
40
143
CPrivKey CKey::GetPrivKey () const {
41
144
assert (fValid );
42
145
CPrivKey privkey;
43
- int privkeylen, ret;
146
+ int ret;
147
+ size_t privkeylen;
44
148
privkey.resize (279 );
45
149
privkeylen = 279 ;
46
- ret = secp256k1_ec_privkey_export (secp256k1_context, begin (), ( unsigned char *)&privkey[0 ], &privkeylen, fCompressed );
150
+ ret = ec_privkey_export_der (secp256k1_context_sign, ( unsigned char *)&privkey[0 ], &privkeylen, begin (), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );
47
151
assert (ret);
48
152
privkey.resize (privkeylen);
49
153
return privkey;
50
154
}
51
155
52
156
CPubKey CKey::GetPubKey () const {
53
157
assert (fValid );
158
+ secp256k1_pubkey pubkey;
159
+ size_t clen = 65 ;
54
160
CPubKey result;
55
- int clen = 65 ;
56
- int ret = secp256k1_ec_pubkey_create (secp256k1_context, (unsigned char *)result.begin (), &clen, begin (), fCompressed );
57
- assert ((int )result.size () == clen);
161
+ int ret = secp256k1_ec_pubkey_create (secp256k1_context_sign, &pubkey, begin ());
58
162
assert (ret);
163
+ secp256k1_ec_pubkey_serialize (secp256k1_context_sign, (unsigned char *)result.begin (), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
164
+ assert (result.size () == clen);
59
165
assert (result.IsValid ());
60
166
return result;
61
167
}
@@ -64,11 +170,13 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_
64
170
if (!fValid )
65
171
return false ;
66
172
vchSig.resize (72 );
67
- int nSigLen = 72 ;
173
+ size_t nSigLen = 72 ;
68
174
unsigned char extra_entropy[32 ] = {0 };
69
175
WriteLE32 (extra_entropy, test_case);
70
- int ret = secp256k1_ecdsa_sign (secp256k1_context, hash.begin (), (unsigned char *)&vchSig[0 ], &nSigLen, begin (), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL );
176
+ secp256k1_ecdsa_signature sig;
177
+ int ret = secp256k1_ecdsa_sign (secp256k1_context_sign, &sig, hash.begin (), begin (), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL );
71
178
assert (ret);
179
+ secp256k1_ecdsa_signature_serialize_der (secp256k1_context_sign, (unsigned char *)&vchSig[0 ], &nSigLen, &sig);
72
180
vchSig.resize (nSigLen);
73
181
return true ;
74
182
}
@@ -92,15 +200,18 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
92
200
return false ;
93
201
vchSig.resize (65 );
94
202
int rec = -1 ;
95
- int ret = secp256k1_ecdsa_sign_compact (secp256k1_context, hash.begin (), &vchSig[1 ], begin (), secp256k1_nonce_function_rfc6979, NULL , &rec);
203
+ secp256k1_ecdsa_recoverable_signature sig;
204
+ int ret = secp256k1_ecdsa_sign_recoverable (secp256k1_context_sign, &sig, hash.begin (), begin (), secp256k1_nonce_function_rfc6979, NULL );
205
+ assert (ret);
206
+ secp256k1_ecdsa_recoverable_signature_serialize_compact (secp256k1_context_sign, (unsigned char *)&vchSig[1 ], &rec, &sig);
96
207
assert (ret);
97
208
assert (rec != -1 );
98
209
vchSig[0 ] = 27 + rec + (fCompressed ? 4 : 0 );
99
210
return true ;
100
211
}
101
212
102
213
bool CKey::Load (CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck =false ) {
103
- if (!secp256k1_ec_privkey_import (secp256k1_context , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
214
+ if (!ec_privkey_import_der (secp256k1_context_sign , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
104
215
return false ;
105
216
fCompressed = vchPubKey.IsCompressed ();
106
217
fValid = true ;
@@ -126,7 +237,7 @@ bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const
126
237
}
127
238
memcpy (ccChild.begin (), out+32 , 32 );
128
239
memcpy ((unsigned char *)keyChild.begin (), begin (), 32 );
129
- bool ret = secp256k1_ec_privkey_tweak_add (secp256k1_context , (unsigned char *)keyChild.begin (), out);
240
+ bool ret = secp256k1_ec_privkey_tweak_add (secp256k1_context_sign , (unsigned char *)keyChild.begin (), out);
130
241
UnlockObject (out);
131
242
keyChild.fCompressed = true ;
132
243
keyChild.fValid = ret;
@@ -184,20 +295,16 @@ void CExtKey::Decode(const unsigned char code[74]) {
184
295
}
185
296
186
297
bool ECC_InitSanityCheck () {
187
- if (!CECKey::SanityCheck ()) {
188
- return false ;
189
- }
190
298
CKey key;
191
299
key.MakeNewKey (true );
192
300
CPubKey pubkey = key.GetPubKey ();
193
301
return key.VerifyPubKey (pubkey);
194
302
}
195
303
196
-
197
304
void ECC_Start () {
198
- assert (secp256k1_context == NULL );
305
+ assert (secp256k1_context_sign == NULL );
199
306
200
- secp256k1_context_t *ctx = secp256k1_context_create (SECP256K1_CONTEXT_SIGN);
307
+ secp256k1_context *ctx = secp256k1_context_create (SECP256K1_CONTEXT_SIGN);
201
308
assert (ctx != NULL );
202
309
203
310
{
@@ -210,12 +317,12 @@ void ECC_Start() {
210
317
UnlockObject (seed);
211
318
}
212
319
213
- secp256k1_context = ctx;
320
+ secp256k1_context_sign = ctx;
214
321
}
215
322
216
323
void ECC_Stop () {
217
- secp256k1_context_t *ctx = secp256k1_context ;
218
- secp256k1_context = NULL ;
324
+ secp256k1_context *ctx = secp256k1_context_sign ;
325
+ secp256k1_context_sign = NULL ;
219
326
220
327
if (ctx) {
221
328
secp256k1_context_destroy (ctx);
0 commit comments