Skip to content
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

Attach Jacobians to function fields and curves #35467

Merged
merged 9 commits into from
Apr 27, 2024

Conversation

kwankyu
Copy link
Collaborator

@kwankyu kwankyu commented Apr 9, 2023

📚 Description

We attach Jacobians to function fields and curves, enabling arithmetic with the points of the Jacobian. Fixes #34232.

A point of Jacobian is represented by an effective divisor D such that the point is the divisor class of D - B (of degree 0) with a fixed base divisor B.

There are two models for Jacobian arithmetic:

  • Hess model: D is internally represented by a pair of certain ideals and arithmetic relies on divisor reduction using Riemann-Roch space computation by Hess' algorithm.
  • Khuri-Makdisi model: D is internally represented by a linear subspace W_D of a linear space V and arithmetic uses Khuri-Makdisi's linear algebra algorithms. For implementation, Implement computations in picard groups via global sections of line bundles #15113 was referenced.

An example with non-hyperelliptic genus 3 curve:

sage: A2.<x,y> = AffineSpace(QQ, 2)
sage: f = y^3 + x^4 - 5*x^2*y + 2*x*y - x^2 - 5*y - 4*x + 1
sage: C = Curve(f, A2)
sage: X = C.projective_closure()
sage: X.genus()
3
sage: X.rational_points(bound=5)
[(0 : 0 : 1), (1/3 : 1/3 : 1)]
sage: Q = X(0,0,1).place()
sage: P = X(1,1,3).place()
sage: D = P - Q
sage: D.degree()
0
sage: J = X.jacobian(model='hess', base_div=3*Q)
sage: G = J.group()
sage: p = G.point(D)
sage: 2*p + 3*p == 5*p
True

An example with elliptic curve:

sage: k.<a> = GF((5,2))
sage: E = EllipticCurve(k,[1,0]); E
Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size 5^2
sage: E.order()
32
sage: P = E([a, 2*a + 4])
sage: P
(a : 2*a + 4 : 1)
sage: P.order()
8
sage: p = P.point_of_jacobian_of_curve()
sage: p
[Place (x + 4*a, y + 3*a + 1)]
sage: p.order()
8
sage: Q = 3*P
sage: q = Q.point_of_jacobian_of_curve()
sage: q == 3*p
True
sage: G = p.parent()
sage: G.order()
32
sage: G
Group of rational points of Jacobian over Finite Field in a of size 5^2 (Hess model)
sage: J = G.parent(); J
Jacobian of Projective Plane Curve over Finite Field in a of size 5^2
 defined by x^2*y + y^3 - x*z^2 (Hess model)
sage: J.curve() == E.affine_patch(2).projective_closure()
True  

An example with hyperelliptic curve:

sage: R.<x> = PolynomialRing(GF(11))
sage: f = x^6 + x + 1
sage: H = HyperellipticCurve(f)
sage: J = H.jacobian()
sage: D = J(H.lift_x(1))
sage: D  # divisor in Mumford representation
(x + 10, y + 6)
sage: jacobian_order = sum(H.frobenius_polynomial())
sage: jacobian_order
234
sage: p = D.point_of_jacobian_of_curve(); p
sage: p  # Jacobian point represented by an effective divisor
[Place (1/x0, 1/x0^3*x1 + 1)
 + Place (x0 + 10, x1 + 6)]
sage: p.order()
39
sage: 234*p == 0
True
sage: G = p.parent()
sage: G
Group of rational points of Jacobian over Finite Field of size 11 (Hess model)
sage: J = G.parent()
sage: J
Jacobian of Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 (Hess model)
sage: C = J.curve()
sage: C
Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2
sage: C.affine_patch(0) == H.affine_patch(2)
True  

Binder prepared with #36245

📝 Checklist

  • The title is concise, informative, and self-explanatory.
  • 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.

⌛ Dependencies

@kwankyu kwankyu changed the title Add jacobian groups to curves and function fields Add Jacobian groups to curves and function fields Apr 9, 2023
@kwankyu kwankyu changed the title Add Jacobian groups to curves and function fields Add Jacobians to function fields and curves Mar 8, 2024
@kwankyu kwankyu changed the title Add Jacobians to function fields and curves Add Jacobians to function fields and algebraic curves Mar 8, 2024
@kwankyu kwankyu force-pushed the add-jacobian-groups branch 6 times, most recently from ab83f91 to 07ca4e0 Compare March 10, 2024 11:58
@kwankyu kwankyu marked this pull request as ready for review March 10, 2024 12:33
@kwankyu kwankyu changed the title Add Jacobians to function fields and algebraic curves Attach Jacobians to function fields and curves Mar 11, 2024
@nbruin
Copy link
Contributor

nbruin commented Mar 11, 2024

Have you considered calling this the Picard group of smooth projective curves instead -- perhaps just the degree 0 part ? Note that the computations only work with divisors over k, so only divisor classes that admit such a representative can be computed with. The Jacobian would be a scheme whose rational points are galois-invariant divisor classes -- and there can be more of those than divisor classes containing a k-rational divisor (for instance, a genus 0 curve has a divisor class for each integer degree, but a pointless conic has no k-rational odd degree divisors).

In addition, Jacobians are more than just their set of rational points. For a rank 0 elliptic curve over Q, the rational points of the Jacobian for a finite group of order at most 12, but the Jacobian itself is isomorphic to the elliptic curve itself. There is quite a bit of explicit work on determining the Jacobian of a genus 1 curve (as an elliptic curve), and that is quite fundamentally using more/different things than just the set of rational points on that Jacobian.

I realize that in cryptographic parlance "Jacobian" and "degree 0 Picard group" often get used interchangeably, but it really gets you in conceptual problems when you move beyond cryptography.

@kwankyu
Copy link
Collaborator Author

kwankyu commented Mar 12, 2024

First thank you for attention. I need input from experts. (fix me if I am loose in the mathematics)

Have you considered calling this the Picard group of smooth projective curves instead -- perhaps just the degree 0 part ?

I thought about it. But the implemented "Jacobian" is something between the Picard group and the Jacobian. So I stuck to the name.

I think the situation is close to that of "algebraic closure" (of a finite field). The implemented "algebraic closure" is essentially a system of finite extensions of the base finite field but makes an illusion of the algebraic closure by manipulating with the system. However there is no Galois group attached to it.

The implemented "Jacobian" of class Jacoban is a system of groups of rational points (represented by divisor classes) over extensions of the base field (of the underlying function field). Each of the groups is the divisor class group (isomorphic to the Picard group of invertible sheaves of degree 0). Here the group is of class JacobianGroup. I tried to make an illusion of the Jacobian by implementing coercing mechanism between the groups.

sage: k = GF(11)
....: R.<x> = PolynomialRing(k)
....: f = x^6 + x + 1
....: H = HyperellipticCurve(f)
sage: J = H.jacobian()
....: D = J(H.lift_x(1))
....: p = D.point_of_jacobian_of_projective_curve()
....: p
[Place (1/x0, 1/x0^3*x1 + 1)
 + Place (x0 + 10, x1 + 6)]
sage: G = p.parent()
....: G
Group of rational points of Jacobian over Finite Field of size 11 (Hess model)
sage: p in G
True
sage: J = G.parent()
sage: J
Jacobian of Projective Plane Curve over Finite Field of size 11 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 (Hess model)
sage: p in J
True
sage: k2 = k.extension(2)
....: G2 = J.group(k2)
sage: k3 = k.extension(3)
....: G3 = J.group(k3)
sage: p2 = G2.get_points(10)[-1]
sage: p3 = G3.get_points(10)[-1]
sage: p2 in G2
True
sage: p3 in G3
True
sage: p2 in J
True
sage: p3 in J
True
sage: p6 = p2 + p3
sage: p6 in G2
False
sage: p6 in G3
False
sage: p6 in J
True

On the other hand, the implemented "Jacobian" is not a scheme. So it does not represent the Jacobian itself. Well, we may implement J.scheme() that returns a scheme (of Sage) as a subscheme of some ambient space. For elliptic curve case, this would be trivial. For cases of underlying curve of higher genus, this may be a daunting task that I cannot do.

... There is quite a bit of explicit work on determining the Jacobian of a genus 1 curve (as an elliptic curve), and that is quite fundamentally using more/different things than just the set of rational points on that Jacobian.

OK. I don't know...

I realize that in cryptographic parlance "Jacobian" and "degree 0 Picard group" often get used interchangeably, but it really gets you in conceptual problems when you move beyond cryptography.

I agree. In the implementation, I am using the class JacobianGroup for the degree 0 Picard group. I am not sure if DivisorClassGroup or PicardGroup might be better choice. Perhaps we may reserve PicardGroup for when we implement sheaves on curves...

@nbruin
Copy link
Contributor

nbruin commented Mar 12, 2024

It looks to me you are really providing divisor class groups. Particularly, your example seems to show a positive linear combination of places on the curve. That would not be of degree 0, so the class represented by that divisor is NOT a degree 0 class and hence NOT an element in Pic^0. So that's not even a point on the Jacobian.

It looks like you do have a distinction between the "jacobian" and the "point sets". That gets a little closer to the Jacobian, but I'm not sure that really gets you anything more than divisor class groups.

There may be some mileage to be gotten from allowing divisor class groups over proper extensions of the field of definition of the curve.

I would recommend to first just implement divisor class groups. Those are already hugely useful. If it even becomes necessary to work with objects a little closer to the Jacobian, we can consider how those can be implemented, but then their points most likely would largely rely on divisor class groups.

You do want to clear up whether you allow for arbitrary divisor class arithmethic (I would recommend it, because that's what falls out of the algorithms anyway) or whether you want to restrict to degree 0 somewhere (computing in the kernel of the degree map will be useful sometimes)

@kwankyu
Copy link
Collaborator Author

kwankyu commented Mar 12, 2024

Ah, sorry! I wanted to "reply" but "edited" your comment by accident. Sorry that I deleted some of your comments.

@kwankyu
Copy link
Collaborator Author

kwankyu commented Mar 12, 2024

It looks to me you are really providing divisor class groups. Particularly, your example seems to show a positive linear combination of places on the curve. That would not be of degree 0, so the class represented by that divisor is NOT a degree 0 class and hence NOT an element in Pic^0. So that's not even a point on the Jacobian.

There is a fixed "base divisor" B which is effective of degree g (in Hess model). Every point (divisor class) is represented by a divisor D - B where D is an effective divisor of the same degree with B. For simplicity, the point is denoted by [D].

@kwankyu
Copy link
Collaborator Author

kwankyu commented Mar 12, 2024

In the lost comment of yours, you suggested me to implement divisor class group first...

This PR did it. No? I don't understand...

@kwankyu
Copy link
Collaborator Author

kwankyu commented Mar 12, 2024

There is a fixed "base divisor" B which is effective of degree g (in Hess model). Every point (divisor class) is represented by a divisor D - B where D is an effective divisor of the same degree with B. For simplicity, the point is denoted by [D].

The base divisor can be provided by the user, but it is automatically chosen otherwise. In the above example,

sage: J.base_divisor()
2*Place (1/x0, 1/x0^3*x1 + 1)

@kwankyu
Copy link
Collaborator Author

kwankyu commented Mar 12, 2024

@mkoeppe Could you downgrade my role in sagemath? My power that can edit others' comments is dangerous. Or is there a way to disable the power?

@kwankyu
Copy link
Collaborator Author

kwankyu commented Mar 12, 2024

I recovered the lost comments from the copy in the email.

@mkoeppe
Copy link
Contributor

mkoeppe commented Mar 12, 2024

You can also access the edit history of the comments, where it says "edited by kwankyu"

@mkoeppe
Copy link
Contributor

mkoeppe commented Apr 2, 2024

Other than that, LGTM; but other reviewers may want to take a look at this version.

@kwankyu
Copy link
Collaborator Author

kwankyu commented Apr 3, 2024

Other than that, LGTM; but other reviewers may want to take a look at this version.

OK. Thanks for review!

@mkoeppe
Copy link
Contributor

mkoeppe commented Apr 10, 2024

Let's just merge it.

@kwankyu
Copy link
Collaborator Author

kwankyu commented Apr 10, 2024

Great! Thanks!

Copy link

github-actions bot commented Apr 10, 2024

Documentation preview for this PR (built with commit d662b20; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@vbraun
Copy link
Member

vbraun commented Apr 10, 2024

merge conflict

vbraun pushed a commit to vbraun/sage that referenced this pull request Apr 17, 2024
    
<!-- Please provide a concise, informative and self-explanatory title.
-->
<!-- Don't put issue numbers in the title. Put it in the Description
below. -->
<!-- For example, instead of "Fixes sagemath#12345", use "Add a new method to
multiply two integers" -->

### 📚 Description

We attach Jacobians to function fields and curves, enabling arithmetic
with the points of the Jacobian. Fixes sagemath#34232.

A point of Jacobian is represented by an effective divisor `D` such that
the point is the divisor class of `D - B` (of degree 0) with a fixed
base divisor `B`.

There are two models for Jacobian arithmetic:

- Hess model:  `D` is internally represented by a pair of certain ideals
and arithmetic relies on divisor reduction using Riemann-Roch space
computation by Hess' algorithm.
- Khuri-Makdisi model: `D` is internally represented by a linear
subspace `W_D` of a linear space `V` and arithmetic uses Khuri-Makdisi's
linear algebra algorithms. For implementation, sagemath#15113 was referenced.


An example with non-hyperelliptic genus 3 curve:
```sage
sage: A2.<x,y> = AffineSpace(QQ, 2)
sage: f = y^3 + x^4 - 5*x^2*y + 2*x*y - x^2 - 5*y - 4*x + 1
sage: C = Curve(f, A2)
sage: X = C.projective_closure()
sage: X.genus()
3
sage: X.rational_points(bound=5)
[(0 : 0 : 1), (1/3 : 1/3 : 1)]
sage: Q = X(0,0,1).place()
sage: P = X(1,1,3).place()
sage: D = P - Q
sage: D.degree()
0
sage: J = X.jacobian(model='hess', base_div=3*Q)
sage: G = J.group()
sage: p = G.point(D)
sage: 2*p + 3*p == 5*p
True
```

An example with elliptic curve:
```sage
sage: k.<a> = GF((5,2))
sage: E = EllipticCurve(k,[1,0]); E
Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size
5^2
sage: E.order()
32
sage: P = E([a, 2*a + 4])
sage: P
(a : 2*a + 4 : 1)
sage: P.order()
8
sage: p = P.point_of_jacobian_of_curve()
sage: p
[Place (x + 4*a, y + 3*a + 1)]
sage: p.order()
8
sage: Q = 3*P
sage: q = Q.point_of_jacobian_of_curve()
sage: q == 3*p
True
sage: G = p.parent()
sage: G.order()
32
sage: G
Group of rational points of Jacobian over Finite Field in a of size 5^2
(Hess model)
sage: J = G.parent(); J
Jacobian of Projective Plane Curve over Finite Field in a of size 5^2
 defined by x^2*y + y^3 - x*z^2 (Hess model)
sage: J.curve() == E.affine_patch(2).projective_closure()
True
```

An example with hyperelliptic curve:
```sage
sage: R.<x> = PolynomialRing(GF(11))
sage: f = x^6 + x + 1
sage: H = HyperellipticCurve(f)
sage: J = H.jacobian()
sage: D = J(H.lift_x(1))
sage: D  # divisor in Mumford representation
(x + 10, y + 6)
sage: jacobian_order = sum(H.frobenius_polynomial())
sage: jacobian_order
234
sage: p = D.point_of_jacobian_of_curve(); p
sage: p  # Jacobian point represented by an effective divisor
[Place (1/x0, 1/x0^3*x1 + 1)
 + Place (x0 + 10, x1 + 6)]
sage: p.order()
39
sage: 234*p == 0
True
sage: G = p.parent()
sage: G
Group of rational points of Jacobian over Finite Field of size 11 (Hess
model)
sage: J = G.parent()
sage: J
Jacobian of Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 (Hess model)
sage: C = J.curve()
sage: C
Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2
sage: C.affine_patch(0) == H.affine_patch(2)
True
```

[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2
/gh/kwankyu/sage/p/35467/add-jacobian-groups-notebook-binder) prepared
with sagemath#36245

<!-- Describe your changes here in detail. -->
<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x
]`. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: sagemath#35467
Reported by: Kwankyu Lee
Reviewer(s): Kwankyu Lee, Matthias Köppe
vbraun pushed a commit to vbraun/sage that referenced this pull request Apr 17, 2024
<!-- Please provide a concise, informative and self-explanatory title.
-->
<!-- Don't put issue numbers in the title. Put it in the Description
below. -->
<!-- For example, instead of "Fixes sagemath#12345", use "Add a new method to
multiply two integers" -->

### 📚 Description

We attach Jacobians to function fields and curves, enabling arithmetic
with the points of the Jacobian. Fixes sagemath#34232.

A point of Jacobian is represented by an effective divisor `D` such that
the point is the divisor class of `D - B` (of degree 0) with a fixed
base divisor `B`.

There are two models for Jacobian arithmetic:

- Hess model:  `D` is internally represented by a pair of certain ideals
and arithmetic relies on divisor reduction using Riemann-Roch space
computation by Hess' algorithm.
- Khuri-Makdisi model: `D` is internally represented by a linear
subspace `W_D` of a linear space `V` and arithmetic uses Khuri-Makdisi's
linear algebra algorithms. For implementation, sagemath#15113 was referenced.

An example with non-hyperelliptic genus 3 curve:
```sage
sage: A2.<x,y> = AffineSpace(QQ, 2)
sage: f = y^3 + x^4 - 5*x^2*y + 2*x*y - x^2 - 5*y - 4*x + 1
sage: C = Curve(f, A2)
sage: X = C.projective_closure()
sage: X.genus()
3
sage: X.rational_points(bound=5)
[(0 : 0 : 1), (1/3 : 1/3 : 1)]
sage: Q = X(0,0,1).place()
sage: P = X(1,1,3).place()
sage: D = P - Q
sage: D.degree()
0
sage: J = X.jacobian(model='hess', base_div=3*Q)
sage: G = J.group()
sage: p = G.point(D)
sage: 2*p + 3*p == 5*p
True
```

An example with elliptic curve:
```sage
sage: k.<a> = GF((5,2))
sage: E = EllipticCurve(k,[1,0]); E
Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size
5^2
sage: E.order()
32
sage: P = E([a, 2*a + 4])
sage: P
(a : 2*a + 4 : 1)
sage: P.order()
8
sage: p = P.point_of_jacobian_of_curve()
sage: p
[Place (x + 4*a, y + 3*a + 1)]
sage: p.order()
8
sage: Q = 3*P
sage: q = Q.point_of_jacobian_of_curve()
sage: q == 3*p
True
sage: G = p.parent()
sage: G.order()
32
sage: G
Group of rational points of Jacobian over Finite Field in a of size 5^2
(Hess model)
sage: J = G.parent(); J
Jacobian of Projective Plane Curve over Finite Field in a of size 5^2
 defined by x^2*y + y^3 - x*z^2 (Hess model)
sage: J.curve() == E.affine_patch(2).projective_closure()
True
```

An example with hyperelliptic curve:
```sage
sage: R.<x> = PolynomialRing(GF(11))
sage: f = x^6 + x + 1
sage: H = HyperellipticCurve(f)
sage: J = H.jacobian()
sage: D = J(H.lift_x(1))
sage: D  # divisor in Mumford representation
(x + 10, y + 6)
sage: jacobian_order = sum(H.frobenius_polynomial())
sage: jacobian_order
234
sage: p = D.point_of_jacobian_of_curve(); p
sage: p  # Jacobian point represented by an effective divisor
[Place (1/x0, 1/x0^3*x1 + 1)
 + Place (x0 + 10, x1 + 6)]
sage: p.order()
39
sage: 234*p == 0
True
sage: G = p.parent()
sage: G
Group of rational points of Jacobian over Finite Field of size 11 (Hess
model)
sage: J = G.parent()
sage: J
Jacobian of Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 (Hess model)
sage: C = J.curve()
sage: C
Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2
sage: C.affine_patch(0) == H.affine_patch(2)
True
```

[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2
/gh/kwankyu/sage/p/35467/add-jacobian-groups-notebook-binder) prepared
with sagemath#36245

<!-- Describe your changes here in detail. -->
<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x
]`. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->

URL: sagemath#35467
Reported by: Kwankyu Lee
Reviewer(s): Kwankyu Lee, Matthias Köppe
vbraun pushed a commit to vbraun/sage that referenced this pull request Apr 18, 2024
    
<!-- Please provide a concise, informative and self-explanatory title.
-->
<!-- Don't put issue numbers in the title. Put it in the Description
below. -->
<!-- For example, instead of "Fixes sagemath#12345", use "Add a new method to
multiply two integers" -->

### 📚 Description

We attach Jacobians to function fields and curves, enabling arithmetic
with the points of the Jacobian. Fixes sagemath#34232.

A point of Jacobian is represented by an effective divisor `D` such that
the point is the divisor class of `D - B` (of degree 0) with a fixed
base divisor `B`.

There are two models for Jacobian arithmetic:

- Hess model:  `D` is internally represented by a pair of certain ideals
and arithmetic relies on divisor reduction using Riemann-Roch space
computation by Hess' algorithm.
- Khuri-Makdisi model: `D` is internally represented by a linear
subspace `W_D` of a linear space `V` and arithmetic uses Khuri-Makdisi's
linear algebra algorithms. For implementation, sagemath#15113 was referenced.


An example with non-hyperelliptic genus 3 curve:
```sage
sage: A2.<x,y> = AffineSpace(QQ, 2)
sage: f = y^3 + x^4 - 5*x^2*y + 2*x*y - x^2 - 5*y - 4*x + 1
sage: C = Curve(f, A2)
sage: X = C.projective_closure()
sage: X.genus()
3
sage: X.rational_points(bound=5)
[(0 : 0 : 1), (1/3 : 1/3 : 1)]
sage: Q = X(0,0,1).place()
sage: P = X(1,1,3).place()
sage: D = P - Q
sage: D.degree()
0
sage: J = X.jacobian(model='hess', base_div=3*Q)
sage: G = J.group()
sage: p = G.point(D)
sage: 2*p + 3*p == 5*p
True
```

An example with elliptic curve:
```sage
sage: k.<a> = GF((5,2))
sage: E = EllipticCurve(k,[1,0]); E
Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size
5^2
sage: E.order()
32
sage: P = E([a, 2*a + 4])
sage: P
(a : 2*a + 4 : 1)
sage: P.order()
8
sage: p = P.point_of_jacobian_of_curve()
sage: p
[Place (x + 4*a, y + 3*a + 1)]
sage: p.order()
8
sage: Q = 3*P
sage: q = Q.point_of_jacobian_of_curve()
sage: q == 3*p
True
sage: G = p.parent()
sage: G.order()
32
sage: G
Group of rational points of Jacobian over Finite Field in a of size 5^2
(Hess model)
sage: J = G.parent(); J
Jacobian of Projective Plane Curve over Finite Field in a of size 5^2
 defined by x^2*y + y^3 - x*z^2 (Hess model)
sage: J.curve() == E.affine_patch(2).projective_closure()
True
```

An example with hyperelliptic curve:
```sage
sage: R.<x> = PolynomialRing(GF(11))
sage: f = x^6 + x + 1
sage: H = HyperellipticCurve(f)
sage: J = H.jacobian()
sage: D = J(H.lift_x(1))
sage: D  # divisor in Mumford representation
(x + 10, y + 6)
sage: jacobian_order = sum(H.frobenius_polynomial())
sage: jacobian_order
234
sage: p = D.point_of_jacobian_of_curve(); p
sage: p  # Jacobian point represented by an effective divisor
[Place (1/x0, 1/x0^3*x1 + 1)
 + Place (x0 + 10, x1 + 6)]
sage: p.order()
39
sage: 234*p == 0
True
sage: G = p.parent()
sage: G
Group of rational points of Jacobian over Finite Field of size 11 (Hess
model)
sage: J = G.parent()
sage: J
Jacobian of Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 (Hess model)
sage: C = J.curve()
sage: C
Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2
sage: C.affine_patch(0) == H.affine_patch(2)
True
```

[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2
/gh/kwankyu/sage/p/35467/add-jacobian-groups-notebook-binder) prepared
with sagemath#36245

<!-- Describe your changes here in detail. -->
<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x
]`. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: sagemath#35467
Reported by: Kwankyu Lee
Reviewer(s): Kwankyu Lee, Matthias Köppe
vbraun pushed a commit to vbraun/sage that referenced this pull request Apr 20, 2024
    
<!-- Please provide a concise, informative and self-explanatory title.
-->
<!-- Don't put issue numbers in the title. Put it in the Description
below. -->
<!-- For example, instead of "Fixes sagemath#12345", use "Add a new method to
multiply two integers" -->

### 📚 Description

We attach Jacobians to function fields and curves, enabling arithmetic
with the points of the Jacobian. Fixes sagemath#34232.

A point of Jacobian is represented by an effective divisor `D` such that
the point is the divisor class of `D - B` (of degree 0) with a fixed
base divisor `B`.

There are two models for Jacobian arithmetic:

- Hess model:  `D` is internally represented by a pair of certain ideals
and arithmetic relies on divisor reduction using Riemann-Roch space
computation by Hess' algorithm.
- Khuri-Makdisi model: `D` is internally represented by a linear
subspace `W_D` of a linear space `V` and arithmetic uses Khuri-Makdisi's
linear algebra algorithms. For implementation, sagemath#15113 was referenced.


An example with non-hyperelliptic genus 3 curve:
```sage
sage: A2.<x,y> = AffineSpace(QQ, 2)
sage: f = y^3 + x^4 - 5*x^2*y + 2*x*y - x^2 - 5*y - 4*x + 1
sage: C = Curve(f, A2)
sage: X = C.projective_closure()
sage: X.genus()
3
sage: X.rational_points(bound=5)
[(0 : 0 : 1), (1/3 : 1/3 : 1)]
sage: Q = X(0,0,1).place()
sage: P = X(1,1,3).place()
sage: D = P - Q
sage: D.degree()
0
sage: J = X.jacobian(model='hess', base_div=3*Q)
sage: G = J.group()
sage: p = G.point(D)
sage: 2*p + 3*p == 5*p
True
```

An example with elliptic curve:
```sage
sage: k.<a> = GF((5,2))
sage: E = EllipticCurve(k,[1,0]); E
Elliptic Curve defined by y^2 = x^3 + x over Finite Field in a of size
5^2
sage: E.order()
32
sage: P = E([a, 2*a + 4])
sage: P
(a : 2*a + 4 : 1)
sage: P.order()
8
sage: p = P.point_of_jacobian_of_curve()
sage: p
[Place (x + 4*a, y + 3*a + 1)]
sage: p.order()
8
sage: Q = 3*P
sage: q = Q.point_of_jacobian_of_curve()
sage: q == 3*p
True
sage: G = p.parent()
sage: G.order()
32
sage: G
Group of rational points of Jacobian over Finite Field in a of size 5^2
(Hess model)
sage: J = G.parent(); J
Jacobian of Projective Plane Curve over Finite Field in a of size 5^2
 defined by x^2*y + y^3 - x*z^2 (Hess model)
sage: J.curve() == E.affine_patch(2).projective_closure()
True
```

An example with hyperelliptic curve:
```sage
sage: R.<x> = PolynomialRing(GF(11))
sage: f = x^6 + x + 1
sage: H = HyperellipticCurve(f)
sage: J = H.jacobian()
sage: D = J(H.lift_x(1))
sage: D  # divisor in Mumford representation
(x + 10, y + 6)
sage: jacobian_order = sum(H.frobenius_polynomial())
sage: jacobian_order
234
sage: p = D.point_of_jacobian_of_curve(); p
sage: p  # Jacobian point represented by an effective divisor
[Place (1/x0, 1/x0^3*x1 + 1)
 + Place (x0 + 10, x1 + 6)]
sage: p.order()
39
sage: 234*p == 0
True
sage: G = p.parent()
sage: G
Group of rational points of Jacobian over Finite Field of size 11 (Hess
model)
sage: J = G.parent()
sage: J
Jacobian of Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2 (Hess model)
sage: C = J.curve()
sage: C
Projective Plane Curve over Finite Field of size 11
 defined by x0^6 + x0^5*x1 + x1^6 - x0^4*x2^2
sage: C.affine_patch(0) == H.affine_patch(2)
True
```

[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2
/gh/kwankyu/sage/p/35467/add-jacobian-groups-notebook-binder) prepared
with sagemath#36245

<!-- Describe your changes here in detail. -->
<!-- Why is this change required? What problem does it solve? -->
<!-- If this PR resolves an open issue, please link to it here. For
example "Fixes sagemath#12345". -->
<!-- If your change requires a documentation PR, please link it
appropriately. -->

### 📝 Checklist

<!-- Put an `x` in all the boxes that apply. It should be `[x]` not `[x
]`. -->

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation accordingly.

### ⌛ Dependencies

<!-- List all open PRs that this PR logically depends on
- sagemath#12345: short description why this is a dependency
- sagemath#34567: ...
-->

<!-- If you're unsure about any of these, don't hesitate to ask. We're
here to help! -->
    
URL: sagemath#35467
Reported by: Kwankyu Lee
Reviewer(s): Kwankyu Lee, Matthias Köppe
@vbraun vbraun merged commit fa7cb94 into sagemath:develop Apr 27, 2024
12 checks passed
@mkoeppe mkoeppe added this to the sage-10.4 milestone Apr 27, 2024
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.

Add Jacobian groups to algebraic curves over finite fields
4 participants