From 0e5b06116678a323bdf1fc433b910eac2d0b5c55 Mon Sep 17 00:00:00 2001 From: Simon Brandhorst Date: Mon, 16 Dec 2024 10:02:58 +0100 Subject: [PATCH] feat: pretty printing for elliptic curves and their points (#1677) --- docs/src/manual/elliptic_curves/basics.md | 6 +- .../manual/elliptic_curves/finite_fields.md | 5 +- src/EllCrv/EllCrv.jl | 74 +++++++++++++------ src/EllCrv/Finite.jl | 17 ++--- src/EllCrv/Isomorphisms.jl | 13 ++-- 5 files changed, 69 insertions(+), 46 deletions(-) diff --git a/docs/src/manual/elliptic_curves/basics.md b/docs/src/manual/elliptic_curves/basics.md index d23cd52c2c..c512e323f5 100644 --- a/docs/src/manual/elliptic_curves/basics.md +++ b/docs/src/manual/elliptic_curves/basics.md @@ -50,12 +50,10 @@ by setting `check = false`. julia> E = elliptic_curve(QQ, [1, 2]); julia> E([1, -2]) -Point (1 : -2 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(1 : -2 : 1) julia> E([2, -4, 2]) -Point (1 : -2 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(1 : -2 : 1) ``` ```@docs diff --git a/docs/src/manual/elliptic_curves/finite_fields.md b/docs/src/manual/elliptic_curves/finite_fields.md index 19bc50fcfc..c752a3fe3a 100644 --- a/docs/src/manual/elliptic_curves/finite_fields.md +++ b/docs/src/manual/elliptic_curves/finite_fields.md @@ -15,12 +15,11 @@ end Return a random point on the elliptic curve $E$ defined over a finite field. -```jldoctest; filter = r"Point.*" +```jldoctest; filter = r"\(.*" julia> E = elliptic_curve(GF(3), [1, 2]); julia> rand(E) -Point (2 : 0 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(2 : 0 : 1) ``` ## Cardinality and orders diff --git a/src/EllCrv/EllCrv.jl b/src/EllCrv/EllCrv.jl index 52be1c875c..2cca8d7f75 100644 --- a/src/EllCrv/EllCrv.jl +++ b/src/EllCrv/EllCrv.jl @@ -167,12 +167,16 @@ disabled by setting `check = false`. ```jldoctest julia> elliptic_curve(QQ, [1, 2, 3, 4, 5]) -Elliptic curve with equation -y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 +Elliptic curve + over rational field +with equation + y^2 + x*y + 3*y = x^3 + 2*x^2 + 4*x + 5 julia> elliptic_curve(GF(3), [1, 1]) -Elliptic curve with equation -y^2 = x^3 + x + 1 +Elliptic curve + over prime field of characteristic 3 +with equation + y^2 = x^3 + x + 1 ``` """ elliptic_curve @@ -253,12 +257,16 @@ disabled by setting `check = false`. julia> Qx, x = QQ["x"]; julia> elliptic_curve(x^3 + x + 1) -Elliptic curve with equation -y^2 = x^3 + x + 1 +Elliptic curve + over rational field +with equation + y^2 = x^3 + x + 1 julia> elliptic_curve(x^3 + x + 1, x) -Elliptic curve with equation -y^2 + x*y = x^3 + x + 1 +Elliptic curve + over rational field +with equation + y^2 + x*y = x^3 + x + 1 ``` """ function elliptic_curve(f::PolyRingElem{T}, h::PolyRingElem{T} = zero(parent(f)); check::Bool = true) where T @@ -292,8 +300,10 @@ julia> K = GF(3) Prime field of characteristic 3 julia> elliptic_curve_from_j_invariant(K(2)) -Elliptic curve with equation -y^2 + x*y = x^3 + 1 +Elliptic curve + over prime field of characteristic 3 +with equation + y^2 + x*y = x^3 + 1 ``` """ function elliptic_curve_from_j_invariant(j::FieldElem) @@ -584,12 +594,10 @@ by setting `check = false`. julia> E = elliptic_curve(QQ, [1, 2]); julia> E([1, -2]) -Point (1 : -2 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(1 : -2 : 1) julia> E([2, -4, 2]) -Point (1 : -2 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(1 : -2 : 1) ``` """ function (E::EllipticCurve{T})(coords::Vector{S}; check::Bool = true) where {S, T} @@ -754,8 +762,31 @@ end # ################################################################################ +function show(io::IO, ::MIME"text/plain", E::EllipticCurve) + io = pretty(io) + println(io, "Elliptic curve") + print(io, Indent(), "over ", Lowercase()) + print(io, base_field(E)) + println(io, Dedent()) + println(io, "with equation") + print(io, Indent()) + _print_equation(io, E) + print(io, Dedent()) +end + function show(io::IO, E::EllipticCurve) - print(io, "Elliptic curve with equation\n") + if is_terse(io) + print(io, "Elliptic curve") + return + end + io = pretty(io) + print(io, "Elliptic curve over ", Lowercase()) + print(terse(io), base_field(E)) + print(io, " with equation ") + _print_equation(io, E) +end + +function _print_equation(io::IO, E::EllipticCurve) a1, a2, a3, a4, a6 = a_invariants(E) sum = Expr(:call, :+) push!(sum.args, Expr(:call, :^, :y, 2)) @@ -807,8 +838,10 @@ function show(io::IO, E::EllipticCurve) print(io, AbstractAlgebra.expr_to_string(AbstractAlgebra.canonicalize(sum))) end + function show(io::IO, P::EllipticCurvePoint) - print(io, "Point ($(P[1]) : $(P[2]) : $(P[3])) of $(P.parent)") + io = pretty(io) + print(io, "($(P[1]) : $(P[2]) : $(P[3]))") end @@ -832,8 +865,7 @@ julia> E = elliptic_curve(QQ, [1, 2]); julia> P = E([1, -2]); julia> P + P -Point (-1 : 0 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(-1 : 0 : 1) ``` """ function +(P::EllipticCurvePoint{T}, Q::EllipticCurvePoint{T}) where T @@ -1126,10 +1158,8 @@ julia> E = elliptic_curve(QQ, [1, 2]); julia> division_points(infinity(E), 2) 2-element Vector{EllipticCurvePoint{QQFieldElem}}: - Point (0 : 1 : 0) of Elliptic curve with equation -y^2 = x^3 + x + 2 - Point (-1 : 0 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 + (0 : 1 : 0) + (-1 : 0 : 1) ``` """ function division_points(P::EllipticCurvePoint, m::S) where S<:Union{Integer, ZZRingElem} diff --git a/src/EllCrv/Finite.jl b/src/EllCrv/Finite.jl index 292352b9a1..ca662ca397 100644 --- a/src/EllCrv/Finite.jl +++ b/src/EllCrv/Finite.jl @@ -1110,22 +1110,19 @@ Return a list of generators of the group of rational points on $E$. # Examples -```jldoctest; filter = r"Point.*" +```jldoctest; filter = r"\(.*" julia> E = elliptic_curve(GF(101, 2), [1, 2]); julia> gens(E) 2-element Vector{EllipticCurvePoint{FqFieldElem}}: - Point (16*o + 42 : 88*o + 97 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 - Point (88*o + 23 : 94*o + 22 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 + (13*o + 83 : 90*o + 25 : 1) + (61*o + 62 : 19*o + 24 : 1) julia> E = elliptic_curve(GF(101), [1, 2]); julia> gens(E) 1-element Vector{EllipticCurvePoint{FqFieldElem}}: - Point (85 : 58 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 + (27 : 57 : 1) ``` """ function gens(E::EllipticCurve{T}) where {T <: FinFieldElem} @@ -1205,12 +1202,10 @@ argument. julia> E = elliptic_curve(GF(101), [1, 2]); julia> P = E([6, 74]) -Point (6 : 74 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(6 : 74 : 1) julia> Q = E([85, 43]) -Point (85 : 43 : 1) of Elliptic curve with equation -y^2 = x^3 + x + 2 +(85 : 43 : 1) julia> disc_log(P, Q) 13 diff --git a/src/EllCrv/Isomorphisms.jl b/src/EllCrv/Isomorphisms.jl index f663fb800b..c87e2ae3a5 100644 --- a/src/EllCrv/Isomorphisms.jl +++ b/src/EllCrv/Isomorphisms.jl @@ -623,15 +623,16 @@ end # ################################################################################ - -function show(io::IO, f::EllCrvIso) +function show(io::IO, ::MIME"text/plain", f::EllCrvIso) + io = pretty(io) E1 = domain(f) E2 = codomain(f) fx, fy, fz = rational_maps(f) - print(io, "Isomorphism from - $(E1) to \n - $(E2) given by \n - (x : y : 1) -> ($(fx) : $(fy) : $(fz) )") + println(io, "Isomorphism") + println(io, Indent(), "from ", E1) + println(io, "to ", E2) + print(io,"given by ") + print(io, "(x : y : 1) -> ($(fx) : $(fy) : $(fz) )") end ################################################################################