From f90efbfeef9cd733aa7590fdf581ff82b999c4b5 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 26 Apr 2016 13:17:00 -0400 Subject: [PATCH] Create signmessagewithprivkey rpc New rpc 'signmessagewithprivkey' which takes a private key to sign a message without using the wallet. --- src/rpc/misc.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index e8a099b4452..09f51857815 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -366,6 +366,48 @@ UniValue verifymessage(const UniValue& params, bool fHelp) return (pubkey.GetID() == keyID); } +UniValue signmessagewithprivkey(const UniValue& params, bool fHelp) +{ + if (fHelp || params.size() != 2) + throw runtime_error( + "signmessagewithprivkey \"privkey\" \"message\"\n" + "\nSign a message with the private key of an address\n" + "\nArguments:\n" + "1. \"privkey\" (string, required) The private key to sign the message with.\n" + "2. \"message\" (string, required) The message to create a signature of.\n" + "\nResult:\n" + "\"signature\" (string) The signature of the message encoded in base 64\n" + "\nExamples:\n" + "\nCreate the signature\n" + + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") + + "\nVerify the signature\n" + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XZ\" \"signature\" \"my message\"") + + "\nAs json rpc\n" + + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"") + ); + + string strPrivkey = params[0].get_str(); + string strMessage = params[1].get_str(); + + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(strPrivkey); + if (!fGood) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); + CKey key = vchSecret.GetKey(); + if (!key.IsValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); + + CHashWriter ss(SER_GETHASH, 0); + ss << strMessageMagic; + ss << strMessage; + + vector vchSig; + if (!key.SignCompact(ss.GetHash(), vchSig)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); + + return EncodeBase64(&vchSig[0], vchSig.size()); +} + UniValue setmocktime(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) @@ -404,6 +446,7 @@ static const CRPCCommand commands[] = { "util", "validateaddress", &validateaddress, true }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true }, { "util", "verifymessage", &verifymessage, true }, + { "util", "signmessagewithprivkey", &signmessagewithprivkey, true }, /* Not shown in help */ { "hidden", "setmocktime", &setmocktime, true },