{ "newmalleablekey", &newmalleablekey, false, false},
{ "adjustmalleablekey", &adjustmalleablekey, false, false},
{ "adjustmalleablepubkey", &adjustmalleablepubkey, false, false},
+ { "listmalleablepubkeys", &listmalleablepubkeys, false, false},
{ "sendalert", &sendalert, false, false},
};
extern json_spirit::Value newmalleablekey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value adjustmalleablekey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value adjustmalleablepubkey(const json_spirit::Array& params, bool fHelp);
+extern json_spirit::Value listmalleablepubkeys(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
return true;
}
+// Initialize from octets stream
+bool CPoint::setPubKey(const CPubKey &vchPubKey)
+{
+ return setBytes(vchPubKey.Raw());
+}
+
// Serialize to octets stream
bool CPoint::getBytes(std::vector<unsigned char> &vchBytes)
{
EC_KEY_free(eckey);
CPoint point;
- if (!point.setBytes(pubKeyL.Raw())) {
+ if (!point.setPubKey(pubKeyL)) {
throw key_error("CMalleablePubKey::GetVariant() : Unable to decode L value");
}
bnHash.setuint160(Hash160(vchLr));
CPoint pointH;
- pointH.setBytes(pubKeyH.Raw());
+ pointH.setPubKey(pubKeyH);
CPoint P;
// Calculate P = Hash(L*r)*G + H
vchPubKeyVariant = CPubKey(vchResult);
}
-std::string CMalleablePubKey::ToString()
+std::string CMalleablePubKey::ToString() const
{
CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
ssKey << *this;
Reset();
CKey L, H;
- if (!L.SetSecret(pvchSecretL, true) || !H.SetSecret(pvchSecretH, true))
+ if (pvchSecretL.size() != 32 || !pvchSecretH.size() != 32 || !L.SetSecret(pvchSecretL, true) || !H.SetSecret(pvchSecretH, true))
{
nVersion = 0;
return false;
}
// Check ownership
-bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant)
+bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const
{
if (IsNull()) {
throw key_error("CMalleableKey::CheckKeyVariant() : Attempting to run on NULL key object.");
}
CPoint point_R;
- if (!point_R.setBytes(R.Raw())) {
+ if (!point_R.setPubKey(R)) {
throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode R value");
}
std::vector<unsigned char> vchPubKeyH = H.GetPubKey().Raw();
CPoint point_H;
- if (!point_H.setBytes(vchPubKeyH)) {
+ if (!point_H.setPubKey(vchPubKeyH)) {
throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode H value");
}
CPoint point_P;
- if (!point_P.setBytes(vchPubKeyVariant.Raw())) {
+ if (!point_P.setPubKey(vchPubKeyVariant)) {
throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode P value");
}
}
// Check ownership and restore private key
-bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant)
+bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const
{
if (IsNull()) {
throw key_error("CMalleableKey::CheckKeyVariant() : Attempting to run on NULL key object.");
}
CPoint point_R;
- if (!point_R.setBytes(R.Raw())) {
+ if (!point_R.setPubKey(R)) {
throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode R value");
}
std::vector<unsigned char> vchPubKeyH = H.GetPubKey().Raw();
CPoint point_H;
- if (!point_H.setBytes(vchPubKeyH)) {
+ if (!point_H.setPubKey(vchPubKeyH)) {
throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode H value");
}
CPoint point_P;
- if (!point_P.setBytes(vchPubKeyVariant.Raw())) {
+ if (!point_P.setPubKey(vchPubKeyVariant)) {
throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode P value");
}
return true;
}
-std::string CMalleableKey::ToString()
+std::string CMalleableKey::ToString() const
{
CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
ssKey << *this;
CMalleableKeyView::CMalleableKeyView(const CMalleableKey &b)
{
+ if (b.vchSecretL.size() != 32)
+ throw key_error("CMalleableKeyView::CMalleableKeyView() : L size must be 32 bytes");
+
+ if (b.vchSecretH.size() != 32)
+ throw key_error("CMalleableKeyView::CMalleableKeyView() : L size must be 32 bytes");
+
vchSecretL = b.vchSecretL;
CKey H;
H.SetSecret(b.vchSecretH, true);
+
vchPubKeyH = H.GetPubKey().Raw();
nVersion = b.nVersion;
}
}
// Check ownership
-bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant)
+bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const
{
if (!R.IsValid()) {
throw key_error("CMalleableKeyView::CheckKeyVariant() : R is invalid");
}
CPoint point_R;
- if (!point_R.setBytes(R.Raw())) {
+ if (!point_R.setPubKey(R)) {
throw key_error("CMalleableKeyView::CheckKeyVariant() : Unable to decode R value");
}
CPoint point_H;
- if (!point_H.setBytes(vchPubKeyH)) {
+ if (!point_H.setPubKey(vchPubKeyH)) {
throw key_error("CMalleableKeyView::CheckKeyVariant() : Unable to decode H value");
}
CPoint point_P;
- if (!point_P.setBytes(vchPubKeyVariant.Raw())) {
+ if (!point_P.setPubKey(vchPubKeyVariant)) {
throw key_error("CMalleableKeyView::CheckKeyVariant() : Unable to decode P value");
}
return true;
}
-std::string CMalleableKeyView::ToString()
+std::string CMalleableKeyView::ToString() const
{
CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION);
ssKey << *this;
// Initialize from octets stream
bool setBytes(const std::vector<unsigned char> &vchBytes);
+ // Initialize from pubkey
+ bool setPubKey(const CPubKey &vchPubKey);
+
// Serialize to octets stream
bool getBytes(std::vector<unsigned char> &vchBytes);
bool operator==(const CMalleablePubKey &b);
bool operator!=(const CMalleablePubKey &b) { return !(*this == b); }
- std::string ToString();
+ std::string ToString() const;
bool SetString(const std::string& strMalleablePubKey);
uint256 GetID() const;
READWRITE(vchSecretH);
)
- std::string ToString();
+ std::string ToString() const;
bool SetString(const std::string& strMalleablePubKey);
void Reset();
void GetSecrets(CSecret &pvchSecretL, CSecret &pvchSecretH) const;
CMalleablePubKey GetMalleablePubKey() const;
- bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant);
- bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant);
+ bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
+ bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const;
};
class CMalleableKeyView
private:
unsigned char nVersion;
CSecret vchSecretL;
- std::vector<unsigned char> vchPubKeyH;
+ CPubKey vchPubKeyH;
static const unsigned char CURRENT_VERSION = 1;
)
bool IsNull() const;
- std::string ToString();
+ std::string ToString() const;
bool SetString(const std::string& strMalleablePubKey);
CMalleablePubKey GetMalleablePubKey() const;
- bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant);
+ bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const;
+
+ bool operator <(const CMalleableKeyView& kv) const { return vchPubKeyH.GetID() < kv.vchPubKeyH.GetID(); }
};
#endif
else
malleableKey.MakeNewKeys();
- CMalleableKeyView keyView(malleableKey);
-
- malleableKeyPair = std::pair<CMalleableKeyView, CMalleableKey>(keyView, malleableKey);
+ const CMalleableKeyView& keyView(malleableKey);
+ mapMalleableKeys[keyView] = malleableKey;
}
bool CCryptoKeyStore::SetCrypted()
virtual bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const =0;
virtual bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const =0;
+ virtual void ListMalleablePubKeys(std::list<CMalleablePubKey> &malleablePubKeyList) const =0;
};
typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;
-typedef std::pair<CMalleableKeyView, CMalleableKey> MalleableKeyPair;
+typedef std::map<CMalleableKeyView, CMalleableKey> MalleableKeyMap;
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
{
protected:
KeyMap mapKeys;
+ MalleableKeyMap mapMalleableKeys;
+
ScriptMap mapScripts;
WatchOnlySet setWatchOnly;
- MalleableKeyPair malleableKeyPair;
public:
bool AddKey(const CKey& key);
bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const
{
- bool result;
{
LOCK(cs_KeyStore);
- result = const_cast<CBasicKeyStore*>(this)->malleableKeyPair.first.CheckKeyVariant(R, pubKeyVariant);
+ for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
+ {
+ if (mi->first.CheckKeyVariant(R, pubKeyVariant))
+ return true;
+ }
}
- return result;
+ return false;
}
bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const
{
- bool result;
{
LOCK(cs_KeyStore);
- result = const_cast<CBasicKeyStore*>(this)->malleableKeyPair.second.CheckKeyVariant(R, pubKeyVariant, privKey);
+ for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
+ {
+ if (mi->second.CheckKeyVariant(R, pubKeyVariant, privKey))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void ListMalleablePubKeys(std::list<CMalleablePubKey> &malleablePubKeyList) const
+ {
+ malleablePubKeyList.clear();
+
+ {
+ LOCK(cs_KeyStore);
+ for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
+ malleablePubKeyList.push_back(mi->first.GetMalleablePubKey());
}
- return result;
}
};
return result;
}
+
+Value listmalleablepubkeys(const Array& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "listmalleablepubkeys\n"
+ "Get list of malleable public keys.\n");
+
+ std::list<CMalleablePubKey> keyList;
+ pwalletMain->ListMalleablePubKeys(keyList);
+
+ Array result;
+ BOOST_FOREACH(const CMalleablePubKey &key, keyList)
+ {
+ result.push_back(key.ToString());
+ }
+
+ return result;
+}