As mentioned in the What is Ristretto chapter, Ristretto defines a new point type, together with formulas for encoding, decoding, equality checking, and hash-to-point operations.
This chapter contains explicit formulas for these operations, aimed at implementors.
A note on type safety
Ristretto points are represented by curve points, but they are not curve points. Not every curve point is a representative of a Ristretto point. The Ristretto group is not a subgroup of the curve, and the Ristretto group is logically distinct from the group of curve points.
For these reasons, Ristretto points should have a different type than curve points, and it should be a type error to mix them. In particular, it's dangerous and unsafe to implement the Ristretto functions as operating on arbitrary curve points, rather than only on the representatives contained in a distinct Ristretto point type.
Implementing Ristretto using an existing Edwards curve implementation requires the following:
- A distinct type for Ristretto points which forwards curve operations on points to their corresponding canonical representative in the Ristretto group (as mentioned in the previous section);
- A function for decoding (so that only the canonical encoding of a coset is accepted);
- A function for encoding (so that two representatives of the same coset are encoded as identical bitstrings);
- A function for equality checking (so that two representatives of the same coset are considered equal);
- A function for hashing to the Ristretto group.
Implementation of these functions requires an inverse square root
function. This is often inlined into a point decompression function,
so we also give formulas for implementing an inverse square root for