From 3a570dc80a7391b7f3943cb83849055318e0217a Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Wed, 21 Sep 2011 17:03:28 +0200 Subject: [PATCH] Use key recovery for message signatures Instead of encoding the public key inside the signature string, use key recovery to do verification. This allows 88-character base64-encoded signature strings instead of 188-character ones. --- src/bitcoinrpc.cpp | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index c8a0076bfa..8468e56105 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -554,15 +554,10 @@ Value signmessage(const Array& params, bool fHelp) ss << strMessage; vector vchSig; - if (!key.Sign(Hash(ss.begin(), ss.end()), vchSig)) + if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig)) throw JSONRPCError(-5, "Sign failed"); - CDataStream sres(SER_NETWORK); - sres << key.GetPubKey(); // public key - sres << vchSig; // signature; - - vector vchRet(sres.begin(), sres.end()); - return EncodeBase64(&vchRet[0], vchRet.size()); + return EncodeBase64(&vchSig[0], vchSig.size()); } Value verifymessage(const Array& params, bool fHelp) @@ -581,31 +576,20 @@ Value verifymessage(const Array& params, bool fHelp) throw JSONRPCError(-3, "Invalid address"); bool fInvalid = false; - vector vchResult = DecodeBase64(strSign.c_str(), &fInvalid); + vector vchSig = DecodeBase64(strSign.c_str(), &fInvalid); if (fInvalid) throw JSONRPCError(-5, "Malformed base64 encoding"); - CDataStream sres(vchResult); - - std::vector vchPubKey; - sres >> vchPubKey; - std::vector vchSig; - sres >> vchSig; + CDataStream ss(SER_GETHASH); + ss << strMessageMagic; + ss << strMessage; CKey key; - if (!key.SetPubKey(vchPubKey)) - throw JSONRPCError(-5, "Invalid public key in signature"); - - if (key.GetAddress() == addr) - { - CDataStream ss(SER_GETHASH); - ss << strMessageMagic; - ss << strMessage; - return key.Verify(Hash(ss.begin(), ss.end()), vchSig); - } - else + if (!key.SetCompactSignature(Hash(ss.begin(), ss.end()), vchSig)) return false; + + return (key.GetAddress() == addr); }