Assessment reports>Babylon Genesis Chain>Addendum>Key recovery succeeding on output from a btc-delegations query test

Key recovery succeeding on output from a btc-delegations query test

func AsigB64(asigHex string) *asig.AdaptorSignature {
    asigBytes, err := base64.StdEncoding.DecodeString(asigHex)
    if err != nil {
        panic(err)
    }
    asig, err := asig.NewAdaptorSignatureFromBytes(asigBytes)
    if err != nil {
        panic(err)
    }
    return asig
}

func PubKeyHex(pkHex string) *btcec.PublicKey {
    pkBytes, err  := hex.DecodeString(pkHex)
    if err != nil {
        panic(err)
    }
    pk, err := schnorr.ParsePubKey(pkBytes)
    if err != nil {
        panic(err)
    }
    return pk
}

func BTCTxHex(txHex string) *wire.MsgTx {
    txBytes, err := hex.DecodeString(txHex)
    if err != nil {
        panic(err)
    }
    tx, err := bbn.NewBTCTxFromBytes(txBytes)
    if err != nil {
        panic(err)
    }
    return tx
}

func TestAdaptorSigRecoverNonceReuseData(t *testing.T) {
/*
root@d1e153fc6607:/# babylond q btcstaking btc-delegations any -o json
{"btc_delegations":[{"staker_addr":"bbn19lravmj3p9fzaugj0lshj0gxy6lgszyzyennjn",
"btc_pk":"98698074342990d6e85e0ae2c9c7a30bd6157dff9170f5367e9a335e4d5aa761","fp_
btc_pk_list":["b1160397022bc88d56d1a5b0fa48f6c584d2b7f5e0680b8a70627e131274e948"
,"75207fd11c06e681a9e842aa9fc5b8e270b4edf7d014e256ff60bf368f6563e9"],"start_heig
ht":"130","end_height":"10130","total_sat":"1000000","staking_tx_hex":"010000000
00101630d4b5c981ab3268ada37bdb7a811af302fc284f37ff67c8ff896d3b14a7caa0100000000f
fffffff0240420f0000000000225120eb7f748889302fc7fc0071db3468ad326b5065493f0eb8ff1
c968f4481f40786cf788b3b00000000160014571ee10c454e543c80f1311b9615781c78a2bb50024
73044022042301314fabd5612b4405eb7498039b635026f55e63e74fd0ae95b304e4d269802206a6
c1fee1cb57668719502f2eb769e942c303bd3716439b7b42b33ca6d7bc02b012102deb5a3f24a647
3da0032f28759da8fb8b44c7b71b384079470701a73f46ff54100000000","slashing_tx_hex":"
0100000001b33b4bc6dd3bdb1d6acdf71a37f907e3fa7ddfebcde6a995a7e30b7a908d4d5e000000
0000ffffffff02a0860100000000001976a914010101010101010101010101010101010101010188
abb8b70d0000000000225120a26d1b5740f281182b952231ef8db18b39ff8d32d6a318605c09746f
e61c133a00000000","delegator_slash_sig_hex":"a0462eacb2b54a0a4c1b13b62579594586f
a583d1a650a1735c566e6088b115f865f072b4fcd8cdb60594b427be694cb0b925ab7bb63d526a2a
d9fe78bc76ff4","covenant_sigs":[{"cov_pk":"2d4ccbe538f846a750d82a77cd742895e51af
cf23d86d05004a356b783902748","adaptor_sigs":["Am/mgpkAyoliiTIJTvrwlx1QXhSctfWFdB
jfFPaGvm5pvnibUZvq4f4KB/xGahtYiYNf4Ls22tAwymSwUfLVvpoB","Alpmcon5FgU2x0Bo396o41D
QZBL/XFBRm7SrhQmRzWLQ6ge75q6MvbXQTVqv36tm+ofd8rn4HJbqQw/QHdMDvrQB"]}],"staking_o
utput_idx":0,"active":true,"status_desc":"ACTIVE","unbonding_time":3,"undelegati
on_response":{"unbonding_tx_hex":"0200000001b33b4bc6dd3bdb1d6acdf71a37f907e3fa7d
dfebcde6a995a7e30b7a908d4d5e0000000000ffffffff01583e0f00000000002251206f484bb06c
b992887f3a1765a7e4f0af1a4458a58a734f81007c650eeae1336c00000000","delegator_unbon
ding_sig_hex":"","covenant_unbonding_sig_list":[{"pk":"2d4ccbe538f846a750d82a77c
d742895e51afcf23d86d05004a356b783902748","sig":"yloDtH0/JclNHEHkxXSvwSpH6QRBwYt2
ThvbCdGCdbRFR4p6FdbveZRPLmILj9Jc1dxfajztbY8Zqfq3px42AQ=="}],"slashing_tx_hex":"0
100000001346c96e5c94af803d83f0edf34634d88eb31bf4d7a6c2ce2d072d2ff1af5f24a0000000
000ffffffff023c860100000000001976a914010101010101010101010101010101010101010188a
b34b40d0000000000225120a26d1b5740f281182b952231ef8db18b39ff8d32d6a318605c09746fe
61c133a00000000","delegator_slashing_sig_hex":"4702cd8b85e89bb46f816955999b32a5c
6cdebd90594e599512a51b35a5b62e0e22b3341e204e599d3c296b768dd6ea324f2dd2251a3b4e0a
5b37cd87320c9c7","covenant_slashing_sigs":[{"cov_pk":"2d4ccbe538f846a750d82a77cd
742895e51afcf23d86d05004a356b783902748","adaptor_sigs":["AqdFvDiaiCFisbVD35gmOqY
1YmNezi2bVGbnEwXOdSa5nG/6YsGjczEOAjrMeNJOUSpLR9B+wAXRqRvt8b2ssf0A","Al2IOjZDqYRT
1/cKhGaEd1MZJRwufUQq/BPQ4eOlUff1rPducLVJTHV6St150C6pD/ygZyIIrBr+hQP3EjeLZ5sA"]}]
},"params_version":0}],"pagination":{"next_key":null,"total":"0"}}
*/
    // Public keys and transactions extracted from above JSON
    covPk := PubKeyHex(
        "2d4ccbe538f846a750d82a77cd742895e51afcf23d86d05004a356b783902748")
    stakerPk := PubKeyHex(
        "98698074342990d6e85e0ae2c9c7a30bd6157dff9170f5367e9a335e4d5aa761")
    fpKeys := []*btcec.PublicKey {
PubKeyHex("b1160397022bc88d56d1a5b0fa48f6c584d2b7f5e0680b8a70627e131274e948"),
PubKeyHex("75207fd11c06e681a9e842aa9fc5b8e270b4edf7d014e256ff60bf368f6563e9"),
    }
    covKeys := []*btcec.PublicKey{covPk}
    asig1Unbond := AsigB64("AqdFvDiaiCFisbVD35gmOqY1YmNezi2bVGbnEwXOdSa5nG/6YsGj
czEOAjrMeNJOUSpLR9B+wAXRqRvt8b2ssf0A")
    asig2Unbond := AsigB64("Al2IOjZDqYRT1/cKhGaEd1MZJRwufUQq/BPQ4eOlUff1rPducLVJ
THV6St150C6pD/ygZyIIrBr+hQP3EjeLZ5sA")
    unbondingSlashingTx := BTCTxHex("0100000001346c96e5c94af803d83f0edf34634d88e
b31bf4d7a6c2ce2d072d2ff1af5f24a0000000000ffffffff023c860100000000001976a91401010
1010101010101010101010101010101010188ab34b40d0000000000225120a26d1b5740f281182b9
52231ef8db18b39ff8d32d6a318605c09746fe61c133a00000000")
    unbondingTx := BTCTxHex("0200000001b33b4bc6dd3bdb1d6acdf71a37f907e3fa7ddfebc
de6a995a7e30b7a908d4d5e0000000000ffffffff01583e0f00000000002251206f484bb06cb9928
87f3a1765a7e4f0af1a4458a58a734f81007c650eeae1336c00000000")
    unbondingOutput := unbondingTx.TxOut[0]
    // Reconstruct the unbonding info for the spend information to construct the message
    unbondingInfo, err := btcstaking.BuildUnbondingInfo(
        stakerPk, fpKeys, covKeys, 1, 10000,
        btcutil.Amount(unbondingOutput.Value),
        &chaincfg.SimNetParams)
    require.NoError(t, err)
    spendInfo, err := unbondingInfo.SlashingPathSpendInfo()
    require.NoError(t, err)

    // Validate the signature (used to confirm via prints that the sigHash was reconstructed correctly)
    unbondingSlashingTx2, err := bstypes.NewBTCSlashingTxFromMsgTx(unbondingSlashingTx)
    require.NoError(t, err)
    _, err = unbondingSlashingTx2.ParseEncVerifyAdaptorSignatures(
        unbondingOutput,
        spendInfo,
        bbn.NewBIP340PubKeyFromBTCPK(covPk),
        []bbn.BIP340PubKey{
            *bbn.NewBIP340PubKeyFromBTCPK(fpKeys[0]),
            *bbn.NewBIP340PubKeyFromBTCPK(fpKeys[1])},
        [][]byte{asig1Unbond.MustMarshal(), asig2Unbond.MustMarshal()},
        )
    require.NoError(t, err)

    // Reconstruct the sigHash
    script := spendInfo.GetPkScriptPath()
    tapLeaf := txscript.NewBaseTapLeaf(script)
    inputFetcher := txscript.NewCannedPrevOutputFetcher(
        unbondingOutput.PkScript,
        unbondingOutput.Value,
    )
    sigHashes := txscript.NewTxSigHashes(unbondingSlashingTx, inputFetcher)
    sigHash, err := txscript.CalcTapscriptSignaturehash(
        sigHashes, txscript.SigHashDefault, unbondingSlashingTx,
        0, inputFetcher, tapLeaf,
    )
    require.NoError(t, err)

    // Recover the covenant private key
    recoveredSk := asig.RecoverNonceReuse(covPk, asig1Unbond, asig2Unbond, sigHash)
    fmt.Printf("recoveredSk %v\n", recoveredSk)
    fmt.Printf("recoveredPk %x\n", schnorr.SerializePubKey(recoveredSk.PubKey()))
    fmt.Printf("covenantPk  %x\n", schnorr.SerializePubKey(covPk))
    require.Equal(t, recoveredSk.PubKey(), covPk)
}
Zellic © 2025Back to top ↑