]>
Commit | Line | Data |
---|---|---|
4405b78d | 1 | // Copyright (c) 2009 Satoshi Nakamoto\r |
2 | // Distributed under the MIT/X11 software license, see the accompanying\r | |
3 | // file license.txt or http://www.opensource.org/licenses/mit-license.php.\r | |
4 | \r | |
5 | \r | |
6 | // secp160k1\r | |
7 | // const unsigned int PRIVATE_KEY_SIZE = 192;\r | |
8 | // const unsigned int PUBLIC_KEY_SIZE = 41;\r | |
9 | // const unsigned int SIGNATURE_SIZE = 48;\r | |
10 | //\r | |
11 | // secp192k1\r | |
12 | // const unsigned int PRIVATE_KEY_SIZE = 222;\r | |
13 | // const unsigned int PUBLIC_KEY_SIZE = 49;\r | |
14 | // const unsigned int SIGNATURE_SIZE = 57;\r | |
15 | //\r | |
16 | // secp224k1\r | |
17 | // const unsigned int PRIVATE_KEY_SIZE = 250;\r | |
18 | // const unsigned int PUBLIC_KEY_SIZE = 57;\r | |
19 | // const unsigned int SIGNATURE_SIZE = 66;\r | |
20 | //\r | |
21 | // secp256k1:\r | |
22 | // const unsigned int PRIVATE_KEY_SIZE = 279;\r | |
23 | // const unsigned int PUBLIC_KEY_SIZE = 65;\r | |
24 | // const unsigned int SIGNATURE_SIZE = 72;\r | |
25 | //\r | |
26 | // see www.keylength.com\r | |
27 | // script supports up to 75 for single byte push\r | |
28 | \r | |
29 | \r | |
30 | \r | |
31 | class key_error : public std::runtime_error\r | |
32 | {\r | |
33 | public:\r | |
34 | explicit key_error(const std::string& str) : std::runtime_error(str) {}\r | |
35 | };\r | |
36 | \r | |
37 | \r | |
cc0b4c3b | 38 | // secure_allocator is defined in serialize.h\r |
4405b78d | 39 | typedef vector<unsigned char, secure_allocator<unsigned char> > CPrivKey;\r |
40 | \r | |
41 | \r | |
42 | \r | |
43 | class CKey\r | |
44 | {\r | |
45 | protected:\r | |
46 | EC_KEY* pkey;\r | |
52109986 | 47 | bool fSet;\r |
4405b78d | 48 | \r |
49 | public:\r | |
50 | CKey()\r | |
51 | {\r | |
52 | pkey = EC_KEY_new_by_curve_name(NID_secp256k1);\r | |
53 | if (pkey == NULL)\r | |
54 | throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");\r | |
52109986 | 55 | fSet = false;\r |
4405b78d | 56 | }\r |
57 | \r | |
58 | CKey(const CKey& b)\r | |
59 | {\r | |
60 | pkey = EC_KEY_dup(b.pkey);\r | |
61 | if (pkey == NULL)\r | |
62 | throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");\r | |
52109986 | 63 | fSet = b.fSet;\r |
4405b78d | 64 | }\r |
65 | \r | |
66 | CKey& operator=(const CKey& b)\r | |
67 | {\r | |
68 | if (!EC_KEY_copy(pkey, b.pkey))\r | |
69 | throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");\r | |
52109986 | 70 | fSet = b.fSet;\r |
4405b78d | 71 | return (*this);\r |
72 | }\r | |
73 | \r | |
74 | ~CKey()\r | |
75 | {\r | |
76 | EC_KEY_free(pkey);\r | |
77 | }\r | |
78 | \r | |
52109986 | 79 | bool IsNull() const\r |
80 | {\r | |
81 | return !fSet;\r | |
82 | }\r | |
83 | \r | |
4405b78d | 84 | void MakeNewKey()\r |
85 | {\r | |
86 | if (!EC_KEY_generate_key(pkey))\r | |
87 | throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");\r | |
52109986 | 88 | fSet = true;\r |
4405b78d | 89 | }\r |
90 | \r | |
91 | bool SetPrivKey(const CPrivKey& vchPrivKey)\r | |
92 | {\r | |
93 | const unsigned char* pbegin = &vchPrivKey[0];\r | |
94 | if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size()))\r | |
95 | return false;\r | |
52109986 | 96 | fSet = true;\r |
4405b78d | 97 | return true;\r |
98 | }\r | |
99 | \r | |
100 | CPrivKey GetPrivKey() const\r | |
101 | {\r | |
102 | unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);\r | |
103 | if (!nSize)\r | |
104 | throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");\r | |
105 | CPrivKey vchPrivKey(nSize, 0);\r | |
106 | unsigned char* pbegin = &vchPrivKey[0];\r | |
107 | if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)\r | |
108 | throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");\r | |
109 | return vchPrivKey;\r | |
110 | }\r | |
111 | \r | |
112 | bool SetPubKey(const vector<unsigned char>& vchPubKey)\r | |
113 | {\r | |
114 | const unsigned char* pbegin = &vchPubKey[0];\r | |
115 | if (!o2i_ECPublicKey(&pkey, &pbegin, vchPubKey.size()))\r | |
116 | return false;\r | |
52109986 | 117 | fSet = true;\r |
4405b78d | 118 | return true;\r |
119 | }\r | |
120 | \r | |
121 | vector<unsigned char> GetPubKey() const\r | |
122 | {\r | |
123 | unsigned int nSize = i2o_ECPublicKey(pkey, NULL);\r | |
124 | if (!nSize)\r | |
125 | throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");\r | |
126 | vector<unsigned char> vchPubKey(nSize, 0);\r | |
127 | unsigned char* pbegin = &vchPubKey[0];\r | |
128 | if (i2o_ECPublicKey(pkey, &pbegin) != nSize)\r | |
129 | throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");\r | |
130 | return vchPubKey;\r | |
131 | }\r | |
132 | \r | |
133 | bool Sign(uint256 hash, vector<unsigned char>& vchSig)\r | |
134 | {\r | |
135 | vchSig.clear();\r | |
136 | unsigned char pchSig[10000];\r | |
137 | unsigned int nSize = 0;\r | |
138 | if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))\r | |
139 | return false;\r | |
140 | vchSig.resize(nSize);\r | |
141 | memcpy(&vchSig[0], pchSig, nSize);\r | |
142 | return true;\r | |
143 | }\r | |
144 | \r | |
145 | bool Verify(uint256 hash, const vector<unsigned char>& vchSig)\r | |
146 | {\r | |
147 | // -1 = error, 0 = bad sig, 1 = good\r | |
148 | if (ECDSA_verify(0, (unsigned char*)&hash, sizeof(hash), &vchSig[0], vchSig.size(), pkey) != 1)\r | |
149 | return false;\r | |
150 | return true;\r | |
151 | }\r | |
152 | \r | |
153 | static bool Sign(const CPrivKey& vchPrivKey, uint256 hash, vector<unsigned char>& vchSig)\r | |
154 | {\r | |
155 | CKey key;\r | |
156 | if (!key.SetPrivKey(vchPrivKey))\r | |
157 | return false;\r | |
158 | return key.Sign(hash, vchSig);\r | |
159 | }\r | |
160 | \r | |
161 | static bool Verify(const vector<unsigned char>& vchPubKey, uint256 hash, const vector<unsigned char>& vchSig)\r | |
162 | {\r | |
163 | CKey key;\r | |
164 | if (!key.SetPubKey(vchPubKey))\r | |
165 | return false;\r | |
166 | return key.Verify(hash, vchSig);\r | |
167 | }\r | |
168 | };\r |