Fix parameter naming inconsistencies between .h and .cpp files
[bitcoinplatinum.git] / src / pubkey.cpp
blobe57fa238cb83b272bb400f1c76a359feef4fc675
1 // Copyright (c) 2009-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "pubkey.h"
7 #include <secp256k1.h>
8 #include <secp256k1_recovery.h>
10 namespace
12 /* Global secp256k1_context object used for verification. */
13 secp256k1_context* secp256k1_context_verify = NULL;
16 /** This function is taken from the libsecp256k1 distribution and implements
17 * DER parsing for ECDSA signatures, while supporting an arbitrary subset of
18 * format violations.
20 * Supported violations include negative integers, excessive padding, garbage
21 * at the end, and overly long length descriptors. This is safe to use in
22 * Bitcoin because since the activation of BIP66, signatures are verified to be
23 * strict DER before being passed to this module, and we know it supports all
24 * violations present in the blockchain before that point.
26 static int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
27 size_t rpos, rlen, spos, slen;
28 size_t pos = 0;
29 size_t lenbyte;
30 unsigned char tmpsig[64] = {0};
31 int overflow = 0;
33 /* Hack to initialize sig with a correctly-parsed but invalid signature. */
34 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
36 /* Sequence tag byte */
37 if (pos == inputlen || input[pos] != 0x30) {
38 return 0;
40 pos++;
42 /* Sequence length bytes */
43 if (pos == inputlen) {
44 return 0;
46 lenbyte = input[pos++];
47 if (lenbyte & 0x80) {
48 lenbyte -= 0x80;
49 if (pos + lenbyte > inputlen) {
50 return 0;
52 pos += lenbyte;
55 /* Integer tag byte for R */
56 if (pos == inputlen || input[pos] != 0x02) {
57 return 0;
59 pos++;
61 /* Integer length for R */
62 if (pos == inputlen) {
63 return 0;
65 lenbyte = input[pos++];
66 if (lenbyte & 0x80) {
67 lenbyte -= 0x80;
68 if (pos + lenbyte > inputlen) {
69 return 0;
71 while (lenbyte > 0 && input[pos] == 0) {
72 pos++;
73 lenbyte--;
75 if (lenbyte >= sizeof(size_t)) {
76 return 0;
78 rlen = 0;
79 while (lenbyte > 0) {
80 rlen = (rlen << 8) + input[pos];
81 pos++;
82 lenbyte--;
84 } else {
85 rlen = lenbyte;
87 if (rlen > inputlen - pos) {
88 return 0;
90 rpos = pos;
91 pos += rlen;
93 /* Integer tag byte for S */
94 if (pos == inputlen || input[pos] != 0x02) {
95 return 0;
97 pos++;
99 /* Integer length for S */
100 if (pos == inputlen) {
101 return 0;
103 lenbyte = input[pos++];
104 if (lenbyte & 0x80) {
105 lenbyte -= 0x80;
106 if (pos + lenbyte > inputlen) {
107 return 0;
109 while (lenbyte > 0 && input[pos] == 0) {
110 pos++;
111 lenbyte--;
113 if (lenbyte >= sizeof(size_t)) {
114 return 0;
116 slen = 0;
117 while (lenbyte > 0) {
118 slen = (slen << 8) + input[pos];
119 pos++;
120 lenbyte--;
122 } else {
123 slen = lenbyte;
125 if (slen > inputlen - pos) {
126 return 0;
128 spos = pos;
129 pos += slen;
131 /* Ignore leading zeroes in R */
132 while (rlen > 0 && input[rpos] == 0) {
133 rlen--;
134 rpos++;
136 /* Copy R value */
137 if (rlen > 32) {
138 overflow = 1;
139 } else {
140 memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
143 /* Ignore leading zeroes in S */
144 while (slen > 0 && input[spos] == 0) {
145 slen--;
146 spos++;
148 /* Copy S value */
149 if (slen > 32) {
150 overflow = 1;
151 } else {
152 memcpy(tmpsig + 64 - slen, input + spos, slen);
155 if (!overflow) {
156 overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
158 if (overflow) {
159 /* Overwrite the result again with a correctly-parsed but invalid
160 signature if parsing failed. */
161 memset(tmpsig, 0, 64);
162 secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
164 return 1;
167 bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
168 if (!IsValid())
169 return false;
170 secp256k1_pubkey pubkey;
171 secp256k1_ecdsa_signature sig;
172 if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
173 return false;
175 if (vchSig.size() == 0) {
176 return false;
178 if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) {
179 return false;
181 /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
182 * not historically been enforced in Bitcoin, so normalize them first. */
183 secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
184 return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
187 bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
188 if (vchSig.size() != 65)
189 return false;
190 int recid = (vchSig[0] - 27) & 3;
191 bool fComp = ((vchSig[0] - 27) & 4) != 0;
192 secp256k1_pubkey pubkey;
193 secp256k1_ecdsa_recoverable_signature sig;
194 if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
195 return false;
197 if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
198 return false;
200 unsigned char pub[65];
201 size_t publen = 65;
202 secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
203 Set(pub, pub + publen);
204 return true;
207 bool CPubKey::IsFullyValid() const {
208 if (!IsValid())
209 return false;
210 secp256k1_pubkey pubkey;
211 return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size());
214 bool CPubKey::Decompress() {
215 if (!IsValid())
216 return false;
217 secp256k1_pubkey pubkey;
218 if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
219 return false;
221 unsigned char pub[65];
222 size_t publen = 65;
223 secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
224 Set(pub, pub + publen);
225 return true;
228 bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
229 assert(IsValid());
230 assert((nChild >> 31) == 0);
231 assert(begin() + 33 == end());
232 unsigned char out[64];
233 BIP32Hash(cc, nChild, *begin(), begin()+1, out);
234 memcpy(ccChild.begin(), out+32, 32);
235 secp256k1_pubkey pubkey;
236 if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, &(*this)[0], size())) {
237 return false;
239 if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
240 return false;
242 unsigned char pub[33];
243 size_t publen = 33;
244 secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
245 pubkeyChild.Set(pub, pub + publen);
246 return true;
249 void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
250 code[0] = nDepth;
251 memcpy(code+1, vchFingerprint, 4);
252 code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
253 code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
254 memcpy(code+9, chaincode.begin(), 32);
255 assert(pubkey.size() == 33);
256 memcpy(code+41, pubkey.begin(), 33);
259 void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
260 nDepth = code[0];
261 memcpy(vchFingerprint, code+1, 4);
262 nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
263 memcpy(chaincode.begin(), code+9, 32);
264 pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
267 bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
268 out.nDepth = nDepth + 1;
269 CKeyID id = pubkey.GetID();
270 memcpy(&out.vchFingerprint[0], &id, 4);
271 out.nChild = _nChild;
272 return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
275 /* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
276 secp256k1_ecdsa_signature sig;
277 if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, &vchSig[0], vchSig.size())) {
278 return false;
280 return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, NULL, &sig));
283 /* static */ int ECCVerifyHandle::refcount = 0;
285 ECCVerifyHandle::ECCVerifyHandle()
287 if (refcount == 0) {
288 assert(secp256k1_context_verify == NULL);
289 secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
290 assert(secp256k1_context_verify != NULL);
292 refcount++;
295 ECCVerifyHandle::~ECCVerifyHandle()
297 refcount--;
298 if (refcount == 0) {
299 assert(secp256k1_context_verify != NULL);
300 secp256k1_context_destroy(secp256k1_context_verify);
301 secp256k1_context_verify = NULL;