diff options
author | Khalahan <khal@bitcoin-contact.org> | 2011-04-24 14:27:52 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2011-09-27 19:48:22 +0200 |
commit | cc2567e32fb62df84f40d3f28f2ee48ab1009775 (patch) | |
tree | 640b26f6bc6b9472f5a9a4f6edfd9f160d8676ad /src | |
parent | e93bf37e86488e481136ca66cd0b6b17b2c2e05e (diff) |
Sign and verify message with bitcoin address and public key
Add padding to input (fixed string + address) before hashing
Diffstat (limited to 'src')
-rw-r--r-- | src/bitcoinrpc.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 23d97db89b..1b2a5b5f7e 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 <bitcoinaddress> <message>\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<unsigned char>& 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<unsigned char> vchMsg(strMessage.begin(), strMessage.end()); + vector<unsigned char> 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 <pubkey> <sign> <message>\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<unsigned char> vchPubKey = ParseHex(strPubKey); + vector<unsigned char> vchSig = ParseHex(strSign); + vector<unsigned char> 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<string, rpcfn_type> 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), |