From 6a8f5087f97c96672864f7a188d41866906553fc Mon Sep 17 00:00:00 2001 From: 0xcy <993921@qq.com> Date: Sat, 14 Dec 2024 23:15:27 +0800 Subject: [PATCH] bugfix: thershold in bls --- plugins/dvt/signature/bls_sign.go | 98 +++++++------------ plugins/dvt/signature/bls_test.go | 22 +---- .../seedworks/tx_signature.go | 10 +- 3 files changed, 44 insertions(+), 86 deletions(-) diff --git a/plugins/dvt/signature/bls_sign.go b/plugins/dvt/signature/bls_sign.go index f90186c..cf15ef7 100644 --- a/plugins/dvt/signature/bls_sign.go +++ b/plugins/dvt/signature/bls_sign.go @@ -4,11 +4,9 @@ import ( dvtSeedworks "another_node/plugins/dvt/seedworks" "another_node/plugins/passkey_relay_party/seedworks" "bytes" - "crypto/sha256" "encoding/json" "fmt" "io" - "math/rand" "net/http" "sync" "time" @@ -31,27 +29,7 @@ func (s signGroup) first() string { return "" } -func randSplit(data string, n int) []string { - lengths := make([]int, n) - total := len(data) - - for i := 0; i < n-1; i++ { - lengths[i] = rand.Intn(total-(n-i-1)) + 1 - total -= lengths[i] - } - lengths[n-1] = total - - groups := make([]string, n) - start := 0 - for i, length := range lengths { - groups[i] = data[start : start+length] - start += length - } - - return groups -} - -func requestSign(host string, group *string, passkeyPubkey []byte, passkey *protocol.ParsedCredentialAssertionData) (*signResponse, error) { +func requestSign(host string, message []byte, passkeyPubkey []byte, passkey *protocol.ParsedCredentialAssertionData) (*signResponse, error) { defer func() { if r := recover(); r != nil { fmt.Println("Recovered from panic:", r) @@ -59,11 +37,11 @@ func requestSign(host string, group *string, passkeyPubkey []byte, passkey *prot }() body := struct { - Message *string `json:"message"` + Message string `json:"message"` PasskeyPubkey []byte `json:"passkeyPubkey"` Passkey *protocol.ParsedCredentialAssertionData `json:"passkey"` }{ - Message: group, + Message: string(message), PasskeyPubkey: passkeyPubkey, Passkey: passkey, } @@ -107,43 +85,46 @@ func requestSign(host string, group *string, passkeyPubkey []byte, passkey *prot return &signResponse, nil } -func aggrSign(host string, signGroup signGroup) ([]string, error) { +func aggrSign(host string, signGroup signGroup) ([]string, [][4]string, error) { var sigs [][2]string + pubkeys := make([][4]string, 0) for _, sign := range signGroup { sigs = append(sigs, [2]string{sign.Signature[0], sign.Signature[1]}) + pubkeys = append(pubkeys, [4]string{sign.PublicKey[0], sign.PublicKey[1], sign.PublicKey[2], sign.PublicKey[3]}) } body := struct { Signatures [][2]string `json:"sigs"` + Pubkeys [][4]string `json:"pubkeys"` }{ Signatures: sigs, } jsonData, err := json.Marshal(body) if err != nil { fmt.Println("Error encoding JSON:", err) - return nil, err + return nil, nil, err } resp, err := http.Post(host+"/aggr", "application/json", bytes.NewBuffer(jsonData)) if err != nil { fmt.Println("Error:", err) - return nil, err + return nil, nil, err } defer resp.Body.Close() respBody, err := io.ReadAll(resp.Body) if err != nil { - return nil, err + return nil, nil, err } var aggrResp struct { Signature []string `json:"sig"` } if err := json.Unmarshal(respBody, &aggrResp); err != nil { - return nil, err + return nil, nil, err } ret := aggrResp.Signature - return ret, nil + return ret, pubkeys, nil } //lint:ignore U1000 ignore unused @@ -190,34 +171,25 @@ func Bls(data []byte, threshold, timeoutSeconds int, dvtNodes []string, passkeyC if len(dvtNodes) < threshold { return nil, dvtSeedworks.ErrNotEnoughSigners{} } - msgHash := fmt.Sprintf("%x", sha256.Sum256(data))[0:31] - groups := randSplit(msgHash, len(dvtNodes)) - mapMsgGroups := make(map[string]string) mapSignatures := make(signGroup) - for i, g := range groups { - mapMsgGroups[dvtNodes[i]] = g - } - var mu sync.Mutex done := make(chan struct{}) - validatorResults := make([]seedworks.ValidatorResult, 0) - for host, g := range mapMsgGroups { - go func(dvtHost string, group string) { - if signResult, err := requestSign(dvtHost, &group, passkeyCAPubKey, passkeyCA); err == nil { + var messagePt [2]string + for _, host := range dvtNodes { + go func() { + if signResult, err := requestSign(host, data, passkeyCAPubKey, passkeyCA); err == nil { mu.Lock() - mapSignatures[dvtHost] = signResult + mapSignatures[host] = signResult sigCount := len(mapSignatures) - validatorResults = append(validatorResults, seedworks.ValidatorResult{ - Message: signResult.Message, - PublicKeys: signResult.PublicKey, - }) mu.Unlock() if sigCount >= threshold { select { case <-done: // close the channel due to enough signatures + messagePt[0] = signResult.Message[0] + messagePt[1] = signResult.Message[1] default: close(done) } @@ -225,35 +197,41 @@ func Bls(data []byte, threshold, timeoutSeconds int, dvtNodes []string, passkeyC } else { fmt.Println(err) } - }(host, g) + }() } timeout := time.After(time.Duration(timeoutSeconds) * time.Second) - var aggr []string - var aggrErr error select { case <-done: firstNode := mapSignatures.first() - aggr, aggrErr = aggrSign(firstNode, mapSignatures) + if aggr, pubkeys, err := aggrSign(firstNode, mapSignatures); err != nil { + return nil, err + } else { + return &seedworks.DvtResult{ + Signatures: aggr, + MessagePt: messagePt, + PublicKeys: pubkeys, + }, nil + } case <-timeout: mu.Lock() sigCount := len(mapSignatures) mu.Unlock() if sigCount >= threshold { firstNode := mapSignatures.first() - aggr, aggrErr = aggrSign(firstNode, mapSignatures) + if aggr, pubkeys, err := aggrSign(firstNode, mapSignatures); err != nil { + return nil, err + } else { + return &seedworks.DvtResult{ + Signatures: aggr, + MessagePt: messagePt, + PublicKeys: pubkeys, + }, nil + } } return nil, dvtSeedworks.ErrNotEnoughSigners{} } - - if aggrErr != nil { - return nil, aggrErr - } - return &seedworks.DvtResult{ - Signatures: aggr, - Validator: validatorResults, - }, nil } // BlsTss sign data using BLS threshold signature scheme diff --git a/plugins/dvt/signature/bls_test.go b/plugins/dvt/signature/bls_test.go index 0322106..d28af85 100644 --- a/plugins/dvt/signature/bls_test.go +++ b/plugins/dvt/signature/bls_test.go @@ -3,22 +3,12 @@ package signature import ( "encoding/base64" "fmt" - "math/rand/v2" "testing" "github.com/go-webauthn/webauthn/protocol" "github.com/herumi/bls-eth-go-binary/bls" ) -func TestRandSplit(t *testing.T) { - data := "asdfasdfasdfasdf314" - n := rand.IntN(3) + 1 - groups := randSplit(data, n) - for _, g := range groups { - fmt.Print(string(g)) - } -} - func TestBls(t *testing.T) { if testing.Short() { t.Skip("skipping test in short mode.") @@ -45,17 +35,11 @@ func TestBls(t *testing.T) { t.Errorf("Expected 2 signatures, got %d", len(dvrResult.Signatures)) } - if len(dvrResult.Validator) < threshold { + if len(dvrResult.PublicKeys) < threshold { t.Errorf("Expected at least %d validators", threshold) } - - for _, v := range dvrResult.Validator { - if len(v.Message) != 2 { - t.Error("Expected messages len to be 2") - } - if len(v.PublicKeys) != 4 { - t.Error("Expected public keys len to be 4") - } + if len(dvrResult.MessagePt) != 2 { + t.Error("Expected messages len to be 2") } } } diff --git a/plugins/passkey_relay_party/seedworks/tx_signature.go b/plugins/passkey_relay_party/seedworks/tx_signature.go index 5dd8c97..898c126 100644 --- a/plugins/passkey_relay_party/seedworks/tx_signature.go +++ b/plugins/passkey_relay_party/seedworks/tx_signature.go @@ -17,15 +17,11 @@ type TxSignature struct { CAPublicKey []byte `json:"-"` } -type ValidatorResult struct { - Message []string `json:"message"` - PublicKeys []string `json:"pubkeys"` -} - // DvtResult aggregate distributed validators signatures by BLS type DvtResult struct { - Signatures []string `json:"signatures"` - Validator []ValidatorResult `json:"validator"` + MessagePt [2]string `json:"message"` + Signatures []string `json:"signatures"` + PublicKeys [][4]string `json:"pubkeys"` } type TxSignatureResult struct {