]> Git Repo - VerusCoin.git/blob - src/key.h
Merge branch 'beta' into mergemaster
[VerusCoin.git] / src / key.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin Core developers
3 // Copyright (c) 2017 The Zcash developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6
7 #ifndef BITCOIN_KEY_H
8 #define BITCOIN_KEY_H
9
10 #include "pubkey.h"
11 #include "serialize.h"
12 #include "support/allocators/secure.h"
13 #include "uint256.h"
14
15 #include <stdexcept>
16 #include <vector>
17
18
19 /**
20  * secure_allocator is defined in allocators.h
21  * CPrivKey is a serialized private key, with all parameters included
22  * (PRIVATE_KEY_SIZE bytes)
23  */
24 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;
25
26 /** An encapsulated private key. */
27 class CKey
28 {
29 public:
30     /**
31      * secp256k1:
32      */
33     static const unsigned int PRIVATE_KEY_SIZE            = 279;
34     static const unsigned int COMPRESSED_PRIVATE_KEY_SIZE = 214;
35     /**
36      * see www.keylength.com
37      * script supports up to 75 for single byte push
38      */
39     static_assert(
40         PRIVATE_KEY_SIZE >= COMPRESSED_PRIVATE_KEY_SIZE,
41         "COMPRESSED_PRIVATE_KEY_SIZE is larger than PRIVATE_KEY_SIZE");
42
43 private:
44     //! Whether this private key is valid. We check for correctness when modifying the key
45     //! data, so fValid should always correspond to the actual state.
46     bool fValid;
47
48     //! Whether the public key corresponding to this private key is (to be) compressed.
49     bool fCompressed;
50
51     //! The actual byte data
52     unsigned char vch[32];
53
54     //! Check whether the 32-byte array pointed to be vch is valid keydata.
55     bool static Check(const unsigned char* vch);
56
57 public:
58     //! Construct an invalid private key.
59     CKey() : fValid(false), fCompressed(false)
60     {
61         LockObject(vch);
62     }
63
64     //! Copy constructor. This is necessary because of memlocking.
65     CKey(const CKey& secret) : fValid(secret.fValid), fCompressed(secret.fCompressed)
66     {
67         LockObject(vch);
68         memcpy(vch, secret.vch, sizeof(vch));
69     }
70
71     //! Destructor (again necessary because of memlocking).
72     ~CKey()
73     {
74         UnlockObject(vch);
75     }
76
77     friend bool operator==(const CKey& a, const CKey& b)
78     {
79         return a.fCompressed == b.fCompressed && a.size() == b.size() &&
80                memcmp(&a.vch[0], &b.vch[0], a.size()) == 0;
81     }
82
83     //! Initialize using begin and end iterators to byte data.
84     template <typename T>
85     void Set(const T pbegin, const T pend, bool fCompressedIn)
86     {
87         if (pend - pbegin != 32) {
88             fValid = false;
89             return;
90         }
91         if (Check(&pbegin[0])) {
92             memcpy(vch, (unsigned char*)&pbegin[0], 32);
93             fValid = true;
94             fCompressed = fCompressedIn;
95         } else {
96             fValid = false;
97         }
98     }
99
100     //! Simple read-only vector-like interface.
101     unsigned int size() const { return (fValid ? 32 : 0); }
102     const unsigned char* begin() const { return vch; }
103     const unsigned char* end() const { return vch + size(); }
104
105     //! Check whether this private key is valid.
106     bool IsValid() const { return fValid; }
107
108     //! Check whether the public key corresponding to this private key is (to be) compressed.
109     bool IsCompressed() const { return fCompressed; }
110
111     //! Initialize from a CPrivKey (serialized OpenSSL private key data).
112     bool SetPrivKey(const CPrivKey& vchPrivKey, bool fCompressed);
113
114     //! Generate a new private key using a cryptographic PRNG.
115     void MakeNewKey(bool fCompressed);
116
117     /**
118      * Convert the private key to a CPrivKey (serialized OpenSSL private key data).
119      * This is expensive. 
120      */
121     CPrivKey GetPrivKey() const;
122
123     /**
124      * Compute the public key from a private key.
125      * This is expensive.
126      */
127     CPubKey GetPubKey() const;
128
129     /**
130      * Create a DER-serialized signature.
131      * The test_case parameter tweaks the deterministic nonce.
132      */
133     bool Sign(const uint256& hash, std::vector<unsigned char>& vchSig, uint32_t test_case = 0) const;
134
135     /**
136      * Create a compact signature (65 bytes), which allows reconstructing the used public key.
137      * The format is one header byte, followed by two times 32 bytes for the serialized r and s values.
138      * The header byte: 0x1B = first key with even y, 0x1C = first key with odd y,
139      *                  0x1D = second key with even y, 0x1E = second key with odd y,
140      *                  add 0x04 for compressed keys.
141      */
142     bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
143
144     //! Derive BIP32 child key.
145     bool Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const;
146
147     /**
148      * Verify thoroughly whether a private key and a public key match.
149      * This is done using a different mechanism than just regenerating it.
150      */
151     bool VerifyPubKey(const CPubKey& vchPubKey) const;
152
153     //! Load private key and check that public key matches.
154     bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck);
155
156     //! Check whether an element of a signature (r or s) is valid.
157     static bool CheckSignatureElement(const unsigned char* vch, int len, bool half);
158 };
159
160 struct CExtKey {
161     unsigned char nDepth;
162     unsigned char vchFingerprint[4];
163     unsigned int nChild;
164     ChainCode chaincode;
165     CKey key;
166
167     friend bool operator==(const CExtKey& a, const CExtKey& b)
168     {
169         return a.nDepth == b.nDepth && memcmp(&a.vchFingerprint[0], &b.vchFingerprint[0], 4) == 0 && a.nChild == b.nChild &&
170                a.chaincode == b.chaincode && a.key == b.key;
171     }
172
173     void Encode(unsigned char code[74]) const;
174     void Decode(const unsigned char code[74]);
175     bool Derive(CExtKey& out, unsigned int nChild) const;
176     CExtPubKey Neuter() const;
177     void SetMaster(const unsigned char* seed, unsigned int nSeedLen);
178 };
179
180 /** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */
181 void ECC_Start(void);
182
183 /** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */
184 void ECC_Stop(void);
185
186 /** Check that required EC support is available at runtime. */
187 bool ECC_InitSanityCheck(void);
188
189 #endif // BITCOIN_KEY_H
This page took 0.03503 seconds and 4 git commands to generate.