* curve: add `EdwardsPoint::compress_batch` and `::random`
We've had various requests to implement batch point compression for
`EdwardsPoint`, e.g. #705.
We can leverage `FieldElement::batch_invert` to implement it, which
results in a fairly significant speedup.
The name `EdwardsPoint::compress_batch` has been chosen to match
`RistrettoPoint::double_and_compress_batch`.
For benchmarking, randomized `EdwardsPoint`s have been used. To obtain
these, an inherent `EdwardsPoint::random` has been extracted from the
existing `Group::random` implementation, which uses rejection sampling.
`Group::random` has been updated to call the inherent
`EdwardsPoint::random`. This avoids a `group` dependency just to run the
batch compression benchmarks.
The following benchmark results have been obtained:
edwards benches/EdwardsPoint compression
time: [3.5029 µs 3.5098 µs 3.5171 µs]
edwards benches/Batch EdwardsPoint compression/1
time: [3.6698 µs 3.6758 µs 3.6817 µs]
edwards benches/Batch EdwardsPoint compression/2
time: [3.8410 µs 3.8461 µs 3.8516 µs]
edwards benches/Batch EdwardsPoint compression/4
time: [4.1534 µs 4.1961 µs 4.2558 µs]
edwards benches/Batch EdwardsPoint compression/8
time: [4.8466 µs 4.8533 µs 4.8600 µs]
edwards benches/Batch EdwardsPoint compression/16
time: [6.1216 µs 6.1315 µs 6.1410 µs]
As you can see, it affords a fairly significant speedup, batch
compressing 16 points in less time than the standard point compression
algorithm would take to compress 2 in a row.