You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
11 KiB

  1. # Tendermint Encoding
  2. ## Amino
  3. Tendermint uses the proto3 derivative [Amino](https://github.com/tendermint/go-amino) for all data structures.
  4. Think of Amino as an object-oriented proto3 with native JSON support.
  5. The goal of the Amino encoding protocol is to bring parity between application
  6. logic objects and persistence objects.
  7. Please see the [Amino
  8. specification](https://github.com/tendermint/go-amino#amino-encoding-for-go) for
  9. more details.
  10. Notably, every object that satisfies an interface (eg. a particular kind of p2p message,
  11. or a particular kind of pubkey) is registered with a global name, the hash of
  12. which is included in the object's encoding as the so-called "prefix bytes".
  13. We define the `func AminoEncode(obj interface{}) []byte` function to take an
  14. arbitrary object and return the Amino encoded bytes.
  15. ## Byte Arrays
  16. The encoding of a byte array is simply the raw-bytes prefixed with the length of
  17. the array as a `UVarint` (what proto calls a `Varint`).
  18. For details on varints, see the [protobuf
  19. spec](https://developers.google.com/protocol-buffers/docs/encoding#varints).
  20. For example, the byte-array `[0xA, 0xB]` would be encoded as `0x020A0B`,
  21. while a byte-array containing 300 entires beginning with `[0xA, 0xB, ...]` would
  22. be encoded as `0xAC020A0B...` where `0xAC02` is the UVarint encoding of 300.
  23. ## Public Key Cryptography
  24. Tendermint uses Amino to distinguish between different types of private keys,
  25. public keys, and signatures. Additionally, for each public key, Tendermint
  26. defines an Address function that can be used as a more compact identifier in
  27. place of the public key. Here we list the concrete types, their names,
  28. and prefix bytes for public keys and signatures, as well as the address schemes
  29. for each PubKey. Note for brevity we don't
  30. include details of the private keys beyond their type and name, as they can be
  31. derived the same way as the others using Amino.
  32. All registered objects are encoded by Amino using a 4-byte PrefixBytes that
  33. uniquely identifies the object and includes information about its underlying
  34. type. For details on how PrefixBytes are computed, see the [Amino
  35. spec](https://github.com/tendermint/go-amino#computing-the-prefix-and-disambiguation-bytes).
  36. In what follows, we provide the type names and prefix bytes directly.
  37. Notice that when encoding byte-arrays, the length of the byte-array is appended
  38. to the PrefixBytes. Thus the encoding of a byte array becomes `<PrefixBytes> <Length> <ByteArray>`. In other words, to encode any type listed below you do not need to be
  39. familiar with amino encoding.
  40. You can simply use below table and concatenate Prefix || Length (of raw bytes) || raw bytes
  41. ( while || stands for byte concatenation here).
  42. | Type | Name | Prefix | Length | Notes |
  43. | ------------------ | ----------------------------- | ---------- | -------- | ----- |
  44. | PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | |
  45. | PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | |
  46. | PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | |
  47. | PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | |
  48. | SignatureEd25519 | tendermint/SignatureEd25519 | 0x2031EA53 | 0x40 | |
  49. | SignatureSecp256k1 | tendermint/SignatureSecp256k1 | 0x7FC4A495 | variable |
  50. |
  51. ### Examples
  52. 1. For example, the 33-byte (or 0x21-byte in hex) Secp256k1 pubkey
  53. `020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9`
  54. would be encoded as
  55. `EB5AE98221020BD40F225A57ED383B440CF073BC5539D0341F5767D2BF2D78406D00475A2EE9`
  56. 2. For example, the variable size Secp256k1 signature (in this particular example 70 or 0x46 bytes)
  57. `304402201CD4B8C764D2FD8AF23ECFE6666CA8A53886D47754D951295D2D311E1FEA33BF02201E0F906BB1CF2C30EAACFFB032A7129358AFF96B9F79B06ACFFB18AC90C2ADD7`
  58. would be encoded as
  59. `16E1FEEA46304402201CD4B8C764D2FD8AF23ECFE6666CA8A53886D47754D951295D2D311E1FEA33BF02201E0F906BB1CF2C30EAACFFB032A7129358AFF96B9F79B06ACFFB18AC90C2ADD7`
  60. ### Addresses
  61. Addresses for each public key types are computed as follows:
  62. #### Ed25519
  63. First 20-bytes of the SHA256 hash of the raw 32-byte public key:
  64. ```
  65. address = SHA256(pubkey)[:20]
  66. ```
  67. NOTE: before v0.22.0, this was the RIPEMD160 of the Amino encoded public key.
  68. #### Secp256k1
  69. RIPEMD160 hash of the SHA256 hash of the OpenSSL compressed public key:
  70. ```
  71. address = RIPEMD160(SHA256(pubkey))
  72. ```
  73. This is the same as Bitcoin.
  74. ## Other Common Types
  75. ### BitArray
  76. The BitArray is used in block headers and some consensus messages to signal
  77. whether or not something was done by each validator. BitArray is represented
  78. with a struct containing the number of bits (`Bits`) and the bit-array itself
  79. encoded in base64 (`Elems`).
  80. ```go
  81. type BitArray struct {
  82. Bits int
  83. Elems []uint64
  84. }
  85. ```
  86. This type is easily encoded directly by Amino.
  87. Note BitArray receives a special JSON encoding in the form of `x` and `_`
  88. representing `1` and `0`. Ie. the BitArray `10110` would be JSON encoded as
  89. `"x_xx_"`
  90. ### Part
  91. Part is used to break up blocks into pieces that can be gossiped in parallel
  92. and securely verified using a Merkle tree of the parts.
  93. Part contains the index of the part in the larger set (`Index`), the actual
  94. underlying data of the part (`Bytes`), and a simple Merkle proof that the part is contained in
  95. the larger set (`Proof`).
  96. ```go
  97. type Part struct {
  98. Index int
  99. Bytes byte[]
  100. Proof byte[]
  101. }
  102. ```
  103. ### MakeParts
  104. Encode an object using Amino and slice it into parts.
  105. ```go
  106. func MakeParts(obj interface{}, partSize int) []Part
  107. ```
  108. ## Merkle Trees
  109. For an overview of Merkle trees, see
  110. [wikipedia](https://en.wikipedia.org/wiki/Merkle_tree)
  111. A Simple Tree is a simple compact binary tree for a static list of items. Simple Merkle trees are used in numerous places in Tendermint to compute a cryptographic digest of a data structure. In a Simple Tree, the transactions and validation signatures of a block are hashed using this simple merkle tree logic.
  112. If the number of items is not a power of two, the tree will not be full
  113. and some leaf nodes will be at different levels. Simple Tree tries to
  114. keep both sides of the tree the same size, but the left side may be one
  115. greater, for example:
  116. ```
  117. Simple Tree with 6 items Simple Tree with 7 items
  118. * *
  119. / \ / \
  120. / \ / \
  121. / \ / \
  122. / \ / \
  123. * * * *
  124. / \ / \ / \ / \
  125. / \ / \ / \ / \
  126. / \ / \ / \ / \
  127. * h2 * h5 * * * h6
  128. / \ / \ / \ / \ / \
  129. h0 h1 h3 h4 h0 h1 h2 h3 h4 h5
  130. ```
  131. Tendermint always uses the `TMHASH` hash function, which is the first 20-bytes
  132. of the SHA256:
  133. ```
  134. func TMHASH(bz []byte) []byte {
  135. shasum := SHA256(bz)
  136. return shasum[:20]
  137. }
  138. ```
  139. ### Simple Merkle Root
  140. The function `SimpleMerkleRoot` is a simple recursive function defined as follows:
  141. ```go
  142. func SimpleMerkleRoot(hashes [][]byte) []byte{
  143. switch len(hashes) {
  144. case 0:
  145. return nil
  146. case 1:
  147. return hashes[0]
  148. default:
  149. left := SimpleMerkleRoot(hashes[:(len(hashes)+1)/2])
  150. right := SimpleMerkleRoot(hashes[(len(hashes)+1)/2:])
  151. return SimpleConcatHash(left, right)
  152. }
  153. }
  154. func SimpleConcatHash(left, right []byte) []byte{
  155. left = encodeByteSlice(left)
  156. right = encodeByteSlice(right)
  157. return TMHASH(append(left, right))
  158. }
  159. ```
  160. Note that the leaves are Amino encoded as byte-arrays (ie. simple Uvarint length
  161. prefix) before being concatenated together and hashed.
  162. Note: we will abuse notion and invoke `SimpleMerkleRoot` with arguments of type `struct` or type `[]struct`.
  163. For `struct` arguments, we compute a `[][]byte` containing the hash of each
  164. field in the struct sorted by the hash of the field name.
  165. For `[]struct` arguments, we compute a `[][]byte` by hashing the individual `struct` elements.
  166. ### Simple Merkle Proof
  167. Proof that a leaf is in a Merkle tree consists of a simple structure:
  168. ```
  169. type SimpleProof struct {
  170. Aunts [][]byte
  171. }
  172. ```
  173. Which is verified using the following:
  174. ```
  175. func (proof SimpleProof) Verify(index, total int, leafHash, rootHash []byte) bool {
  176. computedHash := computeHashFromAunts(index, total, leafHash, proof.Aunts)
  177. return computedHash == rootHash
  178. }
  179. func computeHashFromAunts(index, total int, leafHash []byte, innerHashes [][]byte) []byte{
  180. assert(index < total && index >= 0 && total > 0)
  181. if total == 1{
  182. assert(len(proof.Aunts) == 0)
  183. return leafHash
  184. }
  185. assert(len(innerHashes) > 0)
  186. numLeft := (total + 1) / 2
  187. if index < numLeft {
  188. leftHash := computeHashFromAunts(index, numLeft, leafHash, innerHashes[:len(innerHashes)-1])
  189. assert(leftHash != nil)
  190. return SimpleHashFromTwoHashes(leftHash, innerHashes[len(innerHashes)-1])
  191. }
  192. rightHash := computeHashFromAunts(index-numLeft, total-numLeft, leafHash, innerHashes[:len(innerHashes)-1])
  193. assert(rightHash != nil)
  194. return SimpleHashFromTwoHashes(innerHashes[len(innerHashes)-1], rightHash)
  195. }
  196. ```
  197. ### Simple Tree with Dictionaries
  198. The Simple Tree is used to merkelize a list of items, so to merkelize a
  199. (short) dictionary of key-value pairs, encode the dictionary as an
  200. ordered list of `KVPair` structs. The block hash is such a hash
  201. derived from all the fields of the block `Header`. The state hash is
  202. similarly derived.
  203. ### IAVL+ Tree
  204. Because Tendermint only uses a Simple Merkle Tree, application developers are expect to use their own Merkle tree in their applications. For example, the IAVL+ Tree - an immutable self-balancing binary tree for persisting application state is used by the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/sdk/core/multistore.md)
  205. ## JSON
  206. ### Amino
  207. Amino also supports JSON encoding - registered types are simply encoded as:
  208. ```
  209. {
  210. "type": "<amino type name>",
  211. "value": <JSON>
  212. }
  213. ```
  214. For instance, an ED25519 PubKey would look like:
  215. ```
  216. {
  217. "type": "tendermint/PubKeyEd25519",
  218. "value": "uZ4h63OFWuQ36ZZ4Bd6NF+/w9fWUwrOncrQsackrsTk="
  219. }
  220. ```
  221. Where the `"value"` is the base64 encoding of the raw pubkey bytes, and the
  222. `"type"` is the amino name for Ed25519 pubkeys.
  223. ### Signed Messages
  224. Signed messages (eg. votes, proposals) in the consensus are encoded using Amino-JSON, rather than in the standard binary format
  225. (NOTE: this is subject to change: https://github.com/tendermint/tendermint/issues/1622)
  226. When signing, the elements of a message are sorted by key and prepended with
  227. a `@chain_id` and `@type` field.
  228. We call this encoding the CanonicalSignBytes. For instance, CanonicalSignBytes for a vote would look
  229. like:
  230. ```json
  231. {"@chain_id":"test_chain_id","@type":"vote","block_id":{"hash":"8B01023386C371778ECB6368573E539AFC3CC860","parts":{"hash":"72DB3D959635DFF1BB567BEDAA70573392C51596","total":"1000000"}},"height":"12345","round":"2","timestamp":"2017-12-25T03:00:01.234Z","type":2}
  232. ```