mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-11 15:48:05 +00:00
Incorporate pubkey in signature, check based on address
Include the public key in the signature string, to allow verification based on address.
This commit is contained in:
parent
cc2567e32f
commit
b53d6284eb
@ -526,6 +526,8 @@ Value sendtoaddress(const Array& params, bool fHelp)
|
|||||||
return wtx.GetHash().GetHex();
|
return wtx.GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const string strMessageMagic = "Bitcoin Signed Message:\n";
|
||||||
|
|
||||||
Value signmessage(const Array& params, bool fHelp)
|
Value signmessage(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 2)
|
if (fHelp || params.size() != 2)
|
||||||
@ -533,61 +535,71 @@ Value signmessage(const Array& params, bool fHelp)
|
|||||||
"signmessage <bitcoinaddress> <message>\n"
|
"signmessage <bitcoinaddress> <message>\n"
|
||||||
"Sign a message with the private key of an address");
|
"Sign a message with the private key of an address");
|
||||||
|
|
||||||
|
if (pwalletMain->IsLocked())
|
||||||
|
throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
||||||
|
|
||||||
string strAddress = params[0].get_str();
|
string strAddress = params[0].get_str();
|
||||||
string strMessage = params[1].get_str();
|
string strMessage = params[1].get_str();
|
||||||
strMessage.insert(0, "Padding text - ");
|
|
||||||
|
CBitcoinAddress addr(strAddress);
|
||||||
uint160 hash160;
|
if (!addr.IsValid())
|
||||||
if(!AddressToHash160(strAddress, hash160))
|
|
||||||
throw JSONRPCError(-3, "Invalid address");
|
throw JSONRPCError(-3, "Invalid address");
|
||||||
|
|
||||||
vector<unsigned char>& vchPubKey = mapPubKeys[hash160];
|
|
||||||
CKey key;
|
CKey key;
|
||||||
if(!key.SetPubKey(vchPubKey))
|
if (!pwalletMain->GetKey(addr, key))
|
||||||
throw JSONRPCError(-3, "Public key not found");
|
throw JSONRPCError(-4, "Private key not available");
|
||||||
strMessage.insert(0, HexStr(vchPubKey.begin(), vchPubKey.end()).c_str());
|
|
||||||
|
CDataStream ss(SER_GETHASH);
|
||||||
|
ss << strMessageMagic;
|
||||||
|
ss << strMessage;
|
||||||
|
|
||||||
vector<unsigned char> vchMsg(strMessage.begin(), strMessage.end());
|
|
||||||
vector<unsigned char> vchSig;
|
vector<unsigned char> vchSig;
|
||||||
if (!CKey::Sign(mapKeys[vchPubKey], Hash(vchMsg.begin(), vchMsg.end()), vchSig))
|
if (!key.Sign(Hash(ss.begin(), ss.end()), vchSig))
|
||||||
throw JSONRPCError(-3, "Sign failed");
|
throw JSONRPCError(-5, "Sign failed");
|
||||||
|
|
||||||
Object obj;
|
CDataStream sres(SER_NETWORK);
|
||||||
obj.push_back(Pair("address", strAddress));
|
sres << key.GetPubKey(); // public key
|
||||||
obj.push_back(Pair("pubkey", HexStr(vchPubKey.begin(), vchPubKey.end()).c_str()));
|
sres << vchSig; // signature;
|
||||||
obj.push_back(Pair("sign", HexStr(vchSig.begin(), vchSig.end()).c_str()));
|
|
||||||
|
|
||||||
return obj;
|
return HexStr(sres.begin(), sres.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
Value verifymessage(const Array& params, bool fHelp)
|
Value verifymessage(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (fHelp || params.size() != 3)
|
if (fHelp || params.size() != 3)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"verifymessage <pubkey> <sign> <message>\n"
|
"verifymessage <bitcoinaddress> <signature> <message>\n"
|
||||||
"Verify a signed message with the public key");
|
"Verify a signed message");
|
||||||
|
|
||||||
string strPubKey = params[0].get_str();
|
string strAddress = params[0].get_str();
|
||||||
string strSign = params[1].get_str();
|
string strSign = params[1].get_str();
|
||||||
string strMessage = params[2].get_str();
|
string strMessage = params[2].get_str();
|
||||||
strMessage.insert(0, "Padding text - ");
|
|
||||||
strMessage.insert(0, strPubKey.c_str());
|
|
||||||
|
|
||||||
vector<unsigned char> vchPubKey = ParseHex(strPubKey);
|
CBitcoinAddress addr(strAddress);
|
||||||
vector<unsigned char> vchSig = ParseHex(strSign);
|
if (!addr.IsValid())
|
||||||
vector<unsigned char> vchMsg(strMessage.begin(), strMessage.end());
|
throw JSONRPCError(-3, "Invalid address");
|
||||||
|
|
||||||
|
vector<unsigned char> vchResult = ParseHex(strSign);
|
||||||
|
CDataStream sres(vchResult);
|
||||||
|
|
||||||
|
std::vector<unsigned char> vchPubKey;
|
||||||
|
sres >> vchPubKey;
|
||||||
|
std::vector<unsigned char> vchSig;
|
||||||
|
sres >> vchSig;
|
||||||
|
|
||||||
CKey key;
|
CKey key;
|
||||||
if(!key.SetPubKey(vchPubKey))
|
if (!key.SetPubKey(vchPubKey))
|
||||||
throw JSONRPCError(-3, "Invalid pubkey");
|
throw JSONRPCError(-5, "Invalid public key in signature");
|
||||||
|
|
||||||
if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig))
|
if (key.GetAddress() == addr)
|
||||||
throw JSONRPCError(-3, "Verify failed");
|
{
|
||||||
|
CDataStream ss(SER_GETHASH);
|
||||||
Object obj;
|
ss << strMessageMagic;
|
||||||
obj.push_back(Pair("address", PubKeyToAddress(vchPubKey)));
|
ss << strMessage;
|
||||||
obj.push_back(Pair("pubkey", strPubKey.c_str()));
|
return key.Verify(Hash(ss.begin(), ss.end()), vchSig);
|
||||||
return obj;
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user