src/qt/editaddressdialog.cpp \
src/qt/bitcoinaddressvalidator.cpp \
src/util.cpp \
+ src/key.cpp \
src/script.cpp \
src/main.cpp \
src/init.cpp \
if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig))
return false;
- return (key.GetAddress() == addr);
+ return (CBitcoinAddress(key.GetPubKey()) == addr);
}
--- /dev/null
+// Copyright (c) 2011 The Bitcoin developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+
+#include <openssl/ec.h>
+#include <openssl/ecdsa.h>
+
+// Generate a private key from just the secret parameter
+int EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
+{
+ int ok = 0;
+ BN_CTX *ctx = NULL;
+ EC_POINT *pub_key = NULL;
+
+ if (!eckey) return 0;
+
+ const EC_GROUP *group = EC_KEY_get0_group(eckey);
+
+ if ((ctx = BN_CTX_new()) == NULL)
+ goto err;
+
+ pub_key = EC_POINT_new(group);
+
+ if (pub_key == NULL)
+ goto err;
+
+ if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
+ goto err;
+
+ EC_KEY_set_private_key(eckey,priv_key);
+ EC_KEY_set_public_key(eckey,pub_key);
+
+ ok = 1;
+
+err:
+
+ if (pub_key)
+ EC_POINT_free(pub_key);
+ if (ctx != NULL)
+ BN_CTX_free(ctx);
+
+ return(ok);
+}
+
+// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
+// recid selects which key is recovered
+// if check is nonzero, additional checks are performed
+int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
+{
+ if (!eckey) return 0;
+
+ int ret = 0;
+ BN_CTX *ctx = NULL;
+
+ BIGNUM *x = NULL;
+ BIGNUM *e = NULL;
+ BIGNUM *order = NULL;
+ BIGNUM *sor = NULL;
+ BIGNUM *eor = NULL;
+ BIGNUM *field = NULL;
+ EC_POINT *R = NULL;
+ EC_POINT *O = NULL;
+ EC_POINT *Q = NULL;
+ BIGNUM *rr = NULL;
+ BIGNUM *zero = NULL;
+ int n = 0;
+ int i = recid / 2;
+
+ const EC_GROUP *group = EC_KEY_get0_group(eckey);
+ if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
+ BN_CTX_start(ctx);
+ order = BN_CTX_get(ctx);
+ if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
+ x = BN_CTX_get(ctx);
+ if (!BN_copy(x, order)) { ret=-1; goto err; }
+ if (!BN_mul_word(x, i)) { ret=-1; goto err; }
+ if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
+ field = BN_CTX_get(ctx);
+ if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
+ if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
+ if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
+ if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
+ if (check)
+ {
+ if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
+ if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
+ if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
+ }
+ if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
+ n = EC_GROUP_get_degree(group);
+ e = BN_CTX_get(ctx);
+ if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
+ if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
+ zero = BN_CTX_get(ctx);
+ if (!BN_zero(zero)) { ret=-1; goto err; }
+ if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
+ rr = BN_CTX_get(ctx);
+ if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
+ sor = BN_CTX_get(ctx);
+ if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
+ eor = BN_CTX_get(ctx);
+ if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
+ if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
+ if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
+
+ ret = 1;
+
+err:
+ if (ctx) {
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ }
+ if (R != NULL) EC_POINT_free(R);
+ if (O != NULL) EC_POINT_free(O);
+ if (Q != NULL) EC_POINT_free(Q);
+ return ret;
+}
#include "serialize.h"
#include "uint256.h"
-#include "base58.h"
// secp160k1
// const unsigned int PRIVATE_KEY_SIZE = 192;
// see www.keylength.com
// script supports up to 75 for single byte push
-// Generate a private key from just the secret parameter
-int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key)
-{
- int ok = 0;
- BN_CTX *ctx = NULL;
- EC_POINT *pub_key = NULL;
-
- if (!eckey) return 0;
-
- const EC_GROUP *group = EC_KEY_get0_group(eckey);
-
- if ((ctx = BN_CTX_new()) == NULL)
- goto err;
-
- pub_key = EC_POINT_new(group);
-
- if (pub_key == NULL)
- goto err;
-
- if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
- goto err;
-
- EC_KEY_set_private_key(eckey,priv_key);
- EC_KEY_set_public_key(eckey,pub_key);
-
- ok = 1;
-
-err:
-
- if (pub_key)
- EC_POINT_free(pub_key);
- if (ctx != NULL)
- BN_CTX_free(ctx);
-
- return(ok);
-}
-
-// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields
-// recid selects which key is recovered
-// if check is nonzero, additional checks are performed
-int static inline ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
-{
- if (!eckey) return 0;
-
- int ret = 0;
- BN_CTX *ctx = NULL;
-
- BIGNUM *x = NULL;
- BIGNUM *e = NULL;
- BIGNUM *order = NULL;
- BIGNUM *sor = NULL;
- BIGNUM *eor = NULL;
- BIGNUM *field = NULL;
- EC_POINT *R = NULL;
- EC_POINT *O = NULL;
- EC_POINT *Q = NULL;
- BIGNUM *rr = NULL;
- BIGNUM *zero = NULL;
- int n = 0;
- int i = recid / 2;
-
- const EC_GROUP *group = EC_KEY_get0_group(eckey);
- if ((ctx = BN_CTX_new()) == NULL) { ret = -1; goto err; }
- BN_CTX_start(ctx);
- order = BN_CTX_get(ctx);
- if (!EC_GROUP_get_order(group, order, ctx)) { ret = -2; goto err; }
- x = BN_CTX_get(ctx);
- if (!BN_copy(x, order)) { ret=-1; goto err; }
- if (!BN_mul_word(x, i)) { ret=-1; goto err; }
- if (!BN_add(x, x, ecsig->r)) { ret=-1; goto err; }
- field = BN_CTX_get(ctx);
- if (!EC_GROUP_get_curve_GFp(group, field, NULL, NULL, ctx)) { ret=-2; goto err; }
- if (BN_cmp(x, field) >= 0) { ret=0; goto err; }
- if ((R = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
- if (!EC_POINT_set_compressed_coordinates_GFp(group, R, x, recid % 2, ctx)) { ret=0; goto err; }
- if (check)
- {
- if ((O = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
- if (!EC_POINT_mul(group, O, NULL, R, order, ctx)) { ret=-2; goto err; }
- if (!EC_POINT_is_at_infinity(group, O)) { ret = 0; goto err; }
- }
- if ((Q = EC_POINT_new(group)) == NULL) { ret = -2; goto err; }
- n = EC_GROUP_get_degree(group);
- e = BN_CTX_get(ctx);
- if (!BN_bin2bn(msg, msglen, e)) { ret=-1; goto err; }
- if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
- zero = BN_CTX_get(ctx);
- if (!BN_zero(zero)) { ret=-1; goto err; }
- if (!BN_mod_sub(e, zero, e, order, ctx)) { ret=-1; goto err; }
- rr = BN_CTX_get(ctx);
- if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) { ret=-1; goto err; }
- sor = BN_CTX_get(ctx);
- if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) { ret=-1; goto err; }
- eor = BN_CTX_get(ctx);
- if (!BN_mod_mul(eor, e, rr, order, ctx)) { ret=-1; goto err; }
- if (!EC_POINT_mul(group, Q, eor, R, sor, ctx)) { ret=-2; goto err; }
- if (!EC_KEY_set_public_key(eckey, Q)) { ret=-2; goto err; }
-
- ret = 1;
-
-err:
- if (ctx) {
- BN_CTX_end(ctx);
- BN_CTX_free(ctx);
- }
- if (R != NULL) EC_POINT_free(R);
- if (O != NULL) EC_POINT_free(O);
- if (Q != NULL) EC_POINT_free(Q);
- return ret;
-}
+int extern EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key);
+int extern ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check);
class key_error : public std::runtime_error
{
return false;
return true;
}
-
- // Get the address corresponding to this key
- CBitcoinAddress GetAddress() const
- {
- return CBitcoinAddress(GetPubKey());
- }
};
#endif
bool CBasicKeyStore::AddKey(const CKey& key)
{
CRITICAL_BLOCK(cs_KeyStore)
- mapKeys[key.GetAddress()] = key.GetSecret();
+ mapKeys[CBitcoinAddress(key.GetPubKey())] = key.GetSecret();
return true;
}
return true;
}
-bool CCryptoKeyStore::GetKey(const CBitcoinAddress &address, CKey& keyOut) const
+bool CCryptoKeyStore::GetSecret(const CBitcoinAddress &address, CSecret& vchSecretOut) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
if (!IsCrypted())
- return CBasicKeyStore::GetKey(address, keyOut);
+ return CBasicKeyStore::GetSecret(address, vchSecretOut);
CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
if (mi != mapCryptedKeys.end())
{
const std::vector<unsigned char> &vchPubKey = (*mi).second.first;
const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
- CSecret vchSecret;
- if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
- return false;
- keyOut.SetSecret(vchSecret);
- return true;
+ return DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecretOut);
}
}
return false;
// Check whether a key corresponding to a given address is present in the store.
virtual bool HaveKey(const CBitcoinAddress &address) const =0;
-
- // Retrieve a key corresponding to a given address from the store.
- // Return true if succesful.
- virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const =0;
-
- // Retrieve only the public key corresponding to a given address.
- // This may succeed even if GetKey fails (e.g., encrypted wallets)
+ virtual bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
+ {
+ CSecret vchSecret;
+ if (!GetSecret(address, vchSecret))
+ return false;
+ if (!keyOut.SetSecret(vchSecret))
+ return false;
+ return true;
+ }
+ virtual void GetKeys(std::set<CBitcoinAddress> &setAddress) const =0;
virtual bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
// Generate a new key, and add it to the store
virtual std::vector<unsigned char> GenerateNewKey();
+ virtual bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const
+ {
+ CKey key;
+ if (!GetKey(address, key))
+ return false;
+ vchSecret = key.GetSecret();
+ return true;
+ }
};
typedef std::map<CBitcoinAddress, CSecret> KeyMap;
result = (mapKeys.count(address) > 0);
return result;
}
- bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const
+ void GetKeys(std::set<CBitcoinAddress> &setAddress) const
+ {
+ setAddress.clear();
+ CRITICAL_BLOCK(cs_KeyStore)
+ {
+ KeyMap::const_iterator mi = mapKeys.begin();
+ while (mi != mapKeys.end())
+ {
+ setAddress.insert((*mi).first);
+ mi++;
+ }
+ }
+ }
+ bool GetSecret(const CBitcoinAddress &address, CSecret &vchSecret) const
{
CRITICAL_BLOCK(cs_KeyStore)
{
KeyMap::const_iterator mi = mapKeys.find(address);
if (mi != mapKeys.end())
{
- keyOut.SetSecret((*mi).second);
+ vchSecret = (*mi).second;
return true;
}
}
}
return false;
}
- bool GetKey(const CBitcoinAddress &address, CKey& keyOut) const;
+ bool GetSecret(const CBitcoinAddress &address, CSecret& vchSecret) const;
bool GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char>& vchPubKeyOut) const;
+ void GetKeys(std::set<CBitcoinAddress> &setAddress) const
+ {
+ if (!IsCrypted())
+ {
+ CBasicKeyStore::GetKeys(setAddress);
+ return;
+ }
+ setAddress.clear();
+ CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
+ while (mi != mapCryptedKeys.end())
+ {
+ setAddress.insert((*mi).first);
+ mi++;
+ }
+ }
};
#endif
OBJS= \
obj/checkpoints.o \
obj/crypter.o \
+ obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
OBJS= \
obj/checkpoints.o \
obj/crypter.o \
+ obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \
OBJS= \
obj/checkpoints.o \
obj/crypter.o \
+ obj/key.o \
obj/db.o \
obj/init.o \
obj/irc.o \