Bitcoin Core  0.19.99
P2P Digital Currency
pubkey.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2019 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.
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 
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;
33 
34  /* Hack to initialize sig with a correctly-parsed but invalid signature. */
36 
37  /* Sequence tag byte */
38  if (pos == inputlen || input[pos] != 0x30) {
39  return 0;
40  }
41  pos++;
42 
43  /* Sequence length bytes */
44  if (pos == inputlen) {
45  return 0;
46  }
47  lenbyte = input[pos++];
48  if (lenbyte & 0x80) {
49  lenbyte -= 0x80;
50  if (lenbyte > inputlen - pos) {
51  return 0;
52  }
53  pos += lenbyte;
54  }
55 
56  /* Integer tag byte for R */
57  if (pos == inputlen || input[pos] != 0x02) {
58  return 0;
59  }
60  pos++;
61 
62  /* Integer length for R */
63  if (pos == inputlen) {
64  return 0;
65  }
66  lenbyte = input[pos++];
67  if (lenbyte & 0x80) {
68  lenbyte -= 0x80;
69  if (lenbyte > inputlen - pos) {
70  return 0;
71  }
72  while (lenbyte > 0 && input[pos] == 0) {
73  pos++;
74  lenbyte--;
75  }
76  static_assert(sizeof(size_t) >= 4, "size_t too small");
77  if (lenbyte >= 4) {
78  return 0;
79  }
80  rlen = 0;
81  while (lenbyte > 0) {
82  rlen = (rlen << 8) + input[pos];
83  pos++;
84  lenbyte--;
85  }
86  } else {
87  rlen = lenbyte;
88  }
89  if (rlen > inputlen - pos) {
90  return 0;
91  }
92  rpos = pos;
93  pos += rlen;
94 
95  /* Integer tag byte for S */
96  if (pos == inputlen || input[pos] != 0x02) {
97  return 0;
98  }
99  pos++;
100 
101  /* Integer length for S */
102  if (pos == inputlen) {
103  return 0;
104  }
105  lenbyte = input[pos++];
106  if (lenbyte & 0x80) {
107  lenbyte -= 0x80;
108  if (lenbyte > inputlen - pos) {
109  return 0;
110  }
111  while (lenbyte > 0 && input[pos] == 0) {
112  pos++;
113  lenbyte--;
114  }
115  static_assert(sizeof(size_t) >= 4, "size_t too small");
116  if (lenbyte >= 4) {
117  return 0;
118  }
119  slen = 0;
120  while (lenbyte > 0) {
121  slen = (slen << 8) + input[pos];
122  pos++;
123  lenbyte--;
124  }
125  } else {
126  slen = lenbyte;
127  }
128  if (slen > inputlen - pos) {
129  return 0;
130  }
131  spos = pos;
132 
133  /* Ignore leading zeroes in R */
134  while (rlen > 0 && input[rpos] == 0) {
135  rlen--;
136  rpos++;
137  }
138  /* Copy R value */
139  if (rlen > 32) {
140  overflow = 1;
141  } else {
142  memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
143  }
144 
145  /* Ignore leading zeroes in S */
146  while (slen > 0 && input[spos] == 0) {
147  slen--;
148  spos++;
149  }
150  /* Copy S value */
151  if (slen > 32) {
152  overflow = 1;
153  } else {
154  memcpy(tmpsig + 64 - slen, input + spos, slen);
155  }
156 
157  if (!overflow) {
158  overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
159  }
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);
165  }
166  return 1;
167 }
168 
169 bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
170  if (!IsValid())
171  return false;
172  secp256k1_pubkey pubkey;
174  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
175  if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
176  return false;
177  }
178  if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
179  return false;
180  }
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);
185 }
186 
187 bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
188  if (vchSig.size() != COMPACT_SIGNATURE_SIZE)
189  return false;
190  int recid = (vchSig[0] - 27) & 3;
191  bool fComp = ((vchSig[0] - 27) & 4) != 0;
192  secp256k1_pubkey pubkey;
194  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
195  if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
196  return false;
197  }
198  if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
199  return false;
200  }
201  unsigned char pub[SIZE];
202  size_t publen = SIZE;
203  secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
204  Set(pub, pub + publen);
205  return true;
206 }
207 
208 bool CPubKey::IsFullyValid() const {
209  if (!IsValid())
210  return false;
211  secp256k1_pubkey pubkey;
212  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
213  return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size());
214 }
215 
217  if (!IsValid())
218  return false;
219  secp256k1_pubkey pubkey;
220  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
221  if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
222  return false;
223  }
224  unsigned char pub[SIZE];
225  size_t publen = SIZE;
226  secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
227  Set(pub, pub + publen);
228  return true;
229 }
230 
231 bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
232  assert(IsValid());
233  assert((nChild >> 31) == 0);
234  assert(size() == COMPRESSED_SIZE);
235  unsigned char out[64];
236  BIP32Hash(cc, nChild, *begin(), begin()+1, out);
237  memcpy(ccChild.begin(), out+32, 32);
238  secp256k1_pubkey pubkey;
239  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
240  if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
241  return false;
242  }
243  if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
244  return false;
245  }
246  unsigned char pub[COMPRESSED_SIZE];
247  size_t publen = COMPRESSED_SIZE;
248  secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
249  pubkeyChild.Set(pub, pub + publen);
250  return true;
251 }
252 
253 void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
254  code[0] = nDepth;
255  memcpy(code+1, vchFingerprint, 4);
256  code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
257  code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
258  memcpy(code+9, chaincode.begin(), 32);
259  assert(pubkey.size() == CPubKey::COMPRESSED_SIZE);
260  memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_SIZE);
261 }
262 
263 void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
264  nDepth = code[0];
265  memcpy(vchFingerprint, code+1, 4);
266  nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
267  memcpy(chaincode.begin(), code+9, 32);
268  pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
269 }
270 
271 bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
272  out.nDepth = nDepth + 1;
273  CKeyID id = pubkey.GetID();
274  memcpy(&out.vchFingerprint[0], &id, 4);
275  out.nChild = _nChild;
276  return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
277 }
278 
279 /* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
281  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
282  if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
283  return false;
284  }
285  return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
286 }
287 
288 /* static */ int ECCVerifyHandle::refcount = 0;
289 
291 {
292  if (refcount == 0) {
293  assert(secp256k1_context_verify == nullptr);
294  secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
295  assert(secp256k1_context_verify != nullptr);
296  }
297  refcount++;
298 }
299 
301 {
302  refcount--;
303  if (refcount == 0) {
304  assert(secp256k1_context_verify != nullptr);
305  secp256k1_context_destroy(secp256k1_context_verify);
306  secp256k1_context_verify = nullptr;
307  }
308 }
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *input64, int recid) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a compact ECDSA signature (64 bytes + recovery id).
Definition: main_impl.h:38
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_add(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Tweak a public key by adding tweak times the generator to it.
Definition: secp256k1.c:501
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:36
unsigned char vchFingerprint[4]
Definition: pubkey.h:208
SECP256K1_API int secp256k1_ecdsa_signature_normalize(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sigout, const secp256k1_ecdsa_signature *sigin) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3)
Convert a signature to a normalized lower-S form.
Definition: secp256k1.c:295
unsigned char vch[SIZE]
see www.keylength.com script supports up to 75 for single byte push
Definition: pubkey.h:46
Opaque data structured that holds a parsed ECDSA signature, supporting pubkey recovery.
unsigned char data[64]
Definition: secp256k1.h:80
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:86
static int refcount
Definition: pubkey.h:231
unsigned char nDepth
Definition: pubkey.h:207
static bool CheckLowS(const std::vector< unsigned char > &vchSig)
Check whether a signature is normalized (lower-S).
Definition: pubkey.cpp:279
bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:231
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize a pubkey object into a serialized byte sequence.
Definition: secp256k1.c:186
ChainCode chaincode
Definition: pubkey.h:210
unsigned char * begin()
Definition: uint256.h:54
unsigned int nChild
Definition: pubkey.h:209
const unsigned char * begin() const
Definition: pubkey.h:111
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object.
Definition: secp256k1.c:101
#define SECP256K1_EC_UNCOMPRESSED
Definition: secp256k1.h:173
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize and secp256k1_ec_privkey_export.
Definition: secp256k1.h:172
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:37
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:253
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:263
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
Definition: pubkey.cpp:208
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:187
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
Definition: hash.cpp:71
static secp256k1_context * ctx
Definition: tests.c:46
bool IsValid() const
Definition: pubkey.h:171
An encapsulated public key.
Definition: pubkey.h:30
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:109
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a variable-length public key into the pubkey object.
Definition: secp256k1.c:171
Opaque data structured that holds a parsed ECDSA signature.
Definition: secp256k1.h:79
static constexpr unsigned int COMPACT_SIGNATURE_SIZE
Definition: pubkey.h:39
#define SECP256K1_CONTEXT_VERIFY
Flags to pass to secp256k1_context_create.
Definition: secp256k1.h:167
256-bit opaque blob.
Definition: uint256.h:120
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:271
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msg32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Recover an ECDSA public key from a signature.
Definition: main_impl.h:170
SECP256K1_API int secp256k1_ecdsa_signature_parse_compact(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input64) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse an ECDSA signature in compact (64 bytes) format.
Definition: secp256k1.c:249
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Verify a DER signature (~72 bytes).
Definition: pubkey.cpp:169
void * memcpy(void *a, const void *b, size_t c)
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:17
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
CPubKey pubkey
Definition: pubkey.h:211
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object.
Definition: secp256k1.c:67
static int ecdsa_signature_parse_der_lax(const secp256k1_context *ctx, secp256k1_ecdsa_signature *sig, const unsigned char *input, size_t inputlen)
This function is taken from the libsecp256k1 distribution and implements DER parsing for ECDSA signat...
Definition: pubkey.cpp:27
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:216
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:66
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(const secp256k1_context *ctx, const secp256k1_ecdsa_signature *sig, const unsigned char *msg32, const secp256k1_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Verify an ECDSA signature.
Definition: secp256k1.c:314