try to replace ed25519 lib with a newer one

This commit is contained in:
creamwhip
2022-01-29 19:09:00 +08:00
parent 8488daf9f1
commit 36878c11d5
8 changed files with 181 additions and 175 deletions

View File

@@ -13,7 +13,7 @@ import (
"math/big"
"strings"
"github.com/agl/ed25519/edwards25519"
edwards255192 "filippo.io/edwards25519"
"github.com/binance-chain/tss-lib/common"
"github.com/binance-chain/tss-lib/tss"
"github.com/decred/dcrd/dcrec/edwards/v2"
@@ -29,26 +29,32 @@ func (round *finalization) Start() *tss.Error {
ok := false
var s *big.Int
var sumS *[32]byte
var sumS []byte
_, isTwistedEdwardsCurve := round.Params().EC().(*edwards.TwistedEdwardsCurve)
isSecp256k1Curve := strings.Compare("secp256k1", round.Params().EC().Params().Name) == 0
if isTwistedEdwardsCurve {
sumS = bigIntToEncodedBytes(&round.temp.si)
for j := range round.Parties().IDs() {
sumS = bigIntToEncodedBytes32(&round.temp.si)
for j, Pj := range round.Parties().IDs() {
round.ok[j] = true
if j == round.PartyID().Index {
continue
}
r3msg := round.temp.signRound3Messages[j].Content().(*SignRound3Message)
sjBytes := bigIntToEncodedBytes(r3msg.UnmarshalS())
var tmpSumS [32]byte
edwards25519.ScMulAdd(&tmpSumS, sumS, bigIntToEncodedBytes(big.NewInt(1)), sjBytes)
sumS = &tmpSumS
sjBytes := bigIntToEncodedBytes32(r3msg.UnmarshalS())
var err error
var sc, scSJ *edwards255192.Scalar
if sc, err = new(edwards255192.Scalar).SetCanonicalBytes(sumS[:]); err != nil {
return round.WrapError(err, Pj)
}
if scSJ, err = new(edwards255192.Scalar).SetCanonicalBytes(sjBytes[:]); err != nil {
return round.WrapError(err, Pj)
}
sc = sc.Add(sc, scSJ)
sumS = sc.Bytes()
}
s = encodedBytesToBigInt(sumS)
s = encoded32BytesToBigInt(sumS)
} else if isSecp256k1Curve {
sumSInt := &round.temp.si
modN := common.ModInt(tss.S256().Params().N)
@@ -67,13 +73,13 @@ func (round *finalization) Start() *tss.Error {
// save the signature for final output
signature := new(common.ECSignature)
if isTwistedEdwardsCurve {
signature.Signature = append(bigIntToEncodedBytes(round.temp.r)[:], sumS[:]...)
signature.R = bigIntToEncodedBytes(round.temp.r)[:]
signature.S = bigIntToEncodedBytes(s)[:]
signature.Signature = append(bigIntToEncodedBytes32(round.temp.r)[:], sumS[:]...)
signature.R = bigIntToEncodedBytes32(round.temp.r)[:]
signature.S = bigIntToEncodedBytes32(s)[:]
} else if isSecp256k1Curve {
var r32b, s32b [32]byte
encode32bytes(round.temp.r, &r32b)
encode32bytes(s, &s32b)
round.temp.r.FillBytes(r32b[:])
s.FillBytes(s32b[:])
signature.Signature = append(r32b[:], s32b[:]...)
signature.R = r32b[:]
signature.S = s32b[:]
@@ -121,7 +127,3 @@ func (round *finalization) Update() (bool, *tss.Error) {
func (round *finalization) NextRound() tss.Round {
return nil // finished!
}
func encode32bytes(i *big.Int, buff *[32]byte) {
i.FillBytes(buff[:])
}

View File

@@ -13,7 +13,7 @@ import (
"sync/atomic"
"testing"
"github.com/agl/ed25519/edwards25519"
edwards255192 "filippo.io/edwards25519"
"github.com/decred/dcrd/dcrec/edwards/v2"
"github.com/ipfs/go-log"
"github.com/stretchr/testify/assert"
@@ -108,15 +108,23 @@ signing:
R := parties[0].temp.r
// BEGIN check s correctness
sumS := bigIntToEncodedBytes(&parties[0].temp.si)
sumS := bigIntToEncodedBytes32(&parties[0].temp.si)
for i, p := range parties {
if i == 0 {
continue
}
var tmpSumS [32]byte
edwards25519.ScMulAdd(&tmpSumS, sumS, bigIntToEncodedBytes(big.NewInt(1)), bigIntToEncodedBytes(&p.temp.si))
sumS = &tmpSumS
var siSc *edwards255192.Scalar
sumSSc, err2 := new(edwards255192.Scalar).SetCanonicalBytes(sumS)
if err2 != nil {
t.Errorf("scalar parse error 1 %v", err.Error())
t.FailNow()
}
if siSc, err2 = new(edwards255192.Scalar).SetCanonicalBytes(bigIntToEncodedBytes32(&p.temp.si)); err2 != nil {
t.Errorf("scalar parse error 2 %v", err.Error())
t.FailNow()
}
sumSSc = new(edwards255192.Scalar).Add(sumSSc, siSc)
sumS = sumSSc.Bytes()
}
// END check s correctness
@@ -128,8 +136,8 @@ signing:
Y: pkY,
}
sBytes := copyBytes(parties[0].data.Signature[32:64])
sEncodedBigInt := encodedBytesToBigInt(sBytes)
sBytes := copyBytes32(parties[0].data.Signature[32:64])
sEncodedBigInt := encoded32BytesToBigInt(sBytes)
newSig, err := edwards.ParseSignature(parties[0].data.Signature)
if err != nil {

View File

@@ -77,7 +77,7 @@ func NewSignRound2Message(
func (m *SignRound2Message) ValidateBasic() bool {
return m != nil &&
common.NonEmptyMultiBytes(m.DeCommitment, 3) &&
common.NonEmptyMultiBytes(m.DeCommitment, 5) &&
common.NonEmptyMultiBytes(m.Proof, zkpsch.ProofSchBytesParts)
}

View File

@@ -10,6 +10,8 @@ import (
"errors"
"fmt"
"filippo.io/edwards25519"
"filippo.io/edwards25519/field"
"github.com/binance-chain/tss-lib/common"
"github.com/binance-chain/tss-lib/crypto"
"github.com/binance-chain/tss-lib/crypto/commitments"
@@ -33,15 +35,28 @@ func (round *round1) Start() *tss.Error {
round.resetOK()
// 1. select ri
ri := common.GetRandomPositiveInt(round.Params().EC().Params().N)
ri := common.MustGetRandomInt(256)
// 2. make commitment
pointRi := crypto.ScalarBaseMult(round.Params().EC(), ri)
cmt := commitments.NewHashCommitment(pointRi.X(), pointRi.Y())
// pointRi := crypto.ScalarBaseMult(round.Params().EC(), ri)
riSc, err := new(edwards25519.Scalar).SetBytesWithClamping(reverse(ri.Bytes()))
if err != nil {
return round.WrapError(err)
}
pointRi := new(edwards25519.Point).ScalarBaseMult(riSc)
x, y, z, t := pointRi.ExtendedCoordinates()
bzs := [][]byte{x.Bytes(), y.Bytes(), z.Bytes(), t.Bytes()}
cmt := commitments.NewHashCommitment(common.ByteSlicesToBigInts(bzs)...)
// 3. store r1 message pieces
round.temp.ri = ri
round.temp.pointRi = pointRi
// round.temp.ri = new(big.Int).SetBytes(reverse(riSc.Bytes()))
if round.temp.pointRi, err = crypto.NewECPoint(
round.EC(),
encoded32BytesToBigInt(new(field.Element).Multiply(x, z).Bytes()),
encoded32BytesToBigInt(new(field.Element).Multiply(y, z).Bytes())); err != nil {
return round.WrapError(err)
}
// round.temp.pointRi = crypto.ScalarBaseMult(round.EC(), round.temp.ri)
round.temp.deCommit = cmt.D
i := round.PartyID().Index

View File

@@ -8,10 +8,12 @@ package signing
import (
"crypto/sha512"
"fmt"
"math/big"
"strings"
"github.com/agl/ed25519/edwards25519"
"filippo.io/edwards25519"
"filippo.io/edwards25519/field"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/decred/dcrd/dcrec/edwards/v2"
@@ -32,17 +34,21 @@ func (round *round3) Start() *tss.Error {
round.resetOK()
// 1. init R
var Redwards edwards25519.ExtendedGroupElement
Redwards := new(edwards25519.Point) // extended group element
var Rsecp256k1 *crypto.ECPoint
var riBytes *[32]byte
_, isTwistedEdwardsCurve := round.Params().EC().(*edwards.TwistedEdwardsCurve)
isSecp256k1Curve := strings.Compare("secp256k1", round.Params().EC().Params().Name) == 0
var riBytes []byte
_, isTwistedEdwardsCurve := round.EC().(*edwards.TwistedEdwardsCurve)
isSecp256k1Curve := strings.Compare("secp256k1", round.EC().Params().Name) == 0
if isTwistedEdwardsCurve {
riBytes = bigIntToEncodedBytes(round.temp.ri)
edwards25519.GeScalarMultBase(&Redwards, riBytes)
riBytes = bigIntToEncodedBytes32(round.temp.ri)
sc, err := new(edwards25519.Scalar).SetBytesWithClamping(riBytes)
if err != nil {
return round.WrapError(err)
}
Redwards = Redwards.ScalarBaseMult(sc)
} else if isSecp256k1Curve {
Rsecp256k1 = crypto.ScalarBaseMult(round.Params().EC(), round.temp.ri)
Rsecp256k1 = crypto.ScalarBaseMult(round.EC(), round.temp.ri)
}
// 2-6. compute R
@@ -55,19 +61,22 @@ func (round *round3) Start() *tss.Error {
msg := round.temp.signRound2Messages[j]
r2msg := msg.Content().(*SignRound2Message)
cmtDeCmt := commitments.HashCommitDecommit{C: round.temp.cjs[j], D: r2msg.UnmarshalDeCommitment()}
ok, coordinates := cmtDeCmt.DeCommit()
ok, _ := cmtDeCmt.DeCommit()
if !ok {
return round.WrapError(errors.New("de-commitment verify failed"))
}
if len(coordinates) != 2 {
return round.WrapError(errors.New("length of de-commitment should be 2"))
// the first element is the randomness param; discard it
coordinates := r2msg.GetDeCommitment()
if len(coordinates) != 5 {
return round.WrapError(fmt.Errorf("length of de-commitment should be 4 but was %d", len(coordinates) - 1))
}
coordinates = coordinates[1:]
Rj, err := crypto.NewECPoint(round.Params().EC(), coordinates[0], coordinates[1])
Rj, err := crypto.NewECPoint(round.EC(), encoded32BytesToBigInt(coordinates[0]), encoded32BytesToBigInt(coordinates[1]))
if err != nil {
return round.WrapError(errors.Wrapf(err, "NewECPoint(Rj)"), Pj)
}
proof, err := r2msg.UnmarshalZKProof(round.Params().EC())
proof, err := r2msg.UnmarshalZKProof(round.EC())
if err != nil {
return round.WrapError(errors.New("failed to unmarshal Rj proof"), Pj)
}
@@ -77,8 +86,25 @@ func (round *round3) Start() *tss.Error {
}
if isTwistedEdwardsCurve {
extendedRj := ecPointToExtendedElement(round.Params().EC(), Rj.X(), Rj.Y())
Redwards = addExtendedElements(Redwards, extendedRj)
var err2 error
var x, y, z, t *field.Element
if x, err2 = new(field.Element).SetBytes(coordinates[0]); err2 != nil {
return round.WrapError(err2)
}
if y, err2 = new(field.Element).SetBytes(coordinates[1]); err2 != nil {
return round.WrapError(err2)
}
if z, err2 = new(field.Element).SetBytes(coordinates[2]); err2 != nil {
return round.WrapError(err2)
}
if t, err2 = new(field.Element).SetBytes(coordinates[3]); err2 != nil {
return round.WrapError(err2)
}
extendedRj, err2 := new(edwards25519.Point).SetExtendedCoordinates(x, y, z, t)
if err2 != nil {
return round.WrapError(errors.Wrapf(err2, "1"), Pj)
}
Redwards = new(edwards25519.Point).Add(Redwards, extendedRj)
} else if isSecp256k1Curve {
Rsecp256k1, err = Rsecp256k1.Add(Rj)
if err != nil {
@@ -87,43 +113,48 @@ func (round *round3) Start() *tss.Error {
}
}
var encodedR [32]byte
var encodedPubKey *[32]byte
encodedR := make([]byte, 32)
var encodedPubKey []byte
if isTwistedEdwardsCurve {
Redwards.ToBytes(&encodedR)
encodedPubKey = ecPointToEncodedBytes(round.key.EDDSAPub.X(), round.key.EDDSAPub.Y())
var err error
encodedR = Redwards.Bytes()
if encodedPubKey, err = ecPointToEncodedBytes32(round.key.EDDSAPub.X()); err != nil {
return round.WrapError(err)
}
} else if isSecp256k1Curve {
s := new([32]byte)
s := make([]byte, 32)
round.key.EDDSAPub.X().FillBytes(s[:])
encodedPubKey = s
}
// 7. compute lambda
// h = hash512(k || A || M)
var lambda [64]byte
var 𝜆 *chainhash.Hash
var lambdaReduced [32]byte
var lambdaSc *edwards25519.Scalar
lambda := make([]byte, 0, 64)
if isTwistedEdwardsCurve {
h := sha512.New()
h.Reset()
h.Write(encodedR[:])
h.Write(encodedPubKey[:])
h.Write(round.temp.m.Bytes())
h.Sum(lambda[:0])
lambda = h.Sum(nil)
edwards25519.ScReduce(&lambdaReduced, &lambda)
var err error
if lambdaSc, err = new(edwards25519.Scalar).SetUniformBytes(lambda); err != nil {
return round.WrapError(err)
}
} else if isSecp256k1Curve {
// if R has an odd Y coordinate, we'll add to it until we find an R with even Y.
a := 0
G := crypto.ScalarBaseMult(round.Params().EC(), big.NewInt(1))
G := crypto.ScalarBaseMult(round.EC(), big.NewInt(1))
for ; OddY(Rsecp256k1); a++ { // Y cannot be odd in BIP340
Rsecp256k1, _ = Rsecp256k1.Add(G)
}
round.temp.a = a
//
encode32bytes(Rsecp256k1.X(), &encodedR)
Rsecp256k1.X().FillBytes(encodedR[:])
𝜆 = chainhash.TaggedHash(
[]byte("BIP0340/challenge"), encodedR[:], encodedPubKey[:], round.temp.m.Bytes(),
) // commitment
@@ -135,11 +166,19 @@ func (round *round3) Start() *tss.Error {
}
// 8. compute si
var localS [32]byte
var localS *edwards25519.Scalar
var si *big.Int
if isTwistedEdwardsCurve {
edwards25519.ScMulAdd(&localS, &lambdaReduced, bigIntToEncodedBytes(round.temp.wi), riBytes)
si = encodedBytesToBigInt(&localS)
var err error
var wiSc, riSc *edwards25519.Scalar
if wiSc, err = new(edwards25519.Scalar).SetCanonicalBytes(bigIntToEncodedBytes32(round.temp.wi)); err != nil {
return round.WrapError(err)
}
if riSc, err = new(edwards25519.Scalar).SetCanonicalBytes(riBytes); err != nil {
return round.WrapError(err)
}
localS = localS.MultiplyAdd(lambdaSc, wiSc, riSc)
si = encoded32BytesToBigInt(localS.Bytes())
} else if isSecp256k1Curve {
𝜆wi := big.NewInt(0).Mul(big.NewInt(0).SetBytes(𝜆.CloneBytes()), round.temp.wi)
si = big.NewInt(0).Add(round.temp.ri, 𝜆wi)
@@ -148,7 +187,7 @@ func (round *round3) Start() *tss.Error {
// 9. store r3 message pieces
round.temp.si = *si
if isTwistedEdwardsCurve {
round.temp.r = encodedBytesToBigInt(&encodedR)
round.temp.r = encoded32BytesToBigInt(encodedR)
} else if isSecp256k1Curve {
round.temp.r = Rsecp256k1.X()
}

View File

@@ -12,7 +12,8 @@ import (
"fmt"
"math/big"
"github.com/agl/ed25519/edwards25519"
"filippo.io/edwards25519"
"filippo.io/edwards25519/field"
"github.com/binance-chain/tss-lib/common"
"github.com/binance-chain/tss-lib/crypto"
"github.com/btcsuite/btcd/btcec/v2"
@@ -21,44 +22,45 @@ import (
"github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr"
)
func encodedBytesToBigInt(s *[32]byte) *big.Int {
// Use a copy so we don't screw up our original
// memory.
sCopy := new([32]byte)
for i := 0; i < 32; i++ {
sCopy[i] = s[i]
func encoded32BytesToBigInt(s []byte) *big.Int {
if len(s) > 32 {
panic(fmt.Errorf("encoded32BytesToBigInt expected <= 32 bytes but got %d", len(s)))
}
sCopy := make([]byte, 0, 32)
copy(sCopy, s)
reverse(sCopy)
bi := new(big.Int).SetBytes(sCopy[:])
return bi
return new(big.Int).SetBytes(sCopy)
}
func bigIntToEncodedBytes(a *big.Int) *[32]byte {
s := new([32]byte)
if a == nil {
return s
func bigIntToEncodedBytes32(a *big.Int) []byte {
if len(a.Bytes()) > 32 {
panic(fmt.Errorf("bigIntToEncodedBytes32 expected <= 32 bytes but got %d", len(a.Bytes())))
}
// Caveat: a can be longer than 32 bytes.
s = copyBytes(a.Bytes())
// Reverse the byte string --> little endian after
// encoding.
reverse(s)
return s
var s []byte
if a == nil {
panic("a == nil in bigIntToEncodedBytes32")
}
s = copyBytes32(a.Bytes())
// reverse to become little endian
return reverse(s)
}
func copyBytes(aB []byte) *[32]byte {
func ecPointToEncodedBytes32(x *big.Int) ([]byte, error) {
var err error
fe := new(field.Element)
xB := bigIntToEncodedBytes32(x)
if fe, err = fe.SetBytes(xB); err != nil {
return nil, err
}
return fe.Bytes(), nil
}
func copyBytes32(aB []byte) []byte {
if aB == nil {
return nil
}
s := new([32]byte)
// If we have a short byte string, expand
// it so that it's long enough.
s := make([]byte, 32)
// if short, expand it so that it's long enough
aBLen := len(aB)
if aBLen < 32 {
diff := 32 - aBLen
@@ -66,71 +68,21 @@ func copyBytes(aB []byte) *[32]byte {
aB = append([]byte{0x00}, aB...)
}
}
for i := 0; i < 32; i++ {
s[i] = aB[i]
}
return s
}
func ecPointToEncodedBytes(x *big.Int, y *big.Int) *[32]byte {
s := bigIntToEncodedBytes(y)
xB := bigIntToEncodedBytes(x)
xFE := new(edwards25519.FieldElement)
edwards25519.FeFromBytes(xFE, xB)
isNegative := edwards25519.FeIsNegative(xFE) == 1
if isNegative {
s[31] |= (1 << 7)
} else {
s[31] &^= (1 << 7)
}
return s
}
func reverse(s *[32]byte) {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
}
func addExtendedElements(p, q edwards25519.ExtendedGroupElement) edwards25519.ExtendedGroupElement {
var r edwards25519.CompletedGroupElement
var qCached edwards25519.CachedGroupElement
q.ToCached(&qCached)
edwards25519.GeAdd(&r, &p, &qCached)
var result edwards25519.ExtendedGroupElement
r.ToExtended(&result)
return result
}
func ecPointToExtendedElement(ec elliptic.Curve, x *big.Int, y *big.Int) edwards25519.ExtendedGroupElement {
encodedXBytes := bigIntToEncodedBytes(x)
encodedYBytes := bigIntToEncodedBytes(y)
z := common.GetRandomPositiveInt(ec.Params().N)
encodedZBytes := bigIntToEncodedBytes(z)
var fx, fy, fxy edwards25519.FieldElement
edwards25519.FeFromBytes(&fx, encodedXBytes)
edwards25519.FeFromBytes(&fy, encodedYBytes)
var X, Y, Z, T edwards25519.FieldElement
edwards25519.FeFromBytes(&Z, encodedZBytes)
edwards25519.FeMul(&X, &fx, &Z)
edwards25519.FeMul(&Y, &fy, &Z)
edwards25519.FeMul(&fxy, &fx, &fy)
edwards25519.FeMul(&T, &fxy, &Z)
return edwards25519.ExtendedGroupElement{
X: X,
Y: Y,
Z: Z,
T: T,
}
func addExtendedElements(p, q *edwards25519.Point) (*edwards25519.Point, error) {
new(edwards25519.Point).Add(p, q)
PX, PY, PZ, PT := p.ExtendedCoordinates()
QX, QY, QZ, QT := q.ExtendedCoordinates()
return new(edwards25519.Point).SetExtendedCoordinates(
new(field.Element).Add(PX, QX),
new(field.Element).Add(PY, QY),
new(field.Element).Add(PZ, QZ),
new(field.Element).Add(PT, QT))
}
func OddY(a *crypto.ECPoint) bool {
@@ -287,26 +239,6 @@ func JacobianPointToString(point secp256k1.JacobianPoint) string {
return "[X:" + point.X.String() + ", Y:" + point.Y.String() + ", Z:" + point.Z.String() + "]"
}
func ParsePubKey(pubKeyStr []byte) (*btcec.PublicKey, error) {
if pubKeyStr == nil {
err := fmt.Errorf("nil pubkey byte string")
return nil, err
}
if len(pubKeyStr) != 32 {
err := fmt.Errorf("bad pubkey byte string size (want %v, have %v)",
32, len(pubKeyStr))
return nil, err
}
// We'll manually prepend the compressed byte so we can re-use the
// existing pubkey parsing routine of the main btcec package.
var keyCompressed [btcec.PubKeyBytesLenCompressed]byte
keyCompressed[0] = secp256k1.PubKeyFormatCompressedEven
copy(keyCompressed[1:], pubKeyStr)
return btcec.ParsePubKey(keyCompressed[:])
}
func RSBytesToBtcec(r_ []byte, s_ []byte) (btcec.FieldVal, btcec.ModNScalar) {
var r btcec.FieldVal
var s btcec.ModNScalar
@@ -342,3 +274,10 @@ func NextPointEvenY(curve elliptic.Curve, P *crypto.ECPoint) (*crypto.ECPoint, i
}
return Qptr, a
}
func reverse(s []byte) []byte {
for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
s[i], s[j] = s[j], s[i]
}
return s
}

7
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/binance-chain/tss-lib
go 1.17
require (
github.com/agl/ed25519 v0.0.0-20200305024217-f36fc4b53d43
filippo.io/edwards25519 v1.0.0-rc.1
github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c
github.com/btcsuite/btcd/btcec/v2 v2.0.0
github.com/btcsuite/btcutil v1.0.3-0.20211129182920-9c4bbabe7acd
@@ -22,6 +22,7 @@ require (
)
require (
github.com/agl/ed25519 v0.0.0-20200305024217-f36fc4b53d43 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@@ -42,6 +43,6 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
replace github.com/agl/ed25519 => github.com/binance-chain/edwards25519 v0.0.0-20200305024217-f36fc4b53d43
replace github.com/btcsuite/btcd => github.com/Roasbeef/btcd v0.0.0-20220128222530-5a59e7c0ddfb
replace github.com/agl/ed25519 => github.com/binance-chain/edwards25519 v0.0.0-20200305024217-f36fc4b53d43

2
go.sum
View File

@@ -1,3 +1,5 @@
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Roasbeef/btcd v0.0.0-20220128222530-5a59e7c0ddfb h1:iiJ9fLbB/sG4MGNAOAi6DoezeasH2+Hnv/HN4lMMeu8=
github.com/Roasbeef/btcd v0.0.0-20220128222530-5a59e7c0ddfb/go.mod h1:vkwesBkYQtKXFYQYi9PyahtopbX53Tvk/O/qp2WI6Gk=