Line data Source code
1 : // Copyright (c) 2009-2014 The Bitcoin developers
2 : // Copyright (c) 2017-2020 The PIVX Core developers
3 : // Distributed under the MIT software license, see the accompanying
4 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 :
6 : #include "pubkey.h"
7 :
8 : #include <secp256k1.h>
9 : #include <secp256k1_recovery.h>
10 :
11 : namespace
12 : {
13 : /* Global secp256k1_context object used for verification. */
14 : secp256k1_context* secp256k1_context_verify = nullptr;
15 : } // namespace
16 :
17 : /** This function is taken from the libsecp256k1 distribution and implements
18 : * DER parsing for ECDSA signatures, while supporting an arbitrary subset of
19 : * format violations.
20 : *
21 : * Supported violations include negative integers, excessive padding, garbage
22 : * at the end, and overly long length descriptors. This is safe to use in
23 : * Bitcoin because since the activation of BIP66, signatures are verified to be
24 : * strict DER before being passed to this module, and we know it supports all
25 : * violations present in the blockchain before that point.
26 : */
27 8212652 : static int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
28 8212652 : size_t rpos, rlen, spos, slen;
29 8212652 : size_t pos = 0;
30 8212652 : size_t lenbyte;
31 8212652 : unsigned char tmpsig[64] = {0};
32 8212652 : int overflow = 0;
33 :
34 : /* Hack to initialize sig with a correctly-parsed but invalid signature. */
35 8212652 : secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
36 :
37 : /* Sequence tag byte */
38 8212652 : if (pos == inputlen || input[pos] != 0x30) {
39 : return 0;
40 : }
41 8212648 : pos++;
42 :
43 : /* Sequence length bytes */
44 8212648 : if (pos == inputlen) {
45 : return 0;
46 : }
47 8212648 : lenbyte = input[pos++];
48 8212648 : if (lenbyte & 0x80) {
49 0 : lenbyte -= 0x80;
50 0 : if (lenbyte > inputlen - pos) {
51 : return 0;
52 : }
53 0 : pos += lenbyte;
54 : }
55 :
56 : /* Integer tag byte for R */
57 8212648 : if (pos == inputlen || input[pos] != 0x02) {
58 : return 0;
59 : }
60 8212648 : pos++;
61 :
62 : /* Integer length for R */
63 8212648 : if (pos == inputlen) {
64 : return 0;
65 : }
66 8212648 : lenbyte = input[pos++];
67 8212648 : if (lenbyte & 0x80) {
68 0 : lenbyte -= 0x80;
69 0 : if (lenbyte > inputlen - pos) {
70 : return 0;
71 : }
72 0 : while (lenbyte > 0 && input[pos] == 0) {
73 0 : pos++;
74 0 : lenbyte--;
75 : }
76 0 : static_assert(sizeof(size_t) >= 4, "size_t too small");
77 0 : if (lenbyte >= 4) {
78 : return 0;
79 : }
80 : rlen = 0;
81 0 : while (lenbyte > 0) {
82 0 : rlen = (rlen << 8) + input[pos];
83 0 : pos++;
84 0 : lenbyte--;
85 : }
86 : } else {
87 : rlen = lenbyte;
88 : }
89 8212648 : if (rlen > inputlen - pos) {
90 : return 0;
91 : }
92 8212648 : rpos = pos;
93 8212648 : pos += rlen;
94 :
95 : /* Integer tag byte for S */
96 8212648 : if (pos == inputlen || input[pos] != 0x02) {
97 : return 0;
98 : }
99 8212648 : pos++;
100 :
101 : /* Integer length for S */
102 8212648 : if (pos == inputlen) {
103 : return 0;
104 : }
105 8212648 : lenbyte = input[pos++];
106 8212648 : if (lenbyte & 0x80) {
107 0 : lenbyte -= 0x80;
108 0 : if (lenbyte > inputlen - pos) {
109 : return 0;
110 : }
111 0 : while (lenbyte > 0 && input[pos] == 0) {
112 0 : pos++;
113 0 : lenbyte--;
114 : }
115 0 : static_assert(sizeof(size_t) >= 4, "size_t too small");
116 0 : if (lenbyte >= 4) {
117 : return 0;
118 : }
119 : slen = 0;
120 0 : while (lenbyte > 0) {
121 0 : slen = (slen << 8) + input[pos];
122 0 : pos++;
123 0 : lenbyte--;
124 : }
125 : } else {
126 : slen = lenbyte;
127 : }
128 8212648 : if (slen > inputlen - pos) {
129 : return 0;
130 : }
131 9007440 : spos = pos;
132 :
133 : /* Ignore leading zeroes in R */
134 9007440 : while (rlen > 0 && input[rpos] == 0) {
135 794796 : rlen--;
136 794796 : rpos++;
137 : }
138 : /* Copy R value */
139 8212648 : if (rlen > 32) {
140 8212648 : overflow = 1;
141 : } else {
142 8212648 : memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
143 : }
144 :
145 : /* Ignore leading zeroes in S */
146 8218690 : while (slen > 0 && input[spos] == 0) {
147 6047 : slen--;
148 6047 : spos++;
149 : }
150 : /* Copy S value */
151 8212648 : if (slen > 32) {
152 : overflow = 1;
153 : } else {
154 8212648 : memcpy(tmpsig + 64 - slen, input + spos, slen);
155 : }
156 :
157 8212648 : if (!overflow) {
158 1572590 : overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
159 : }
160 8212648 : if (overflow) {
161 : /* Overwrite the result again with a correctly-parsed but invalid
162 : signature if parsing failed. */
163 6640058 : memset(tmpsig, 0, 64);
164 6640058 : secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
165 : }
166 : return 1;
167 : }
168 :
169 842005 : bool CPubKey::Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const
170 : {
171 842005 : if (!IsValid())
172 : return false;
173 842005 : secp256k1_pubkey pubkey;
174 842005 : secp256k1_ecdsa_signature sig;
175 842005 : assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
176 851222 : if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
177 : return false;
178 : }
179 842005 : if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
180 : return false;
181 : }
182 : /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
183 : * not historically been enforced in Bitcoin, so normalize them first. */
184 842001 : secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
185 842001 : return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
186 : }
187 :
188 6016 : bool CPubKey::RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig)
189 : {
190 6016 : if (vchSig.size() != COMPACT_SIGNATURE_SIZE)
191 : return false;
192 6016 : int recid = (vchSig[0] - 27) & 3;
193 6016 : bool fComp = ((vchSig[0] - 27) & 4) != 0;
194 6016 : secp256k1_pubkey pubkey;
195 6016 : secp256k1_ecdsa_recoverable_signature sig;
196 6016 : assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
197 6016 : if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
198 : return false;
199 : }
200 6016 : if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
201 : return false;
202 : }
203 6016 : unsigned char pub[PUBLIC_KEY_SIZE];
204 6016 : size_t publen = PUBLIC_KEY_SIZE;
205 9558 : secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
206 6016 : Set(pub, pub + publen);
207 6016 : return true;
208 : }
209 :
210 116 : bool CPubKey::IsFullyValid() const
211 : {
212 116 : if (!IsValid())
213 : return false;
214 115 : secp256k1_pubkey pubkey;
215 115 : assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
216 115 : return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size());
217 : }
218 :
219 0 : bool CPubKey::Decompress()
220 : {
221 0 : if (!IsValid())
222 : return false;
223 0 : secp256k1_pubkey pubkey;
224 0 : assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
225 0 : if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
226 : return false;
227 : }
228 0 : unsigned char pub[PUBLIC_KEY_SIZE];
229 0 : size_t publen = PUBLIC_KEY_SIZE;
230 0 : secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
231 0 : Set(pub, pub + publen);
232 0 : return true;
233 : }
234 :
235 18033 : bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const
236 : {
237 18033 : assert(IsValid());
238 18033 : assert((nChild >> 31) == 0);
239 18033 : assert(size() == COMPRESSED_PUBLIC_KEY_SIZE);
240 18033 : unsigned char out[64];
241 18033 : BIP32Hash(cc, nChild, *begin(), begin()+1, out);
242 18033 : memcpy(ccChild.begin(), out+32, 32);
243 18033 : secp256k1_pubkey pubkey;
244 18033 : assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
245 18033 : if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
246 : return false;
247 : }
248 18033 : if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
249 : return false;
250 : }
251 18033 : unsigned char pub[COMPRESSED_PUBLIC_KEY_SIZE];
252 18033 : size_t publen = COMPRESSED_PUBLIC_KEY_SIZE;
253 18033 : secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
254 18033 : pubkeyChild.Set(pub, pub + publen);
255 18033 : return true;
256 : }
257 :
258 28 : void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
259 : {
260 28 : code[0] = nDepth;
261 28 : memcpy(code+1, vchFingerprint, 4);
262 28 : code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
263 28 : code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
264 28 : memcpy(code+9, chaincode.begin(), 32);
265 28 : assert(pubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE);
266 28 : memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_PUBLIC_KEY_SIZE);
267 28 : }
268 :
269 19 : void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
270 : {
271 19 : nDepth = code[0];
272 19 : memcpy(vchFingerprint, code+1, 4);
273 19 : nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
274 19 : memcpy(chaincode.begin(), code+9, 32);
275 19 : pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
276 19 : }
277 :
278 18033 : bool CExtPubKey::Derive(CExtPubKey& out, unsigned int _nChild) const
279 : {
280 18033 : out.nDepth = nDepth + 1;
281 18033 : CKeyID id = pubkey.GetID();
282 18033 : memcpy(&out.vchFingerprint[0], &id, 4);
283 18033 : out.nChild = _nChild;
284 18033 : return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
285 : }
286 :
287 7370648 : /* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
288 7370648 : secp256k1_ecdsa_signature sig;
289 7370648 : assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
290 7370648 : if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
291 : return false;
292 : }
293 7370648 : return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
294 : }
295 :
296 : /* static */ int ECCVerifyHandle::refcount = 0;
297 :
298 795 : ECCVerifyHandle::ECCVerifyHandle()
299 : {
300 795 : if (refcount == 0) {
301 795 : assert(secp256k1_context_verify == nullptr);
302 795 : secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
303 795 : assert(secp256k1_context_verify != nullptr);
304 : }
305 795 : refcount++;
306 795 : }
307 :
308 794 : ECCVerifyHandle::~ECCVerifyHandle()
309 : {
310 794 : refcount--;
311 794 : if (refcount == 0) {
312 794 : assert(secp256k1_context_verify != nullptr);
313 794 : secp256k1_context_destroy(secp256k1_context_verify);
314 794 : secp256k1_context_verify = nullptr;
315 : }
316 794 : }
|