@@ -31,6 +31,7 @@ import (
3131 "github.com/btcsuite/btcd/btcec/v2/ecdsa"
3232 "github.com/btcsuite/btcd/btcjson"
3333 "github.com/btcsuite/btcd/btcutil"
34+ "github.com/btcsuite/btcd/btcutil/bip322"
3435 "github.com/btcsuite/btcd/btcutil/message"
3536 "github.com/btcsuite/btcd/chaincfg"
3637 "github.com/btcsuite/btcd/chaincfg/chainhash"
@@ -3590,7 +3591,24 @@ func handleSignMessageWithPrivKey(s *rpcServer, cmd interface{}, closeChan <-cha
35903591 }
35913592 }
35923593
3593-
3594+ // If an address was provided, use BIP-322 signing.
3595+ if c .Address != nil {
3596+ addr , err := btcutil .DecodeAddress (* c .Address , s .cfg .ChainParams )
3597+ if err != nil {
3598+ return nil , & btcjson.RPCError {
3599+ Code : btcjson .ErrRPCInvalidAddressOrKey ,
3600+ Message : "Invalid address: " + err .Error (),
3601+ }
3602+ }
3603+ sig , err := bip322 .Sign (wif .PrivKey , addr , c .Message )
3604+ if err != nil {
3605+ return nil , & btcjson.RPCError {
3606+ Code : btcjson .ErrRPCInvalidParameter ,
3607+ Message : "BIP-322 signing failed: " + err .Error (),
3608+ }
3609+ }
3610+ return sig , nil
3611+ }
35943612
35953613 sig := ecdsa .SignCompact (wif .PrivKey , message .Hash (c .Message ), wif .CompressPubKey )
35963614 return base64 .StdEncoding .EncodeToString (sig ), nil
@@ -3756,53 +3774,32 @@ func handleVerifyMessage(s *rpcServer, cmd interface{}, closeChan <-chan struct{
37563774 }
37573775 }
37583776
3759- // Only P2PKH addresses are valid for signing.
3760- if _ , ok := addr .(* btcutil.AddressPubKeyHash ); ! ok {
3761- return nil , & btcjson.RPCError {
3762- Code : btcjson .ErrRPCType ,
3763- Message : "Address is not a pay-to-pubkey-hash address" ,
3764- }
3777+ // Try legacy (BIP-137) verification first.
3778+ valid , err := message .Verify (addr , c .Message , c .Signature )
3779+ if err == nil {
3780+ return valid , nil
37653781 }
37663782
3767- // Decode base64 signature .
3768- sig , err := base64 . StdEncoding . DecodeString ( c .Signature )
3783+ // Try BIP-322 verification .
3784+ valid , err = bip322 . Verify ( addr , c . Message , c .Signature )
37693785 if err != nil {
3770- return nil , & btcjson.RPCError {
3771- Code : btcjson .ErrRPCParse .Code ,
3772- Message : "Malformed base64 encoding: " + err .Error (),
3786+ switch {
3787+ case errors .Is (err , bip322 .ErrInconclusive ):
3788+ return nil , & btcjson.RPCError {
3789+ Code : btcjson .ErrRPCInvalidAddressOrKey ,
3790+ Message : "Invalid signature: " + err .Error (),
3791+ }
3792+ case errors .Is (err , bip322 .ErrMalformedSignature ):
3793+ return nil , & btcjson.RPCError {
3794+ Code : btcjson .ErrRPCParse .Code ,
3795+ Message : "Malformed base64 encoding: " + err .Error (),
3796+ }
37733797 }
3774- }
37753798
3776- // Validate the signature - this just shows that it was valid at all.
3777- // we will compare it with the key next.
3778- var buf bytes.Buffer
3779- wire .WriteVarString (& buf , 0 , messageSignatureHeader )
3780- wire .WriteVarString (& buf , 0 , c .Message )
3781- expectedMessageHash := chainhash .DoubleHashB (buf .Bytes ())
3782- pk , wasCompressed , err := ecdsa .RecoverCompact (sig ,
3783- expectedMessageHash )
3784- if err != nil {
3785- // Mirror Bitcoin Core behavior, which treats error in
3786- // RecoverCompact as invalid signature.
3787- return false , nil
3788- }
3789-
3790- // Reconstruct the pubkey hash.
3791- var serializedPK []byte
3792- if wasCompressed {
3793- serializedPK = pk .SerializeCompressed ()
3794- } else {
3795- serializedPK = pk .SerializeUncompressed ()
3796- }
3797- address , err := btcutil .NewAddressPubKey (serializedPK , params )
3798- if err != nil {
3799- // Again mirror Bitcoin Core behavior, which treats error in public key
3800- // reconstruction as invalid signature.
38013799 return false , nil
38023800 }
38033801
3804- // Return boolean if addresses match.
3805- return address .EncodeAddress () == c .Address , nil
3802+ return valid , nil
38063803}
38073804
38083805// handleVersion implements the version command.
0 commit comments