Merge branch 'master' into feat/cli-show-fsm-state

This commit is contained in:
programmer10110 2020-10-19 12:10:13 +03:00
commit 08c4e128f1
14 changed files with 214 additions and 114 deletions

37
.github/workflows/go.yml vendored Normal file
View File

@ -0,0 +1,37 @@
name: Go
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.x
uses: actions/setup-go@v2
with:
go-version: ^1.13
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Install gocv
run: |
git clone https://github.com/hybridgroup/gocv.git
cd gocv
make install
cd ..
echo "Successfully installed gocv!"
- name: Build
run: make build-linux
- name: Test
run: make test-short

View File

@ -16,7 +16,7 @@ make test-short
# How to run this code?
Please refer to [this page](HowTo.md) for a complete guide for running the minimal application testnet.
Please refer to [this page](HowTo.md) for a complete guide to running the minimal application testnet.
# Repository description
@ -29,9 +29,6 @@ Please refer to [this page](HowTo.md) for a complete guide for running the minim
* `./storage` Two Bulletin Board implementations: File storage for local debugging and Kafka storage for real-world scenarios.
# Related repositories
* [kyber-bls12381](https://github.com/depools/kyber-bls12381) BLS threshold signature library based on kyber's BLS threshold signatures library
* [bls12-381](https://github.com/depools/bls12-381) high speed BLS12-381 implementation in go, based on kyber's one
* [kyber](https://github.com/corestario/kyber/) dkg library, fork of DEDIS' kyber library
## Moving parts
@ -106,3 +103,26 @@ If at any point something goes wrong (timeout reached, the deal is invalid, publ
If not enough participants signal their willingness to sign within a timeout or signal their rejection to sign, signature process is aborted.
We organize logic in the hot node as a set of simple state machines that change state only by external trigger, such as CLI command, message from cold node, or a new message on Bulletin Board. That way it can be easily tested and audited.
# Finite-state machines description
We moved away from the idea of one large state machine that would perform all tasks, so we divided the functionality into three separate state machines:
* SignatureProposalFSM - responsible for collecting agreements to participate in a specific DKG round
* DKGProposalFSM - responsible for collecting a neccessary data (pubkeys, commits, deals, responses and reconstructed pubkeys) for a DKG process
* SigningProposalFSM - responsible for signature process (collecting agreements to sign a message, collecting partial signs and reconstructed full signature)
We implemented a FSMPoolProvider containing all three state machines that we can switch between each other by hand calling necessary events.
For example, when SignatureProposalFSM collected all agreements from every participant it's state becomes *state_sig_proposal_collected*.
That means it's time to start a new DKG round to create shared public key. We can do it by sending *event_dkg_init_process* event to the FSM.
# Visual representation of FSMs
### SignatureProposalFSM
![SignatureProposalFSM](images/sigFSM.png)
### DKGProposalFSM
![DKGProposalFSM](images/dkgFSM.png)
### SigningProposalFSM
![SigningProposalFSM](images/signingFSM.png)

View File

@ -4,6 +4,7 @@ import (
"bytes"
"encoding/json"
"fmt"
prysmBLS "github.com/prysmaticlabs/prysm/shared/bls"
"os"
"sync"
"testing"
@ -28,14 +29,15 @@ const (
)
type Node struct {
ParticipantID int
Participant string
Machine *Machine
commits []requests.DKGProposalCommitConfirmationRequest
deals []requests.DKGProposalDealConfirmationRequest
responses []requests.DKGProposalResponseConfirmationRequest
masterKeys []requests.DKGProposalMasterKeyConfirmationRequest
partialSigns []requests.SigningProposalPartialSignRequest
ParticipantID int
Participant string
Machine *Machine
commits []requests.DKGProposalCommitConfirmationRequest
deals []requests.DKGProposalDealConfirmationRequest
responses []requests.DKGProposalResponseConfirmationRequest
masterKeys []requests.DKGProposalMasterKeyConfirmationRequest
partialSigns []requests.SigningProposalPartialSignRequest
reconstructedSignatures []client.ReconstructedSignature
}
func (n *Node) storeOperation(t *testing.T, msg storage.Message) {
@ -71,7 +73,11 @@ func (n *Node) storeOperation(t *testing.T, msg storage.Message) {
}
n.partialSigns = append(n.partialSigns, req)
case client.SignatureReconstructed:
return
var req client.ReconstructedSignature
if err := json.Unmarshal(msg.Data, &req); err != nil {
t.Fatalf("failed to unmarshal fsm req: %v", err)
}
n.reconstructedSignatures = append(n.reconstructedSignatures, req)
default:
t.Fatalf("invalid event: %s", msg.Event)
}
@ -311,7 +317,22 @@ func TestAirgappedAllSteps(t *testing.T) {
}
})
fmt.Println("DKG succeeded, signature recovered")
//verify signatures
for _, n := range tr.nodes {
for i := 0; i < len(n.reconstructedSignatures); i++ {
if !bytes.Equal(n.reconstructedSignatures[0].Signature, n.reconstructedSignatures[i].Signature) {
t.Fatalf("signatures are not equal!")
}
if err := n.Machine.VerifySign(msgToSign, n.reconstructedSignatures[i].Signature, DKGIdentifier); err != nil {
t.Fatal("signature is not verified!")
}
}
}
//keys and signatures are equal, so let's test it on prysm compatibility
testKyberPrysm(t, tr.nodes[0].masterKeys[0].MasterKey, tr.nodes[0].reconstructedSignatures[0].Signature, msgToSign)
fmt.Println("DKG succeeded, signature recovered and verified")
}
func TestAirgappedMachine_Replay(t *testing.T) {
@ -558,7 +579,36 @@ func TestAirgappedMachine_Replay(t *testing.T) {
}
})
fmt.Println("DKG succeeded, signature recovered")
//verify signatures
for _, n := range tr.nodes {
for i := 0; i < len(n.reconstructedSignatures); i++ {
if !bytes.Equal(n.reconstructedSignatures[0].Signature, n.reconstructedSignatures[i].Signature) {
t.Fatalf("signatures are not equal!")
}
if err := n.Machine.VerifySign(msgToSign, n.reconstructedSignatures[i].Signature, DKGIdentifier); err != nil {
t.Fatal("signature is not verified!")
}
}
}
//keys and signatures are equal, so let's test it on prysm compatibility
testKyberPrysm(t, tr.nodes[0].masterKeys[0].MasterKey, tr.nodes[0].reconstructedSignatures[0].Signature, msgToSign)
fmt.Println("DKG succeeded, signature recovered and verified")
}
func testKyberPrysm(t *testing.T, pubkey, signature, msg []byte) {
prysmSig, err := prysmBLS.SignatureFromBytes(signature)
if err != nil {
t.Fatalf("failed to get prysm sig from bytes: %v", err)
}
prysmPubKey, err := prysmBLS.PublicKeyFromBytes(pubkey)
if err != nil {
t.Fatalf("failed to get prysm pubkey from bytes: %v", err)
}
if !prysmSig.Verify(prysmPubKey, msg) {
t.Fatalf("failed to verify prysm signature")
}
}
func runStep(transport *Transport, cb func(n *Node, wg *sync.WaitGroup)) {

View File

@ -5,7 +5,7 @@ import (
"encoding/json"
"fmt"
bls "github.com/depools/kyber-bls12381"
bls "github.com/corestario/kyber/pairing/bls12381"
"github.com/corestario/kyber"
dkgPedersen "github.com/corestario/kyber/share/dkg/pedersen"

View File

@ -7,7 +7,7 @@ import (
"fmt"
"log"
bls12381 "github.com/depools/kyber-bls12381"
bls12381 "github.com/corestario/kyber/pairing/bls12381"
client "github.com/depools/dc4bc/client/types"
"github.com/syndtr/goleveldb/leveldb"

View File

@ -15,13 +15,13 @@ import (
"testing"
"time"
bls12381 "github.com/corestario/kyber/pairing/bls12381"
"github.com/depools/dc4bc/airgapped"
"github.com/depools/dc4bc/client/types"
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
"github.com/depools/dc4bc/fsm/types/requests"
"github.com/depools/dc4bc/qr"
"github.com/depools/dc4bc/storage"
bls12381 "github.com/depools/kyber-bls12381"
)
type node struct {

0
fsm-states.md Normal file
View File

View File

@ -2,96 +2,29 @@ package main
import (
"fmt"
"github.com/looplab/fsm"
"github.com/depools/dc4bc/fsm/fsm"
"github.com/depools/dc4bc/fsm/state_machines/dkg_proposal_fsm"
"github.com/depools/dc4bc/fsm/state_machines/signature_proposal_fsm"
"github.com/depools/dc4bc/fsm/state_machines/signing_proposal_fsm"
"log"
)
func main() {
signatureProposalFSM := fsm.NewFSM(
"idle",
fsm.Events{
{Name: "proposal_spotted", Src: []string{"idle"}, Dst: "validate_proposal"},
{Name: "proposal_valid", Src: []string{"validate_proposal"}, Dst: "proposed"},
{Name: "proposal_invalid", Src: []string{"validate_proposal"}, Dst: "idle"},
{Name: "recieve_yay", Src: []string{"proposed"}, Dst: "process_yay"},
{Name: "receive_nay", Src: []string{"proposed"}, Dst: "process_nay"},
{Name: "send_nay", Src: []string{"proposed"}, Dst: "proposed"},
{Name: "send_yay", Src: []string{"proposed"}, Dst: "proposed"},
{Name: "enough_yays", Src: []string{"process_yay"}, Dst: "signing"},
{Name: "enough_nays", Src: []string{"process_nay"}, Dst: "abort"},
{Name: "not_enough_yays", Src: []string{"process_yay"}, Dst: "proposed"},
{Name: "not_enough_nays", Src: []string{"process_nay"}, Dst: "proposed"},
},
fsm.Callbacks{},
)
fmt.Print(fsm.Visualize(signatureProposalFSM))
dkgFSM, ok := dkg_proposal_fsm.New().(*dkg_proposal_fsm.DKGProposalFSM)
if !ok {
log.Fatal("invalid type")
}
fmt.Println(fsm.Visualize(dkgFSM.FSM))
signatureConstructFSM := fsm.NewFSM(
"idle",
fsm.Events{
{Name: "request_airgapped_sig", Src: []string{"signing"}, Dst: "signing"},
{Name: "transmit_airgapped_sig", Src: []string{"signing"}, Dst: "signing"},
{Name: "receive_sig", Src: []string{"signing"}, Dst: "process_sig"},
{Name: "enough_signature_shares", Src: []string{"process_sig"}, Dst: "reconstruct_signature"},
{Name: "not_enough_signature_shares", Src: []string{"process_sig"}, Dst: "signing"},
{Name: "signature_reconstucted", Src: []string{"reconstruct_signature"}, Dst: "publish_signature"},
{Name: "signature_published", Src: []string{"publish_signature"}, Dst: "fin"},
{Name: "failed_to_reconstuct_signature", Src: []string{"reconstruct_signature"}, Dst: "signing"},
},
fsm.Callbacks{},
)
fmt.Print(fsm.Visualize(signatureConstructFSM))
DkgProposeFSM := fsm.NewFSM(
"idle",
fsm.Events{
{Name: "proposal_spotted", Src: []string{"idle"}, Dst: "validate_proposal"},
{Name: "proposal_valid", Src: []string{"validate_proposal"}, Dst: "proposed"},
{Name: "proposal_invalid", Src: []string{"validate_proposal"}, Dst: "idle"},
{Name: "recieve_yay", Src: []string{"proposed"}, Dst: "process_yay"},
{Name: "receive_nay", Src: []string{"proposed"}, Dst: "abort"},
{Name: "send_nay", Src: []string{"proposed"}, Dst: "proposed"},
{Name: "send_yay", Src: []string{"proposed"}, Dst: "proposed"},
{Name: "not_enough_yays", Src: []string{"process_yay"}, Dst: "proposed"},
{Name: "all_yays", Src: []string{"process_yay"}, Dst: "dkg_commitments"},
{Name: "timeout", Src: []string{"proposed"}, Dst: "abort"},
},
fsm.Callbacks{},
)
fmt.Print(fsm.Visualize(DkgProposeFSM))
DkgCommitFSM := fsm.NewFSM(
"dkg_commitments",
fsm.Events{
{Name: "request_airgapped_commitment", Src: []string{"dkg_commitments"}, Dst: "dkg_commitments"},
{Name: "transmit_airgapped_commitment", Src: []string{"dkg_commitments"}, Dst: "dkg_commitments"},
{Name: "recieve_commitment", Src: []string{"dkg_commitments"}, Dst: "process_commitment"},
{Name: "invalid_commitment", Src: []string{"process_commitment"}, Dst: "abort"},
{Name: "all_commitments", Src: []string{"process_commitment"}, Dst: "dkg_deals"},
{Name: "not_enough_commitments", Src: []string{"process_commitment"}, Dst: "dkg_commitments"},
{Name: "timeout", Src: []string{"dkg_commitments"}, Dst: "abort"},
},
fsm.Callbacks{},
)
fmt.Print(fsm.Visualize(DkgCommitFSM))
DkgDealsFSM := fsm.NewFSM(
"dkg_deals",
fsm.Events{
{Name: "pass_commitements_and_request_airgapped_deals", Src: []string{"dkg_deals"}, Dst: "dkg_deals"},
{Name: "transmit_airgapped_deals", Src: []string{"dkg_deals"}, Dst: "dkg_deals"},
{Name: "transmit_airgapped_error", Src: []string{"dkg_deals"}, Dst: "abort"},
{Name: "recieve_deal", Src: []string{"dkg_deals"}, Dst: "process_deal"},
{Name: "not_my_deal", Src: []string{"process_deal"}, Dst: "dkg_deals"},
{Name: "invalid_deal", Src: []string{"process_deal"}, Dst: "abort"},
{Name: "enough_deals", Src: []string{"process_deal"}, Dst: "dkg_construct_tss"},
{Name: "not_enough_deals", Src: []string{"process_deal"}, Dst: "dkg_deals"},
{Name: "pass_deals_and_request_airgapped_public_key", Src: []string{"dkg_construct_tss"}, Dst: "dkg_construct_tss"},
{Name: "transmit_airgapped_public_key", Src: []string{"dkg_construct_tss"}, Dst: "fin"},
{Name: "transmit_airgapped_error", Src: []string{"dkg_construct_tss"}, Dst: "abort"},
{Name: "timeout", Src: []string{"dkg_deals"}, Dst: "abort"},
},
fsm.Callbacks{},
)
fmt.Print(fsm.Visualize(DkgDealsFSM))
sigFSM, ok := signature_proposal_fsm.New().(*signature_proposal_fsm.SignatureProposalFSM)
if !ok {
log.Fatal("invalid type")
}
fmt.Println(fsm.Visualize(sigFSM.FSM))
signingFSM, ok := signing_proposal_fsm.New().(*signing_proposal_fsm.SigningProposalFSM)
if !ok {
log.Fatal("invalid type")
}
fmt.Println(fsm.Visualize(signingFSM.FSM))
}

44
fsm/fsm/utils.go Normal file
View File

@ -0,0 +1,44 @@
package fsm
import (
"bytes"
"fmt"
)
func Visualize(fsm *FSM) string {
var buf bytes.Buffer
states := make(map[string]int)
buf.WriteString(fmt.Sprintf(`digraph fsm {`))
buf.WriteString("\n")
// make sure the initial state is at top
for k, v := range fsm.transitions {
if k.source == fsm.currentState {
states[string(k.source)]++
states[string(v.dstState)]++
buf.WriteString(fmt.Sprintf(` "%s" -> "%s" [ label = "%s" ];`, k.source, v.dstState, k.event))
buf.WriteString("\n")
}
}
for k, v := range fsm.transitions {
if k.source != fsm.currentState {
states[string(k.source)]++
states[string(v.dstState)]++
buf.WriteString(fmt.Sprintf(` "%s" -> "%s" [ label = "%s" ];`, k.source, v.dstState, k.event))
buf.WriteString("\n")
}
}
buf.WriteString("\n")
for k := range states {
buf.WriteString(fmt.Sprintf(` "%s";`, k))
buf.WriteString("\n")
}
buf.WriteString(fmt.Sprintln("}"))
return buf.String()
}

13
go.mod
View File

@ -3,24 +3,23 @@ module github.com/depools/dc4bc
go 1.13
require (
github.com/corestario/kyber v1.5.0
github.com/depools/kyber-bls12381 v0.0.0-20200929134032-c24859b7d890
github.com/corestario/kyber v1.6.0
github.com/golang/mock v1.4.4
github.com/google/go-cmp v0.2.0
github.com/google/go-cmp v0.5.0
github.com/google/uuid v1.1.1
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b
github.com/looplab/fsm v0.1.0
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7
github.com/prysmaticlabs/prysm v1.0.0-alpha.29.0.20201014075528-022b6667e5d0
github.com/segmentio/kafka-go v0.4.2
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
github.com/spf13/cobra v1.0.0
github.com/stretchr/testify v1.6.1
github.com/syndtr/goleveldb v1.0.0
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca
gocv.io/x/gocv v0.24.0
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
golang.org/x/text v0.3.3 // indirect
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
lukechampine.com/frand v1.3.0
)
replace golang.org/x/crypto => github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5
replace github.com/ethereum/go-ethereum => github.com/ethereum/go-ethereum v1.9.22

21
go.sum
View File

@ -16,10 +16,10 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/corestario/kyber v1.3.0/go.mod h1:kIWfWekm8kSJNti3Fo3DCV0GHEH050MWQrdvZdefbkk=
github.com/corestario/kyber v1.4.0 h1:jSB8P5vBvRDiFESJHxlx9BzH1+E1FDQSuu7xfiCy3HY=
github.com/corestario/kyber v1.4.0/go.mod h1:kIWfWekm8kSJNti3Fo3DCV0GHEH050MWQrdvZdefbkk=
github.com/corestario/kyber v1.5.0 h1:wNkoKD6yYAJV8p8JmJYF0jdJzCx4LlDJQT6wobWPl+I=
github.com/corestario/kyber v1.5.0/go.mod h1:mzxQ0SX6j2O1bH1EbCDcXxnEZx2pDskatkkSaINGKVA=
github.com/corestario/kyber v1.6.0 h1:ix91T0CMHjT2dlLaJbg5e/qYOG/Fvx0YHC4qdiE8BxY=
github.com/corestario/kyber v1.6.0/go.mod h1:8seqKJ5KGwEPN98iYQLoKFulfFn90ZxcdKSxb29A5XM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -28,7 +28,9 @@ github.com/depools/kyber-bls12381 v0.0.0-20200929134032-c24859b7d890 h1:ra3VcXLA
github.com/depools/kyber-bls12381 v0.0.0-20200929134032-c24859b7d890/go.mod h1:82QP3olqMtRnlRCNxEc9/EKk1qlFCOklxasHvSnXMSI=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
@ -43,6 +45,7 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
@ -57,7 +60,9 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b h1:FQ7+9fxhyp82ks9vAuyPzG0/vVbWwMwLJ+P6yJI5FN8=
@ -73,8 +78,10 @@ github.com/klauspost/compress v1.9.8 h1:VMAMUUOh+gaxKTMk+zqbjsSjsIcUcL/LF4o63i82
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/looplab/fsm v0.1.0 h1:Qte7Zdn/5hBNbXzP7yxVU4OIFHWXBovyTT2LaBTyC20=
github.com/looplab/fsm v0.1.0/go.mod h1:m2VaOfDHxqXBBMgc26m6yUOwkFn8H2AlJDE+jd/uafI=
@ -87,7 +94,9 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I=
@ -135,13 +144,16 @@ github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5 h1:u8i49c+BxloX3
github.com/tendermint/crypto v0.0.0-20180820045704-3764759f34a5/go.mod h1:z4YtwM70uOnk8h0pjJYlj3zdYwi9l03By6iAIF5j/Pk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0=
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs=
go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw=
go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ=
go.dedis.ch/kyber/v3 v3.0.9 h1:i0ZbOQocHUjfFasBiUql5zVeC7u/vahFd96DFA8UOWk=
go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg=
go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo=
go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4=
@ -161,6 +173,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -196,13 +209,17 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

BIN
images/dkgFSM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

BIN
images/sigFSM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
images/signingFSM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB