curve25519-dalek icon indicating copy to clipboard operation
curve25519-dalek copied to clipboard

Batch double-and-compress (on ristretto255) fails on the identity point

Open pornin opened this issue 2 years ago • 1 comments

RistrettoPoint::double_and_compress_batch() may fail if one of the input points is the Ristretto identity. The function computes, for each input point, the values e, f, g, and h (in a BatchCompressState structure) then inverts the product of all four values. All the inversions are performed in a call to FieldElement::batch_invert(). However, that function does not tolerate zeros as input; there is even an explicit assert!() to verify that all inputs are non-zero.

Values e and f can be zero for some points which all represent the Ristretto identity (namely, when the representative element is, on the twisted Edwards curve, a point of order 1, 2 or 8). In particular, you get that situation by using the point returned by RistrettoPoint::identity(). In that case, the corresponding input to batch_invert() is zero, and the assertion fails, which triggers a panic.

To fix this issue, it suffices to make batch_invert() tolerate zeros, returning zero as an "inverse" of itself (while zero is not formally invertible, returning zero as its own inverse works with the double-and-compress formulas). This can be done by "skipping" zeros (in a constant-time way, of course) in both passes of the batch invert function.

pornin avatar Jun 23 '22 20:06 pornin

PR #399 contains a fix.

pornin avatar Jun 23 '22 20:06 pornin

Closed in #399

rozbb avatar Nov 05 '22 15:11 rozbb