Skip to content

Commit

Permalink
Converted all key formats to Hex, added dumppubkey RPC call
Browse files Browse the repository at this point in the history
  • Loading branch information
lukem512 committed Aug 22, 2014
1 parent 029528d commit ead5e92
Show file tree
Hide file tree
Showing 10 changed files with 69 additions and 97 deletions.
11 changes: 5 additions & 6 deletions README.md
Expand Up @@ -6,9 +6,8 @@ An alternative cryptocurrency disrupting the already rather disrupting crypto ma
Technical Information

+ ~100,000,000 coins
+ 48 coins rewarded per block, halving every ~12 months
+ minimum reward of 1 coin per block
+ 30 second block times
+ 16 coins rewarded per block, halving every 4 years
+ 60 second block times
+ difficulty retargeting using a time-warp resistant implementation of KGW

Notable differences from Bitcoin
Expand All @@ -17,11 +16,11 @@ Notable differences from Bitcoin
+ replacement of ECDSA with Schnorr signing
+ use of secp256r1 curve over secp256k1
+ requirement for public key when verifying transactions
+ modification to RPC interface s.t. public keys are Base64 encoded

Modifications to the RPC API
+ verifymessage <maxcoinaddress> <publickey> <signature> <message>
+ makekeypair [prefix]
+ verifymessage <publickey> <signature> <message>
+ makekeypair [hex-encoded prefix]
+ dumppubkey <maxcoinaddress>

Additional technical details can be found in the [Wiki](https://github.com/Max-Coin/maxcoin/wiki/_pages).

Expand Down
1 change: 1 addition & 0 deletions src/bitcoinrpc.cpp
Expand Up @@ -251,6 +251,7 @@ static const CRPCCommand vRPCCommands[] =
{ "submitblock", &submitblock, false, false },
{ "listsinceblock", &listsinceblock, false, false },
{ "dumpprivkey", &dumpprivkey, true, false },
{ "dumppubkey", &dumppubkey, true, false },
{ "importprivkey", &importprivkey, false, false },
{ "listunspent", &listunspent, false, false },
{ "getrawtransaction", &getrawtransaction, false, false },
Expand Down
1 change: 1 addition & 0 deletions src/bitcoinrpc.h
Expand Up @@ -138,6 +138,7 @@ extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHe
extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
extern json_spirit::Value dumppubkey(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);

extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
Expand Down
12 changes: 9 additions & 3 deletions src/keystore.cpp
Expand Up @@ -124,17 +124,23 @@ bool CCryptoKeyStore::AddKey(const CKey& key)
if (!IsCrypted())
return CBasicKeyStore::AddKey(key);

if (IsLocked())
if (IsLocked()) {
printf("CCryptoKeyStore::AddKey() : wallet is locked\n");
return false;
}

std::vector<unsigned char> vchCryptedSecret;
CPubKey vchPubKey = key.GetPubKey();
bool fCompressed;
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret))
if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), vchPubKey.GetHash(), vchCryptedSecret)) {
printf("CCryptoKeyStore::AddKey() : EncryptSecret() failed\n");
return false;
}

if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) {
printf("CCryptoKeyStore::AddKey() : AddCryptedKey() failed\n");
return false;
}
}
return true;
}
Expand Down
60 changes: 7 additions & 53 deletions src/qt/signverifymessagedialog.cpp
Expand Up @@ -158,15 +158,16 @@ void SignVerifyMessageDialog::on_signMessageButton_SM_clicked()
ui->statusLabel_SM->setStyleSheet("QLabel { color: green; }");
ui->statusLabel_SM->setText(QString("<nobr>") + tr("Message signed.") + QString("</nobr>"));

ui->pubkeyOut_VM->setText(QString::fromStdString(EncodeBase64(&vchPubKey[0], vchPubKey.size())));
ui->signatureOut_SM->setText(QString::fromStdString(EncodeBase64(&vchSig[0], vchSig.size())));
ui->pubkeyOut_VM->setText(QString::fromStdString(HexStr(vchPubKey.begin(), vchPubKey.end())));
ui->signatureOut_SM->setText(QString::fromStdString(HexStr(vchSig.begin(), vchSig.end())));
}

void SignVerifyMessageDialog::on_copySignatureButton_SM_clicked()
{
QApplication::clipboard()->setText(ui->signatureOut_SM->text());
}


void SignVerifyMessageDialog::on_clearButton_SM_clicked()
{
ui->addressIn_SM->clear();
Expand All @@ -192,51 +193,15 @@ void SignVerifyMessageDialog::on_addressBookButton_VM_clicked()

void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
{
CBitcoinAddress addr(ui->addressIn_VM->text().toStdString());
if (!addr.IsValid())
{
ui->addressIn_VM->setValid(false);
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_VM->setText(tr("The entered address is invalid.") + QString(" ") + tr("Please check the address and try again."));
return;
}
CKeyID keyID;
if (!addr.GetKeyID(keyID))
{
ui->addressIn_VM->setValid(false);
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_VM->setText(tr("The entered address does not refer to a key.") + QString(" ") + tr("Please check the address and try again."));
return;
}

bool fInvalid = false;
std::vector<unsigned char> vchSig = DecodeBase64(ui->signatureIn_VM->text().toStdString().c_str(), &fInvalid);

if (fInvalid)
{
ui->signatureIn_VM->setValid(false);
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_VM->setText(tr("The signature could not be decoded.") + QString(" ") + tr("Please check the signature and try again."));
return;
}

std::vector<unsigned char> vchSig = ParseHex(ui->signatureIn_VM->text().toStdString());
CDataStream ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << ui->messageIn_VM->document()->toPlainText().toStdString();

// get the public key from UI
fInvalid = false;
std::vector<unsigned char> vchPubKey = DecodeBase64(ui->pubkeyIn_VM->text().toStdString().c_str(), &fInvalid);

if (fInvalid)
{
ui->pubkeyIn_VM->setValid(false);
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_VM->setText(tr("The public key could not be decoded.") + QString(" ") + tr("Please check it and try again."));
return;
}
// get the public key from Ui
std::vector<unsigned char> vchPubKey = ParseHex(ui->pubkeyIn_VM->text().toStdString());

CPubKey pubkey(vchPubKey);
CPubKey pubkey(vchPubKey); // TODO - this doesn't work.
if (!pubkey.IsValid())
{
ui->pubkeyIn_VM->setValid(false);
Expand All @@ -262,17 +227,6 @@ void SignVerifyMessageDialog::on_verifyMessageButton_VM_clicked()
return;
}

// TODO
// add the public key
//key.SetPubKey();

if (!(CBitcoinAddress(key.GetPubKey().GetID()) == addr))
{
ui->statusLabel_VM->setStyleSheet("QLabel { color: red; }");
ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verification failed.") + QString("</nobr>"));
return;
}

ui->statusLabel_VM->setStyleSheet("QLabel { color: green; }");
ui->statusLabel_VM->setText(QString("<nobr>") + tr("Message verified.") + QString("</nobr>"));
}
Expand Down
22 changes: 21 additions & 1 deletion src/rpcdump.cpp
Expand Up @@ -37,7 +37,7 @@ Value importprivkey(const Array& params, bool fHelp)
if (fHelp || params.size() < 1 || params.size() > 3)
throw runtime_error(
"importprivkey <maxcoinprivkey> [label] [rescan=true]\n"
"Adds a private key (as returned by dumpprivkey) to your wallet.");
"Adds a private key (as returned by dumpprivkey or makeykeypair) to your wallet.");

string strSecret = params[0].get_str();
string strLabel = "";
Expand Down Expand Up @@ -97,3 +97,23 @@ Value dumpprivkey(const Array& params, bool fHelp)
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
return CBitcoinSecret(vchSecret, fCompressed).ToString();
}

Value dumppubkey(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 1)
throw runtime_error(
"dumpubkey <maxcoinaddress>\n"
"Reveals the public key corresponding to <maxcoinaddress>.");

string strAddress = params[0].get_str();
CBitcoinAddress address;
if (!address.SetString(strAddress))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid MaxCoin address");
CKeyID keyID;
if (!address.GetKeyID(keyID))
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
CPubKey vchPubKey;
if (!pwalletMain->GetPubKey(keyID, vchPubKey))
throw JSONRPCError(RPC_WALLET_ERROR, "Public key for address " + strAddress + " is not known");
return HexStr(vchPubKey.Raw());
}
6 changes: 3 additions & 3 deletions src/rpcnet.cpp
Expand Up @@ -232,16 +232,16 @@ Value makekeypair(const Array& params, bool fHelp)
pubKey = key.GetPubKey();
vchPubKey = pubKey.Raw();
nCount++;
} while (nCount < 10000 && strPrefix != HexStr(vchPubKey.begin(), vchPubKey.end()).substr(0, strPrefix.size()));
} while (nCount < 10000 && strPrefix != HexStr(vchPubKey).substr(0, strPrefix.size()));

if (strPrefix != HexStr(vchPubKey.begin(), vchPubKey.end()).substr(0, strPrefix.size()))
if (strPrefix != HexStr(vchPubKey).substr(0, strPrefix.size()))
return Value::null;

bool isCompressed;
CSecret secretKey = key.GetSecret(isCompressed);

Object result;
result.push_back(Pair("PublicKey", HexStr(vchPubKey.begin(), vchPubKey.end())));
result.push_back(Pair("PublicKey", HexStr(vchPubKey)));
result.push_back(Pair("PrivateKey", CBitcoinSecret(secretKey, isCompressed).ToString()));
return result;
}
Expand Down
2 changes: 1 addition & 1 deletion src/rpcrawtransaction.cpp
Expand Up @@ -58,7 +58,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out)
int nRequired;

out.push_back(Pair("asm", scriptPubKey.ToString()));
out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())));
out.push_back(Pair("hex", HexStr(scriptPubKey)));

if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired))
{
Expand Down
36 changes: 10 additions & 26 deletions src/rpcwallet.cpp
Expand Up @@ -343,38 +343,23 @@ Value signmessage(const Array& params, bool fHelp)
if (!key.Sign(ss.GetHash(), vchSig))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");

return EncodeBase64(&vchSig[0], vchSig.size());
return HexStr(vchSig.begin(), vchSig.end());
}

Value verifymessage(const Array& params, bool fHelp)
{

if (fHelp || params.size() != 4)
if (fHelp || params.size() != 3)
throw runtime_error(
"verifymessage <maxcoinaddress> <publickey> <signature> <message>\n"
"verifymessage <publickey> <signature> <message>\n"
"Verify a signed message");

string strAddress = params[0].get_str();
string strPubKey = params[1].get_str();
string strSign = params[2].get_str();
string strMessage = params[3].get_str();
string strPubKey = params[0].get_str();
string strSign = params[1].get_str();
string strMessage = params[2].get_str();

CBitcoinAddress addr(strAddress);
if (!addr.IsValid())
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");

CKeyID keyID;
if (!addr.GetKeyID(keyID))
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");

bool fInvalid = false;
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
if (fInvalid)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding in signature");

vector<unsigned char> vchPubKey = DecodeBase64(strPubKey.c_str(), &fInvalid);
if (fInvalid)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding in public key");
vector<unsigned char> vchSig = ParseHex(strSign);
vector<unsigned char> vchPubKey = ParseHex(strPubKey);

CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
Expand All @@ -385,7 +370,7 @@ Value verifymessage(const Array& params, bool fHelp)
if (!key.Verify(ss.GetHash(), vchSig))
return false;

return (key.GetPubKey().GetID() == keyID);
return true;
}


Expand Down Expand Up @@ -1452,8 +1437,7 @@ class DescribeAddressVisitor : public boost::static_visitor<Object>
CPubKey vchPubKey;
pwalletMain->GetPubKey(keyID, vchPubKey);
obj.push_back(Pair("isscript", false));
//obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
obj.push_back(Pair("pubkey", EncodeBase64(&vchPubKey.Raw()[0], vchPubKey.Raw().size())));
obj.push_back(Pair("pubkey", HexStr(vchPubKey.Raw())));
obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed()));
return obj;
}
Expand Down
15 changes: 11 additions & 4 deletions src/wallet.cpp
Expand Up @@ -51,13 +51,20 @@ CPubKey CWallet::GenerateNewKey()

bool CWallet::AddKey(const CKey& key)
{
bool fCompressed;
if (!CCryptoKeyStore::AddKey(key))
bool fCompressed, fRet;
if (!CCryptoKeyStore::AddKey(key)) {
printf("CWallet::AddKey() : CCryptoKeyStore::AddKey() failed\n");
return false;
}
if (!fFileBacked)
return true;
if (!IsCrypted())
return CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetSecret(fCompressed));
if (!IsCrypted()) {
fRet = CWalletDB(strWalletFile).WriteKey(key.GetPubKey(), key.GetSecret(fCompressed));
if (!fRet) {
printf("CWallet::AddKey() : could CWalletDB.WriteKey() failed\n");
}
return fRet;
}
return true;
}

Expand Down

0 comments on commit ead5e92

Please sign in to comment.