-
Notifications
You must be signed in to change notification settings - Fork 83
Description
Over a year ago, we discussed in a MRL meeting the uniformity of Monero's hash-to-point function. I raised the concern due to the complete lack of documentation and understanding, wanting to ensure the implementation was proper. In the worst case, the algorithm would presumably be biased by a few bits, reducing our security by ~2 bits.
I've spent the last ~13 hours working on this and come to the conclusion our implemented hash to point is in fact Elligator. Specifically, it's the Elligator 2 map applied to Curve25519 as detailed in Section 5.5 of the Elligator paper. This is distinct from Elligator 2 as specified in Section 5.2 and as seen in standards due to a slightly different choice in the second candidate x coordinate.
While the oddity of a slightly different specification isn't worth pushing the issue over, now that the answer has been found, what is worth pushing the issue over is how Elligator 2 is biased.
Fix r ∈ R, and write (x, y) = ψ(r). ... −ux(x+A) = −uv(v+A) = −uv(−vur2) = u2v2r2, which is a square.
The points output from Elligator 2 will only be the points whose x coordinates satisfy −ux(x+A) being square, which is only half of the points on the elliptic curve.
The solution is simply to invoke Elligator 2 twice, summing the result. This will make the bias negligible. With the FCMP++ upgrade, we'll no longer invoke a hash-to-point on historical outputs (requiring context on hold they are to determine which output to use), solely hashing them once upon accumulation (and never again). This, along with the fact it's already a hard fork, makes it a prime position to perform the upgrade during.
Additionally, we can discuss not just invoking Elligator 2 twice, yet moving to the standardized version as it'll have implementations already available, simplifying ecosystem development.