-
-
Notifications
You must be signed in to change notification settings - Fork 543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement elliptic-curve point addition for general rings #33228
Comments
comment:1
some failing doctests, see patchbot report |
Branch pushed to git repo; I updated commit sha1. New commits:
|
comment:4
Elliptic gurus, please say your word on these changes! |
comment:5
This is interesting -- as well as being the author of the "temporary hack", I also came across this issue when trying to implement Schoof's algorithm from basics wih a student. I'll take a look. |
comment:7
In case you are interested, Alex Best corrected some typos Bosma–Lenstra paper formulas for addition law for elliptic curves over a general ring, see Appendix A of https://open.bu.edu/bitstream/handle/2144/43150/Best_bu_0017E_16371.pdf I bet he must have them implemented somewhere... |
comment:8
Replying to @edgarcosta:
Interesting, thanks! Generalizing the formulas to not fail when non-units are encountered was a next step on my list (and the original motivation to move Replying to @JohnCremona:
Sadly, this change alone does not yet allow implementing a straightforward Schoof (e.g., because the current addition formulas attempt to divide by zero divisors rather frequently in that context). But we'll get there! :-) |
comment:9
I reealise that it may be annoying to make comments about chunks of code which were just copied over but I would change the lines
to
where the first two are just python while the 3rd is simpler and mathematically equivalent. However, are you sure that the z-coordinate will always be 1 for nonzero points over non-fields? I will keep reading... |
comment:10
Another simplification: after the preceding check, if x1==x2 then also y1==y2 (unless you do not want me to assume that quadratics over non-fields have no more than 2 roots, in which case my previous suggestion may not be valid either):
Apart from these (which I know don't have much to do with your chenges) I think this looks good. Can you add at least one test to show that what used to work (over Z/NZ say) still does, and also something which used not to work but now does? |
Dependencies: #34417 |
This comment has been minimized.
This comment has been minimized.
comment:13
I've included Alex' version of the Bosma-Lenstra formulas to compute point additions over fairly general rings. One thing I'm not quite sure about is how to combine the results of the two formulas in case neither gives a valid projective point — in the current code, this is done by brute-forcing random linear combinations, but there must be a more algebraic way. (It's fairly straightforward for Bézout rings.) New commits:
|
comment:14
Looks pretty good to me. Here are some questions/suggestions.
I'll also give John Cremona a chance to take a look at this, since he was commenting on an earlier version. |
comment:15
Thanks for your comments.
|
comment:16
Since I was asked, I'll comment. Two points:
I think it could work to have some parameter to the elliptic curve constructor like
|
comment:17
Replying to @JohnCremona:
Of course; the patch does it like this already. The 10× difference is between the field-specific formulas and the general formulas, not between before and after. The only case which is now slower (but more correct!) than before is |
comment:18
Replying to @yyyyx4:
Thanks for clarifying (and I know that I could also have looked at the code, but it is good to have this stated explicitly on the ticket). This deals with my second point, at least! |
comment:19
Two plugin issues:
There's also a doctest failure:
|
comment:20
Adapting the standard formulas to quotients of Euclidean domains seems reasonable. |
Branch pushed to git repo; I updated commit sha1. This was a forced push. Last 10 new commits:
|
comment:22
I had a shot at adapting the standard formulas to quotients of Euclidean domains. Performance comparison for a single point addition modulo
I think we don't need to add another hack to the sage: R = Zmod(13 * 17, is_field=True)
sage: E = EllipticCurve(R, [1,0])
sage: P = E.lift_x(4)
sage: 123*P
Traceback (most recent call last):
...
ZeroDivisionError: inverse of Mod(34, 221) does not exist Replying to David Roe:
That's #34417. |
comment:23
Replying to Lorenz Panny:
That's nice, however: sage: E = EllipticCurve(Zmod(35, is_field=True), [5,1])
sage: E.base_field()
...
AttributeError: 'EllipticCurve_generic_with_category' object has no attribute 'base_field' in fact sage: parent(E)
<class 'sage.schemes.elliptic_curves.ell_generic.EllipticCurve_generic_with_category'> so it would still need "the hack" (broken as of 9.6 and fixed in #34681). sage: parent(EllipticCurve(Zmod(7, is_field=True), [5,1]))
<class 'sage.schemes.elliptic_curves.ell_finite_field.EllipticCurve_finite_field_with_category'> Actually: sage: Zmod(35, is_field=True).is_field()
False so, what's the effect of |
comment:24
Also, this is potentially dangerous: sage: Zmod(35, is_field=True) is Zmod(35, is_field=False)
True This means the example above works after clearing the cache: sage: Zmod._cache.clear()
sage: E = EllipticCurve(Zmod(35, is_field=True), [5,1])
sage: E.base_field()
Ring of integers modulo 35 But then one might get a scary error message sage: Zmod(35).is_field(proof=True)
...
ValueError: THIS SAGE SESSION MIGHT BE SERIOUSLY COMPROMISED!
The order 35 is not prime, but this ring has been put
into the category of fields. This may already have consequences
in other parts of Sage. Either it was a mistake of the user,
or a probabilistic primality test has failed.
In the latter case, please inform the developers. |
…CurvePoint The method `EllipticCurve_generic.__contains__()` checks for inheritance from `EllipticCurvePoint`; however, the other classes for points on elliptic curves do not inherit from this class. This pull request fixes this. Note that there is some overlap with sagemath#33228. This change makes `P in E` much faster: - Over **Q**: ```python E = EllipticCurve('37a1') P = E((0, -1)) %timeit P in E ``` Before: `35.3 µs ± 186 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `324 ns ± 0.535 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` - Over a finite field: ```python F.<a> = FiniteField((23, 2), modulus='random') E = EllipticCurve_from_j(F.random_element()) P = E.random_point() %timeit P in E ``` Before: `36.4 µs ± 542 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `333 ns ± 5.03 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` URL: sagemath#37415 Reported by: Peter Bruin Reviewer(s): Kwankyu Lee, Peter Bruin
…CurvePoint The method `EllipticCurve_generic.__contains__()` checks for inheritance from `EllipticCurvePoint`; however, the other classes for points on elliptic curves do not inherit from this class. This pull request fixes this. Note that there is some overlap with sagemath#33228. This change makes `P in E` much faster: - Over **Q**: ```python E = EllipticCurve('37a1') P = E((0, -1)) %timeit P in E ``` Before: `35.3 µs ± 186 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `324 ns ± 0.535 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` - Over a finite field: ```python F.<a> = FiniteField((23, 2), modulus='random') E = EllipticCurve_from_j(F.random_element()) P = E.random_point() %timeit P in E ``` Before: `36.4 µs ± 542 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `333 ns ± 5.03 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` URL: sagemath#37415 Reported by: Peter Bruin Reviewer(s): Kwankyu Lee, Peter Bruin
…CurvePoint The method `EllipticCurve_generic.__contains__()` checks for inheritance from `EllipticCurvePoint`; however, the other classes for points on elliptic curves do not inherit from this class. This pull request fixes this. Note that there is some overlap with sagemath#33228. This change makes `P in E` much faster: - Over **Q**: ```python E = EllipticCurve('37a1') P = E((0, -1)) %timeit P in E ``` Before: `35.3 µs ± 186 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `324 ns ± 0.535 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` - Over a finite field: ```python F.<a> = FiniteField((23, 2), modulus='random') E = EllipticCurve_from_j(F.random_element()) P = E.random_point() %timeit P in E ``` Before: `36.4 µs ± 542 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `333 ns ± 5.03 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` URL: sagemath#37415 Reported by: Peter Bruin Reviewer(s): Kwankyu Lee, Peter Bruin
…CurvePoint The method `EllipticCurve_generic.__contains__()` checks for inheritance from `EllipticCurvePoint`; however, the other classes for points on elliptic curves do not inherit from this class. This pull request fixes this. Note that there is some overlap with sagemath#33228. This change makes `P in E` much faster: - Over **Q**: ```python E = EllipticCurve('37a1') P = E((0, -1)) %timeit P in E ``` Before: `35.3 µs ± 186 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `324 ns ± 0.535 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` - Over a finite field: ```python F.<a> = FiniteField((23, 2), modulus='random') E = EllipticCurve_from_j(F.random_element()) P = E.random_point() %timeit P in E ``` Before: `36.4 µs ± 542 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)` After: `333 ns ± 5.03 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)` URL: sagemath#37415 Reported by: Peter Bruin Reviewer(s): Kwankyu Lee, Peter Bruin
… rings Here we revive the effort from sagemath#33228 to implement point-addition formulas on elliptic curves over (more) general rings. This resolves sagemath#33228. URL: sagemath#39036 Reported by: Lorenz Panny Reviewer(s): Lorenz Panny, Vincent Macri
… rings Here we revive the effort from sagemath#33228 to implement point-addition formulas on elliptic curves over (more) general rings. This resolves sagemath#33228. URL: sagemath#39036 Reported by: Lorenz Panny Reviewer(s): Lorenz Panny, Vincent Macri
Currently, point addition for elliptic curves is only defined in
EllipticCurvePoint_field
and its children. This patch implements point arithmetic forEllipticCurvePoint
, while also keeping the specialized (faster) implementation for fields. This is useful for symbolic computations, such as the ones that show up in a basic version of Schoof's algorithm (where we compute in a polynomial ring modulo the ideal generated by a division polynomial and the curve equation).Another implication of this is that we can remove part of the "temporary" hack for elliptic-curve points over ℤ/n that was introduced in #1975.
Depends on #34417
Depends on #34463
CC: @JohnCremona @roed314 @edgarcosta @alexjbest
Component: elliptic curves
Author: Lorenz Panny
Branch/Commit: public/generalize_elliptic_curve_point_addition_to_rings @
940f8a2
Issue created by migration from https://trac.sagemath.org/ticket/33228
The text was updated successfully, but these errors were encountered: