diff --git a/.circleci/config.yml b/.circleci/config.yml index b6a1f200c..68a3ab417 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -31,6 +31,12 @@ commands: command: | sudo apt-get update && sudo apt-get -y install libtool make libsodium + setup_bls_library_build: + steps: + - run: + name: "Install build tools to build BLS library" + command: | + sudo apt-get update && sudo apt-get -y install gcc run_test: parameters: script_path: @@ -48,6 +54,7 @@ commands: keys: - go-mod-v1-{{ checksum "go.sum" }} - make_libsodium + - setup_bls_library_build - run: name: "Running test" command: | @@ -75,6 +82,7 @@ jobs: - attach_workspace: at: /tmp/workspace - make_libsodium + - setup_bls_library_build - run: name: "Build binaries" command: make install install_abci @@ -147,7 +155,7 @@ jobs: name: run localnet and exit on failure command: | set -x - docker run --rm -v "$PWD":/go/src/github.com/tendermint/tendermint -w /go/src/github.com/tendermint/tendermint golang:1.14.1-alpine /bin/sh -c "apk add --update make && make build-linux" + docker run --rm -v "$PWD":/go/src/github.com/tendermint/tendermint -w /go/src/github.com/tendermint/tendermint golang:1.14.1-alpine /bin/sh -c "apk add --update git make gcc libc-dev build-base && make build" make localnet-start & ./scripts/localnet-blocks-test.sh 40 5 10 localhost @@ -165,6 +173,7 @@ jobs: steps: - checkout_with_submodules - make_libsodium + - setup_bls_library_build - run: mkdir -p $GOPATH/src/github.com/tendermint - run: ln -sf /home/circleci/project $GOPATH/src/github.com/tendermint/tendermint - run: bash test/p2p/circleci.sh << parameters.ipv >> @@ -360,7 +369,7 @@ jobs: ./scripts/get_nodejs.sh # build the binaries with a proper version of Go # Build Tendermint - docker run --rm -v "$PWD":/go/src/github.com/tendermint/tendermint -w /go/src/github.com/tendermint/tendermint golang:1.14.1-alpine /bin/sh -c "apk add --update make git && make build-linux" + docker run --rm -v "$PWD":/go/src/github.com/tendermint/tendermint -w /go/src/github.com/tendermint/tendermint golang:1.14.1-alpine /bin/sh -c "apk add --update git make gcc libc-dev build-base && make build" # Build contract-tests docker run --rm -v "$PWD":/go/src/github.com/tendermint/tendermint -w /go/src/github.com/tendermint/tendermint ubuntu:20.10 ./scripts/prepare_dredd_test.sh # This docker image works with go 1.7, we can install here the hook handler that contract-tests is going to use diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 32a2edbaa..6f51bfff2 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -5,6 +5,7 @@ ### BREAKING CHANGES: - State + - [state] [\#92](https://github.com/line/tendermint/pull/92) Genesis state - CLI/RPC/Config @@ -14,8 +15,8 @@ - Go API - ### FEATURES: +- [BLS] [\#81](https://github.com/line/tendermint/issues/81) Modify to generate at the same time as Ed25519 key generation ### IMPROVEMENTS: diff --git a/Makefile b/Makefile index 013d1255c..df645221b 100644 --- a/Makefile +++ b/Makefile @@ -222,8 +222,8 @@ build-docker: ############################################################################### # Build linux binary on other platforms -build-linux: tools $(PREPARE_LIBSODIUM_TARGET) $(LIBSODIUM_TARGET) - GOOS=linux GOARCH=amd64 $(MAKE) build +build-linux: + docker run --rm -v `pwd`:/go/src/github.com/tendermint/tendermint -w /go/src/github.com/tendermint/tendermint golang:1.14.1-alpine /bin/sh -c "apk add --update git make gcc libc-dev build-base && make build" .PHONY: build-linux build-docker-localnode: diff --git a/crypto/bls/bls.go b/crypto/bls/bls.go new file mode 100644 index 000000000..6c82192a6 --- /dev/null +++ b/crypto/bls/bls.go @@ -0,0 +1,142 @@ +package bls + +import ( + "bytes" + "crypto/subtle" + "fmt" + + "github.com/herumi/bls-eth-go-binary/bls" + amino "github.com/tendermint/go-amino" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/tmhash" +) + +var _ crypto.PrivKey = PrivKeyBLS12{} + +const ( + PrivKeyAminoName = "tendermint/PrivKeyBLS12" + PubKeyAminoName = "tendermint/PubKeyBLS12" + PrivKeyBLS12Size = 32 + PubKeyBLS12Size = 48 + SignatureSize = 96 +) + +var cdc = amino.NewCodec() + +func init() { + cdc.RegisterInterface((*crypto.PubKey)(nil), nil) + cdc.RegisterConcrete(PubKeyBLS12{}, + PubKeyAminoName, nil) + + cdc.RegisterInterface((*crypto.PrivKey)(nil), nil) + cdc.RegisterConcrete(PrivKeyBLS12{}, + PrivKeyAminoName, nil) + + err := bls.Init(bls.BLS12_381) + if err != nil { + panic(fmt.Sprintf("ERROR: %s", err)) + } + err = bls.SetETHmode(bls.EthModeLatest) + if err != nil { + panic(fmt.Sprintf("ERROR: %s", err)) + } +} + +// PrivKeyBLS12 implements crypto.PrivKey. +type PrivKeyBLS12 [PrivKeyBLS12Size]byte + +// GenPrivKey generates a new BLS12-381 private key. +func GenPrivKey() PrivKeyBLS12 { + sigKey := bls.SecretKey{} + sigKey.SetByCSPRNG() + sigKeyBinary := PrivKeyBLS12{} + copy(sigKeyBinary[:], sigKey.Serialize()) + return sigKeyBinary +} + +// Bytes marshals the privkey using amino encoding. +func (privKey PrivKeyBLS12) Bytes() []byte { + return cdc.MustMarshalBinaryBare(privKey) +} + +// Sign produces a signature on the provided message. +func (privKey PrivKeyBLS12) Sign(msg []byte) ([]byte, error) { + blsKey := bls.SecretKey{} + err := blsKey.Deserialize(privKey[:]) + if err != nil { + panic(fmt.Sprintf("Failed to copy the private key: %s", err)) + } + sign := blsKey.SignByte(msg) + return sign.Serialize(), nil +} + +// PubKey gets the corresponding public key from the private key. +func (privKey PrivKeyBLS12) PubKey() crypto.PubKey { + blsKey := bls.SecretKey{} + err := blsKey.Deserialize(privKey[:]) + if err != nil { + panic(fmt.Sprintf("Failed to copy the private key: %s", err)) + } + pubKey := blsKey.GetPublicKey() + pubKeyBinary := PubKeyBLS12{} + copy(pubKeyBinary[:], pubKey.Serialize()) + return pubKeyBinary +} + +// Equals - you probably don't need to use this. +// Runs in constant time based on length of the keys. +func (privKey PrivKeyBLS12) Equals(other crypto.PrivKey) bool { + if otherEd, ok := other.(PrivKeyBLS12); ok { + return subtle.ConstantTimeCompare(privKey[:], otherEd[:]) == 1 + } + return false +} + +var _ crypto.PubKey = PubKeyBLS12{} + +// PubKeyBLS12 implements crypto.PubKey for the BLS12-381 signature scheme. +type PubKeyBLS12 [PubKeyBLS12Size]byte + +// Address is the SHA256-20 of the raw pubkey bytes. +func (pubKey PubKeyBLS12) Address() crypto.Address { + return tmhash.SumTruncated(pubKey[:]) +} + +// Bytes marshals the PubKey using amino encoding. +func (pubKey PubKeyBLS12) Bytes() []byte { + bz, err := cdc.MarshalBinaryBare(pubKey) + if err != nil { + panic(err) + } + return bz +} + +func (pubKey PubKeyBLS12) VerifyBytes(msg []byte, sig []byte) bool { + // make sure we use the same algorithm to sign + if len(sig) != SignatureSize { + return false + } + blsPubKey := bls.PublicKey{} + err := blsPubKey.Deserialize(pubKey[:]) + if err != nil { + panic(fmt.Sprintf("Failed to copy the public key: [%X] %s", pubKey[:], err)) + } + blsSign := bls.Sign{} + err = blsSign.Deserialize(sig) + if err != nil { + return false + } + return blsSign.VerifyByte(&blsPubKey, msg) +} + +func (pubKey PubKeyBLS12) String() string { + return fmt.Sprintf("PubKeyBLS12{%X}", pubKey[:]) +} + +// nolint: golint +func (pubKey PubKeyBLS12) Equals(other crypto.PubKey) bool { + if otherEd, ok := other.(PubKeyBLS12); ok { + return bytes.Equal(pubKey[:], otherEd[:]) + } + return false +} diff --git a/crypto/bls/bls_test.go b/crypto/bls/bls_test.go new file mode 100644 index 000000000..ea968a903 --- /dev/null +++ b/crypto/bls/bls_test.go @@ -0,0 +1,275 @@ +package bls_test + +import ( + "bytes" + "fmt" + amino "github.com/tendermint/go-amino" + "github.com/tendermint/tendermint/crypto/ed25519" + "testing" + + b "github.com/herumi/bls-eth-go-binary/bls" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/bls" +) + +func TestPrivKeyBLS12_Bytes(t *testing.T) { + pk := bls.GenPrivKey() + b := pk.Bytes() + if len(b) != 37 { + t.Fatalf("bytes length: %d != %d", len(b), 37) + } + if !bytes.Equal(b, pk.Bytes()) { + t.Errorf("bytes is not identical by call") + } +} + +func TestPrivKeyBLS12_Sign(t *testing.T) { + msg := []byte{0, 1, 2, 3, 4, 5} + sign, err := bls.GenPrivKey().Sign(msg) + if err != nil { + t.Fatalf("Signing failed: %s", err) + } + if sign == nil { + t.Errorf("Signature is nil") + } + if len(sign) != bls.SignatureSize { + t.Errorf("Unexpected signature size: %d != %d", len(sign), bls.SignatureSize) + } +} + +func TestPrivKeyBLS12_PubKey(t *testing.T) { + pubKey := bls.GenPrivKey().PubKey() + if pubKey == nil { + t.Errorf("Public key is nil") + } +} + +func TestPrivKeyBLS12_Equals(t *testing.T) { + privKey := bls.GenPrivKey() + anotherPrivKey := bls.GenPrivKey() + if !privKey.Equals(privKey) { + t.Error("A is not identical") + } + if privKey.Equals(anotherPrivKey) || anotherPrivKey.Equals(privKey) { + t.Error("Different A and B were determined to be identical") + } + + cdc := amino.NewCodec() + json, err := cdc.MarshalJSON(privKey) + if err != nil { + t.Fatalf("Marshalling failed: %s", err) + } + var restoredPrivKey = bls.PrivKeyBLS12{} + err = cdc.UnmarshalJSON(json, &restoredPrivKey) + if err != nil { + t.Fatalf("Unmarshalling failed: %s", err) + } + if !privKey.Equals(restoredPrivKey) || !restoredPrivKey.Equals(privKey) { + t.Errorf("Restored A was not identical") + } + + ed25519PrivKey := ed25519.GenPrivKey() + if privKey.Equals(ed25519PrivKey) { + t.Errorf("Different types of keys were matched") + } +} + +func TestPubKeyBLS12_Address(t *testing.T) { + privKey := bls.GenPrivKey() + pubKey := privKey.PubKey() + address := pubKey.Address() + if len(address) != 20 { + t.Errorf("Address length %d is not %d", len(address), 20) + } +} + +func TestPubKeyBLS12_Bytes(t *testing.T) { + privKey := bls.GenPrivKey() + pubKey := privKey.PubKey() + b := pubKey.Bytes() + if len(b) != 53 { + t.Errorf("Byte length %d is not %d", len(b), 53) + } + if !bytes.Equal(b, pubKey.Bytes()) { + t.Errorf("Difference bytes was generated from the same public key") + } + if bytes.Equal(b, bls.GenPrivKey().PubKey().Bytes()) { + t.Errorf("The same bytes was generated from different public key") + } +} + +func TestPubKeyBLS12_VerifyBytes(t *testing.T) { + privKey := bls.GenPrivKey() + pubKey := privKey.PubKey() + msg := []byte{0, 1, 2, 3, 4, 5} + sign, _ := privKey.Sign(msg) + if !pubKey.VerifyBytes(msg, sign) { + t.Errorf("Signature validation failed for the same message") + } + + corruptedMessage := make([]byte, len(msg)) + copy(corruptedMessage, msg) + corruptedMessage[0] ^= 1 + if pubKey.VerifyBytes(corruptedMessage, sign) { + t.Errorf("Signature validation succeeded for the different messages") + } + + otherPubKey := bls.GenPrivKey().PubKey() + if otherPubKey.VerifyBytes(msg, sign) { + t.Errorf("Signature validation succeeded for the different public key") + } + + ed25519Sign, _ := ed25519.GenPrivKey().Sign(msg) + if pubKey.VerifyBytes(msg, ed25519Sign) { + t.Errorf("Verification accepted by ed25519 signature") + } + + emptySign := make([]byte, 0) + if pubKey.VerifyBytes(msg, emptySign) { + t.Errorf("Verification accepted by empty bytes") + } + + zeroSign := make([]byte, bls.SignatureSize) + if pubKey.VerifyBytes(msg, zeroSign) { + t.Errorf("Verification accepted by zero-filled bytes") + } +} + +func TestPubKeyBLS12_String(t *testing.T) { + fmt.Printf("%s\n", bls.GenPrivKey().PubKey()) +} + +func TestPubKeyBLS12_Equals(t *testing.T) { + privKey := bls.GenPrivKey() + pubKey := privKey.PubKey() + samePubKey := privKey.PubKey() + if !pubKey.Equals(samePubKey) { + t.Errorf("Different public keys are generated from the same private key") + } + + anotherPubKey := bls.GenPrivKey().PubKey() + if pubKey.Equals(anotherPubKey) { + t.Errorf("The same public keys are generated from different private keys") + } + + ed25519PubKey := ed25519.GenPrivKey().PubKey() + if pubKey.Equals(ed25519PubKey) { + t.Errorf("Got a match on a different kind of key") + } +} + +func TestBasicSignatureFunctions(t *testing.T) { + privateKey := b.SecretKey{} + privateKey.SetByCSPRNG() + publicKey := privateKey.GetPublicKey() + + duplicatedPrivateKey := b.SecretKey{} + err := duplicatedPrivateKey.Deserialize(privateKey.Serialize()) + if err != nil { + t.Fatalf("Private key deserialization failed.") + } + + if len(privateKey.Serialize()) != bls.PrivKeyBLS12Size { + t.Fatalf("The constant size %d of the private key is different from the actual size %d.", + bls.PrivKeyBLS12Size, len(privateKey.Serialize())) + } + + duplicatedPublicKey := b.PublicKey{} + err = duplicatedPublicKey.Deserialize(publicKey.Serialize()) + if err != nil { + t.Fatalf("Public key deserialization failed.") + } + + if len(publicKey.Serialize()) != bls.PubKeyBLS12Size { + t.Fatalf("The constant size %d of the public key is different from the actual size %d.", + bls.PubKeyBLS12Size, len(publicKey.Serialize())) + } + + duplicatedSignature := func(sig *b.Sign) *b.Sign { + duplicatedSign := b.Sign{} + err := duplicatedSign.Deserialize(sig.Serialize()) + if err != nil { + t.Fatalf("Signature deserialization failed.") + } + + if len(sig.Serialize()) != bls.SignatureSize { + t.Fatalf("The constant size %d of the signature is different from the actual size %d.", + bls.SignatureSize, len(sig.Serialize())) + } + return &duplicatedSign + } + + msg := []byte("hello, world") + for _, privKey := range []b.SecretKey{privateKey, duplicatedPrivateKey} { + for _, pubKey := range []*b.PublicKey{publicKey, &duplicatedPublicKey} { + signature := privKey.SignByte(msg) + if !signature.VerifyByte(pubKey, msg) { + t.Errorf("Signature verification failed.") + } + + if !duplicatedSignature(signature).VerifyByte(pubKey, msg) { + t.Errorf("Signature verification failed.") + } + + for i := 0; i < len(msg); i++ { + for j := 0; j < 8; j++ { + garbled := make([]byte, len(msg)) + copy(garbled, msg) + garbled[i] ^= 1 << (8 - j - 1) + if bytes.Equal(msg, garbled) { + t.Fatalf("Not a barbled message") + } + if signature.VerifyByte(pubKey, garbled) { + t.Errorf("Signature verification was successful against a garbled byte sequence.") + } + if duplicatedSignature(signature).VerifyByte(pubKey, garbled) { + t.Errorf("Signature verification was successful against a garbled byte sequence.") + } + } + } + } + } +} + +func TestSignatureAggregation(t *testing.T) { + publicKeys := make([]b.PublicKey, 25) + aggregatedSignature := b.Sign{} + aggregatedPublicKey := b.PublicKey{} + msg := []byte("hello, world") + for i := 0; i < len(publicKeys); i++ { + privateKey := b.SecretKey{} + privateKey.SetByCSPRNG() + publicKeys[i] = *privateKey.GetPublicKey() + aggregatedSignature.Add(privateKey.SignByte(msg)) + aggregatedPublicKey.Add(&publicKeys[i]) + } + + if !aggregatedSignature.FastAggregateVerify(publicKeys, msg) { + t.Errorf("Aggregated signature verification failed.") + } + if !aggregatedSignature.VerifyByte(&aggregatedPublicKey, msg) { + t.Errorf("Aggregated signature verification failed.") + } +} + +func TestSignAndValidateBLS12(t *testing.T) { + privKey := bls.GenPrivKey() + pubKey := privKey.PubKey() + + msg := crypto.CRandBytes(128) + sig, err := privKey.Sign(msg) + require.Nil(t, err) + fmt.Printf("restoring signature: %x\n", sig) + + // Test the signature + assert.True(t, pubKey.VerifyBytes(msg, sig)) + + // Mutate the signature, just one bit. + // TODO: Replace this with a much better fuzzer, tendermint/ed25519/issues/10 + sig[7] ^= byte(0x01) + + assert.False(t, pubKey.VerifyBytes(msg, sig)) +} diff --git a/go.mod b/go.mod index aadb452fd..ef3f746c7 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/golang/protobuf v1.4.0 github.com/gorilla/websocket v1.4.2 github.com/gtank/merlin v0.1.1 + github.com/herumi/bls-eth-go-binary v0.0.0-20200522010937-01d282b5380b github.com/libp2p/go-buffer-pool v0.0.2 github.com/magiconair/properties v1.8.1 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index 80eda7433..96c2dd96a 100644 --- a/go.sum +++ b/go.sum @@ -69,6 +69,7 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d h1:49RLWk1j44Xu4fjHb6JFYmeUnDORVwHNkDxaQ0ctCVU= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/datastream/go-fn v0.0.0-20130403065544-37331e464987 h1:S3JwKvmPJITKLLH7r3WYbBLjXu4lEZU9gFBLj01zaNU= @@ -193,6 +194,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/herumi/bls-eth-go-binary v0.0.0-20200522010937-01d282b5380b h1:mu+F5uA3Y68oB6KXZqWlASKMetbNufhQx2stMI+sD+Y= +github.com/herumi/bls-eth-go-binary v0.0.0-20200522010937-01d282b5380b/go.mod h1:luAnRm3OsMQeokhGzpYmc0ZKwawY7o87PUEP11Z7r7U= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= @@ -332,10 +335,12 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -389,12 +394,12 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1 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/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= 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= github.com/yahoo/coname v0.0.0-20170609175141-84592ddf8673 h1:PSg2cEFd+9Ae/r5x5iO8cJ3VmTbZNQp6X8tHDmVJAbA= github.com/yahoo/coname v0.0.0-20170609175141-84592ddf8673/go.mod h1:Wq2sZrP++Us4tAw1h58MHS8BGIpC4NmKHfvw2QWBe9U= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= @@ -429,8 +434,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -449,7 +452,6 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -497,10 +499,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200103221440-774c71fcf114 h1:DnSr2mCsxyCE6ZgIkmcWUQY2R5cH/6wL7eIxEmQOMSE= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200519205726-57a9e4404bf7/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= diff --git a/networks/local/Makefile b/networks/local/Makefile index 98517851d..20c5d8f46 100644 --- a/networks/local/Makefile +++ b/networks/local/Makefile @@ -4,4 +4,3 @@ all: docker build --tag tendermint/localnode localnode .PHONY: all - diff --git a/networks/local/localnode/Dockerfile b/networks/local/localnode/Dockerfile index 008952eb5..4aee97557 100644 --- a/networks/local/localnode/Dockerfile +++ b/networks/local/localnode/Dockerfile @@ -3,7 +3,7 @@ MAINTAINER Greg Szabo RUN apk update && \ apk upgrade && \ - apk --no-cache add curl jq file + apk --no-cache add curl jq file gcc libc-dev build-base VOLUME [ /tendermint ] WORKDIR /tendermint diff --git a/p2p/key.go b/p2p/key.go index f4c9413ab..4af5a5416 100644 --- a/p2p/key.go +++ b/p2p/key.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/bls" "github.com/tendermint/tendermint/crypto/ed25519" tmos "github.com/tendermint/tendermint/libs/os" ) @@ -25,7 +26,8 @@ const IDByteLength = crypto.AddressSize // NodeKey is the persistent peer key. // It contains the nodes private key for authentication. type NodeKey struct { - PrivKey crypto.PrivKey `json:"priv_key"` // our priv key + PrivKey crypto.PrivKey `json:"priv_key"` // our priv key + SigKey bls.PrivKeyBLS12 `json:"sig_key"` // for signature aggregation } // ID returns the peer's canonical ID - the hash of its public key. @@ -38,6 +40,10 @@ func (nodeKey *NodeKey) PubKey() crypto.PubKey { return nodeKey.PrivKey.PubKey() } +func (nodeKey *NodeKey) SigPubKey() crypto.PubKey { + return nodeKey.SigKey.PubKey() +} + // PubKeyToID returns the ID corresponding to the given PubKey. // It's the hex-encoding of the pubKey.Address(). func PubKeyToID(pubKey crypto.PubKey) ID { @@ -72,8 +78,10 @@ func LoadNodeKey(filePath string) (*NodeKey, error) { func genNodeKey(filePath string) (*NodeKey, error) { privKey := ed25519.GenPrivKey() + sigKey := bls.GenPrivKey() nodeKey := &NodeKey{ PrivKey: privKey, + SigKey: sigKey, } jsonBytes, err := cdc.MarshalJSON(nodeKey)