Skip to content

Commit

Permalink
bugfix: thershold in bls
Browse files Browse the repository at this point in the history
  • Loading branch information
fanhousanbu committed Dec 14, 2024
1 parent 1a58cdc commit 6a8f508
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 86 deletions.
98 changes: 38 additions & 60 deletions plugins/dvt/signature/bls_sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -31,39 +29,19 @@ 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)
}
}()

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,
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -190,70 +171,67 @@ 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)
}
}
} 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
Expand Down
22 changes: 3 additions & 19 deletions plugins/dvt/signature/bls_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand All @@ -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")
}
}
}
Expand Down
10 changes: 3 additions & 7 deletions plugins/passkey_relay_party/seedworks/tx_signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 6a8f508

Please sign in to comment.