diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..729e64b --- /dev/null +++ b/.github/workflows/go.yml @@ -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 diff --git a/README.md b/README.md index 97ae8bd..b24db3b 100644 --- a/README.md +++ b/README.md @@ -103,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) diff --git a/airgapped/airgapped_test.go b/airgapped/airgapped_test.go index 117b351..d07d100 100644 --- a/airgapped/airgapped_test.go +++ b/airgapped/airgapped_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/json" "fmt" + prysmBLS "github.com/prysmaticlabs/prysm/shared/bls" "os" "sync" "testing" @@ -328,6 +329,9 @@ func TestAirgappedAllSteps(t *testing.T) { } } + //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") } @@ -587,9 +591,26 @@ func TestAirgappedMachine_Replay(t *testing.T) { } } + //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)) { var wg = &sync.WaitGroup{} for _, node := range transport.nodes { diff --git a/airgapped/dkg.go b/airgapped/dkg.go index 47d9204..bfecfe3 100644 --- a/airgapped/dkg.go +++ b/airgapped/dkg.go @@ -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" diff --git a/airgapped/storage.go b/airgapped/storage.go index d7c139f..5302f68 100644 --- a/airgapped/storage.go +++ b/airgapped/storage.go @@ -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" diff --git a/client/flow_test.go b/client/flow_test.go index d473761..b9b8b5a 100644 --- a/client/flow_test.go +++ b/client/flow_test.go @@ -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 { diff --git a/fsm-states.md b/fsm-states.md new file mode 100644 index 0000000..e69de29 diff --git a/fsm/cmd/state_machines/state_machines.go b/fsm/cmd/state_machines/state_machines.go index 3d5e3ed..bbda536 100644 --- a/fsm/cmd/state_machines/state_machines.go +++ b/fsm/cmd/state_machines/state_machines.go @@ -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)) } diff --git a/fsm/fsm/utils.go b/fsm/fsm/utils.go new file mode 100644 index 0000000..22d1604 --- /dev/null +++ b/fsm/fsm/utils.go @@ -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() +} diff --git a/go.mod b/go.mod index 7c3d197..f5f8658 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 5b1f246..821618a 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/images/dkgFSM.png b/images/dkgFSM.png new file mode 100644 index 0000000..7a6bcfc Binary files /dev/null and b/images/dkgFSM.png differ diff --git a/images/sigFSM.png b/images/sigFSM.png new file mode 100644 index 0000000..4f87041 Binary files /dev/null and b/images/sigFSM.png differ diff --git a/images/signingFSM.png b/images/signingFSM.png new file mode 100644 index 0000000..4c41897 Binary files /dev/null and b/images/signingFSM.png differ