This commit is contained in:
programmer10110 2020-08-26 17:12:24 +03:00
parent 039a664564
commit 1cb71bc631
4 changed files with 118 additions and 48 deletions

View File

@ -3,6 +3,7 @@ package airgapped
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
"log" "log"
"sync" "sync"
@ -190,6 +191,10 @@ func (am *AirgappedMachine) HandleOperation(operation client.Operation) (client.
err = am.handleStateDkgResponsesAwaitConfirmations(&operation) err = am.handleStateDkgResponsesAwaitConfirmations(&operation)
case dkg_proposal_fsm.StateDkgMasterKeyAwaitConfirmations: case dkg_proposal_fsm.StateDkgMasterKeyAwaitConfirmations:
err = am.handleStateDkgMasterKeyAwaitConfirmations(&operation) err = am.handleStateDkgMasterKeyAwaitConfirmations(&operation)
case signing_proposal_fsm.StateSigningAwaitPartialKeys:
err = am.handleStateSigningAwaitPartialSigns(&operation)
case signing_proposal_fsm.StateSigningPartialKeysCollected:
err = am.reconstructThresholdSignature(&operation)
default: default:
err = fmt.Errorf("invalid operation type: %s", operation.Type) err = fmt.Errorf("invalid operation type: %s", operation.Type)
} }

View File

@ -7,6 +7,7 @@ import (
client "github.com/depools/dc4bc/client/types" client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/fsm/fsm" "github.com/depools/dc4bc/fsm/fsm"
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm" "github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests" "github.com/depools/dc4bc/fsm/types/requests"
"github.com/depools/dc4bc/fsm/types/responses" "github.com/depools/dc4bc/fsm/types/responses"
"github.com/depools/dc4bc/storage" "github.com/depools/dc4bc/storage"
@ -29,6 +30,7 @@ type Node struct {
deals []requests.DKGProposalDealConfirmationRequest deals []requests.DKGProposalDealConfirmationRequest
responses []requests.DKGProposalResponseConfirmationRequest responses []requests.DKGProposalResponseConfirmationRequest
masterKeys []requests.DKGProposalMasterKeyConfirmationRequest masterKeys []requests.DKGProposalMasterKeyConfirmationRequest
partialSigns []requests.SigningProposalPartialKeyRequest
} }
func (n *Node) storeOperation(t *testing.T, msg storage.Message) { func (n *Node) storeOperation(t *testing.T, msg storage.Message) {
@ -57,6 +59,12 @@ func (n *Node) storeOperation(t *testing.T, msg storage.Message) {
t.Fatalf("failed to unmarshal fsm req: %v", err) t.Fatalf("failed to unmarshal fsm req: %v", err)
} }
n.masterKeys = append(n.masterKeys, req) n.masterKeys = append(n.masterKeys, req)
case signing_proposal_fsm.EventSigningPartialKeyReceived:
var req requests.SigningProposalPartialKeyRequest
if err := json.Unmarshal(msg.Data, &req); err != nil {
t.Fatalf("failed to unmarshal fsm req: %v", err)
}
n.partialSigns = append(n.partialSigns, req)
default: default:
t.Fatalf("invalid event: %s", msg.Event) t.Fatalf("invalid event: %s", msg.Event)
} }
@ -91,7 +99,7 @@ func createOperation(t *testing.T, opType string, to string, req interface{}) cl
} }
func TestAirgappedAllSteps(t *testing.T) { func TestAirgappedAllSteps(t *testing.T) {
nodesCount := 25 nodesCount := 10
participants := make([]string, nodesCount) participants := make([]string, nodesCount)
for i := 0; i < nodesCount; i++ { for i := 0; i < nodesCount; i++ {
participants[i] = fmt.Sprintf("Participant#%d", i) participants[i] = fmt.Sprintf("Participant#%d", i)
@ -220,27 +228,52 @@ func TestAirgappedAllSteps(t *testing.T) {
} }
msgToSign := []byte("i am a message") msgToSign := []byte("i am a message")
sigShares := make([][]byte, 0)
for _, n := range tr.nodes { //partialSigns
sigShare, err := n.Machine.createPartialSign(msgToSign, DKGIdentifier) runStep(tr, func(n *Node, wg *sync.WaitGroup) {
defer wg.Done()
payload := responses.SigningProposalParticipantInvitationsResponse{
SrcPayload: msgToSign,
}
op := createOperation(t, string(signing_proposal_fsm.StateSigningAwaitPartialKeys), "", payload)
operation, err := n.Machine.HandleOperation(op)
if err != nil { if err != nil {
t.Fatalf("failed to create sig share: %v", err.Error()) t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
} }
sigShares = append(sigShares, sigShare) for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
} }
})
fullSign, err := tr.nodes[0].Machine.recoverFullSign(msgToSign, sigShares, DKGIdentifier) //recover full signature
runStep(tr, func(n *Node, wg *sync.WaitGroup) {
defer wg.Done()
var payload responses.SigningProcessParticipantResponse
for _, req := range n.partialSigns {
p := responses.SigningProcessParticipantEntry{
ParticipantId: req.ParticipantId,
Addr: fmt.Sprintf("Participant#%d", req.ParticipantId),
PartialSign: req.PartialSign,
}
payload.Participants = append(payload.Participants, &p)
}
payload.SrcPayload = msgToSign
op := createOperation(t, string(signing_proposal_fsm.StateSigningPartialKeysCollected), "", payload)
operation, err := n.Machine.HandleOperation(op)
if err != nil { if err != nil {
t.Fatalf("failed to recover full sign: %v", err.Error()) t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
} }
for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
}
})
for _, n := range tr.nodes { fmt.Println("DKG succeeded, signature recovered")
if err = n.Machine.verifySign(msgToSign, fullSign, DKGIdentifier); err != nil {
t.Fatalf("failed to verify signature: %v", err)
}
}
fmt.Println("DKG succeeded, signature recovered and verified")
} }
func runStep(transport *Transport, cb func(n *Node, wg *sync.WaitGroup)) { func runStep(transport *Transport, cb func(n *Node, wg *sync.WaitGroup)) {

View File

@ -1,41 +1,73 @@
package airgapped package airgapped
import ( import (
"encoding/json"
"fmt" "fmt"
client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests"
"github.com/depools/dc4bc/fsm/types/responses"
"go.dedis.ch/kyber/v3/sign/bls" "go.dedis.ch/kyber/v3/sign/bls"
"go.dedis.ch/kyber/v3/sign/tbls" "go.dedis.ch/kyber/v3/sign/tbls"
) )
// commented because fsm is not ready // commented because fsm is not ready
//func (am *AirgappedMachine) handleStateSigningAwaitPartialKeys(o *client.Operation) error { func (am *AirgappedMachine) handleStateSigningAwaitPartialSigns(o *client.Operation) error {
// var ( var (
// payload responses.DKGProposalResponsesParticipantResponse payload responses.SigningProposalParticipantInvitationsResponse
// err error err error
// ) )
//
// if err = json.Unmarshal(o.Payload, &payload); err != nil { if err = json.Unmarshal(o.Payload, &payload); err != nil {
// return fmt.Errorf("failed to unmarshal payload: %w", err) return fmt.Errorf("failed to unmarshal payload: %w", err)
// } }
//
// partialSign, err := am.createPartialSign(nil, o.DKGIdentifier) partialSign, err := am.createPartialSign(payload.SrcPayload, o.DKGIdentifier)
// if err != nil { if err != nil {
// return fmt.Errorf("failed to create partialSign for msg: %w", err) return fmt.Errorf("failed to create partialSign for msg: %w", err)
// } }
//
// req := requests.SigningProposalPartialKeyRequest{ participantID, err := am.getParticipantID(o.DKGIdentifier)
// ParticipantId: 0, // TODO: from where? if err != nil {
// PartialSign: partialSign, return fmt.Errorf("failed to get paricipant id: %w", err)
// CreatedAt: o.CreatedAt, }
// } req := requests.SigningProposalPartialKeyRequest{
// reqBz, err := json.Marshal(req) ParticipantId: participantID,
// if err != nil { PartialSign: partialSign,
// return fmt.Errorf("failed to generate fsm request: %w", err) CreatedAt: o.CreatedAt,
// } }
// reqBz, err := json.Marshal(req)
// o.Result = reqBz if err != nil {
// o.Event = signing_proposal_fsm.EventSigningPartialKeyReceived return fmt.Errorf("failed to generate fsm request: %w", err)
// return nil }
//}
o.Event = signing_proposal_fsm.EventSigningPartialKeyReceived
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
return nil
}
func (am *AirgappedMachine) reconstructThresholdSignature(o *client.Operation) error {
var (
payload responses.SigningProcessParticipantResponse
err error
)
if err = json.Unmarshal(o.Payload, &payload); err != nil {
return fmt.Errorf("failed to unmarshal payload: %w", err)
}
partialSignatures := make([][]byte, 0, len(payload.Participants))
for _, participant := range payload.Participants {
partialSignatures = append(partialSignatures, participant.PartialSign)
}
reconstructedSignature, err := am.recoverFullSign(payload.SrcPayload, partialSignatures, o.DKGIdentifier)
if err != nil {
return fmt.Errorf("failed to reconsruct full signature for msg: %w", err)
}
fmt.Println(reconstructedSignature)
return nil
}
func (am *AirgappedMachine) createPartialSign(msg []byte, dkgIdentifier string) ([]byte, error) { func (am *AirgappedMachine) createPartialSign(msg []byte, dkgIdentifier string) ([]byte, error) {
blsKeyring, err := am.loadBLSKeyring(dkgIdentifier) blsKeyring, err := am.loadBLSKeyring(dkgIdentifier)

View File

@ -313,7 +313,7 @@ func (am *AirgappedMachine) handleStateDkgMasterKeyAwaitConfirmations(o *client.
o.Event = dkg_proposal_fsm.EventDKGMasterKeyConfirmationReceived o.Event = dkg_proposal_fsm.EventDKGMasterKeyConfirmationReceived
o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz)) o.ResultMsgs = append(o.ResultMsgs, createMessage(*o, reqBz))
fmt.Println(dkgInstance.ParticipantID, pubKey.String()) //fmt.Println(dkgInstance.ParticipantID, pubKey.String())
return nil return nil
} }