Bitcoin Core  21.99.0
P2P Digital Currency
pubkey.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2020 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 #include <secp256k1_schnorrsig.h>
11 
12 namespace
13 {
14 /* Global secp256k1_context object used for verification. */
15 secp256k1_context* secp256k1_context_verify = nullptr;
16 } // namespace
17 
28 int ecdsa_signature_parse_der_lax(const secp256k1_context* ctx, secp256k1_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
29  size_t rpos, rlen, spos, slen;
30  size_t pos = 0;
31  size_t lenbyte;
32  unsigned char tmpsig[64] = {0};
33  int overflow = 0;
34 
35  /* Hack to initialize sig with a correctly-parsed but invalid signature. */
37 
38  /* Sequence tag byte */
39  if (pos == inputlen || input[pos] != 0x30) {
40  return 0;
41  }
42  pos++;
43 
44  /* Sequence length bytes */
45  if (pos == inputlen) {
46  return 0;
47  }
48  lenbyte = input[pos++];
49  if (lenbyte & 0x80) {
50  lenbyte -= 0x80;
51  if (lenbyte > inputlen - pos) {
52  return 0;
53  }
54  pos += lenbyte;
55  }
56 
57  /* Integer tag byte for R */
58  if (pos == inputlen || input[pos] != 0x02) {
59  return 0;
60  }
61  pos++;
62 
63  /* Integer length for R */
64  if (pos == inputlen) {
65  return 0;
66  }
67  lenbyte = input[pos++];
68  if (lenbyte & 0x80) {
69  lenbyte -= 0x80;
70  if (lenbyte > inputlen - pos) {
71  return 0;
72  }
73  while (lenbyte > 0 && input[pos] == 0) {
74  pos++;
75  lenbyte--;
76  }
77  static_assert(sizeof(size_t) >= 4, "size_t too small");
78  if (lenbyte >= 4) {
79  return 0;
80  }
81  rlen = 0;
82  while (lenbyte > 0) {
83  rlen = (rlen << 8) + input[pos];
84  pos++;
85  lenbyte--;
86  }
87  } else {
88  rlen = lenbyte;
89  }
90  if (rlen > inputlen - pos) {
91  return 0;
92  }
93  rpos = pos;
94  pos += rlen;
95 
96  /* Integer tag byte for S */
97  if (pos == inputlen || input[pos] != 0x02) {
98  return 0;
99  }
100  pos++;
101 
102  /* Integer length for S */
103  if (pos == inputlen) {
104  return 0;
105  }
106  lenbyte = input[pos++];
107  if (lenbyte & 0x80) {
108  lenbyte -= 0x80;
109  if (lenbyte > inputlen - pos) {
110  return 0;
111  }
112  while (lenbyte > 0 && input[pos] == 0) {
113  pos++;
114  lenbyte--;
115  }
116  static_assert(sizeof(size_t) >= 4, "size_t too small");
117  if (lenbyte >= 4) {
118  return 0;
119  }
120  slen = 0;
121  while (lenbyte > 0) {
122  slen = (slen << 8) + input[pos];
123  pos++;
124  lenbyte--;
125  }
126  } else {
127  slen = lenbyte;
128  }
129  if (slen > inputlen - pos) {
130  return 0;
131  }
132  spos = pos;
133 
134  /* Ignore leading zeroes in R */
135  while (rlen > 0 && input[rpos] == 0) {
136  rlen--;
137  rpos++;
138  }
139  /* Copy R value */
140  if (rlen > 32) {
141  overflow = 1;
142  } else {
143  memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
144  }
145 
146  /* Ignore leading zeroes in S */
147  while (slen > 0 && input[spos] == 0) {
148  slen--;
149  spos++;
150  }
151  /* Copy S value */
152  if (slen > 32) {
153  overflow = 1;
154  } else {
155  memcpy(tmpsig + 64 - slen, input + spos, slen);
156  }
157 
158  if (!overflow) {
159  overflow = !secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
160  }
161  if (overflow) {
162  /* Overwrite the result again with a correctly-parsed but invalid
163  signature if parsing failed. */
164  memset(tmpsig, 0, 64);
165  secp256k1_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
166  }
167  return 1;
168 }
169 
171 {
172  assert(bytes.size() == 32);
173  std::copy(bytes.begin(), bytes.end(), m_keydata.begin());
174 }
175 
177 {
178  assert(sigbytes.size() == 64);
179  secp256k1_xonly_pubkey pubkey;
180  if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &pubkey, m_keydata.data())) return false;
181  return secp256k1_schnorrsig_verify(secp256k1_context_verify, sigbytes.data(), msg.begin(), &pubkey);
182 }
183 
184 bool XOnlyPubKey::CheckPayToContract(const XOnlyPubKey& base, const uint256& hash, bool parity) const
185 {
186  secp256k1_xonly_pubkey base_point;
187  if (!secp256k1_xonly_pubkey_parse(secp256k1_context_verify, &base_point, base.data())) return false;
188  return secp256k1_xonly_pubkey_tweak_add_check(secp256k1_context_verify, m_keydata.begin(), parity, &base_point, hash.begin());
189 }
190 
191 bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
192  if (!IsValid())
193  return false;
194  secp256k1_pubkey pubkey;
196  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
197  if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
198  return false;
199  }
200  if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
201  return false;
202  }
203  /* libsecp256k1's ECDSA verification requires lower-S signatures, which have
204  * not historically been enforced in Bitcoin, so normalize them first. */
205  secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, &sig, &sig);
206  return secp256k1_ecdsa_verify(secp256k1_context_verify, &sig, hash.begin(), &pubkey);
207 }
208 
209 bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
210  if (vchSig.size() != COMPACT_SIGNATURE_SIZE)
211  return false;
212  int recid = (vchSig[0] - 27) & 3;
213  bool fComp = ((vchSig[0] - 27) & 4) != 0;
214  secp256k1_pubkey pubkey;
216  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
217  if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_verify, &sig, &vchSig[1], recid)) {
218  return false;
219  }
220  if (!secp256k1_ecdsa_recover(secp256k1_context_verify, &pubkey, &sig, hash.begin())) {
221  return false;
222  }
223  unsigned char pub[SIZE];
224  size_t publen = SIZE;
225  secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, fComp ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED);
226  Set(pub, pub + publen);
227  return true;
228 }
229 
230 bool CPubKey::IsFullyValid() const {
231  if (!IsValid())
232  return false;
233  secp256k1_pubkey pubkey;
234  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
235  return secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size());
236 }
237 
239  if (!IsValid())
240  return false;
241  secp256k1_pubkey pubkey;
242  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
243  if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
244  return false;
245  }
246  unsigned char pub[SIZE];
247  size_t publen = SIZE;
248  secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_UNCOMPRESSED);
249  Set(pub, pub + publen);
250  return true;
251 }
252 
253 bool CPubKey::Derive(CPubKey& pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const {
254  assert(IsValid());
255  assert((nChild >> 31) == 0);
256  assert(size() == COMPRESSED_SIZE);
257  unsigned char out[64];
258  BIP32Hash(cc, nChild, *begin(), begin()+1, out);
259  memcpy(ccChild.begin(), out+32, 32);
260  secp256k1_pubkey pubkey;
261  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
262  if (!secp256k1_ec_pubkey_parse(secp256k1_context_verify, &pubkey, vch, size())) {
263  return false;
264  }
265  if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context_verify, &pubkey, out)) {
266  return false;
267  }
268  unsigned char pub[COMPRESSED_SIZE];
269  size_t publen = COMPRESSED_SIZE;
270  secp256k1_ec_pubkey_serialize(secp256k1_context_verify, pub, &publen, &pubkey, SECP256K1_EC_COMPRESSED);
271  pubkeyChild.Set(pub, pub + publen);
272  return true;
273 }
274 
275 void CExtPubKey::Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const {
276  code[0] = nDepth;
277  memcpy(code+1, vchFingerprint, 4);
278  code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
279  code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
280  memcpy(code+9, chaincode.begin(), 32);
281  assert(pubkey.size() == CPubKey::COMPRESSED_SIZE);
282  memcpy(code+41, pubkey.begin(), CPubKey::COMPRESSED_SIZE);
283 }
284 
285 void CExtPubKey::Decode(const unsigned char code[BIP32_EXTKEY_SIZE]) {
286  nDepth = code[0];
287  memcpy(vchFingerprint, code+1, 4);
288  nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
289  memcpy(chaincode.begin(), code+9, 32);
290  pubkey.Set(code+41, code+BIP32_EXTKEY_SIZE);
291 }
292 
293 bool CExtPubKey::Derive(CExtPubKey &out, unsigned int _nChild) const {
294  out.nDepth = nDepth + 1;
295  CKeyID id = pubkey.GetID();
296  memcpy(&out.vchFingerprint[0], &id, 4);
297  out.nChild = _nChild;
298  return pubkey.Derive(out.pubkey, out.chaincode, _nChild, chaincode);
299 }
300 
301 /* static */ bool CPubKey::CheckLowS(const std::vector<unsigned char>& vchSig) {
303  assert(secp256k1_context_verify && "secp256k1_context_verify must be initialized to use CPubKey.");
304  if (!ecdsa_signature_parse_der_lax(secp256k1_context_verify, &sig, vchSig.data(), vchSig.size())) {
305  return false;
306  }
307  return (!secp256k1_ecdsa_signature_normalize(secp256k1_context_verify, nullptr, &sig));
308 }
309 
310 /* static */ int ECCVerifyHandle::refcount = 0;
311 
313 {
314  if (refcount == 0) {
315  assert(secp256k1_context_verify == nullptr);
316  secp256k1_context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
317  assert(secp256k1_context_verify != nullptr);
318  }
319  refcount++;
320 }
321 
323 {
324  refcount--;
325  if (refcount == 0) {
326  assert(secp256k1_context_verify != nullptr);
327  secp256k1_context_destroy(secp256k1_context_verify);
328  secp256k1_context_verify = nullptr;
329  }
330 }
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:662
unsigned char vchFingerprint[4]
Definition: pubkey.h:242
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:404
assert(!tx.IsCoinBase())
constexpr C * end() const noexcept
Definition: span.h:171
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:28
Opaque data structured that holds a parsed ECDSA signature, supporting pubkey recovery.
unsigned char data[64]
Definition: secp256k1.h:81
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:87
constexpr std::size_t size() const noexcept
Definition: span.h:182
static int refcount
Definition: pubkey.h:270
unsigned char nDepth
Definition: pubkey.h:241
static bool CheckLowS(const std::vector< unsigned char > &vchSig)
Check whether a signature is normalized (lower-S).
Definition: pubkey.cpp:301
bool Derive(CPubKey &pubkeyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode &cc) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:253
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:295
bool CheckPayToContract(const XOnlyPubKey &base, const uint256 &hash, bool parity) const
Definition: pubkey.cpp:184
const unsigned char * data() const
Definition: uint256.h:55
ChainCode chaincode
Definition: pubkey.h:244
bool VerifySchnorr(const uint256 &msg, Span< const unsigned char > sigbytes) const
Verify a Schnorr signature against this public key.
Definition: pubkey.cpp:176
unsigned char * begin()
Definition: uint256.h:58
unsigned int nChild
Definition: pubkey.h:243
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object (created in dynamically allocated memory).
Definition: secp256k1.c:195
#define SECP256K1_EC_UNCOMPRESSED
Definition: secp256k1.h:177
#define SECP256K1_EC_COMPRESSED
Flag to pass to secp256k1_ec_pubkey_serialize.
Definition: secp256k1.h:176
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:38
void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const
Definition: pubkey.cpp:275
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE])
Definition: pubkey.cpp:285
size_t size() const
Definition: pubkey.h:237
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid()) ...
Definition: pubkey.cpp:230
Opaque data structure that holds a parsed and valid "x-only" public key.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_parse(const secp256k1_context *ctx, secp256k1_xonly_pubkey *pubkey, const unsigned char *input32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a 32-byte sequence into a xonly_pubkey object.
Definition: main_impl.h:21
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:209
void BIP32Hash(const ChainCode &chainCode, unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
Definition: hash.cpp:72
static secp256k1_context * ctx
Definition: tests.c:36
An encapsulated public key.
Definition: pubkey.h:31
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_xonly_pubkey_tweak_add_check(const secp256k1_context *ctx, const unsigned char *tweaked_pubkey32, int tweaked_pk_parity, const secp256k1_xonly_pubkey *internal_pubkey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5)
Checks that a tweaked pubkey is the result of calling secp256k1_xonly_pubkey_tweak_add with internal_...
Definition: main_impl.h:109
XOnlyPubKey(Span< const unsigned char > bytes)
Construct an x-only pubkey from exactly 32 bytes.
Definition: pubkey.cpp:170
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:277
Opaque data structured that holds a parsed ECDSA signature.
Definition: secp256k1.h:80
uint256 m_keydata
Definition: pubkey.h:222
#define SECP256K1_CONTEXT_VERIFY
Flags to pass to secp256k1_context_create, secp256k1_context_preallocated_size, and secp256k1_context...
Definition: secp256k1.h:170
constexpr C * begin() const noexcept
Definition: span.h:170
256-bit opaque blob.
Definition: uint256.h:124
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:293
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:137
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:358
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Verify a DER signature (~72 bytes).
Definition: pubkey.cpp:191
constexpr C * data() const noexcept
Definition: span.h:169
void * memcpy(void *a, const void *b, size_t c)
const unsigned int BIP32_EXTKEY_SIZE
Definition: pubkey.h:18
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:21
CPubKey pubkey
Definition: pubkey.h:245
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:92
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object (in dynamically allocated memory).
Definition: secp256k1.c:151
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:238
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_schnorrsig_verify(const secp256k1_context *ctx, const unsigned char *sig64, const unsigned char *msg32, const secp256k1_xonly_pubkey *pubkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Verify a Schnorr signature.
Definition: main_impl.h:190
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:67
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:423
const unsigned char * data() const
Definition: pubkey.h:236