diff --git a/test/go.mod b/test/go.mod index d668d35..f76a5cf 100644 --- a/test/go.mod +++ b/test/go.mod @@ -8,6 +8,7 @@ require ( github.com/IBM/TSS/mpc/bls v0.0.0-20230831100430-0b667a5e3f1c github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.24.0 + gonum.org/v1/gonum v0.14.0 ) require ( diff --git a/test/go.sum b/test/go.sum index 4c2ad11..d50cc54 100644 --- a/test/go.sum +++ b/test/go.sum @@ -2,12 +2,8 @@ bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U= bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= github.com/IBM/TSS v0.0.0-20230829210007-7d14382e6520 h1:yNUHLKPCUy3r8jTtHgL1XLI/Ls9p9pqPyufgn2u/Nxk= github.com/IBM/TSS v0.0.0-20230829210007-7d14382e6520/go.mod h1:wGdNkjuFEVFx96kkq8at32/6jx4mxK/v1Uuv2NXL6KE= -github.com/IBM/TSS/mpc/binance/ecdsa v0.0.0-20230829113924-1fdc6af426a6 h1:fsBM5FsNnqD2dLuYy6M18dhNvTtHGeaa708vetJp8N0= -github.com/IBM/TSS/mpc/binance/ecdsa v0.0.0-20230829113924-1fdc6af426a6/go.mod h1:x1sVGyOg5o3WKA2zXE3U9xFL118sv34UkR1iLko/Sxw= github.com/IBM/TSS/mpc/binance/ecdsa v0.0.0-20230831100430-0b667a5e3f1c h1:50RbYqPzlfz4b6VBSpDRTKAXr7W4iOUCYlJVG3xu8Z4= github.com/IBM/TSS/mpc/binance/ecdsa v0.0.0-20230831100430-0b667a5e3f1c/go.mod h1:x1sVGyOg5o3WKA2zXE3U9xFL118sv34UkR1iLko/Sxw= -github.com/IBM/TSS/mpc/binance/eddsa v0.0.0-20230829113924-1fdc6af426a6 h1:O7IajpefjgELGC9a5ngZJsd91dvx86DWbg4vFLgBxds= -github.com/IBM/TSS/mpc/binance/eddsa v0.0.0-20230829113924-1fdc6af426a6/go.mod h1:52sjVGVEFhbZZCMNIggMmgiYdntup7KCguOcJ3E1xS4= github.com/IBM/TSS/mpc/binance/eddsa v0.0.0-20230831100430-0b667a5e3f1c h1:s/MhAuV9WWxfOE6b6hpXN+iIMBTskfH1Rt6voRElV7I= github.com/IBM/TSS/mpc/binance/eddsa v0.0.0-20230831100430-0b667a5e3f1c/go.mod h1:52sjVGVEFhbZZCMNIggMmgiYdntup7KCguOcJ3E1xS4= github.com/IBM/mathlib v0.0.3-0.20230822192135-eacb031f2534 h1:czEcwFbFXczHL8gGyMb6zzL40vyVcrB2vuHR/eWGgUo= @@ -72,8 +68,8 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -184,7 +180,7 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -193,8 +189,9 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0= +gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= diff --git a/test/tbls/tbls_test.go b/test/tbls/tbls_test.go index a55f37f..a241c37 100644 --- a/test/tbls/tbls_test.go +++ b/test/tbls/tbls_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/zap" "go.uber.org/zap/zapcore" + "gonum.org/v1/gonum/stat/combin" ) func TestThresholdBLS(t *testing.T) { @@ -53,7 +54,7 @@ func TestThresholdBLS(t *testing.T) { } }() - shares, start := keygen(t, parties, n) + shares, start := keygen(t, parties, n, n-1) elapsed := time.Since(start) t.Log("DKG elapsed", elapsed) @@ -115,6 +116,123 @@ func TestThresholdBLS(t *testing.T) { } } +func TestThresholdBLSVarThreshold(t *testing.T) { + var tests = []struct { + n, threshold, k int + mustPass bool + }{ + //{3, 1, 2, true}, // it seems that t=1 is invalid?! + //{3, 2, 1, false}, + {3, 2, 2, true}, + {3, 2, 3, true}, + {5, 2, 2, true}, + {5, 2, 3, true}, + //{5, 3, 2, false}, + {5, 3, 3, true}, + //{5, 4, 3, false}, + {5, 4, 4, true}, + {5, 4, 5, true}, + {7, 5, 5, true}, + {15, 10, 11, true}, + //{31, 21, 22, true}, // fails - DKG timeout + } + + for _, tt := range tests { + testThresholdBLSVarThreshold(t, tt.n, tt.threshold, tt.k, tt.mustPass) + } +} + +func testThresholdBLSVarThreshold(t *testing.T, n, threshold, k int, mustPass bool) { + var commParties []*comm.Party + var signers []*tlsgen.CertKeyPair + var loggers []*commLogger + var listeners []net.Listener + var stopFuncs []func() + + members, certPool, loggers, signers, listeners, commParties, membershipFunc, parties, kgf := setup(t, n, loggers, signers, listeners, commParties) + + for id := 1; id <= n; id++ { + stop, s := createParty(id, kgf, signers[id-1], n, certPool, listeners, loggers, commParties, membershipFunc) + parties = append(parties, s) + stopFuncs = append(stopFuncs, stop) + } + + defer func() { + for _, stop := range stopFuncs { + stop() + } + }() + + shares, start := keygen(t, parties, n, threshold) + + elapsed := time.Since(start) + t.Log("DKG elapsed", elapsed) + + // Create the threshold signers. + thresholdSigners := make([]*bls.TBLS, n) + for id := 1; id <= n; id++ { + thresholdSigners[id-1] = &bls.TBLS{ + Logger: logger(id, t.Name()), + Party: uint16(id), + } + } + + // Initialize them with a nil send function + for i, signer := range thresholdSigners { + signer.Init(members, threshold, nil) + signer.SetShareData(shares[i]) + } + + var signatures [][]byte + + // Sign a message + msg := []byte("Three can keep a secret, if two of them are dead.") + digest := sha256Digest(msg) + for _, signer := range thresholdSigners { + sig, err := signer.Sign(nil, digest) + assert.NoError(t, err) + signatures = append(signatures, sig) + } + + // check that all signers return the same pk?! + var pk []byte + for _, signer := range thresholdSigners { + pki, err := signer.ThresholdPK() + assert.NoError(t, err) + if pk == nil { + pk = pki + } else { + assert.Equal(t, pk, pki) + } + } + + // create a verifier + var v bls.Verifier + err := v.Init(pk) + assert.NoError(t, err) + + var sig []byte + for _, p := range combin.Combinations(k, threshold) { + var sigs [][]byte + var partyIDs []uint16 + + for _, i := range p { + sigs = append(sigs, signatures[i]) + partyIDs = append(partyIDs, uint16(i+1)) + } + + sig, err = v.AggregateSignatures(sigs, partyIDs) + assert.NoError(t, err) + } + + err = v.Verify(digest, sig) + if mustPass { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } +} + func TestBenchmark(t *testing.T) { var commParties []*comm.Party var signers []*tlsgen.CertKeyPair @@ -138,7 +256,7 @@ func TestBenchmark(t *testing.T) { } }() - shares, start := keygen(t, parties, n) + shares, start := keygen(t, parties, n, n-1) elapsed := time.Since(start) t.Log("DKG elapsed", elapsed) @@ -264,7 +382,7 @@ func BenchmarkParallelInvocation(b *testing.B) { } }() - shares, start := keygen(b, parties, n) + shares, start := keygen(b, parties, n, n-1) elapsed := time.Since(start) b.Log("DKG elapsed", elapsed) @@ -351,7 +469,7 @@ func BenchmarkParallelInvocation(b *testing.B) { var gsig []byte var gerr error -func keygen(t TestingT, parties []MpcParty, n int) ([][]byte, time.Time) { +func keygen(t TestingT, parties []MpcParty, n int, threshold int) ([][]byte, time.Time) { var wg sync.WaitGroup wg.Add(len(parties)) @@ -362,7 +480,7 @@ func keygen(t TestingT, parties []MpcParty, n int) ([][]byte, time.Time) { for i, p := range parties { go func(i int, p MpcParty) { defer wg.Done() - secretShareData, err := p.KeyGen(ctx, len(parties), n-1) + secretShareData, err := p.KeyGen(ctx, len(parties), threshold) shares[i] = secretShareData assert.NoError(t, err) assert.NotNil(t, secretShareData)