1414#include < secp256k1.h>
1515#include < secp256k1_ecdh.h>
1616#include < secp256k1_schnorr.h>
17+ #include < secp256k1_recovery.h>
1718
18- static secp256k1_context_t * secp256k1_context = NULL ;
19+ static secp256k1_context* secp256k1_context_sign = NULL ;
20+
21+ /* * These functions are taken from the libsecp256k1 distribution and are very ugly. */
22+ static int ec_privkey_import_der (const secp256k1_context* ctx, unsigned char *out32, const unsigned char *privkey, size_t privkeylen) {
23+ const unsigned char *end = privkey + privkeylen;
24+ int lenb = 0 ;
25+ int len = 0 ;
26+ memset (out32, 0 , 32 );
27+ /* sequence header */
28+ if (end < privkey+1 || *privkey != 0x30 ) {
29+ return 0 ;
30+ }
31+ privkey++;
32+ /* sequence length constructor */
33+ if (end < privkey+1 || !(*privkey & 0x80 )) {
34+ return 0 ;
35+ }
36+ lenb = *privkey & ~0x80 ; privkey++;
37+ if (lenb < 1 || lenb > 2 ) {
38+ return 0 ;
39+ }
40+ if (end < privkey+lenb) {
41+ return 0 ;
42+ }
43+ /* sequence length */
44+ len = privkey[lenb-1 ] | (lenb > 1 ? privkey[lenb-2 ] << 8 : 0 );
45+ privkey += lenb;
46+ if (end < privkey+len) {
47+ return 0 ;
48+ }
49+ /* sequence element 0: version number (=1) */
50+ if (end < privkey+3 || privkey[0 ] != 0x02 || privkey[1 ] != 0x01 || privkey[2 ] != 0x01 ) {
51+ return 0 ;
52+ }
53+ privkey += 3 ;
54+ /* sequence element 1: octet string, up to 32 bytes */
55+ if (end < privkey+2 || privkey[0 ] != 0x04 || privkey[1 ] > 0x20 || end < privkey+2 +privkey[1 ]) {
56+ return 0 ;
57+ }
58+ memcpy (out32 + 32 - privkey[1 ], privkey + 2 , privkey[1 ]);
59+ if (!secp256k1_ec_seckey_verify (ctx, out32)) {
60+ memset (out32, 0 , 32 );
61+ return 0 ;
62+ }
63+ return 1 ;
64+ }
65+
66+ static int ec_privkey_export_der (const secp256k1_context *ctx, unsigned char *privkey, size_t *privkeylen, const unsigned char *key32, int compressed) {
67+ secp256k1_pubkey pubkey;
68+ size_t pubkeylen = 0 ;
69+ if (!secp256k1_ec_pubkey_create (ctx, &pubkey, key32)) {
70+ *privkeylen = 0 ;
71+ return 0 ;
72+ }
73+ if (compressed) {
74+ static const unsigned char begin[] = {
75+ 0x30 ,0x81 ,0xD3 ,0x02 ,0x01 ,0x01 ,0x04 ,0x20
76+ };
77+ static const unsigned char middle[] = {
78+ 0xA0 ,0x81 ,0x85 ,0x30 ,0x81 ,0x82 ,0x02 ,0x01 ,0x01 ,0x30 ,0x2C ,0x06 ,0x07 ,0x2A ,0x86 ,0x48 ,
79+ 0xCE ,0x3D ,0x01 ,0x01 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
80+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
81+ 0xFF ,0xFF ,0xFE ,0xFF ,0xFF ,0xFC ,0x2F ,0x30 ,0x06 ,0x04 ,0x01 ,0x00 ,0x04 ,0x01 ,0x07 ,0x04 ,
82+ 0x21 ,0x02 ,0x79 ,0xBE ,0x66 ,0x7E ,0xF9 ,0xDC ,0xBB ,0xAC ,0x55 ,0xA0 ,0x62 ,0x95 ,0xCE ,0x87 ,
83+ 0x0B ,0x07 ,0x02 ,0x9B ,0xFC ,0xDB ,0x2D ,0xCE ,0x28 ,0xD9 ,0x59 ,0xF2 ,0x81 ,0x5B ,0x16 ,0xF8 ,
84+ 0x17 ,0x98 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
85+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFE ,0xBA ,0xAE ,0xDC ,0xE6 ,0xAF ,0x48 ,0xA0 ,0x3B ,0xBF ,0xD2 ,0x5E ,
86+ 0x8C ,0xD0 ,0x36 ,0x41 ,0x41 ,0x02 ,0x01 ,0x01 ,0xA1 ,0x24 ,0x03 ,0x22 ,0x00
87+ };
88+ unsigned char *ptr = privkey;
89+ memcpy (ptr, begin, sizeof (begin)); ptr += sizeof (begin);
90+ memcpy (ptr, key32, 32 ); ptr += 32 ;
91+ memcpy (ptr, middle, sizeof (middle)); ptr += sizeof (middle);
92+ pubkeylen = 33 ;
93+ secp256k1_ec_pubkey_serialize (ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_COMPRESSED);
94+ ptr += pubkeylen;
95+ *privkeylen = ptr - privkey;
96+ } else {
97+ static const unsigned char begin[] = {
98+ 0x30 ,0x82 ,0x01 ,0x13 ,0x02 ,0x01 ,0x01 ,0x04 ,0x20
99+ };
100+ static const unsigned char middle[] = {
101+ 0xA0 ,0x81 ,0xA5 ,0x30 ,0x81 ,0xA2 ,0x02 ,0x01 ,0x01 ,0x30 ,0x2C ,0x06 ,0x07 ,0x2A ,0x86 ,0x48 ,
102+ 0xCE ,0x3D ,0x01 ,0x01 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
103+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
104+ 0xFF ,0xFF ,0xFE ,0xFF ,0xFF ,0xFC ,0x2F ,0x30 ,0x06 ,0x04 ,0x01 ,0x00 ,0x04 ,0x01 ,0x07 ,0x04 ,
105+ 0x41 ,0x04 ,0x79 ,0xBE ,0x66 ,0x7E ,0xF9 ,0xDC ,0xBB ,0xAC ,0x55 ,0xA0 ,0x62 ,0x95 ,0xCE ,0x87 ,
106+ 0x0B ,0x07 ,0x02 ,0x9B ,0xFC ,0xDB ,0x2D ,0xCE ,0x28 ,0xD9 ,0x59 ,0xF2 ,0x81 ,0x5B ,0x16 ,0xF8 ,
107+ 0x17 ,0x98 ,0x48 ,0x3A ,0xDA ,0x77 ,0x26 ,0xA3 ,0xC4 ,0x65 ,0x5D ,0xA4 ,0xFB ,0xFC ,0x0E ,0x11 ,
108+ 0x08 ,0xA8 ,0xFD ,0x17 ,0xB4 ,0x48 ,0xA6 ,0x85 ,0x54 ,0x19 ,0x9C ,0x47 ,0xD0 ,0x8F ,0xFB ,0x10 ,
109+ 0xD4 ,0xB8 ,0x02 ,0x21 ,0x00 ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,0xFF ,
110+ 0xFF ,0xFF ,0xFF ,0xFF ,0xFE ,0xBA ,0xAE ,0xDC ,0xE6 ,0xAF ,0x48 ,0xA0 ,0x3B ,0xBF ,0xD2 ,0x5E ,
111+ 0x8C ,0xD0 ,0x36 ,0x41 ,0x41 ,0x02 ,0x01 ,0x01 ,0xA1 ,0x44 ,0x03 ,0x42 ,0x00
112+ };
113+ unsigned char *ptr = privkey;
114+ memcpy (ptr, begin, sizeof (begin)); ptr += sizeof (begin);
115+ memcpy (ptr, key32, 32 ); ptr += 32 ;
116+ memcpy (ptr, middle, sizeof (middle)); ptr += sizeof (middle);
117+ pubkeylen = 65 ;
118+ secp256k1_ec_pubkey_serialize (ctx, ptr, &pubkeylen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
119+ ptr += pubkeylen;
120+ *privkeylen = ptr - privkey;
121+ }
122+ return 1 ;
123+ }
19124
20125bool CKey::Check (const unsigned char *vch) {
21126 return eccrypto::Check (vch);
@@ -30,7 +135,7 @@ void CKey::MakeNewKey(bool fCompressedIn) {
30135}
31136
32137bool CKey::SetPrivKey (const CPrivKey &privkey, bool fCompressedIn ) {
33- if (!secp256k1_ec_privkey_import (secp256k1_context , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
138+ if (!ec_privkey_import_der (secp256k1_context_sign , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
34139 return false ;
35140 fCompressed = fCompressedIn ;
36141 fValid = true ;
@@ -40,10 +145,11 @@ bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
40145CPrivKey CKey::GetPrivKey () const {
41146 assert (fValid );
42147 CPrivKey privkey;
43- int privkeylen, ret;
148+ int ret;
149+ size_t privkeylen;
44150 privkey.resize (279 );
45151 privkeylen = 279 ;
46- ret = secp256k1_ec_privkey_export (secp256k1_context, begin (), ( unsigned char *)&privkey[0 ], &privkeylen, fCompressed );
152+ ret = ec_privkey_export_der (secp256k1_context_sign, ( unsigned char *)&privkey[0 ], &privkeylen, begin (), fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );
47153 assert (ret);
48154 privkey.resize (privkeylen);
49155 return privkey;
@@ -52,11 +158,11 @@ CPrivKey CKey::GetPrivKey() const {
52158CPubKey CKey::GetPubKey () const {
53159 assert (fValid );
54160 CPubKey result;
55- int clen = 65 ;
56- secp256k1_pubkey_t pubkey;
57- int ret = secp256k1_ec_pubkey_create (secp256k1_context , &pubkey, begin ());
58- secp256k1_ec_pubkey_serialize (secp256k1_context , (unsigned char *)result.begin (), &clen, &pubkey, fCompressed );
59- assert (( int ) result.size () == clen);
161+ size_t clen = 65 ;
162+ secp256k1_pubkey pubkey;
163+ int ret = secp256k1_ec_pubkey_create (secp256k1_context_sign , &pubkey, begin ());
164+ secp256k1_ec_pubkey_serialize (secp256k1_context_sign , (unsigned char *)result.begin (), &clen, &pubkey, fCompressed ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED );
165+ assert (result.size () == clen);
60166 assert (ret);
61167 assert (result.IsValid ());
62168 return result;
@@ -65,9 +171,9 @@ CPubKey CKey::GetPubKey() const {
65171uint256 CKey::ECDH (const CPubKey& pubkey) const {
66172 assert (fValid );
67173 uint256 result;
68- secp256k1_pubkey_t pkey;
69- assert (secp256k1_ec_pubkey_parse (secp256k1_context , &pkey, pubkey.begin (), pubkey.size ()));
70- assert (secp256k1_ecdh (secp256k1_context , result.begin (), &pkey, begin ()));
174+ secp256k1_pubkey pkey;
175+ assert (secp256k1_ec_pubkey_parse (secp256k1_context_sign , &pkey, pubkey.begin (), pubkey.size ()));
176+ assert (secp256k1_ecdh (secp256k1_context_sign , result.begin (), &pkey, begin ()));
71177 return result;
72178}
73179
@@ -78,7 +184,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_
78184 int nSigLen = 64 ;
79185 unsigned char extra_entropy[32 ] = {0 };
80186 WriteLE32 (extra_entropy, test_case);
81- int ret = secp256k1_schnorr_sign (secp256k1_context, hash. begin (), ( unsigned char *)&vchSig[0 ], begin (), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL );
187+ int ret = secp256k1_schnorr_sign (secp256k1_context_sign, ( unsigned char *)&vchSig[0 ], hash. begin () , begin (), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL );
82188 assert (ret);
83189 vchSig.resize (nSigLen);
84190 return true ;
@@ -103,15 +209,18 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
103209 return false ;
104210 vchSig.resize (65 );
105211 int rec = -1 ;
106- secp256k1_ecdsa_signature_t sig;
107- assert (secp256k1_ecdsa_sign (secp256k1_context, hash.begin (), &sig, begin (), secp256k1_nonce_function_rfc6979, NULL ));
108- assert (secp256k1_ecdsa_signature_serialize_compact (secp256k1_context, &vchSig[1 ], &rec, &sig));
212+ secp256k1_ecdsa_recoverable_signature sig;
213+ int ret = secp256k1_ecdsa_sign_recoverable (secp256k1_context_sign, &sig, hash.begin (), begin (), secp256k1_nonce_function_rfc6979, NULL );
214+ assert (ret);
215+ secp256k1_ecdsa_recoverable_signature_serialize_compact (secp256k1_context_sign, (unsigned char *)&vchSig[1 ], &rec, &sig);
216+ assert (ret);
217+ assert (rec != -1 );
109218 vchSig[0 ] = 27 + rec + (fCompressed ? 4 : 0 );
110219 return true ;
111220}
112221
113222bool CKey::Load (CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck =false ) {
114- if (!secp256k1_ec_privkey_import (secp256k1_context , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
223+ if (!ec_privkey_import_der (secp256k1_context_sign , (unsigned char *)begin (), &privkey[0 ], privkey.size ()))
115224 return false ;
116225 fCompressed = vchPubKey.IsCompressed ();
117226 fValid = true ;
@@ -137,7 +246,7 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild
137246 }
138247 memcpy (ccChild, out+32 , 32 );
139248 memcpy ((unsigned char *)keyChild.begin (), begin (), 32 );
140- bool ret = secp256k1_ec_privkey_tweak_add (secp256k1_context , (unsigned char *)keyChild.begin (), out);
249+ bool ret = secp256k1_ec_privkey_tweak_add (secp256k1_context_sign , (unsigned char *)keyChild.begin (), out);
141250 UnlockObject (out);
142251 keyChild.fCompressed = true ;
143252 keyChild.fValid = ret;
@@ -203,9 +312,9 @@ bool ECC_InitSanityCheck() {
203312
204313
205314void ECC_Start () {
206- assert (secp256k1_context == NULL );
315+ assert (secp256k1_context_sign == NULL );
207316
208- secp256k1_context_t *ctx = secp256k1_context_create (SECP256K1_CONTEXT_SIGN);
317+ secp256k1_context *ctx = secp256k1_context_create (SECP256K1_CONTEXT_SIGN);
209318 assert (ctx != NULL );
210319
211320 {
@@ -218,12 +327,12 @@ void ECC_Start() {
218327 UnlockObject (seed);
219328 }
220329
221- secp256k1_context = ctx;
330+ secp256k1_context_sign = ctx;
222331}
223332
224333void ECC_Stop () {
225- secp256k1_context_t *ctx = secp256k1_context ;
226- secp256k1_context = NULL ;
334+ secp256k1_context *ctx = secp256k1_context_sign ;
335+ secp256k1_context_sign = NULL ;
227336
228337 if (ctx) {
229338 secp256k1_context_destroy (ctx);
0 commit comments