From 5d38f4aa36a04092a9d2141b97c62f75961a616f Mon Sep 17 00:00:00 2001 From: zhdllwyc Date: Tue, 30 Aug 2022 00:40:55 -0500 Subject: [PATCH] ecdsa dkls --- tss/ecdsa/dkls/ecdsaDKLS.go | 73 +++++++ .../ecdsaDKLSParty.go} | 17 +- .../ecdsaDKLS_test.go} | 188 ++++++++++++------ .../ecdsalocalDKLS.go} | 31 ++- tss/ecdsa/{ot => dkls}/fmul/fmulLocal.go | 8 + tss/ecdsa/{ot => dkls}/fmul/fmulParty.go | 0 tss/ecdsa/{ot => dkls}/fmul/fmul_test.go | 8 - tss/ecdsa/ot/ecdsaTSSOT.go | 136 ------------- 8 files changed, 228 insertions(+), 233 deletions(-) create mode 100644 tss/ecdsa/dkls/ecdsaDKLS.go rename tss/ecdsa/{ot/ecdsaTSSOTParty.go => dkls/ecdsaDKLSParty.go} (83%) rename tss/ecdsa/{ot/ecdsaTSSOT_test.go => dkls/ecdsaDKLS_test.go} (51%) rename tss/ecdsa/{ot/ecdsaLocalTSSOT.go => dkls/ecdsalocalDKLS.go} (96%) rename tss/ecdsa/{ot => dkls}/fmul/fmulLocal.go (96%) rename tss/ecdsa/{ot => dkls}/fmul/fmulParty.go (100%) rename tss/ecdsa/{ot => dkls}/fmul/fmul_test.go (95%) delete mode 100644 tss/ecdsa/ot/ecdsaTSSOT.go diff --git a/tss/ecdsa/dkls/ecdsaDKLS.go b/tss/ecdsa/dkls/ecdsaDKLS.go new file mode 100644 index 000000000..3a923fddb --- /dev/null +++ b/tss/ecdsa/dkls/ecdsaDKLS.go @@ -0,0 +1,73 @@ +// Reference: https://eprint.iacr.org/2018/499.pdf +// 2 out of 2 party threhsold signature scheme +// Figure 1 and Protocol 1 and 2 + +package dkls + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "errors" + "math/big" + + "github.com/cloudflare/circl/group" +) + +// Input: myGroup, the group we operate in +// Input: sk, the real secret key +// Output: share1, share2 the multiplicative secret key shares for 2 parties. +func KeyShareGen(myGroup group.Group, sk group.Scalar) (group.Scalar, group.Scalar) { + share1 := myGroup.RandomNonZeroScalar(rand.Reader) + share1Inv := myGroup.NewScalar() + share1Inv.Inv(share1) + + share2 := myGroup.NewScalar() + share2.Mul(share1Inv, sk) + + return share1, share2 +} + +func hashToInt(hash []byte, c elliptic.Curve) *big.Int { + orderBits := c.Params().N.BitLen() + orderBytes := (orderBits + 7) / 8 + + if len(hash) > orderBytes { + hash = hash[:orderBytes] + } + + ret := new(big.Int).SetBytes(hash) + excess := len(hash)*8 - orderBits + if excess > 0 { + ret.Rsh(ret, uint(excess)) + } + return ret +} + +// ECDSA threshold signature verification +// Input: (r,s), the signature +// Input: hashMSG, the message +// Input: publicKey, the ECDSA public key +// Output: verification passed or not +func Verify(r, s group.Scalar, hashMSG []byte, publicKey *ecdsa.PublicKey) error { + rBig := new(big.Int) + sBig := new(big.Int) + + rByte, errByte := r.MarshalBinary() + if errByte != nil { + panic(errByte) + } + rBig.SetBytes(rByte) + + sByte, errByte := s.MarshalBinary() + if errByte != nil { + panic(errByte) + } + sBig.SetBytes(sByte) + + verify := ecdsa.Verify(publicKey, hashMSG, rBig, sBig) + if !verify { + return errors.New("ECDSA threshold verification failed") + } + return nil +} diff --git a/tss/ecdsa/ot/ecdsaTSSOTParty.go b/tss/ecdsa/dkls/ecdsaDKLSParty.go similarity index 83% rename from tss/ecdsa/ot/ecdsaTSSOTParty.go rename to tss/ecdsa/dkls/ecdsaDKLSParty.go index 30f11d982..600fe183e 100644 --- a/tss/ecdsa/ot/ecdsaTSSOTParty.go +++ b/tss/ecdsa/dkls/ecdsaDKLSParty.go @@ -1,8 +1,8 @@ -package ECDSAOT +package dkls import ( "github.com/cloudflare/circl/group" - "github.com/cloudflare/circl/tss/ecdsa/ot/Fmul" + "github.com/cloudflare/circl/tss/ecdsa/dkls/fmul" ) // The sender of Fmul @@ -18,10 +18,10 @@ type AlicePre struct { a group.Scalar // A random blinding for beaver's triple ta group.Scalar // Additive share of a*b - receivera Fmul.ReceiverFmul // Receiver of Fmul for a*b + receivera fmul.ReceiverFmul // Receiver of Fmul for a*b tkA group.Scalar // Additive share of 1/kA*1/kB - receiverkAInv Fmul.ReceiverFmul // Receiver of Fmul for 1/kA*1/kB + receiverkAInv fmul.ReceiverFmul // Receiver of Fmul for 1/kA*1/kB myGroup group.Group // The elliptic curve we operate in } @@ -37,10 +37,10 @@ type BobPre struct { b group.Scalar // A random blinding for beaver's triple tb group.Scalar // Additive share of a*b - senderb Fmul.SenderFmul // Sender of Fmul for a*b + senderb fmul.SenderFmul // Sender of Fmul for a*b tkB group.Scalar // Additive share of 1/kA*1/kB - senderkBInv Fmul.SenderFmul // Sender of Fmul for 1/kA*1/kB + senderkBInv fmul.SenderFmul // Sender of Fmul for 1/kA*1/kB myGroup group.Group // The elliptic curve we operate in } @@ -53,7 +53,7 @@ type Alice struct { ta group.Scalar // Additive share of a*b tkA group.Scalar // Additive share of 1/kA*1/kB Rx group.Scalar // x coordinate of point [kA][kB]G - beaver group.Scalar //skA/(kA*a) + beaver group.Scalar // skA/(kA*a) } type Bob struct { @@ -64,6 +64,5 @@ type Bob struct { tb group.Scalar // Additive share of a*b tkB group.Scalar // Additive share of 1/kA*1/kB Rx group.Scalar // x coordinate of point [kA][kB]G - beaver group.Scalar //skB/(kB*b) - + beaver group.Scalar // skB/(kB*b) } diff --git a/tss/ecdsa/ot/ecdsaTSSOT_test.go b/tss/ecdsa/dkls/ecdsaDKLS_test.go similarity index 51% rename from tss/ecdsa/ot/ecdsaTSSOT_test.go rename to tss/ecdsa/dkls/ecdsaDKLS_test.go index e89e18c31..0f3eda18d 100644 --- a/tss/ecdsa/ot/ecdsaTSSOT_test.go +++ b/tss/ecdsa/dkls/ecdsaDKLS_test.go @@ -1,4 +1,8 @@ -package ECDSAOT +// Reference: https://eprint.iacr.org/2018/499.pdf +// 2 out of 2 party threhsold signature scheme +// Figure 1 and Protocol 1 and 2 + +package dkls import ( "crypto/ecdsa" @@ -9,11 +13,10 @@ import ( "github.com/cloudflare/circl/group" ) -const TestECDSAOTCount = 10 +const testECDSAOTCount = 10 func genKey(myGroup group.Group, curve elliptic.Curve) (group.Scalar, *ecdsa.PublicKey) { privateKey, err := ecdsa.GenerateKey(curve, rand.Reader) - if err != nil { panic(err) } @@ -37,17 +40,80 @@ func genKey(myGroup group.Group, curve elliptic.Curve) (group.Scalar, *ecdsa.Pub return secretScalar, publicKey } +// Input: myGroup, the group we operate in +// Output: precomputation information for signature generation +func precomputation(myGroup group.Group, alice *AlicePre, bob *BobPre, Alice *Alice, Bob *Bob) error { + // Initialization + DB, bAs, kBInvAs := bob.BobInit(myGroup) + + // Round 1 + // bob sends DB, bAs, kBInvAs, to alice + V, r, RPrime, aBs, kAInvBs := alice.AliceRound1(myGroup, DB, bAs, kBInvAs, alice.label, bob.label) + + // Round 2 + // alice sends a proof (V, r) of she knows the kA for R=[kA]DB as well as R' to bob + // alice sends aBs, kAInvBs, to bob + e0b, e1b, e0kBInv, e1kBInv, err := bob.BobRound2(V, r, RPrime, aBs, kAInvBs, alice.label, bob.label) + if err != nil { + return err + } + + // Round 3 + // bob sends e0b, e1b, e0kBInv, e1kBInv, to alice + sigmaa, vsa, sigmakAInv, vskAInv, err := alice.AliceRound3(e0b, e1b, e0kBInv, e1kBInv) + if err != nil { + return err + } + + // Round 4 + // alice sends sigmaa, vsa, sigmakAInv, vskAInv to bob + bob.BobRound4(sigmaa, sigmakAInv, vsa, vskAInv) + + Alice.SetParamters(alice) + Bob.SetParamters(bob) + + return nil +} + +// Input: myGroup, the group we operate in +// Input: Alice and Bob +// Input: hash, the hash of the message we want to sign +// Input: curve, the curve we operate in +func sigGen(myGroup group.Group, Alice *Alice, Bob *Bob, hash []byte, curve elliptic.Curve) group.Scalar { + // Convert hash to scalar + hashBig := hashToInt(hash, curve) + hashByte := hashBig.Bytes() + + hashScalar := myGroup.NewScalar() + errByte := hashScalar.UnmarshalBinary(hashByte) + if errByte != nil { + panic(errByte) + } + beaverAlice := Alice.SigGenInit() + beaverBob := Bob.SigGenInit() + + // Round 1 + // Alice and Bob sends beaverAlice: skA/(kA*a), beaverBob: skB/(kB*b) to each other + sigAlice := Alice.SigGenRound1(beaverBob, hashScalar) + sigBob := Bob.SigGenRound1(beaverAlice, hashScalar) + + // Round 2 + // Either Alice or Bob can send the signature share to the other one and then combine + signature := SigGenRound2(myGroup, sigAlice, sigBob) + return signature +} + func testECDSAOT(t *testing.T, myGroup group.Group, curve elliptic.Curve) { - var Alice Alice - var Bob Bob + var AliceSign Alice + var BobSign Bob // Precomputation - var alice AlicePre - var bob BobPre + var alicePre AlicePre + var bobPre BobPre // Set alice and bob label - alice.label = []byte("alice") - bob.label = []byte("bob") - errPre := Precomputation(myGroup, &alice, &bob, &Alice, &Bob) + alicePre.label = []byte("alice") + bobPre.label = []byte("bob") + errPre := precomputation(myGroup, &alicePre, &bobPre, &AliceSign, &BobSign) if errPre != nil { t.Error("Precomputation fail") } @@ -55,15 +121,15 @@ func testECDSAOT(t *testing.T, myGroup group.Group, curve elliptic.Curve) { // Generate key shares (precomputation is separate from key shares) prvScalar, pub := genKey(myGroup, curve) share1, share2 := KeyShareGen(myGroup, prvScalar) - Alice.SetKeyShare(share1) - Bob.SetKeyShare(share2) + AliceSign.SetKeyShare(share1) + BobSign.SetKeyShare(share2) // Online signature generation hash := []byte("Cloudflare: meow meow") - signature := SigGen(myGroup, &Alice, &Bob, hash, curve) + signature := sigGen(myGroup, &AliceSign, &BobSign, hash, curve) // Verify the signature - errVerify := Verify(Alice.Rx, signature, hash, pub) + errVerify := Verify(AliceSign.Rx, signature, hash, pub) if errVerify != nil { t.Error("Signature verification fail") } @@ -71,7 +137,7 @@ func testECDSAOT(t *testing.T, myGroup group.Group, curve elliptic.Curve) { func TestECDSAOT(t *testing.T) { t.Run("ECDSAOT", func(t *testing.T) { - for i := 0; i < TestECDSAOTCount; i++ { + for i := 0; i < testECDSAOTCount; i++ { currGroup := group.P256 currCurve := elliptic.P256() testECDSAOT(t, currGroup, currCurve) @@ -80,101 +146,99 @@ func TestECDSAOT(t *testing.T) { } func benchECDSAOTPRE(b *testing.B, myGroup group.Group, curve elliptic.Curve) { - - var Alice Alice - var Bob Bob + var AliceSign Alice + var BobSign Bob // Precomputation - var alice AlicePre - var bob BobPre + var alicePre AlicePre + var bobPre BobPre // Set alice and bob label - alice.label = []byte("alice") - bob.label = []byte("bob") + alicePre.label = []byte("alice") + bobPre.label = []byte("bob") b.Run(curve.Params().Name+"-PreInit", func(b *testing.B) { for i := 0; i < b.N; i++ { - bob.BobInit(myGroup) + bobPre.BobInit(myGroup) } }) - DB, bAs, kBInvAs := bob.BobInit(myGroup) + DB, bAs, kBInvAs := bobPre.BobInit(myGroup) b.Run(curve.Params().Name+"-PreRound1", func(b *testing.B) { for i := 0; i < b.N; i++ { - alice.AliceRound1(myGroup, DB, bAs, kBInvAs, alice.label, bob.label) + alicePre.AliceRound1(myGroup, DB, bAs, kBInvAs, alicePre.label, bobPre.label) } }) - V, r, RPrime, aBs, kAInvBs := alice.AliceRound1(myGroup, DB, bAs, kBInvAs, alice.label, bob.label) + V, r, RPrime, aBs, kAInvBs := alicePre.AliceRound1(myGroup, DB, bAs, kBInvAs, alicePre.label, bobPre.label) b.Run(curve.Params().Name+"-PreRound2", func(b *testing.B) { for i := 0; i < b.N; i++ { - _, _, _, _, err := bob.BobRound2(V, r, RPrime, aBs, kAInvBs, alice.label, bob.label) + _, _, _, _, err := bobPre.BobRound2(V, r, RPrime, aBs, kAInvBs, alicePre.label, bobPre.label) if err != nil { b.Error("PreRound2 zk verification fail") } } }) - e0b, e1b, e0kBInv, e1kBInv, err := bob.BobRound2(V, r, RPrime, aBs, kAInvBs, alice.label, bob.label) + e0b, e1b, e0kBInv, e1kBInv, err := bobPre.BobRound2(V, r, RPrime, aBs, kAInvBs, alicePre.label, bobPre.label) if err != nil { b.Error("PreRound2 zk verification fail") } b.Run(curve.Params().Name+"-PreRound3", func(b *testing.B) { for i := 0; i < b.N; i++ { - _, _, _, _, err := alice.AliceRound3(e0b, e1b, e0kBInv, e1kBInv) + _, _, _, _, err = alicePre.AliceRound3(e0b, e1b, e0kBInv, e1kBInv) if err != nil { b.Error("PreRound3 decryption fail") } } }) - sigmaa, vsa, sigmakAInv, vskAInv, err := alice.AliceRound3(e0b, e1b, e0kBInv, e1kBInv) + sigmaa, vsa, sigmakAInv, vskAInv, err := alicePre.AliceRound3(e0b, e1b, e0kBInv, e1kBInv) if err != nil { b.Error("PreRound3 decryption fail") } b.Run(curve.Params().Name+"-PreRound4", func(b *testing.B) { for i := 0; i < b.N; i++ { - bob.BobRound4(sigmaa, sigmakAInv, vsa, vskAInv) + bobPre.BobRound4(sigmaa, sigmakAInv, vsa, vskAInv) } }) - bob.BobRound4(sigmaa, sigmakAInv, vsa, vskAInv) + bobPre.BobRound4(sigmaa, sigmakAInv, vsa, vskAInv) - Alice.SetParamters(&alice) - Bob.SetParamters(&bob) + AliceSign.SetParamters(&alicePre) + BobSign.SetParamters(&bobPre) // Generate key shares prvScalar, pub := genKey(myGroup, curve) share1, share2 := KeyShareGen(myGroup, prvScalar) - Alice.SetKeyShare(share1) - Bob.SetKeyShare(share2) + AliceSign.SetKeyShare(share1) + BobSign.SetKeyShare(share2) // Online signature generation hash := []byte("Cloudflare: meow meow") - signature := SigGen(myGroup, &Alice, &Bob, hash, curve) + signature := sigGen(myGroup, &AliceSign, &BobSign, hash, curve) // Verify the signature - errVerify := Verify(Alice.Rx, signature, hash, pub) + errVerify := Verify(AliceSign.Rx, signature, hash, pub) if errVerify != nil { b.Error("Signature verification fail") } - } func benchECDSAOTSign(b *testing.B, myGroup group.Group, curve elliptic.Curve) { - var Alice Alice - var Bob Bob + var AliceSign Alice + var BobSign Bob // Precomputation - var alice AlicePre - var bob BobPre + var alicePre AlicePre + var bobPre BobPre // Set alice and bob label - alice.label = []byte("alice") - bob.label = []byte("bob") - err := Precomputation(myGroup, &alice, &bob, &Alice, &Bob) + alicePre.label = []byte("alice") + bobPre.label = []byte("bob") + err := precomputation(myGroup, &alicePre, &bobPre, &AliceSign, &BobSign) if err != nil { b.Error("Precomputation fail") } @@ -182,8 +246,8 @@ func benchECDSAOTSign(b *testing.B, myGroup group.Group, curve elliptic.Curve) { // Generate key shares prvScalar, pub := genKey(myGroup, curve) share1, share2 := KeyShareGen(myGroup, prvScalar) - Alice.SetKeyShare(share1) - Bob.SetKeyShare(share2) + AliceSign.SetKeyShare(share1) + BobSign.SetKeyShare(share2) // Online signature generation hash := []byte("Cloudflare: meow meow") @@ -198,23 +262,23 @@ func benchECDSAOTSign(b *testing.B, myGroup group.Group, curve elliptic.Curve) { b.Run(curve.Params().Name+"-SignInit", func(b *testing.B) { for i := 0; i < b.N; i++ { - Alice.SigGenInit() - Bob.SigGenInit() + AliceSign.SigGenInit() + BobSign.SigGenInit() } }) - beaverAlice := Alice.SigGenInit() - beaverBob := Bob.SigGenInit() + beaverAlice := AliceSign.SigGenInit() + beaverBob := BobSign.SigGenInit() b.Run(curve.Params().Name+"-SignRound1", func(b *testing.B) { for i := 0; i < b.N; i++ { - Alice.SigGenRound1(beaverBob, hashScalar) - Bob.SigGenRound1(beaverAlice, hashScalar) + AliceSign.SigGenRound1(beaverBob, hashScalar) + BobSign.SigGenRound1(beaverAlice, hashScalar) } }) - sigAlice := Alice.SigGenRound1(beaverBob, hashScalar) - sigBob := Bob.SigGenRound1(beaverAlice, hashScalar) + sigAlice := AliceSign.SigGenRound1(beaverBob, hashScalar) + sigBob := BobSign.SigGenRound1(beaverAlice, hashScalar) b.Run(curve.Params().Name+"-SignRound2", func(b *testing.B) { for i := 0; i < b.N; i++ { @@ -225,22 +289,20 @@ func benchECDSAOTSign(b *testing.B, myGroup group.Group, curve elliptic.Curve) { signature := SigGenRound2(myGroup, sigAlice, sigBob) // Verify the signature - errVerify := Verify(Alice.Rx, signature, hash, pub) + errVerify := Verify(AliceSign.Rx, signature, hash, pub) if errVerify != nil { b.Error("Signature verification fail") } - } func BenchmarkECDSAOTPRE(b *testing.B) { pubkeyCurve := elliptic.P256() - curr_group := group.P256 - benchECDSAOTPRE(b, curr_group, pubkeyCurve) - + currGroup := group.P256 + benchECDSAOTPRE(b, currGroup, pubkeyCurve) } func BenchmarkECDSAOTSign(b *testing.B) { pubkeyCurve := elliptic.P256() - curr_group := group.P256 - benchECDSAOTSign(b, curr_group, pubkeyCurve) + currGroup := group.P256 + benchECDSAOTSign(b, currGroup, pubkeyCurve) } diff --git a/tss/ecdsa/ot/ecdsaLocalTSSOT.go b/tss/ecdsa/dkls/ecdsalocalDKLS.go similarity index 96% rename from tss/ecdsa/ot/ecdsaLocalTSSOT.go rename to tss/ecdsa/dkls/ecdsalocalDKLS.go index b5e8a2b3e..8dca6f9e0 100644 --- a/tss/ecdsa/ot/ecdsaLocalTSSOT.go +++ b/tss/ecdsa/dkls/ecdsalocalDKLS.go @@ -1,13 +1,12 @@ -package ECDSAOT +package dkls import ( "crypto/rand" "errors" - "github.com/cloudflare/circl/tss/ecdsa/ot/Fmul" - zkRDL "github.com/cloudflare/circl/zk/dl" - "github.com/cloudflare/circl/group" + "github.com/cloudflare/circl/tss/ecdsa/dkls/fmul" + zkRDL "github.com/cloudflare/circl/zk/dl" "golang.org/x/crypto/sha3" ) @@ -54,7 +53,6 @@ func (alice *AlicePre) AliceRound1(myGroup group.Group, DB group.Element, bAs, k // Input: aBs, kAInvBs for Fmul of a*b and 1/kA*1/kB // Output: e0b, e1b, e0kBInv, e1kBInv, encryption of m0s and m1s for a*b and 1/kA*1/kB func (bob *BobPre) BobRound2(V group.Element, r group.Scalar, RPrime group.Element, aBs, kAInvBs []group.Element, aliceLabel, bobLabel []byte) ([][]byte, [][]byte, [][]byte, [][]byte, error) { - // Generate R and verify proof from alice err := bob.getRandomNonce(V, RPrime, r, aliceLabel, bobLabel) if err != nil { @@ -73,7 +71,6 @@ func (bob *BobPre) BobRound2(V group.Element, r group.Scalar, RPrime group.Eleme // Input: e0b, e1b, e0kBInv, e1kBInv, encryption of m0s and m1s for a*b and 1/kA*1/kB // Output: sigmaa, vsa, sigmakAInv, vskAInv, Blinding sigma and Array of v for (a and kAInv) func (alice *AlicePre) AliceRound3(e0b, e1b, e0kBInv, e1kBInv [][]byte) (group.Scalar, []group.Scalar, group.Scalar, []group.Scalar, error) { - sigmaa, vsa, sigmakAInv, vskAInv, errDec := alice.addShareGenRound3(e0b, e1b, e0kBInv, e1kBInv) if errDec != nil { return nil, nil, nil, nil, errDec @@ -162,7 +159,9 @@ func (alice *AlicePre) initRandomNonce(myGroup group.Group, DB group.Element, al } // Construct zero knowledge proof that alice knows kA where R=[kA]DB - V, r := zkRDL.ProveGen(myGroup, alice.DB, alice.R, alice.kA, aliceLabel, bobLabel) + dst := "zeroknowledge" + rnd := rand.Reader + V, r := zkRDL.ProveGen(myGroup, alice.DB, alice.R, alice.kA, aliceLabel, bobLabel, []byte(dst), rnd) return V, r, alice.RPrime } @@ -172,7 +171,6 @@ func (alice *AlicePre) initRandomNonce(myGroup group.Group, DB group.Element, al // Input: RPrime, from alice // Input: V, r a proof from alice that she knows kA where R=[kA]DB func (bob *BobPre) getRandomNonce(V, RPrime group.Element, r group.Scalar, aliceLabel, bobLabel []byte) error { - RPrimeByte, errByte := RPrime.MarshalBinary() if errByte != nil { panic(errByte) @@ -213,7 +211,9 @@ func (bob *BobPre) getRandomNonce(V, RPrime group.Element, r group.Scalar, alice } // Verify the proof - verify := zkRDL.Verify(bob.myGroup, bob.DB, bob.R, V, r, aliceLabel, bobLabel) + dst := "zeroknowledge" + + verify := zkRDL.Verify(bob.myGroup, bob.DB, bob.R, V, r, aliceLabel, bobLabel, []byte(dst)) if !verify { return errors.New("zero knowledge proof verification fails") } @@ -234,7 +234,7 @@ func (bob *BobPre) getRandomNonce(V, RPrime group.Element, r group.Scalar, alice func (bob *BobPre) addShareGenInit(myGroup group.Group) ([]group.Element, []group.Element) { bob.b = myGroup.RandomNonZeroScalar(rand.Reader) - n := Fmul.DecideNumOT(myGroup, 128) + n := fmul.DecideNumOT(myGroup, 128) bAs := bob.senderb.SenderInit(myGroup, bob.b, n) kBInvAs := bob.senderkBInv.SenderInit(myGroup, bob.kBInv, n) @@ -251,7 +251,7 @@ func (bob *BobPre) addShareGenInit(myGroup group.Group) ([]group.Element, []grou func (alice *AlicePre) addShareGenRound1(myGroup group.Group, bAs, kBInvAs []group.Element) ([]group.Element, []group.Element) { alice.a = myGroup.RandomNonZeroScalar(rand.Reader) - n := Fmul.DecideNumOT(myGroup, 128) + n := fmul.DecideNumOT(myGroup, 128) aBs := alice.receivera.ReceiverRound1(myGroup, bAs, alice.a, n) kAInvBs := alice.receiverkAInv.ReceiverRound1(myGroup, kBInvAs, alice.kAInv, n) @@ -265,8 +265,7 @@ func (alice *AlicePre) addShareGenRound1(myGroup group.Group, bAs, kBInvAs []gro // Input: aBs, kAInvBs from alice // Output: e0b, e1b, e0kBInv, e1kBInv, encryption of m0s and m1s for a*b and 1/kA*1/kB func (bob *BobPre) addShareGenRound2(aBs, kAInvBs []group.Element) ([][]byte, [][]byte, [][]byte, [][]byte) { - - n := Fmul.DecideNumOT(bob.myGroup, 128) + n := fmul.DecideNumOT(bob.myGroup, 128) e0b, e1b := bob.senderb.SenderRound2(aBs, n) e0kBInv, e1kBInv := bob.senderkBInv.SenderRound2(kAInvBs, n) @@ -279,8 +278,7 @@ func (bob *BobPre) addShareGenRound2(aBs, kAInvBs []group.Element) ([][]byte, [] // Input: e0b, e1b, e0kBInv, e1kBInv, encryption of m0s and m1s for a*b and 1/kA*1/kB // Output: sigmaa, vsa, sigmakAInv, vskAInv, Blinding sigma and Array of v for (a and kAInv) func (alice *AlicePre) addShareGenRound3(e0b, e1b, e0kBInv, e1kBInv [][]byte) (group.Scalar, []group.Scalar, group.Scalar, []group.Scalar, error) { - - n := Fmul.DecideNumOT(alice.myGroup, 128) + n := fmul.DecideNumOT(alice.myGroup, 128) sigmaa, vsa, errDec := alice.receivera.ReceiverRound3(e0b, e1b, n) if errDec != nil { @@ -298,8 +296,7 @@ func (alice *AlicePre) addShareGenRound3(e0b, e1b, e0kBInv, e1kBInv [][]byte) (g // Input: sigmaa, vsa, sigmakAInv, vskAInv, Blinding sigma and Array of v for (a and kAInv), from alice func (bob *BobPre) addShareGenRound4(sigmaa, sigmakAInv group.Scalar, vsa, vskAInv []group.Scalar) { - - n := Fmul.DecideNumOT(bob.myGroup, 128) + n := fmul.DecideNumOT(bob.myGroup, 128) bob.senderb.SenderRound4(vsa, sigmaa, n) bob.senderkBInv.SenderRound4(vskAInv, sigmakAInv, n) diff --git a/tss/ecdsa/ot/fmul/fmulLocal.go b/tss/ecdsa/dkls/fmul/fmulLocal.go similarity index 96% rename from tss/ecdsa/ot/fmul/fmulLocal.go rename to tss/ecdsa/dkls/fmul/fmulLocal.go index dd7ae2bd5..0ad7d13ae 100644 --- a/tss/ecdsa/ot/fmul/fmulLocal.go +++ b/tss/ecdsa/dkls/fmul/fmulLocal.go @@ -10,6 +10,14 @@ import ( "golang.org/x/sync/errgroup" ) +// Input: myGroup, the group we operate in +// Input: securityParameter +// Output: The number of SimOT needed +func DecideNumOT(myGroup group.Group, sp int) int { + numSimOT := int(myGroup.Params().ScalarLength*8) + sp + return numSimOT +} + // ---- Sender Initialization ---- // Input: myGroup, the group we operate in diff --git a/tss/ecdsa/ot/fmul/fmulParty.go b/tss/ecdsa/dkls/fmul/fmulParty.go similarity index 100% rename from tss/ecdsa/ot/fmul/fmulParty.go rename to tss/ecdsa/dkls/fmul/fmulParty.go diff --git a/tss/ecdsa/ot/fmul/fmul_test.go b/tss/ecdsa/dkls/fmul/fmul_test.go similarity index 95% rename from tss/ecdsa/ot/fmul/fmul_test.go rename to tss/ecdsa/dkls/fmul/fmul_test.go index 896983cdf..ca8ebefd6 100644 --- a/tss/ecdsa/ot/fmul/fmul_test.go +++ b/tss/ecdsa/dkls/fmul/fmul_test.go @@ -15,14 +15,6 @@ import ( const testFmulCount = 50 -// Input: myGroup, the group we operate in -// Input: securityParameter -// Output: The number of SimOT needed -func DecideNumOT(myGroup group.Group, sp int) int { - numSimOT := int(myGroup.Params().ScalarLength*8) + sp - return numSimOT -} - // Input: aInput, bInput, the private input from both sender and receiver // Input: myGroup, the group we operate in // Input: n, the total number of SimOT diff --git a/tss/ecdsa/ot/ecdsaTSSOT.go b/tss/ecdsa/ot/ecdsaTSSOT.go deleted file mode 100644 index 45686ee44..000000000 --- a/tss/ecdsa/ot/ecdsaTSSOT.go +++ /dev/null @@ -1,136 +0,0 @@ -// Reference: https://eprint.iacr.org/2018/499.pdf -// 2 out of 2 party threhsold signature scheme -// Figure 1 and Protocol 1 and 2 - -package ECDSAOT - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "errors" - "math/big" - - "github.com/cloudflare/circl/group" -) - -// Input: myGroup, the group we operate in -// Input: sk, the real secret key -// Output: share1, share2 the multiplicative secret key shares for 2 parties. -func KeyShareGen(myGroup group.Group, sk group.Scalar) (group.Scalar, group.Scalar) { - share1 := myGroup.RandomNonZeroScalar(rand.Reader) - share1Inv := myGroup.NewScalar() - share1Inv.Inv(share1) - - share2 := myGroup.NewScalar() - share2.Mul(share1Inv, sk) - - return share1, share2 -} - -// Input: myGroup, the group we operate in -// Output: precomputation information for signature generation -func Precomputation(myGroup group.Group, alice *AlicePre, bob *BobPre, Alice *Alice, Bob *Bob) error { - - // Initialization - DB, bAs, kBInvAs := bob.BobInit(myGroup) - - // Round 1 - // bob sends DB, bAs, kBInvAs, to alice - V, r, RPrime, aBs, kAInvBs := alice.AliceRound1(myGroup, DB, bAs, kBInvAs, alice.label, bob.label) - - // Round 2 - // alice sends a proof (V, r) of she knows the kA for R=[kA]DB as well as R' to bob - // alice sends aBs, kAInvBs, to bob - e0b, e1b, e0kBInv, e1kBInv, err := bob.BobRound2(V, r, RPrime, aBs, kAInvBs, alice.label, bob.label) - if err != nil { - return err - } - - // Round 3 - // bob sends e0b, e1b, e0kBInv, e1kBInv, to alice - sigmaa, vsa, sigmakAInv, vskAInv, err := alice.AliceRound3(e0b, e1b, e0kBInv, e1kBInv) - if err != nil { - return err - } - - // Round 4 - // alice sends sigmaa, vsa, sigmakAInv, vskAInv to bob - bob.BobRound4(sigmaa, sigmakAInv, vsa, vskAInv) - - Alice.SetParamters(alice) - Bob.SetParamters(bob) - - return nil -} - -// Input: myGroup, the group we operate in -// Input: Alice and Bob -// Input: hash, the hash of the message we want to sign -// Input: curve, the curve we operate in -func SigGen(myGroup group.Group, Alice *Alice, Bob *Bob, hash []byte, curve elliptic.Curve) group.Scalar { - // Convert hash to scalar - hashBig := hashToInt(hash, curve) - hashByte := hashBig.Bytes() - - hashScalar := myGroup.NewScalar() - errByte := hashScalar.UnmarshalBinary(hashByte) - if errByte != nil { - panic(errByte) - } - beaverAlice := Alice.SigGenInit() - beaverBob := Bob.SigGenInit() - - // Round 1 - // Alice and Bob sends beaverAlice: skA/(kA*a), beaverBob: skB/(kB*b) to each other - sigAlice := Alice.SigGenRound1(beaverBob, hashScalar) - sigBob := Bob.SigGenRound1(beaverAlice, hashScalar) - - // Round 2 - // Either Alice or Bob can send the signature share to the other one and then combine - signature := SigGenRound2(myGroup, sigAlice, sigBob) - return signature -} - -func hashToInt(hash []byte, c elliptic.Curve) *big.Int { - orderBits := c.Params().N.BitLen() - orderBytes := (orderBits + 7) / 8 - if len(hash) > orderBytes { - hash = hash[:orderBytes] - } - - ret := new(big.Int).SetBytes(hash) - excess := len(hash)*8 - orderBits - if excess > 0 { - ret.Rsh(ret, uint(excess)) - } - return ret -} - -// ECDSA threshold signature verification -// Input: (r,s), the signature -// Input: hashMSG, the message -// Input: publicKey, the ECDSA public key -// Output: verification passed or not -func Verify(r, s group.Scalar, hashMSG []byte, publicKey *ecdsa.PublicKey) error { - rBig := new(big.Int) - sBig := new(big.Int) - - rByte, errByte := r.MarshalBinary() - if errByte != nil { - panic(errByte) - } - rBig.SetBytes(rByte) - - sByte, errByte := s.MarshalBinary() - if errByte != nil { - panic(errByte) - } - sBig.SetBytes(sByte) - - verify := ecdsa.Verify(publicKey, hashMSG, rBig, sBig) - if !verify { - return errors.New("ECDSA threshold verification failed") - } - return nil -}