PRCYCoin  2.0.0.7rc1
P2P Digital Currency
pubkey.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2014 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include "pubkey.h"
6 
7 #include "eccryptoverify.h"
8 
9 #ifdef USE_SECP256K1
10 #include <secp256k1.h>
11 #else
12 #include "ecwrapper.h"
13 #endif
14 
15 bool CPubKey::Verify(const uint256& hash, const std::vector<unsigned char>& vchSig) const
16 {
17  if (!IsValid())
18  return false;
19 #ifdef USE_SECP256K1
20  if (secp256k1_ecdsa_verify((const unsigned char*)&hash, 32, &vchSig[0], vchSig.size(), begin(), size()) != 1)
21  return false;
22 #else
23  CECKey key;
24  if (!key.SetPubKey(begin(), size()))
25  return false;
26  if (!key.Verify(hash, vchSig))
27  return false;
28 #endif
29  return true;
30 }
31 
32 bool CPubKey::RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig)
33 {
34  if (vchSig.size() != 65)
35  return false;
36  int recid = (vchSig[0] - 27) & 3;
37  bool fComp = ((vchSig[0] - 27) & 4) != 0;
38 #ifdef USE_SECP256K1
39  int pubkeylen = 65;
40  if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, 32, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid))
41  return false;
42  assert((int)size() == pubkeylen);
43 #else
44  CECKey key;
45  if (!key.Recover(hash, &vchSig[1], recid))
46  return false;
47  std::vector<unsigned char> pubkey;
48  key.GetPubKey(pubkey, fComp);
49  Set(pubkey.begin(), pubkey.end());
50 #endif
51  return true;
52 }
53 
55 {
56  if (!IsValid())
57  return false;
58 #ifdef USE_SECP256K1
59  if (!secp256k1_ecdsa_pubkey_verify(begin(), size()))
60  return false;
61 #else
62  CECKey key;
63  if (!key.SetPubKey(begin(), size()))
64  return false;
65 #endif
66  return true;
67 }
68 
70 {
71  if (!IsValid())
72  return false;
73 #ifdef USE_SECP256K1
74  int clen = size();
75  int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen);
76  assert(ret);
77  assert(clen == (int)size());
78 #else
79  CECKey key;
80  if (!key.SetPubKey(begin(), size()))
81  return false;
82  std::vector<unsigned char> pubkey;
83  key.GetPubKey(pubkey, false);
84  Set(pubkey.begin(), pubkey.end());
85 #endif
86  return true;
87 }
88 
89 bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const
90 {
91  assert(IsValid());
92  assert((nChild >> 31) == 0);
93  assert(begin() + 33 == end());
94  unsigned char out[64];
95  BIP32Hash(cc, nChild, *begin(), begin() + 1, out);
96  memcpy(ccChild, out + 32, 32);
97 #ifdef USE_SECP256K1
98  pubkeyChild = *this;
99  bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out);
100 #else
101  CECKey key;
102  bool ret = key.SetPubKey(begin(), size());
103  ret &= key.TweakPublic(out);
104  std::vector<unsigned char> pubkey;
105  key.GetPubKey(pubkey, true);
106  pubkeyChild.Set(pubkey.begin(), pubkey.end());
107 #endif
108  return ret;
109 }
110 
111 void CExtPubKey::Encode(unsigned char code[74]) const
112 {
113  code[0] = nDepth;
114  memcpy(code + 1, vchFingerprint, 4);
115  code[5] = (nChild >> 24) & 0xFF;
116  code[6] = (nChild >> 16) & 0xFF;
117  code[7] = (nChild >> 8) & 0xFF;
118  code[8] = (nChild >> 0) & 0xFF;
119  memcpy(code + 9, vchChainCode, 32);
120  assert(pubkey.size() == 33);
121  memcpy(code + 41, pubkey.begin(), 33);
122 }
123 
124 void CExtPubKey::Decode(const unsigned char code[74])
125 {
126  nDepth = code[0];
127  memcpy(vchFingerprint, code + 1, 4);
128  nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
129  memcpy(vchChainCode, code + 9, 32);
130  pubkey.Set(code + 41, code + 74);
131 }
132 
133 bool CExtPubKey::Derive(CExtPubKey& out, unsigned int nChild) const
134 {
135  out.nDepth = nDepth + 1;
136  CKeyID id = pubkey.GetID();
137  memcpy(&out.vchFingerprint[0], &id, 4);
138  out.nChild = nChild;
139  return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode);
140 }
ecwrapper.h
CPubKey::Set
void Set(const T pbegin, const T pend)
Initialize a public key using begin/end iterators to byte data.
Definition: pubkey.h:71
base_uint::size
unsigned int size() const
Definition: arith_uint256.h:260
memcpy
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:15
CPubKey::Decompress
bool Decompress()
Turn this public key into an uncompressed public key.
Definition: pubkey.cpp:69
eccryptoverify.h
CKeyID
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:29
CExtPubKey::nDepth
unsigned char nDepth
Definition: pubkey.h:206
pubkey.h
CExtPubKey::Derive
bool Derive(CExtPubKey &out, unsigned int nChild) const
Definition: pubkey.cpp:133
CExtPubKey::nChild
unsigned int nChild
Definition: pubkey.h:208
CPubKey::begin
const unsigned char * begin() const
Definition: pubkey.h:95
secp256k1.h
secp256k1_ecdsa_recover_compact
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover_compact(const unsigned char *msg, int msglen, const unsigned char *sig64, unsigned char *pubkey, int *pubkeylen, int compressed, int recid) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4) SECP256K1_ARG_NONNULL(5)
Recover an ECDSA public key from a compact signature.
Definition: secp256k1.c:141
CECKey
RAII Wrapper around OpenSSL's EC_KEY.
Definition: ecwrapper.h:16
CExtPubKey::vchFingerprint
unsigned char vchFingerprint[4]
Definition: pubkey.h:207
CPubKey::Verify
bool Verify(const uint256 &hash, const std::vector< unsigned char > &vchSig) const
Verify a DER signature (~72 bytes).
Definition: pubkey.cpp:15
CPubKey::end
const unsigned char * end() const
Definition: pubkey.h:96
CExtPubKey::vchChainCode
unsigned char vchChainCode[32]
Definition: pubkey.h:209
CPubKey::size
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:94
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
secp256k1_ecdsa_verify
SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_verify(const unsigned char *msg, int msglen, const unsigned char *sig, int siglen, const unsigned char *pubkey, int pubkeylen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(5)
Verify an ECDSA signature.
Definition: secp256k1.c:43
CKey::GetPubKey
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:79
CPubKey::RecoverCompact
bool RecoverCompact(const uint256 &hash, const std::vector< unsigned char > &vchSig)
Recover a public key from a compact signature.
Definition: pubkey.cpp:32
CPubKey::Derive
bool Derive(CPubKey &pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const
Derive BIP32 child pubkey.
Definition: pubkey.cpp:89
CExtPubKey::Decode
void Decode(const unsigned char code[74])
Definition: pubkey.cpp:124
BIP32Hash
void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
Definition: hash.cpp:73
CPubKey
An encapsulated public key.
Definition: pubkey.h:37
key
CKey key
Definition: bip38tooldialog.cpp:173
CPubKey::IsFullyValid
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:54
CPubKey::IsValid
bool IsValid() const
Definition: pubkey.h:159
CExtPubKey::pubkey
CPubKey pubkey
Definition: pubkey.h:210
CExtPubKey
Definition: pubkey.h:205
CPubKey::GetID
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:143
CExtPubKey::Encode
void Encode(unsigned char code[74]) const
Definition: pubkey.cpp:111