Skip to content

Commit

Permalink
Merge pull request #87 from keithsue/sufay/verify-signatures
Browse files Browse the repository at this point in the history
Add psbt signature verification
  • Loading branch information
liangping authored Jun 20, 2024
2 parents 56cdfe6 + a4814e5 commit f6eff15
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
3 changes: 3 additions & 0 deletions x/btcbridge/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ func (m msgServer) SubmitWithdrawSignatures(goCtx context.Context, msg *types.Ms
}

// verify the signatures
if !types.VerifyPsbtSignatures(packet) {
return nil, types.ErrInvalidSignatures
}

// Set the signing request status to signed
request := m.GetSigningRequest(ctx, msg.Txid)
Expand Down
62 changes: 60 additions & 2 deletions x/btcbridge/types/signature.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,64 @@
package types

func (m *BitcoinSigningRequest) ValidateSignatures(sigs []string) bool {
import (
secp256k1 "github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/btcsuite/btcd/btcutil/psbt"
"github.com/btcsuite/btcd/txscript"
)

return false
// VerifyPsbtSignatures verifies the signatures of the given psbt
// Note: assume that the psbt is valid and all inputs are native segwit
func VerifyPsbtSignatures(p *psbt.Packet) bool {
// build previous output fetcher
prevOutputFetcher := txscript.NewMultiPrevOutFetcher(nil)

for i, txIn := range p.UnsignedTx.TxIn {
prevOutput := p.Inputs[i].WitnessUtxo
if prevOutput == nil {
return false
}

prevOutputFetcher.AddPrevOut(txIn.PreviousOutPoint, prevOutput)
}

// verify signatures
for i := range p.Inputs {
output := p.Inputs[i].WitnessUtxo
hashType := p.Inputs[i].SighashType

witness := p.Inputs[i].FinalScriptWitness
if len(witness) < 72+33 {
return false
}

sigBytes := witness[0 : len(witness)-33]
pkBytes := witness[len(witness)-33:]

if sigBytes[len(sigBytes)-1] != byte(hashType) {
return false
}

sig, err := ecdsa.ParseDERSignature(sigBytes[0 : len(sigBytes)-1])
if err != nil {
return false
}

pk, err := secp256k1.ParsePubKey(pkBytes)
if err != nil {
return false
}

sigHash, err := txscript.CalcWitnessSigHash(output.PkScript, txscript.NewTxSigHashes(p.UnsignedTx, prevOutputFetcher),
hashType, p.UnsignedTx, i, output.Value)
if err != nil {
return false
}

if !sig.Verify(sigHash, pk) {
return false
}
}

return true
}

0 comments on commit f6eff15

Please sign in to comment.