1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
7 // const unsigned int PRIVATE_KEY_SIZE = 192;
8 // const unsigned int PUBLIC_KEY_SIZE = 41;
9 // const unsigned int SIGNATURE_SIZE = 48;
12 // const unsigned int PRIVATE_KEY_SIZE = 222;
13 // const unsigned int PUBLIC_KEY_SIZE = 49;
14 // const unsigned int SIGNATURE_SIZE = 57;
17 // const unsigned int PRIVATE_KEY_SIZE = 250;
18 // const unsigned int PUBLIC_KEY_SIZE = 57;
19 // const unsigned int SIGNATURE_SIZE = 66;
22 // const unsigned int PRIVATE_KEY_SIZE = 279;
23 // const unsigned int PUBLIC_KEY_SIZE = 65;
24 // const unsigned int SIGNATURE_SIZE = 72;
26 // see www.keylength.com
27 // script supports up to 75 for single byte push
31 class key_error
: public std::runtime_error
34 explicit key_error(const std::string
& str
) : std::runtime_error(str
) {}
38 // secure_allocator is defined in serialize.h
39 typedef vector
<unsigned char, secure_allocator
<unsigned char> > CPrivKey
;
52 pkey
= EC_KEY_new_by_curve_name(NID_secp256k1
);
54 throw key_error("CKey::CKey() : EC_KEY_new_by_curve_name failed");
60 pkey
= EC_KEY_dup(b
.pkey
);
62 throw key_error("CKey::CKey(const CKey&) : EC_KEY_dup failed");
66 CKey
& operator=(const CKey
& b
)
68 if (!EC_KEY_copy(pkey
, b
.pkey
))
69 throw key_error("CKey::operator=(const CKey&) : EC_KEY_copy failed");
86 if (!EC_KEY_generate_key(pkey
))
87 throw key_error("CKey::MakeNewKey() : EC_KEY_generate_key failed");
91 bool SetPrivKey(const CPrivKey
& vchPrivKey
)
93 const unsigned char* pbegin
= &vchPrivKey
[0];
94 if (!d2i_ECPrivateKey(&pkey
, &pbegin
, vchPrivKey
.size()))
100 CPrivKey
GetPrivKey() const
102 unsigned int nSize
= i2d_ECPrivateKey(pkey
, NULL
);
104 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
105 CPrivKey
vchPrivKey(nSize
, 0);
106 unsigned char* pbegin
= &vchPrivKey
[0];
107 if (i2d_ECPrivateKey(pkey
, &pbegin
) != nSize
)
108 throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
112 bool SetPubKey(const vector
<unsigned char>& vchPubKey
)
114 const unsigned char* pbegin
= &vchPubKey
[0];
115 if (!o2i_ECPublicKey(&pkey
, &pbegin
, vchPubKey
.size()))
121 vector
<unsigned char> GetPubKey() const
123 unsigned int nSize
= i2o_ECPublicKey(pkey
, NULL
);
125 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
126 vector
<unsigned char> vchPubKey(nSize
, 0);
127 unsigned char* pbegin
= &vchPubKey
[0];
128 if (i2o_ECPublicKey(pkey
, &pbegin
) != nSize
)
129 throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
133 bool Sign(uint256 hash
, vector
<unsigned char>& vchSig
)
136 unsigned char pchSig
[10000];
137 unsigned int nSize
= 0;
138 if (!ECDSA_sign(0, (unsigned char*)&hash
, sizeof(hash
), pchSig
, &nSize
, pkey
))
140 vchSig
.resize(nSize
);
141 memcpy(&vchSig
[0], pchSig
, nSize
);
145 bool Verify(uint256 hash
, const vector
<unsigned char>& vchSig
)
147 // -1 = error, 0 = bad sig, 1 = good
148 if (ECDSA_verify(0, (unsigned char*)&hash
, sizeof(hash
), &vchSig
[0], vchSig
.size(), pkey
) != 1)
153 static bool Sign(const CPrivKey
& vchPrivKey
, uint256 hash
, vector
<unsigned char>& vchSig
)
156 if (!key
.SetPrivKey(vchPrivKey
))
158 return key
.Sign(hash
, vchSig
);
161 static bool Verify(const vector
<unsigned char>& vchPubKey
, uint256 hash
, const vector
<unsigned char>& vchSig
)
164 if (!key
.SetPubKey(vchPubKey
))
166 return key
.Verify(hash
, vchSig
);