Fix signmessage RPC to match Core.
AFAICT this function has never worked correctly due to the hash being signed not matching the hash created by Core. Core wallet writes serialized strings to a double-sha256 hashing stream, while we were using string concatination. This produced different messages since the message before hashing did not include compact integers (called varints in btcsuite code) preceding each string with the string length. Tested by creating signed messages from btcwallet and verifying them with Bitcoin-Qt, as well as creating signatures from Bitcoin-Qt and verifying them with btcwallet. Fixes #323.
This commit is contained in:
parent
cef002139f
commit
4f6edce6dc
1 changed files with 10 additions and 4 deletions
14
rpcserver.go
14
rpcserver.go
|
@ -2732,9 +2732,12 @@ func SignMessage(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (in
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fullmsg := "Bitcoin Signed Message:\n" + cmd.Message
|
var buf bytes.Buffer
|
||||||
|
wire.WriteVarString(&buf, 0, "Bitcoin Signed Message:\n")
|
||||||
|
wire.WriteVarString(&buf, 0, cmd.Message)
|
||||||
|
messageHash := wire.DoubleSha256(buf.Bytes())
|
||||||
sigbytes, err := btcec.SignCompact(btcec.S256(), privKey,
|
sigbytes, err := btcec.SignCompact(btcec.S256(), privKey,
|
||||||
wire.DoubleSha256([]byte(fullmsg)), ainfo.Compressed())
|
messageHash, ainfo.Compressed())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -3138,9 +3141,12 @@ func VerifyMessage(w *wallet.Wallet, chainSvr *chain.Client, icmd interface{}) (
|
||||||
|
|
||||||
// Validate the signature - this just shows that it was valid at all.
|
// Validate the signature - this just shows that it was valid at all.
|
||||||
// we will compare it with the key next.
|
// we will compare it with the key next.
|
||||||
|
var buf bytes.Buffer
|
||||||
|
wire.WriteVarString(&buf, 0, "Bitcoin Signed Message:\n")
|
||||||
|
wire.WriteVarString(&buf, 0, cmd.Message)
|
||||||
|
expectedMessageHash := wire.DoubleSha256(buf.Bytes())
|
||||||
pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
|
pk, wasCompressed, err := btcec.RecoverCompact(btcec.S256(), sig,
|
||||||
wire.DoubleSha256([]byte("Bitcoin Signed Message:\n"+
|
expectedMessageHash)
|
||||||
cmd.Message)))
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue