How Monero's proof of work works
Monero’s proof of work is called RandomX. Unlike Bitcoin’s SHA-256, which runs the same tiny hash function on every attempt, RandomX asks miners to execute a small random program on a virtual machine, hit memory hard while doing it, and then hash the result. The goal is to make efficient mining look as much like a normal CPU workload as possible — and to make custom ASIC design much harder. ## Overview RandomX takes two inputs: a key K (derived from an older block hash, changed roughly every 2.8 days) and a hashing input H (the candidate block header plus a nonce, changed with every attempt). The key builds a large shared memory dataset; the per-attempt input seeds a virtual machine that runs 8 chained programs. The final machine state is hashed into a 256-bit output. If that output is below the network target, the block is valid. ## Step-by-step: what a miner actually computes 1. **Build the cache from the key.** RandomX runs Argon2d on K to produce a 256 MiB cache. Argon2d is memory-hard, forcing the machine to touch a lot of memory. 2. **Expand the cache into the dataset.** From that cache, RandomX builds a dataset of about 2080 MiB (2,147,483,648 bytes base + 33,554,368 bytes extra). This is read-only during hashing and forces regular DRAM traffic — each program iteration reads one 64-byte dataset item, totaling 16,384 reads per hash. 3. **Initialize the scratchpad from the block input.** RandomX computes Hash512(H) using Blake2b, then uses an AES-based generator to fill a 2 MiB scratchpad. The scratchpad is split to mimic CPU cache levels: 16 KiB L1, 256 KiB L2, 2 MiB L3. It is meant to live in CPU cache, not DRAM. 4. **Generate a random program.** RandomX generates a 256-instruction program for its virtual machine. Every instruction is 8 bytes long, and any 8-byte word is a valid instruction — so programs can be generated by filling a buffer with random bytes. Instructions include integer math, 64-bit multiplies, floating-point operations (IEEE 754 double precision, including division and square root, using all four rounding modes), 128-bit vector operations, memory loads and stores, and occasional branches. 5. **Run the program loop.** The VM executes the 256-instruction program in a loop for 2048 iterations. Each iteration reads about 504 bytes from memory and writes
