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