Skip to content

Commit

Permalink
crypto: add in secp256k1 support (#5500)
Browse files Browse the repository at this point in the history
Secp256k1 was removed in the protobuf migration, this pr adds it back in order to provide this functionality for users (band)

Closes: #5495
  • Loading branch information
tac0turtle committed Oct 19, 2020
1 parent b3238cd commit 6f908eb
Show file tree
Hide file tree
Showing 16 changed files with 711 additions and 100 deletions.
1 change: 1 addition & 0 deletions .markdownlintignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
docs/node_modules
CHANGELOG.md
docs/architecture/*
crypto/secp256k1/**
scripts/*
.github
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
- [evidence] [\#5319](https://github.com/tendermint/tendermint/issues/5319) Remove Amnesia & potentialAmnesia evidence types and removed POLC. (@marbar3778)
- [evidence] [\#5361](https://github.com/tendermint/tendermint/pull/5361) Add LightClientAttackEvidence and change evidence interface (@cmwaters)
- [params] [\#5319](https://github.com/tendermint/tendermint/issues/5319) Remove `ProofofTrialPeriod` from evidence params (@marbar3778)
- [crypto/secp256k1] [\#5280](https://github.com/tendermint/tendermint/issues/5280) `secp256k1` has been removed from the Tendermint repo. (@marbar3778)
- [light] [\#5347](https://github.com/tendermint/tendermint/issues/5347) `NewClient`, `NewHTTPClient`, `VerifyHeader` and `VerifyLightBlockAtHeight` now accept `context.Context` as 1st param (@melekes)
- [state] [\#5348](https://github.com/tendermint/tendermint/issues/5348) Define an Interface for the state store. (@marbar3778)

Expand Down
105 changes: 51 additions & 54 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,63 +10,63 @@ the encoding format (see "Protocol Buffers," below) and the block header (see "B

### ABCI Changes

* New ABCI methods (`ListSnapshots`, `LoadSnapshotChunk`, `OfferSnapshot`, and `ApplySnapshotChunk`)
were added to support the new State Sync feature.
Previously, syncing a new node to a preexisting network could take days; but with State Sync,
new nodes are able to join a network in a matter of seconds.
Read [the spec](https://docs.tendermint.com/master/spec/abci/apps.html#state-sync)
if you want to learn more about State Sync, or if you'd like your application to use it.
(If you don't want to support State Sync in your application, you can just implement these new
ABCI methods as no-ops, leaving them empty.)

* `KV.Pair` has been replaced with `abci.EventAttribute`. The `EventAttribute.Index` field
* New ABCI methods (`ListSnapshots`, `LoadSnapshotChunk`, `OfferSnapshot`, and `ApplySnapshotChunk`)
were added to support the new State Sync feature.
Previously, syncing a new node to a preexisting network could take days; but with State Sync,
new nodes are able to join a network in a matter of seconds.
Read [the spec](https://docs.tendermint.com/master/spec/abci/apps.html#state-sync)
if you want to learn more about State Sync, or if you'd like your application to use it.
(If you don't want to support State Sync in your application, you can just implement these new
ABCI methods as no-ops, leaving them empty.)

* `KV.Pair` has been replaced with `abci.EventAttribute`. The `EventAttribute.Index` field
allows ABCI applications to dictate which events should be indexed.

* The blockchain can now start from an arbitrary initial height,
* The blockchain can now start from an arbitrary initial height,
provided to the application via `RequestInitChain.InitialHeight`.

* ABCI evidence type is now an enum with two recognized types of evidence:
`DUPLICATE_VOTE` and `LIGHT_CLIENT_ATTACK`.
Applications should be able to handle these evidence types
* ABCI evidence type is now an enum with two recognized types of evidence:
`DUPLICATE_VOTE` and `LIGHT_CLIENT_ATTACK`.
Applications should be able to handle these evidence types
(i.e., through slashing or other accountability measures).

* The [`PublicKey` type](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/crypto/keys.proto#L13-L15)
(used in ABCI as part of `ValidatorUpdate`) now uses a `oneof` protobuf type.
Note that since Tendermint only supports ed25519 validator keys, there's only one
* The [`PublicKey` type](https://github.com/tendermint/tendermint/blob/master/proto/tendermint/crypto/keys.proto#L13-L15)
(used in ABCI as part of `ValidatorUpdate`) now uses a `oneof` protobuf type.
Note that since Tendermint only supports ed25519 validator keys, there's only one
option in the `oneof`. For more, see "Protocol Buffers," below.

* The field `Proof`, on the ABCI type `ResponseQuery`, is now named `ProofOps`.
For more, see "Crypto," below.
* The field `Proof`, on the ABCI type `ResponseQuery`, is now named `ProofOps`.
For more, see "Crypto," below.

### P2P Protocol

The default codec is now proto3, not amino. The schema files can be found in the `/proto`
directory. For more, see "Protobuf," below.
directory. For more, see "Protobuf," below.

### Blockchain Protocol

* `Header#LastResultsHash` previously was the root hash of a Merkle tree built from `ResponseDeliverTx(Code, Data)` responses.
* `Header#LastResultsHash` previously was the root hash of a Merkle tree built from `ResponseDeliverTx(Code, Data)` responses.
As of 0.34,`Header#LastResultsHash` is now the root hash of a Merkle tree built from:
* `BeginBlock#Events`
* Root hash of a Merkle tree built from `ResponseDeliverTx(Code, Data,
GasWanted, GasUsed, Events)` responses
* `BeginBlock#Events`

* Merkle hashes of empty trees previously returned nothing, but now return the hash of an empty input,
to conform with [RFC-6962](https://tools.ietf.org/html/rfc6962).
to conform with [RFC-6962](https://tools.ietf.org/html/rfc6962).
This mainly affects `Header#DataHash`, `Header#LastResultsHash`, and
`Header#EvidenceHash`, which are often empty. Non-empty hashes can also be affected, e.g. if their
inputs depend on other (empty) Merkle hashes, giving different results.

### Transaction Indexing

Tendermint now relies on the application to tell it which transactions to index. This means that
in the `config.toml`, generated by Tendermint, there is no longer a way to specify which
Tendermint now relies on the application to tell it which transactions to index. This means that
in the `config.toml`, generated by Tendermint, there is no longer a way to specify which
transactions to index. `tx.height` & `tx.hash` will always be indexed when using the `kv` indexer.

Applications must now choose to either a) enable indexing for all transactions, or
Applications must now choose to either a) enable indexing for all transactions, or
b) allow node operators to decide which transactions to index.
Applications can notify Tendermint to index a specific transaction by setting
Applications can notify Tendermint to index a specific transaction by setting
`Index: bool` to `true` in the Event Attribute:

```go
Expand All @@ -82,19 +82,19 @@ Applications can notify Tendermint to index a specific transaction by setting

### Protocol Buffers

Tendermint 0.34 replaces Amino with Protocol Buffers for encoding.
This migration is extensive and results in a number of changes, however,
Tendermint 0.34 replaces Amino with Protocol Buffers for encoding.
This migration is extensive and results in a number of changes, however,
Tendermint only uses the types generated from Protocol Buffers for disk and
wire serialization.
wire serialization.
**This means that these changes should not affect you as a Tendermint user.**

However, Tendermint users and contributors may note the following changes:

* Directory layout changes: All proto files have been moved under one directory, `/proto`.
This is in line with the recommended file layout by [Buf](https://buf.build).
* Directory layout changes: All proto files have been moved under one directory, `/proto`.
This is in line with the recommended file layout by [Buf](https://buf.build).
For more, see the [Buf documentation](https://buf.build/docs/lint-checkers#file_layout).
* ABCI Changes: As noted in the "ABCI Changes" section above, the `PublicKey` type now uses
a `oneof` type.
* ABCI Changes: As noted in the "ABCI Changes" section above, the `PublicKey` type now uses
a `oneof` type.

For more on the Protobuf changes, please see our [blog post on this migration](https://medium.com/tendermint/tendermint-0-34-protocol-buffers-and-you-8c40558939ae).

Expand All @@ -114,30 +114,27 @@ Tendermint 0.34 includes new and updated consensus parameters.

#### Keys

* Keys no longer include a type prefix. For example, ed25519 pubkeys have been renamed from
`PubKeyEd25519` to `PubKey`. This reduces stutter (e.g., `ed25519.PubKey`).
* Keys no longer include a type prefix. For example, ed25519 pubkeys have been renamed from
`PubKeyEd25519` to `PubKey`. This reduces stutter (e.g., `ed25519.PubKey`).
* Keys are now byte slices (`[]byte`) instead of byte arrays (`[<size>]byte`).
* The multisig functionality that was previously in Tendermint now has
a new home within the Cosmos SDK:
* The multisig functionality that was previously in Tendermint now has
a new home within the Cosmos SDK:
[`cosmos/cosmos-sdk/types/multisig`](https://github.com/cosmos/cosmos-sdk/blob/master/crypto/types/multisig/multisignature.go).
* Similarly, secp256k1 has been removed from the Tendermint repo.
There is still [a secp256k1 implementation in the Cosmos SDK](https://github.com/cosmos/cosmos-sdk/tree/443e0c1f89bd3730a731aea30453bd732f7efa35/crypto/keys/secp256k1),
and we recommend you use that package for all your secp256k1 needs.

#### `merkle` Package

* `SimpleHashFromMap()` and `SimpleProofsFromMap()` were removed.
* The prefix `Simple` has been removed. (For example, `SimpleProof` is now called `Proof`.)
* All protobuf messages have been moved to the `/proto` directory.
* The protobuf message `Proof` that contained multiple ProofOp's has been renamed to `ProofOps`.
As noted above, this affects the ABCI type `ResponseQuery`:
* The prefix `Simple` has been removed. (For example, `SimpleProof` is now called `Proof`.)
* All protobuf messages have been moved to the `/proto` directory.
* The protobuf message `Proof` that contained multiple ProofOp's has been renamed to `ProofOps`.
As noted above, this affects the ABCI type `ResponseQuery`:
The field that was named Proof is now named `ProofOps`.
* `HashFromByteSlices` and `ProofsFromByteSlices` now return a hash for empty inputs, to conform with
[RFC-6962](https://tools.ietf.org/html/rfc6962).

### `libs` Package

The `bech32` package has moved to the Cosmos SDK:
The `bech32` package has moved to the Cosmos SDK:
[`cosmos/cosmos-sdk/types/bech32`](https://github.com/cosmos/cosmos-sdk/tree/4173ea5ebad906dd9b45325bed69b9c655504867/types/bech32).

### CLI
Expand All @@ -147,37 +144,37 @@ See [the docs](https://docs.tendermint.com/master/tendermint-core/light-client-p

### Light Client

We have a new, rewritten light client! You can
We have a new, rewritten light client! You can
[read more](https://medium.com/tendermint/everything-you-need-to-know-about-the-tendermint-light-client-f80d03856f98)
about the justifications and details behind this change.
about the justifications and details behind this change.

Other user-relevant changes include:

* The old `lite` package was removed; the new light client uses the `light` package.
* The `Verifier` was broken up into two pieces:
* Core verification logic (pure `VerifyX` functions)
* The `Verifier` was broken up into two pieces:
* Core verification logic (pure `VerifyX` functions)
* `Client` object, which represents the complete light client
* The RPC client can be found in the `/rpc` directory.
* The RPC client can be found in the `/rpc` directory.
* The HTTP(S) proxy is located in the `/proxy` directory.

### `state` Package

* A new field `State.InitialHeight` has been added to record the initial chain height, which must be `1`
(not `0`) if starting from height `1`. This can be configured via the genesis field `initial_height`.
* The `state` package now has a `Store` interface. All functions in
[state/store.go](https://github.com/tendermint/tendermint/blob/56911ee35298191c95ef1c7d3d5ec508237aaff4/state/store.go#L42-L42)
* The `state` package now has a `Store` interface. All functions in
[state/store.go](https://github.com/tendermint/tendermint/blob/56911ee35298191c95ef1c7d3d5ec508237aaff4/state/store.go#L42-L42)
are now part of the interface. The interface returns errors on all methods and can be used by calling `state.NewStore(dbm.DB)`.

### `privval` Package

All requests are now accompanied by the chain ID from the network.
This is a optional field and can be ignored by key management systems.
This is a optional field and can be ignored by key management systems.
It is recommended to check the chain ID if using the same key management system for multiple chains.

### RPC

`/unsafe_start_cpu_profiler`, `/unsafe_stop_cpu_profiler` and
`/unsafe_write_heap_profile` were removed.
`/unsafe_write_heap_profile` were removed.
For profiling, please use the pprof server, which can
be enabled through `--rpc.pprof_laddr=X` flag or `pprof_laddr=X` config setting
in the rpc section.
Expand Down
2 changes: 1 addition & 1 deletion abci/example/kvstore/persistent_kvstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ func (app *PersistentKVStoreApplication) execValidatorTx(tx []byte) types.Respon

// add, update, or remove a validator
func (app *PersistentKVStoreApplication) updateValidator(v types.ValidatorUpdate) types.ResponseDeliverTx {
key := []byte("val:" + string(v.PubKey.GetEd25519()))
pubkey, err := cryptoenc.PubKeyFromProto(v.PubKey)
if err != nil {
panic(fmt.Errorf("can't decode public key: %w", err))
}
key := []byte("val:" + string(pubkey.Bytes()))

if v.Power == 0 {
// remove validator
Expand Down
6 changes: 3 additions & 3 deletions crypto/ed25519/ed25519.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const (
// private key representations used by RFC 8032.
SeedSize = 32

keyType = "ed25519"
KeyType = "ed25519"
)

func init() {
Expand Down Expand Up @@ -93,7 +93,7 @@ func (privKey PrivKey) Equals(other crypto.PrivKey) bool {
}

func (privKey PrivKey) Type() string {
return keyType
return KeyType
}

// GenPrivKey generates a new ed25519 private key.
Expand Down Expand Up @@ -159,7 +159,7 @@ func (pubKey PubKey) String() string {
}

func (pubKey PubKey) Type() string {
return keyType
return KeyType
}

func (pubKey PubKey) Equals(other crypto.PubKey) bool {
Expand Down
16 changes: 16 additions & 0 deletions crypto/encoding/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (

"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/libs/json"
pc "github.com/tendermint/tendermint/proto/tendermint/crypto"
)

func init() {
json.RegisterType((*pc.PublicKey)(nil), "tendermint.crypto.PublicKey")
json.RegisterType((*pc.PublicKey_Ed25519)(nil), "tendermint.crypto.PublicKey_Ed25519")
json.RegisterType((*pc.PublicKey_Secp256K1)(nil), "tendermint.crypto.PublicKey_Secp256K1")
}

// PubKeyToProto takes crypto.PubKey and transforms it to a protobuf Pubkey
Expand All @@ -24,6 +26,12 @@ func PubKeyToProto(k crypto.PubKey) (pc.PublicKey, error) {
Ed25519: k,
},
}
case secp256k1.PubKey:
kp = pc.PublicKey{
Sum: &pc.PublicKey_Secp256K1{
Secp256K1: k,
},
}
default:
return kp, fmt.Errorf("toproto: key type %v is not supported", k)
}
Expand All @@ -41,6 +49,14 @@ func PubKeyFromProto(k pc.PublicKey) (crypto.PubKey, error) {
pk := make(ed25519.PubKey, ed25519.PubKeySize)
copy(pk, k.Ed25519)
return pk, nil
case *pc.PublicKey_Secp256K1:
if len(k.Secp256K1) != secp256k1.PubKeySize {
return nil, fmt.Errorf("invalid size for PubKeyEd25519. Got %d, expected %d",
len(k.Secp256K1), secp256k1.PubKeySize)
}
pk := make(secp256k1.PubKey, secp256k1.PubKeySize)
copy(pk, k.Secp256K1)
return pk, nil
default:
return nil, fmt.Errorf("fromproto: key type %v is not supported", k)
}
Expand Down
Loading

0 comments on commit 6f908eb

Please sign in to comment.