Mastering Monero: Notes

2020-08-13


These are notes on Mastering Monero. They are by no means exhaustive. I have skipped portions here and there based on my prior knowledge and what I wanted to record. The book itself isn't long, so any portion that I have skipped here can quickly be referenced in the source.


Introduction to Cryptocurrencies and Monero

In traditional banking there is no actual movement of assets. Two banks simply edit their databases to reflect that funds have been transferred.

Blockchains are a technology allowing networks to establish decentralized consensus. Sharing a ledger makes it possible to build currencies on top of a blockchain.

But pseudonymity is not ideal. When you receive a crypto payment, you don't learn the sender's name and only see their address. However, since anyone can access a complete copy of the entire blockchain on which every account balance and history is public, you can indirectly find out quite a bit of information about the sender. This is worse than the traditional banking system, in which you cannot simply find out a person's balance and entire history of txns.

Nicolas van Saberhagen published the CryptoNote protocol in 2013 and it became the foundation for the anonymously created Bytecoin. The anonymous user thankful_for_today revealed Bytecoin to have already been mostly mined and thus potentially dangerously centralized and so he incorporated the features into a new currency Monero launched in 2014.

Getting Started: Receiving, Storing and Sending Monero

A wallet handles all the cryptography so that you only need to manage a seed and address(es). The wallet uses the seed to locate and spend moneroj and to generate addresses. If you lose your seed, there is no way to recover access to your moneroj.

A hot wallet holds small amounts for day-to-day use, and a cold wallet is more secure and used for long-term savings or large amounts. You can connect your wallet to a remote node instead of storing the entire blockchain on your device. Nodes are computers that have downloaded the entire blockchain and sync others' wallets and relay others' txns. Running a node is different from mining.

Your address is never stored on the blockchain thanks to stealth addresses, and each seed can generate multiple subaddresses that all deposit to the same wallet. Each Monero account has a single primary address. Wallets may wait up to 20 minutes for confirmation before marking funds as received.

You can share a view-only version of your wallet, which can see incoming txns but cannot send or view outgoing funds (good for transparency). This involves sharing a secret view key.

You can use OpenAlias to get a human-readable Monero address.

You can check transaction keys in order to check proof of payment.

Operational security in keeping your funds safe:

How Monero Works

When you set up a wallet for the first time, it generates a new seed that is kept secret and used to access moneroj on the blockchain. Initialization is done on the device (can be offline).

A digital signature is a method for confirming the authenticity and source of data or a message.

In Bitcoin, each message explicitly declares which outputs are being spent. This is useful for maintaining a record of unspect txn outputs (UTXOs) which can be valid inputs for new txns. But such a straightfforward proof of ownership is bad for privacy. Monero has a lot of different privacy technologies:

The Monero network

When your wallet broadcasts a message, the network temporarily stores it in a list of pending txns called the memory pool. Miners collect these unconfirmed txns into blocks. Each block contains a set of txns, a hash pointer to the previous block, and a nonce which is a special string given by the miner.

A hash proves that each block is directly linked to an unaltered version of the previous block, so the smallest modification attempt by an attacker will raise a red flag on every subsequent block. The nonce is extremely computationally difficult to find. It is impossible to plan ahead for calculating the nonce.

Nodes are the backbone of the peer-to-peer network. All nodes are equal participants and are hosted on all sorts of computers. A newly initialized node downloads the entire blockchain and verifies the validity of each txn and block. It receives these transmissions from many peer nodes.

Miners collect unconfirmed txns from their memory pool, check their validity (proof, signatures, key image), draft a list of txns to include in a block, include a hash of the previous block, and work to find the nonce to complete the block. Upon finding the nonce, the miner announces their version of the block and the rest of the network appends it to their copy of the blockchain.

Network latency can cause momentary splits in the blockchain as two miners can independently complete two different block versions at the same height.

Finding the nonce that completes the block is a hard puzzle that is only solvable by brute force. A miner who successfully mines a block is paid in a block reward and in a txn fee.

A Proof of Work (PoW) system is one that couples important network functions with the search for a useless nonce. It enforces decentralization by requiring validation to be submitted with a nonce.

A Deep Dive Into Monero & Cryptography

Monero prints final addresses and keys in base-58 (similar to base-64 but modified to avoid ambigious characters).

The elliptic curve that Monero uses is called Twisted Edwards or Ed25519, which is the birational equivalent of the Montgomery curve Curve25519. It is expressed as $$-x^2+y^2=1-(\frac{121665}{121666})x^2y^2$$ which is the same as the general elliptic curve equation with parameters \(a=-1, b=\frac{121665}{121666}\).

Elliptic curve discrete logarithm problem: After adding the curve generator point to itself many times, the resulting point cannot be used to determine how many times the operation occured.

Whereas Bitcoin uses asymmetric encryption with just two keys (private key and public key), Monero uses a framework with four keys:

  1. Public view key: verify addresses validity

  2. Private view key: viewing balance, fees, txn amounts

  3. Public spend key: txn verification

  4. Private spend key: txn signing (i.e. sending moneroj)

The public address is a representation of the public view key and the public spend key, whereas Bitcoin uses a hash of the single public key.

A (collision-resistant) hash function is necessary for generating addresses and keys. Monero uses the CryptoNote hash algorithm which is built on SHA3 (designed by non-NSA engineers). CryptoNote is Keccak-256 with 32-byte output for both txn and block hashing. The user's operating system provides the initial seed/entropy source to which Monero repeatedly applies Keccak hashing, with each output serving as the input for the next hash.

A seed is a unique 256-bit integer, often represented as a 64-bit base-16 number or as a phrase which is a 24-"digit" base-1626 "number".

Even though Monero has built-in privacy with ring signatures, stealth addresses, and RingCT, data can still be collected "off-chain" (from other sources).

Calculating the stealth address to which to send according to CryptoNote: $$X=H(r*PubV|i)G+PubS$$ where \(r\) is the txn private key (256 bit scalar only known to sender) and \(i\) is the output index. The recipient scans the blockchain for txns belonging to him, takes the public txn key \(R\), and checks for which output \(X=H(PrivV*R|i)G+PubS\).

As an auditing feature, coinbase txn amounts are not masked. All other txns use RingCT which has two components:

Ring signatures cannot be cryptographically examined to determine the true signer. Every ring signature produces a key image derived from the output actually being spent, and the key image does not reveal the true signer. Since the network cannot identify which outputs are spent, it instead keeps track of the key images.

Monero stores its blockchain with the Lightning Memory Mapped Database (LMDB).

Blocks have three components: header, base txn, and list of txn IDs.

  1. Block header: major_version, minor_version, timestamp, prev_id, nonce

  2. Base txn (single txn for the coinbase reward): version, unlock_time, input_num=1, input_type=0xff, height, output_num, outputs

  3. Txn ID list: number of identifiers followed by the Keccak hashes of the txn bodies

  4. The block ID is a hash of the size of block_header, block_header, Merkle root hash, and number of txns. The Merkle root hash keeps the txns of a block tamper-free.

The block size is dynamic, unlike Bitcoin whose 1 MB fixed block size has caused scaling issues leading to bottlenecks that cause high fees and delayed processing. Monero on the other hand allows miners to use larger blocks to accomodate increased traffic but includes a penalty function that decreases the block reward for oversized blocks. For the median size of the last 100 blocks \(M_N\) and block size \(B\), if \(B>M_N\) and the block size is greater than 300 kB then the penalty is the base reward multiplied by \((\frac{B}{M_N}-1)^2\).

Larger txns incur a higher fee. Per kB, the fee is $$\frac{R}{R_\theta}*\frac{M_\theta}{M}*F_\theta*\frac{60}{300}*4$$ for the base reward, the reference base reward (10 XMR), the block size limit, the minimum block size limit (300 kB), and .002 XMR, respectively. This takes into account the increase in median block size relative to minimum block size.

Community and Contributing

Skipped

Monero integration for developers

Zooko's triangle: difficulty of designing name systems that are simultaneously decure, decentralized, and human-meaningful. Because Monero addresses are not human-meaningful, Monero Core Team released OpenAlias--a text DNS record containing a prefix and a recipient address--as a human-readable way to communicate addresses.

Developers integrating Monero can use Monero's C++ API or the remote procedure call (RPC) interface which is accessible with HTTP requests. RPC is simple to implement and allows generating addresses and subaddresses and transferring funds, but it does not scale effectively for big applications.

Plenty of development specifics skipped here. Refer to the source.