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

View File

@ -7,6 +7,7 @@ import (
client "github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/fsm/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/responses"
"github.com/depools/dc4bc/storage"
@ -29,6 +30,7 @@ type Node struct {
deals []requests.DKGProposalDealConfirmationRequest
responses []requests.DKGProposalResponseConfirmationRequest
masterKeys []requests.DKGProposalMasterKeyConfirmationRequest
partialSigns []requests.SigningProposalPartialKeyRequest
}
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)
}
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:
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) {
nodesCount := 25
nodesCount := 10
participants := make([]string, nodesCount)
for i := 0; i < nodesCount; i++ {
participants[i] = fmt.Sprintf("Participant#%d", i)
@ -220,27 +228,52 @@ func TestAirgappedAllSteps(t *testing.T) {
}
msgToSign := []byte("i am a message")
sigShares := make([][]byte, 0)
for _, n := range tr.nodes {
sigShare, err := n.Machine.createPartialSign(msgToSign, DKGIdentifier)
//partialSigns
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 {
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)
}
fullSign, err := tr.nodes[0].Machine.recoverFullSign(msgToSign, sigShares, DKGIdentifier)
if err != nil {
t.Fatalf("failed to recover full sign: %v", err.Error())
}
for _, n := range tr.nodes {
if err = n.Machine.verifySign(msgToSign, fullSign, DKGIdentifier); err != nil {
t.Fatalf("failed to verify signature: %v", err)
for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
}
}
})
fmt.Println("DKG succeeded, signature recovered and verified")
//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 {
t.Fatalf("%s: failed to handle operation %s: %v", n.Participant, op.Type, err)
}
for _, msg := range operation.ResultMsgs {
tr.BroadcastMessage(t, msg)
}
})
fmt.Println("DKG succeeded, signature recovered")
}
func runStep(transport *Transport, cb func(n *Node, wg *sync.WaitGroup)) {

View File

@ -1,41 +1,73 @@
package airgapped
import (
"encoding/json"
"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/tbls"
)
// commented because fsm is not ready
//func (am *AirgappedMachine) handleStateSigningAwaitPartialKeys(o *client.Operation) error {
// var (
// payload responses.DKGProposalResponsesParticipantResponse
// err error
// )
//
// if err = json.Unmarshal(o.Payload, &payload); err != nil {
// return fmt.Errorf("failed to unmarshal payload: %w", err)
// }
//
// partialSign, err := am.createPartialSign(nil, o.DKGIdentifier)
// if err != nil {
// return fmt.Errorf("failed to create partialSign for msg: %w", err)
// }
//
// req := requests.SigningProposalPartialKeyRequest{
// ParticipantId: 0, // TODO: from where?
// PartialSign: partialSign,
// CreatedAt: o.CreatedAt,
// }
// reqBz, err := json.Marshal(req)
// if err != nil {
// return fmt.Errorf("failed to generate fsm request: %w", err)
// }
//
// o.Result = reqBz
// o.Event = signing_proposal_fsm.EventSigningPartialKeyReceived
// return nil
//}
func (am *AirgappedMachine) handleStateSigningAwaitPartialSigns(o *client.Operation) error {
var (
payload responses.SigningProposalParticipantInvitationsResponse
err error
)
if err = json.Unmarshal(o.Payload, &payload); err != nil {
return fmt.Errorf("failed to unmarshal payload: %w", err)
}
partialSign, err := am.createPartialSign(payload.SrcPayload, o.DKGIdentifier)
if err != nil {
return fmt.Errorf("failed to create partialSign for msg: %w", err)
}
participantID, err := am.getParticipantID(o.DKGIdentifier)
if err != nil {
return fmt.Errorf("failed to get paricipant id: %w", err)
}
req := requests.SigningProposalPartialKeyRequest{
ParticipantId: participantID,
PartialSign: partialSign,
CreatedAt: o.CreatedAt,
}
reqBz, err := json.Marshal(req)
if err != nil {
return fmt.Errorf("failed to generate fsm request: %w", err)
}
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) {
blsKeyring, err := am.loadBLSKeyring(dkgIdentifier)

View File

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