Hi everyone,
I played with equihash algorithm for the last week or two. It appears that the only global information need to be stored in the global memory is the tree of collision pairs. The rest can be implemented locally for each layer k - thanks to Tromp for the idea.
I’m not on the market, so do not think will have a profit by myself implementing it. So I post it here, and would be interested to see how greedy the community is.
The algorithm is layered in stages with each stage can be implemented as a separate device. The downside is that each parameter set need its own arrangement.
Algorithm:
Layer 0: Compute hashes for 2[1] consecutive indexes. Submit each hash for each index to the next layer one at a time (currently 200 bits per clock cycle, or 2 cyclesdepending on the pins count).
Each hash can be seen as an array of (k+1) digits of size n/(k+1), currently 10 digits 20 bits each.
Layer 1.
This and the later layers have 2[2] buckets containing, say 4 or 5 or to be determined to be statistically efficient elements (on average there are 2 elements, but we need more for the algorithm to work). Each element consists of the following fields {
index - the index produces this hash,
remaining hash - last k digits of hash.
}. On top of it we have counter of the number of items in a bucket.
Fill in buckets:
for each input:
We put the last k digits into first free slot in the bucket with index equal to the first digit, store the index of this hash and increment the number of elements in this bucket.
Outcome:
Each bucket contains only the elements starting from the same digit → xor of these and only these elements is 0.
Transmit to upper layer:
for each bucket take all pairs (if the number of elements are greater than 1) and
- store a sorted pair of corresponding indeces in global memory
- submit to next layer one at a time:
a. xor value of the remainig part of the hashes in the pair
b. smallest index
c. reference to stored pair
Layer 0 done.
Layer 1:9
Fill in buckets:
For each pair put the obtained index, reference to stored pair and all digits of received hash except the first one in the first available slot in the bucket corresponding to the first digit. If the bucket if full either drop pair of stop algorithm (it depends on the statistics, that need to be determined in simulated experiments, what is more efficient).
Then transmit to upper layer as described in the Layer 0, except we need to check if the smallest indexes for each element in a pair are different.
Last Layer:
as a hash we get just a single hash digit. if it is 0 this is a solution. using stored references we need to recurcevly collect indexes of the solution.
Done.
ZCash: t1QcpGrXBhx7K5f5Lgw9mzhyBEx44Bnk73P