Skip to content

Commit

Permalink
Add method to sign arbitrary msg using bip322 (#184)
Browse files Browse the repository at this point in the history
* Add method to arbitrary msg using bip322
  • Loading branch information
KonradStaniec authored Jul 18, 2024
1 parent 5ab83e6 commit 6b67265
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 0 deletions.
27 changes: 27 additions & 0 deletions itest/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"testing"
"time"

"github.com/babylonchain/babylon/crypto/bip322"
btcctypes "github.com/babylonchain/babylon/x/btccheckpoint/types"

staking "github.com/babylonchain/babylon/btcstaking"
Expand Down Expand Up @@ -1533,6 +1534,32 @@ func TestBitcoindWalletRpcApi(t *testing.T) {
require.Equal(t, walletcontroller.TxInChain, status)
}

func TestBitcoindWalletBip322Signing(t *testing.T) {
h := NewBitcoindHandler(t)
h.Start()
passphrase := "pass"

_ = h.CreateWallet("test-wallet", passphrase)
cfg, c := defaultStakerConfig(t, passphrase)

segwitAddress, err := c.GetNewAddress("")
require.NoError(t, err)

controller, err := walletcontroller.NewRpcWalletController(cfg)
require.NoError(t, err)

err = controller.UnlockWallet(30)
require.NoError(t, err)

msg := []byte("test message")

bip322Signature, err := controller.SignBip322NativeSegwit(msg, segwitAddress)
require.NoError(t, err)

err = bip322.Verify(msg, bip322Signature, segwitAddress, regtestParams)
require.NoError(t, err)
}

func TestSendingStakingTransaction_Restaking(t *testing.T) {
// need to have at least 300 block on testnet as only then segwit is activated.
// Mature output is out which has 100 confirmations, which means 200mature outputs
Expand Down
44 changes: 44 additions & 0 deletions walletcontroller/client.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package walletcontroller

import (
"encoding/hex"
"fmt"
"sort"

"github.com/babylonchain/babylon/crypto/bip322"
"github.com/babylonchain/btc-staker/stakercfg"
scfg "github.com/babylonchain/btc-staker/stakercfg"
"github.com/babylonchain/btc-staker/types"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcjson"
"github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
Expand Down Expand Up @@ -256,3 +259,44 @@ func (w *RpcWalletController) TxDetails(txHash *chainhash.Hash, pkScript []byte)
return nil, TxNotFound, fmt.Errorf("invalid bitcoin backend")
}
}

// SignBip322NativeSegwit signs arbitrary message using bip322 signing scheme.
// To work properly:
// - wallet must be unlocked
// - address must be under wallet control
// - address must be native segwit address
func (w *RpcWalletController) SignBip322NativeSegwit(msg []byte, address btcutil.Address) (wire.TxWitness, error) {
toSpend, err := bip322.GetToSpendTx(msg, address)

if err != nil {
return nil, fmt.Errorf("failed to bip322 to spend tx: %w", err)
}

if !txscript.IsPayToWitnessPubKeyHash(toSpend.TxOut[0].PkScript) {
return nil, fmt.Errorf("Bip322NativeSegwit support only native segwit addresses")
}

toSpendhash := toSpend.TxHash()

toSign := bip322.GetToSignTx(toSpend)

amt := float64(0)
signed, all, err := w.SignRawTransactionWithWallet2(toSign, []btcjson.RawTxWitnessInput{
{
Txid: toSpendhash.String(),
Vout: 0,
ScriptPubKey: hex.EncodeToString(toSpend.TxOut[0].PkScript),
Amount: &amt,
},
})

if err != nil {
return nil, fmt.Errorf("failed to sign raw transaction while creating bip322 signature: %w", err)
}

if !all {
return nil, fmt.Errorf("failed to create bip322 signature, address %s is not under wallet control", address)
}

return signed.TxIn[0].Witness, nil
}
1 change: 1 addition & 0 deletions walletcontroller/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ type WalletController interface {
SendRawTransaction(tx *wire.MsgTx, allowHighFees bool) (*chainhash.Hash, error)
ListOutputs(onlySpendable bool) ([]Utxo, error)
TxDetails(txHash *chainhash.Hash, pkScript []byte) (*notifier.TxConfirmation, TxStatus, error)
SignBip322NativeSegwit(msg []byte, address btcutil.Address) (wire.TxWitness, error)
}

0 comments on commit 6b67265

Please sign in to comment.