Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: configurable ecdsa curve and support secp256k1 #45

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 62 additions & 27 deletions mpc/binance/ecdsa/mpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ import (
"time"

"github.com/bnb-chain/tss-lib/v2/tss"
"github.com/btcsuite/btcd/btcec/v2"
s256k1 "github.com/btcsuite/btcd/btcec/v2"
btcecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa"
"github.com/decred/dcrd/dcrec/secp256k1/v4"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"
)
Expand Down Expand Up @@ -109,45 +113,76 @@ func (parties parties) Mapping() map[string]*tss.PartyID {
}

func TestTSS(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add another test which initializes it with secp256k1.

Perhaps add a loop that iterates over both curve options?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a loop to iterate over the curves

pA := NewParty(1, elliptic.P256(), logger("pA", t.Name()))
pB := NewParty(2, elliptic.P256(), logger("pB", t.Name()))
pC := NewParty(3, elliptic.P256(), logger("pC", t.Name()))
curves := []elliptic.Curve{
elliptic.P256(),
s256k1.S256(),
}

for _, tc := range curves {
t.Run(tc.Params().Name, func(t *testing.T) {
pA := NewParty(1, tc, logger("pA", t.Name()))
pB := NewParty(2, tc, logger("pB", t.Name()))
pC := NewParty(3, tc, logger("pC", t.Name()))

t.Logf("Created parties")

t.Logf("Created parties")
parties := parties{pA, pB, pC}
parties.init(senders(parties))

parties := parties{pA, pB, pC}
parties.init(senders(parties))
t.Logf("Running DKG")

t.Logf("Running DKG")
t1 := time.Now()
shares, err := parties.keygen()
assert.NoError(t, err)
t.Logf("DKG elapsed %s", time.Since(t1))

t1 := time.Now()
shares, err := parties.keygen()
assert.NoError(t, err)
t.Logf("DKG elapsed %s", time.Since(t1))
parties.init(senders(parties))

parties.init(senders(parties))
parties.setShareData(shares)
t.Logf("Signing")

parties.setShareData(shares)
t.Logf("Signing")
msgToSign := []byte("bla bla")

msgToSign := []byte("bla bla")
t.Logf("Signing message")
t1 = time.Now()
sigs, err := parties.sign(digest(msgToSign))
assert.NoError(t, err)
t.Logf("Signing completed in %v", time.Since(t1))

sigSet := make(map[string]struct{})
for _, s := range sigs {
sigSet[string(s)] = struct{}{}
}
assert.Len(t, sigSet, 1)

t.Logf("Signing message")
t1 = time.Now()
sigs, err := parties.sign(digest(msgToSign))
assert.NoError(t, err)
t.Logf("Signing completed in %v", time.Since(t1))
pk, err := parties[0].TPubKey()
assert.NoError(t, err)

sigSet := make(map[string]struct{})
for _, s := range sigs {
sigSet[string(s)] = struct{}{}
assert.True(t, verifySignature(tc.Params().Name, pk, msgToSign, sigs[0]))
})
}
assert.Len(t, sigSet, 1)
}

func verifySignature(curveName string, pk *ecdsa.PublicKey, msg []byte, sig []byte) bool {
switch curveName {
case elliptic.P256().Params().Name:
return ecdsa.VerifyASN1(pk, digest(msg), sig)
case s256k1.S256().Params().Name:
// convert pk to s256k1.PublicKey
xFieldVal, yFieldVal := new(secp256k1.FieldVal), new(secp256k1.FieldVal)
xFieldVal.SetByteSlice(pk.X.Bytes())
yFieldVal.SetByteSlice(pk.Y.Bytes())
btcecPubKey := btcec.NewPublicKey(xFieldVal, yFieldVal)

signature, err := btcecdsa.ParseDERSignature(sig)
if err != nil {
return false
}

pk, err := parties[0].TPubKey()
assert.NoError(t, err)
return signature.Verify(digest(msg), btcecPubKey)
}

assert.True(t, ecdsa.VerifyASN1(pk, digest(msgToSign), sigs[0]))
return false
}

func senders(parties parties) []Sender {
Expand Down
70 changes: 53 additions & 17 deletions test/binance/ecdsa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,40 +7,57 @@ import (
"testing"

ecdsa_scheme "github.com/IBM/TSS/mpc/binance/ecdsa"

. "github.com/IBM/TSS/types"
s256k1 "github.com/btcsuite/btcd/btcec/v2"
btcecdsa "github.com/btcsuite/btcd/btcec/v2/ecdsa"

"github.com/stretchr/testify/assert"
)

func TestThresholdBinanceECDSA(t *testing.T) {
n := 4
curves := []elliptic.Curve{
elliptic.P256(),
s256k1.S256(),
}

var verifySig signatureVerifyFunc
for _, curve := range curves {
t.Run(curve.Params().Name, func(t *testing.T) {
n := 4

var signatureAlgorithms func([]*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer)
var verifySig signatureVerifyFunc
var signatureAlgorithms func([]*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer)

verifySig = verifySignatureECDSA
signatureAlgorithms = func(loggers []*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer) {
return ecdsaKeygenAndSign(elliptic.P256(), loggers)
}
verifySig = getVerifySignature(curve)
signatureAlgorithms = func(loggers []*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer) {
return ecdsaKeygenAndSign(curve, loggers)
}

testScheme(t, n, signatureAlgorithms, verifySig, false)
testScheme(t, n, signatureAlgorithms, verifySig, false)
})
}
}

func TestFastThresholdBinanceECDSA(t *testing.T) {
n := 4
curves := []elliptic.Curve{
elliptic.P256(),
s256k1.S256(),
}

var verifySig signatureVerifyFunc
for _, curve := range curves {
t.Run(curve.Params().Name, func(t *testing.T) {
n := 4

var signatureAlgorithms func([]*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer)
var verifySig signatureVerifyFunc
var signatureAlgorithms func([]*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer)

verifySig = verifySignatureECDSA
signatureAlgorithms = func(loggers []*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer) {
return ecdsaKeygenAndSign(elliptic.P256(), loggers)
}
verifySig = getVerifySignature(curve)
signatureAlgorithms = func(loggers []*commLogger) (func(uint16) KeyGenerator, func(uint16) Signer) {
return ecdsaKeygenAndSign(curve, loggers)
}

testScheme(t, n, signatureAlgorithms, verifySig, true)
testScheme(t, n, signatureAlgorithms, verifySig, true)
})
}
}

func ecdsaKeygenAndSign(curve elliptic.Curve, loggers []*commLogger) (func(id uint16) KeyGenerator, func(id uint16) Signer) {
Expand All @@ -54,6 +71,25 @@ func ecdsaKeygenAndSign(curve elliptic.Curve, loggers []*commLogger) (func(id ui
return kgf, sf
}

func getVerifySignature(curve elliptic.Curve) func(pkBytes []byte, t *testing.T, msg string, signature []byte) {
switch curve.Params().Name {
case s256k1.S256().Params().Name:
return verifySignatureSecp256k1
default:
return verifySignatureECDSA
}
}

func verifySignatureSecp256k1(pkBytes []byte, t *testing.T, msg string, signature []byte) {
pk, err := s256k1.ParsePubKey(pkBytes)
assert.NoError(t, err)

sig, err := btcecdsa.ParseDERSignature(signature)
assert.NoError(t, err)

assert.True(t, sig.Verify(sha256Digest([]byte(msg)), pk))
}

func verifySignatureECDSA(pkBytes []byte, t *testing.T, msg string, signature []byte) {
pk, err := x509.ParsePKIXPublicKey(pkBytes)
assert.NoError(t, err)
Expand Down
2 changes: 2 additions & 0 deletions test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/IBM/TSS/mpc/binance/ecdsa => ../mpc/binance/ecdsa
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, let's not do this.

You can make a change to the mpc/binance/ecdsa package in this PR, and then wait for this PR to be merged, and then make a new PR that would just take the latest version into the go.mod of the test module.


replace github.com/IBM/TSS/mpc/bls => ../mpc/bls

replace github.com/agl/ed25519 => github.com/binance-chain/edwards25519 v0.0.0-20200305024217-f36fc4b53d43
Expand Down