Cosmos
-date: 2023-02-04
- last updated: 2023-02-04
Overview
Cosmos is the hub to almost 50 blockchains based on the Tendermint consensus engine and Inter-Blockchain Communication (IBC) protocol. It is also one of the earliest proponents for cross-chain communication and defined the first set of communication specificiations24. From a purely technical point of view, the signature scheme for signing blocks, Ed25519, is also often used in many other protocols, such as NEAR.
Cosmos Hub itself has 175 validators25 and is built upon Tendermint, in which validators sign blocks using EdDSA on Curve25519 (i.e., Ed25519)26.
Consensus Mechanism
For a deep dive on Tendemints Consensus, please read The latest gossip on BFT consensus: The paper presents Tendermint, a new protocol for ordering events in a distributed network under adversarial conditions.
Following is an excerpt from What is Tendermint
Tendermint is an easy-to-understand, mostly asynchronous, BFT consensus protocol. The protocol follows a simple state machine that looks like this:
Participants in the protocol are called validators; they take turns proposing blocks of transactions and voting on them. Blocks are committed in a chain, with one block at each height. A block may fail to be committed, in which case the protocol moves to the next round, and a new validator gets to propose a block for that height. Two stages of voting are required to successfully commit a block; we call them pre-vote and pre-commit. A block is committed when more than 2/3 of validators pre-commit for the same block in the same round.
There is a picture of a couple doing the polka because validators are doing something like a polka dance. When more than two-thirds of the validators pre-vote for the same block, we call that a polka. Every pre-commit must be justified by a polka in the same round.
Validators may fail to commit a block for a number of reasons; the current proposer may be offline, or the network may be slow. Tendermint allows them to establish that a validator should be skipped. Validators wait a small amount of time to receive a complete proposal block from the proposer before voting to move to the next round. This reliance on a timeout is what makes Tendermint a weakly synchronous protocol, rather than an asynchronous one. However, the rest of the protocol is asynchronous, and validators only make progress after hearing from more than two-thirds of the validator set. A simplifying element of Tendermint is that it uses the same mechanism to commit a block as it does to skip to the next round.
Assuming less than one-third of the validators are Byzantine, Tendermint guarantees that safety will never be violated - that is, validators will never commit conflicting blocks at the same height. To do this it introduces a few locking rules which modulate which paths can be followed in the flow diagram. Once a validator precommits a block, it is locked on that block. Then,
- it must prevote for the block it is locked on
- it can only unlock, and precommit for a new block, if there is a polka for that block in a later round
Signing Mechanism
Below is an excerpt from Tendermint Specification
Tendermint uses Protobuf Oneof to distinguish between different types public keys, and signatures. Additionally, for each public key, Tendermint defines an Address function that can be used as a more compact identifier in place of the public key.
Key Types
Each type specifies it's own pubkey, address, and signature format.
Ed25519
The address is the first 20-bytes of the SHA256 hash of the raw 32-byte public key:
address = SHA256(pubkey)[:20]
The signature is the raw 64-byte ED25519 signature.
Tendermint adopted zip215 for verification of ed25519 signatures.
Note: This change will be released in the next major release of Tendermint-Go (0.35).
Secp256k1
The address is the first 20-bytes of the SHA256 hash of the raw 32-byte public key:
address = SHA256(pubkey)[:20]
Following is an excerpt from Tendermint docs: Validator Keys
Currently Tendermint uses Ed25519 (opens new window)keys which are widely supported across the security sector and HSMs.
Code Review
Signing
- ed25519: Sign produces a signature on the provided message. This assumes the privkey is wellformed in the golang format. The first 32 bytes should be random, corresponding to the normal ed25519 private key. The latter 32 bytes should be the compressed public key. If these conditions aren't met, Sign will panic or produce an incorrect signature.
- secp256k1
- sr25519
- codec.go: Tranforms protobuf publick key to crypto public keys and vice versa. Support secp256k1 and edd25519.
Consensus
- consensus
- state: State handles execution of the consensus algorithm. It processes votes and proposals, and upon reaching agreement, commits blocks to the chain and executes them against the application. The internal state machine receives input from peers, the internal validator, and from a timer.
Cryptographic Primitives
general primitives- bits: BitArray is a thread-safe implementation of a bit array.
- bytes: Byte functions including marshalling and unmarshalling into JSON as well as fingerprint which returns the first 6 bytes of a byte slice.
- clist: provide a goroutine-safe linked-list. This list can be traversed concurrently by any number of goroutines. However, removed CElements cannot be added back.
- cmap: a goroutine-safe map
- flowrate: provides the tools for monitoring and limiting the flow rate of an arbitrary data stream.
- json: provides functions for marshaling and unmarshaling JSON in a format that is backwards-compatible with Amino JSON encoding. This mostly differs from encoding/json in encoding of integers (64-bit integers are encoded as strings, not numbers), and handling of interfaces (wrapped in an interface object with type/value keys).
- math: math functions including fractions and safemath.
- pubsub: implements a pub-sub model with a single publisher (Server) and multiple subscribers (clients).
- strings: string manipulation functions.
- armor: implementation of OpenPGP ASCII Armor.
- xchacha20poly1305: Tendermint implementation of ChaCha20-Poly1305 an authenticated encryption with additional data (AEAD) algorithm, that combines the ChaCha20 stream cipher with the Poly1305 message authentication code.
- xsalsa20symmetric: Tendermint implementation of Salsa20.
- random.go: only uses the OS's randomness. CRandHex returns a hex encoded string that's floor(numDigits/2) *2 long.*Note: CRandHex(24) gives 96 bits of randomness that are usually strong enough for most purposes.*
- rand: prng, that is seeded with OS randomness. The OS randomness is obtained from crypto/rand, however none of the provided methods are suitable for cryptographic usage. They all utilize math/rand's prng internally. All of the methods here are suitable for concurrent use. This is achieved by using a mutex lock on all of the provided methods.
References
Consensus- Tendermint Byzantine Consensus Algorithm Specification: Specification for Tendermints Consensus including state machine, background gossip (messaging) and proofs.
- Tendermint Consensus Overview: Tendermint Consensus Overview Documentation.
- Proposer Selection Procedure Specification: Specifies the Proposer Selection Procedure that is used in Tendermint to choose a round proposer for its "leader-based-protocol".
- Ed25519: high-speed high-security signatures: Ed25519 Signature Information
- High-speed high-security signatures: Paper introducing Ed25519 signatures
- Tendermint Validator Keys: Tendermint Documentation highlighting the use of Ed25519 keys for validators.
- Tendermint Public Key Cryptography: Documenation on Tendermints Public Key Cryptography.
- Tendermint Crypto Code Base: crypto is the cryptographic package adapted for Tendermint's uses (go)
- key.go: Tendermint Validator Key Management(go). LoadOrGenNodeKey attempts to load the NodeKey from the given filePath. If the file does not exist, it generates and saves a new NodeKey.
- ed25519.go: Used for signing messages with an ed25519 private key.
- Light Client: he objective of the light client protocol is to get a commit for a recent block hash where the commit includes a majority of signatures from the last known validator set. From there, all the application state is verifiable with merkle proofs.
- tendermint light package(go): Tendermint light clients allow bandwidth & compute-constrained devices, such as smartphones, low-power embedded chips, or other blockchains to efficiently verify the consensus of a Tendermint blockchain. This forms the basis of safe and efficient state synchronization for new network nodes and inter-blockchain communication (where a light client of one Tendermint instance runs in another chain's state machine). (tendermint light source code(go)).