From cc2567e32fb62df84f40d3f28f2ee48ab1009775 Mon Sep 17 00:00:00 2001 From: Khalahan Date: Sun, 24 Apr 2011 14:27:52 +0200 Subject: [PATCH] Sign and verify message with bitcoin address and public key Add padding to input (fixed string + address) before hashing --- src/bitcoinrpc.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 23d97db8..1b2a5b5f 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -526,6 +526,70 @@ Value sendtoaddress(const Array& params, bool fHelp) return wtx.GetHash().GetHex(); } +Value signmessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "signmessage \n" + "Sign a message with the private key of an address"); + + string strAddress = params[0].get_str(); + string strMessage = params[1].get_str(); + strMessage.insert(0, "Padding text - "); + + uint160 hash160; + if(!AddressToHash160(strAddress, hash160)) + throw JSONRPCError(-3, "Invalid address"); + + vector& vchPubKey = mapPubKeys[hash160]; + CKey key; + if(!key.SetPubKey(vchPubKey)) + throw JSONRPCError(-3, "Public key not found"); + strMessage.insert(0, HexStr(vchPubKey.begin(), vchPubKey.end()).c_str()); + + vector vchMsg(strMessage.begin(), strMessage.end()); + vector vchSig; + if (!CKey::Sign(mapKeys[vchPubKey], Hash(vchMsg.begin(), vchMsg.end()), vchSig)) + throw JSONRPCError(-3, "Sign failed"); + + Object obj; + obj.push_back(Pair("address", strAddress)); + obj.push_back(Pair("pubkey", HexStr(vchPubKey.begin(), vchPubKey.end()).c_str())); + obj.push_back(Pair("sign", HexStr(vchSig.begin(), vchSig.end()).c_str())); + + return obj; +} + +Value verifymessage(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 3) + throw runtime_error( + "verifymessage \n" + "Verify a signed message with the public key"); + + string strPubKey = params[0].get_str(); + string strSign = params[1].get_str(); + string strMessage = params[2].get_str(); + strMessage.insert(0, "Padding text - "); + strMessage.insert(0, strPubKey.c_str()); + + vector vchPubKey = ParseHex(strPubKey); + vector vchSig = ParseHex(strSign); + vector vchMsg(strMessage.begin(), strMessage.end()); + + CKey key; + if(!key.SetPubKey(vchPubKey)) + throw JSONRPCError(-3, "Invalid pubkey"); + + if (!key.Verify(Hash(vchMsg.begin(), vchMsg.end()), vchSig)) + throw JSONRPCError(-3, "Verify failed"); + + Object obj; + obj.push_back(Pair("address", PubKeyToAddress(vchPubKey))); + obj.push_back(Pair("pubkey", strPubKey.c_str())); + return obj; +} + Value getreceivedbyaddress(const Array& params, bool fHelp) { @@ -1636,6 +1700,8 @@ pair pCallTable[] = make_pair("sendmany", &sendmany), make_pair("gettransaction", &gettransaction), make_pair("listtransactions", &listtransactions), + make_pair("signmessage", &signmessage), + make_pair("verifymessage", &verifymessage), make_pair("getwork", &getwork), make_pair("listaccounts", &listaccounts), make_pair("settxfee", &settxfee),