http://www.cs.cmu.edu/~dga/crypto/cuckoo/analysis.pdfVery hackish proof-of-concept:
http://www.cs.cmu.edu/~dga/crypto/cuckoo/partitioned.jlI'm releasing this well in advance of what I would normally do for academic work because I think it's worth pushing the discussion of proof-of-work functions forward fast -- crypto moves too fast these days -- but please be aware that it's not done yet and requires a lot more polish. The bottom line is as I suggested above: It successfully TMTO's but still requires something like 1-3% of the "full" graph space, because that's what gets passed to the solver after edge trimming. I don't think this is the final word in optimizing for cuckoo cycle -- I believe there are some further nifty optimizations possible, though I think this gets the first primary attack vector down.
John, I'd love your feedback on whether this is clear and/or needs help, or if you find some of the handwavy O(N) parts too vague to constitute a real threat. I plan to clean it up more, but, as noted, I figured that it's better to swallow my perfectionism and push the crappy version out there faster to get the dialogue rolling, since I don't have coauthors on it to push it in the right direction.
Feedback appreciated!
(The weakest part of the analysis, btw, is the growth rate of the dictionaries used to track the other live nodes. With 7 iterations of edge trimming, for example, they actually grow slightly larger than the original node set in a partition, but less than 2x its size in some spot checks. I need to think more carefully about how that affects some of the asymptotic factors.)
As an example of the latter, with a partition initially containing 16384 nodes:
609 live nodes at start of iteration 6
Size of hop 2 dictionary: 3140
Size of hop 3 dictionary: 4940
Size of hop 4 dictionary: 6841
Size of hop 5 dictionary: 8873
That's 23794 total dictionary entries, or 1.45x the initial partition size, and at iteration 7, it's grown to 26384, or 1.61x. It's not an exponential explosion, so I'm not worried about it invalidating the major part of the result, but it's the place where I or someone else should focus some algorithmic attention to reduce.
update 2: To run the julia code, install Julia, and then type:
include("partitioned.jl")
It's glacially slow. For the impatient, reduce the problem size from 2^27 to something smaller first, like 2^20, and the partition accordingly. (Note: I use "N" to mean the size of one half of the bipartite graph, whereas John's formulation uses it to include both, so n=2^27 is equivalent to john's 2^28)
Update 3: Herp derp. That dictionary growth was my stupidity - I forgot to not include the edge back to the node that caused the insertion in the first place, so it's got a little bit of accidental exponential growth. I'll fix that tomorrow. That should get it back to closer to the linear scaling I'd expected.
Update 4: Fixed that above silliness with adding back inbound edges. Much improved dictionary size, now in line with what it should have been:
647 live nodes at start of iteration 6
Size of hop 2 dictionary: 2803
Size of hop 3 dictionary: 3554
Size of hop 4 dictionary: 4152
Size of hop 5 dictionary: 4404
By the end of iteration 7, the sum of all dictionaries (for that run) was 15797, slightly less than the number of nodes in the original partition, so at least through 7 iterations, the space for dictionaries remains O(|P| log N). Empirically speaking only, of course, since I haven't really done that analysis as it needs to be.
Julia code file on the website updated.