Ok, I’ll try.

Part I, the overall mining scheme since megacrypto has asked for it.

To mine you get a “work” which is first part of final block, consisting of version (4 bytes), prevhash (32), merkle root (32), reserved (32), time (4), bits (4) and nonce (32) total 140 bytes. When pool mining, you will get the first part of nonce from the pool, and only the second part you will choose by yourself. Otherwise if you sole mine then all nonce is yours.

Then you make 2**20 = 1048576 hashes, each is 50 bytes of BLAKE2b function of 140 bytes of “work” concatenated with 4 bytes of hash index. Then you split each hash in the middle to two strings of equal size, getting 2**21 = 2097152 strings of 25 bytes (200 bits) each. This requires at least 50 megabytes of memory, effectively kicking out modern FPGA and ASIC approaches to high performing mining for other coins.

Note, number 21 is equal to N / (K + 1) + 1 and number 200 is equal to N, where N = 200 and K = 9 are Equihash parameters chosen for Zcash.

Next you solve Wagner’s algorithm. What is it? You must peek 2**K = 512 different strings from those 2097152, such as binary XOR of them is zero. Moreover, some other properties of your selection must be assured. First, on each split by two of your indexes the left ones must be ordered, and second, on each split by two of your indexes resulting XOR of strings must have 20*height zero bits from the left. More on algorithm is in the part II.

When you find some solution (typical nonce provide around of two solutions on average), you fill the rest of block with solution length (3 bytes in special encoding always the same value 1344) and solution itself, which is encoded by 21 bits per index, thus 21*512 bits that is exactly 1344 bytes.

There is a target, which means the difficulty barrier. You make sha256 hash of sha256 hash of your total block of 140+3+1344=1487 bytes, and then your compare your double sha256 with the target. Below the target is good, and then you can propagate your block if sole or submit your job results if you do pool mining.

Caveat of bit ordering and start of indexing everywhere.

Part II, the Wagner’s algorithm, which is the core of Zcash mining.

You will make K+1=10 steps, and in the beginning you have 2097152 original strings of 25 bytes each (200 bits). On each step you will be interested in next 20 bits from those 200 bits strings, i.e. bits from 0 to 19 on first step, 0 to 39 on second etc (counting from zero from left). On each step you try to combine pairs of strings from previous step and keep only the pairs that have common interesting bits (in other words, XOR of which is zero in interesting bits). So, on each step you will get growing binary trees of indexes in the original strings: one index on step 1, two indexes on step 2, four indexes on step 3 etc. Note that all indexes in one tree must be unique. At the final step you will have 512 unique indexes combined into desired properties of the algorithm.

There are some optimizations implemented in reference miner and more optimizations in winners of miner contest. Basically it’s about peeking correct pairs. Note that you don’t need to try each index to each, you can first sort them and then try to combine only while interested bits are the same (reference miner), or you can put strings in the buckets indexed by interesting bits (other miners), and keep those buckets compact to fit into processor caches (that’s the key of speed). Also, you can do things in parallel to use multicore CPU and GPU advantages.