Skip to content

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:

consensus-logic

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,

  1. it must prevote for the block it is locked on
  2. 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.
hash functions
  • tmhash: Tendermint implementation of SHA256 hash.
  • hash: included in tmhash.
encryption random number generators
  • 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.
serilization/deserialization

References

Consensus Signing Light Client
  • 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)).
Serialization/DeSerialization Staking Additional

[24] See Cosmos IBC documentation

[25] See Cosmos Hub overview

[26] See Tendermint Core documentation