Overview of the remaining course topics: Cryptography, different consensus protocols, details on Bitcoin/Ethereum, presentations on DeFi primitives, DAOs, NFTs, Scaling, MEV, zk-tech.
Hash functions
Hash function is a function that
- has input = any string (in reality there is a large upper bound, bits is common);
- has ouput = some fixed size number (often 256-bit);
- is efficiently computable, which means computation for n-bit string takes O(n) time.
You should think of a hash function as a map
Example: computing the remainder: H(x)= x (mod 97).
Applications: checksums to detect typos.
- 3. Checksums are also used in credit cards, vin numbers (US and Canada)
Such simple hash functions are helpful to detect accidents, but not to prevent attacks. For example, these two IBANs are very similar but have the same checksum, and so an attacker may try to sub one with the other in order to steal money:
CH5604835012345678009 vs CH5604835012345687709
The above is an example of a collision. To prevent attacks we need:
Cryptographic(ally secure) hash function is a hash function satisfying:
- Collision resistance
- Pre-image resistance
- Puzzle-friendliness (intuitively ”uniform randomness”)
Let’s take a close look at these properties. (Later on we will also cover the construction of hash functions.)
Cryptographic hash functions: properties and applications.
1. Collision resistance
2. Pre-image resistance
3: Puzzle-friendliness (intuitively ”uniform randomness”)
Cryptographic hash functions: construction
There are several components that we need to introduce:
(1) Block ciphers (cryptography’s workhorse construction)
(2) Compression functions
(3) Davies-Meyer construction
(4) Merkle-Damgrad paradigm
SHA-256 example (hash function used in Bitcoin)
- Block cipher is chosen: SHACAL-2 (x (256 bit), k (512 bit) ) → x’ (256 bit)
- Compression function is constructed using the Davies-Meyer method: h( H (256 bit) , m (512 bit) ) = SHACAL-2 ( H, m ) H
- SHA-256 hash function is constructed using the Merkle-Damgrad paradigm.
Hash pointers and Merkle trees
Hash pointer is a data structure that consists of: (1) a pointer to where data is stored; (2) hash of that data.
Whereas a regular pointer gives you a way to retrieve the information, a hash pointer also gives you a way to verify that the information hasn’t changed.
Block chain data structure is a sequence of blocks with hash pointers to previous blocks.
The key property of a block chain data structure is that it is temper evident, which means that by storing the head of a blockchain, any alteration of previous data will result in a change of our hash.
Merkle tree is another data structure that uses hash pointers. Each hash is obtained by concatenating the two lower hashes and taking their hash.
It is also temper evident, but has the following advantages over the block chain:
- Proof of membership. Given n pieces of data (above n=4), only about log(n) hashes are needed in order to prove that some particular piece of data is stored in a Merkle tree.
If a “light client” knows the root hash and wants to be convinced that data3 is stored in the merkle tree, a “full-node” (the one that stores the merkle tree) only needs to send the 2 green hashes to “light-client”. Note that .
- Proof of non-membership. If pieces of data are sorted (lexicographically, say), then proof of non-membership requires O(log(n)) items to be shown. (just show that two consecutive items are stored, and the item in question would need to be between them)
Super-important blockchain applications of Merkle trees. (explained here)
- In Bitcoin, full nodes store all txs inside Merkle trees (takes hundreds of GBs), while light clients (= wallets) store only the hash roots, and can prove membership of transactions in a fast manner by asking full nodes for merkle proofs.
- In Ethereum, not only txs are stored in a Merkle tree, but also the Ehereum state is stored in a Merkle tree. There are also Merkle trees for txs receipts and for storages of smart contracts (see the diagraь below).
- Archival nodes: in each block they store all txs + all Ethereum state in Merkle trees.
- Full nodes (typical node): in each block they store all txs in Merkle trees and store only the Merkle root of Ethereum state; can query archival nodes for the state.
- Light clients (wallets): in each block they store Merkle root of txs and Merkle root of Ethereum state; can query archival nodes for states (usually this is done by a central provider), and full nodes for txs.
Various Ethereum nodes: