Skip to content

Conversation

GiacomoPope
Copy link
Contributor

@GiacomoPope GiacomoPope commented Mar 11, 2024

This PR removes the call to _points_fast_sqrt() for computing the set of all points as it (seems) to always be slower than using _points_via_group_structure().

While performing this change, I also attempted to clean up the code and simplify / clarify certain docstrings.

Justification

When a curve is defined over a prime order finite field with order larger than 50, the set of all points is computed using the group structure of the curve.

However, when a curve is implemented over a non-prime field or a field with order less than 50, the set of all points is instead computed by brute-force enumeration by checking all x-coordinates.

For all cases I have tested, this enumeration is slower.

Small characteristic, prime field

When p < 50:

sage: E = EllipticCurve(GF(11), [1,1])
sage: %timeit E._points_via_group_structure()
165 µs ± 8.19 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
sage: %timeit E._points_fast_sqrt()
366 µs ± 34.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
sage: sorted(E._points_via_group_structure()) == sorted(E._points_fast_sqrt())
True

When p > 50

sage: E = EllipticCurve(GF(163), [1,1])
sage: %timeit E._points_via_group_structure()
2.49 ms ± 40.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
sage: %timeit E._points_fast_sqrt()
4.1 ms ± 112 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
sage: sorted(E._points_via_group_structure()) == sorted(E._points_fast_sqrt())
True

Small characteristic, non-prime field

When the order is smaller than 50:

sage: E = EllipticCurve(GF(2^5), [1,0,1,0,1])
sage: %timeit E._points_via_group_structure()
277 µs ± 10.2 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
sage: %timeit E._points_fast_sqrt()
2.96 ms ± 135 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
sage: sorted(E._points_via_group_structure()) == sorted(E._points_fast_sqrt())
True

When the order is larger than 50:

sage: E = EllipticCurve(GF(11^3), [1,1])
sage: %timeit E._points_via_group_structure()
15.6 ms ± 1.17 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)
sage: %timeit E._points_fast_sqrt()
71.4 ms ± 2.94 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
sage: sorted(E._points_via_group_structure()) == sorted(E._points_fast_sqrt())
True

Further comments

  • The commit which introduced _points_fast_sqrt() as a method implemented it for hyperelliptic curves over finite fields and then added HyperellipticCurve_finite_field as a parent to EllipticCurve_finite_field to inherit this function. With the removal of the slower _points_fast_sqrt(), this parent inheritance has been removed.

  • ruff noticed that from sage.sets.set import Set was unused, so I removed it

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation accordingly.

@edgarcosta
Copy link
Member

LGTM

Copy link

Documentation preview for this PR (built with commit 0e285f6; changes) is ready! 🎉

@vbraun vbraun merged commit fd7608f into sagemath:develop Mar 31, 2024
@GiacomoPope GiacomoPope deleted the simplify_elliptic_points branch April 1, 2024 01:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants