Merge #12079: Improve prioritisetransaction test coverage
[bitcoinplatinum.git] / src / pubkey.cpp
blob6e601a6f13704c9ba8a79687d1bb72718c5ef472
1 // Copyright (c) 2009-2017 The Bitcoin Core developers
2 // Copyright (c) 2017 The Zcash developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include <pubkey.h>
8 #include <secp256k1.h>
9 #include <secp256k1_recovery.h>
11 namespace
13 /* Global secp256k1_context object used for verification. */
14 secp256k1_context* secp256k1_context_verify = nullptr;
15 } // namespace
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.
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.
27 static int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
28 size_t rpos, rlen, spos, slen;
29 size_t pos = 0;
30 size_t lenbyte;
31 unsigned char tmpsig[64] = {0};
32 int overflow = 0;
34 /* Hack to initialize sig with a correctly-parsed but invalid signature. */
35 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
37 /* Sequence tag byte */
38 if (pos == inputlen || input[pos] != 0x30) {
39 return 0;
41 pos++;
43 /* Sequence length bytes */
44 if (pos == inputlen) {
45 return 0;
47 lenbyte = input[pos++];
48 if (lenbyte & 0x80) {
49 lenbyte -= 0x80;
50 if (lenbyte > inputlen - pos) {
51 return 0;
53 pos += lenbyte;
56 /* Integer tag byte for R */
57 if (pos == inputlen || input[pos] != 0x02) {
58 return 0;
60 pos++;
62 /* Integer length for R */
63 if (pos == inputlen) {
64 return 0;
66 lenbyte = input[pos++];
67 if (lenbyte & 0x80) {
68 lenbyte -= 0x80;
69 if (lenbyte > inputlen - pos) {
70 return 0;
72 while (lenbyte > 0 && input[pos] == 0) {
73 pos++;
74 lenbyte--;
76 static_assert(sizeof(size_t) >= 4, "size_t too small");
77 if (lenbyte >= 4) {
78 return 0;
80 rlen = 0;
81 while (lenbyte > 0) {
82 rlen = (rlen << 8) + input[pos];
83 pos++;
84 lenbyte--;
86 } else {
87 rlen = lenbyte;
89 if (rlen > inputlen - pos) {
90 return 0;
92 rpos = pos;
93 pos += rlen;
95 /* Integer tag byte for S */
96 if (pos == inputlen || input[pos] != 0x02) {
97 return 0;
99 pos++;
101 /* Integer length for S */
102 if (pos == inputlen) {
103 return 0;
105 lenbyte = input[pos++];
106 if (lenbyte & 0x80) {
107 lenbyte -= 0x80;
108 if (lenbyte > inputlen - pos) {
109 return 0;
111 while (lenbyte > 0 && input[pos] == 0) {
112 pos++;
113 lenbyte--;
115 static_assert(sizeof(size_t) >= 4, "size_t too small");
116 if (lenbyte >= 4) {
117 return 0;
119 slen = 0;
120 while (lenbyte > 0) {
121 slen = (slen << 8) + input[pos];
122 pos++;
123 lenbyte--;
125 } else {
126 slen = lenbyte;
128 if (slen > inputlen - pos) {
129 return 0;
131 spos = pos;
133 /* Ignore leading zeroes in R */
134 while (rlen > 0 && input[rpos] == 0) {
135 rlen--;
136 rpos++;
138 /* Copy R value */
139 if (rlen > 32) {
140 overflow = 1;
141 } else {
142 memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
145 /* Ignore leading zeroes in S */
146 while (slen > 0 && input[spos] == 0) {
147 slen--;
148 spos++;
150 /* Copy S value */
151 if (slen > 32) {
152 overflow = 1;
153 } else {
154 memcpy(tmpsig + 64 - slen, input + spos, slen);
157 if (!overflow) {
158 overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
160 if (overflow) {
161 /* Overwrite the result again with a correctly-parsed but invalid
162 signature if parsing failed. */
163 memset(tmpsig, 0, 64);
164 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
166 return 1;
169 bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
170 if (!IsValid())
171 return false;
172 secp256k1_pubkey pubkey;
173 secp256k1_ecdsa_signature sig;
174 if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
175 return false;
177 if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
178 return false;
180 /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
181 * not historically been enforced in Bitcoin, so normalize them first. */
182 secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
183 return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
186 bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
187 if (vchSig.size() != COMPACT_SIGNATURE_SIZE)
188 return false;
189 int recid = (vchSig[0] - 27) & 3;
190 bool fComp = ((vchSig[0] - 27) & 4) != 0;
191 secp256k1_pubkey pubkey;
192 secp256k1_ecdsa_recoverable_signature sig;
193 if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
194 return false;
196 if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
197 return false;
199 unsigned char pub[PUBLIC_KEY_SIZE];
200 size_t publen = PUBLIC_KEY_SIZE;
201 secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
202 Set(pub, pub + publen);
203 return true;
206 bool CPubKey::IsFullyValid() const {
207 if (!IsValid())
208 return false;
209 secp256k1_pubkey pubkey;
210 return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size());
213 bool CPubKey::Decompress() {
214 if (!IsValid())
215 return false;
216 secp256k1_pubkey pubkey;
217 if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
218 return false;
220 unsigned char pub[PUBLIC_KEY_SIZE];
221 size_t publen = PUBLIC_KEY_SIZE;
222 secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
223 Set(pub, pub + publen);
224 return true;
227 bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
228 assert(IsValid());
229 assert((nChild >> 31) == 0);
230 assert(size() == COMPRESSED_PUBLIC_KEY_SIZE);
231 unsigned char out[64];
232 BIP32Hash(cc, nChild, *begin(), begin()+1, out);
233 memcpy(ccChild.begin(), out+32, 32);
234 secp256k1_pubkey pubkey;
235 if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
236 return false;
238 if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
239 return false;
241 unsigned char pub[COMPRESSED_PUBLIC_KEY_SIZE];
242 size_t publen = COMPRESSED_PUBLIC_KEY_SIZE;
243 secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
244 pubkeyChild.Set(pub, pub + publen);
245 return true;
248 void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
249 code[0] = nDepth;
250 memcpy(code+1, vchFingerprint, 4);
251 code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
252 code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
253 memcpy(code+9, chaincode.begin(), 32);
254 assert(pubkey.size() == CPubKey::COMPRESSED_PUBLIC_KEY_SIZE);
255 memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_PUBLIC_KEY_SIZE);
258 void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
259 nDepth = code[0];
260 memcpy(vchFingerprint, code+1, 4);
261 nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
262 memcpy(chaincode.begin(), code+9, 32);
263 pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
266 bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
267 out.nDepth = nDepth + 1;
268 CKeyID id = pubkey.GetID();
269 memcpy(&out.vchFingerprint[0], &id, 4);
270 out.nChild = _nChild;
271 return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
274 /* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
275 secp256k1_ecdsa_signature sig;
276 if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
277 return false;
279 return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
282 /* static */ int ECCVerifyHandle::refcount = 0;
284 ECCVerifyHandle::ECCVerifyHandle()
286 if (refcount == 0) {
287 assert(secp256k1_context_verify == nullptr);
288 secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
289 assert(secp256k1_context_verify != nullptr);
291 refcount++;
294 ECCVerifyHandle::~ECCVerifyHandle()
296 refcount--;
297 if (refcount == 0) {
298 assert(secp256k1_context_verify != nullptr);
299 secp256k1_context_destroy(secp256k1_context_verify);
300 secp256k1_context_verify = nullptr;