Path: blob/main/Magma-Reference/richelot_aux.m
323 views
/*1This code was downloaded from https://homes.esat.kuleuven.be/~wcastryc/ on 3 August 20222*/34function FromProdToJac(C, E, P_c, Q_c, P, Q, a)5Fp2 := BaseField(C);6R<x> := PolynomialRing(Fp2);78P_c2 := 2^(a-1)*P_c;9Q_c2 := 2^(a-1)*Q_c;10P2 := 2^(a-1)*P;11Q2 := 2^(a-1)*Q;1213alp1 := P_c2[1];14alp2 := Q_c2[1];15alp3 := (P_c2 + Q_c2)[1];16bet1 := P2[1];17bet2 := Q2[1];18bet3 := (P2 + Q2)[1];19a1 := (alp3 - alp2)^2/(bet3 - bet2) + (alp2 - alp1)^2/(bet2 - bet1) + (alp1 - alp3)^2/(bet1 - bet3);20b1 := (bet3 - bet2)^2/(alp3 - alp2) + (bet2 - bet1)^2/(alp2 - alp1) + (bet1 - bet3)^2/(alp1 - alp3);21a2 := alp1*(bet3 - bet2) + alp2*(bet1 - bet3) + alp3*(bet2 - bet1);22b2 := bet1*(alp3 - alp2) + bet2*(alp1 - alp3) + bet3*(alp2 - alp1);23Deltalp := (alp1 - alp2)^2*(alp1 - alp3)^2*(alp2 - alp3)^2;24Deltbet := (bet1 - bet2)^2*(bet1 - bet3)^2*(bet2 - bet3)^2;25A := Deltbet*a1/a2;26B := Deltalp*b1/b2;2728h := - (A*(alp2 - alp1)*(alp1 - alp3)*x^2 + B*(bet2 - bet1)*(bet1 - bet3)) *29(A*(alp3 - alp2)*(alp2 - alp1)*x^2 + B*(bet3 - bet2)*(bet2 - bet1)) *30(A*(alp1 - alp3)*(alp3 - alp2)*x^2 + B*(bet1 - bet3)*(bet3 - bet2));3132t1 := -(A/B)*b2/b1;33t2 := (bet1*(bet3 - bet2)^2/(alp3 - alp2) + bet2*(bet1 - bet3)^2/(alp1 - alp3) + bet3*(bet2 - bet1)^2/(alp2 - alp1))/b1;34s1 := -(B/A)*a2/a1;35s2 := (alp1*(alp3 - alp2)^2/(bet3 - bet2) + alp2*(alp1 - alp3)^2/(bet1 - bet3) + alp3*(alp2 - alp1)^2/(bet2 - bet1))/a1;3637Uff<u0, u1, v0, v1> := FunctionField(Fp2, 4);38A4<U0, U1, V0, V1> := AffineSpace(Fp2, 4); U := Parent(U0);3940u0tilde := 1/u0;41u1tilde := u1/u0;42v0tilde := (u1*v0 - u0*v1)/u0^2;43v1tilde := (u1^2*v0 - u0*v0 - u0*u1*v1)/u0^2;4445lamb1 := - (Deltbet/A^3)*v1tilde/(s1*u1tilde);46lamb2 := - (Deltalp/B^3)*v1/(t1*u1);4748x1 := lamb1^2 + alp1 + alp2 + alp3 - s1*(u1tilde^2 - 2*u0tilde) - 2*s2;49y1 := -lamb1*(x1 - s2 + (u0tilde*v1tilde - u1tilde*v0tilde)*s1/v1tilde);5051x2 := lamb2^2 + bet1 + bet2 + bet3 - t1*(u1^2 - 2*u0) - 2*t2;52y2 := -lamb2*(x2 - t2 + (u0*v1 - u1*v0)*t1/v1);5354eq1 := U ! Numerator(x1 - P_c[1]);55eq2 := U ! Numerator(y1 - P_c[2]);56eq3 := U ! Numerator(x2 - P[1]);57eq4 := U ! Numerator(y2 - P[2]);58eq5 := 2*V0^2 - 2*V0*V1*U1 + V1^2*(U1^2 - 2*U0)59- 2*Coefficient(h, 0)60- (-U1)*Coefficient(h, 1)61- (U1^2 - 2*U0)*Coefficient(h, 2)62- (-U1^3 + 3*U0*U1)*Coefficient(h, 3)63- (U1^4 - 4*U1^2*U0 + 2*U0^2)*Coefficient(h, 4)64- (-U1^5 + 5*U1^3*U0 - 5*U1*U0^2)*Coefficient(h, 5)65- (U1^6 - 6*U1^4*U0 + 9*U1^2*U0^2 - 2*U0^3)*Coefficient(h, 6);6667V := Scheme(A4, [eq1, eq2, eq3, eq4, eq5]);6869// point with zero coordinates probably correspond to "extra" solutions, we should be left with 4 sols70// (code may fail over small fields)7172realsols := [];73for D in Points(V) do74Dseq := Eltseq(D);75if not 0 in Dseq then76realsols cat:= [Dseq];77end if;78end for;7980// print "Number of inverse images found:", #realsols, "(hopefully 4)";8182J := Jacobian(HyperellipticCurve(h));83sol := Random(realsols);84D := elt<J | x^2 + sol[2]*x + sol[1], sol[4]*x + sol[3]>;85imPcP := 2*D;8687// now for (Q_c, Q)8889eq1 := U ! Numerator(x1 - Q_c[1]);90eq2 := U ! Numerator(y1 - Q_c[2]);91eq3 := U ! Numerator(x2 - Q[1]);92eq4 := U ! Numerator(y2 - Q[2]);93V := Scheme(A4, [eq1, eq2, eq3, eq4, eq5]);94realsols := [];95for D in Points(V) do96Dseq := Eltseq(D);97if not 0 in Dseq then98realsols cat:= [Dseq];99end if;100end for;101// print "Number of inverse images found:", #realsols, "(hopefully 4)";102sol := Random(realsols);103D := elt<J | x^2 + sol[2]*x + sol[1], sol[4]*x + sol[3]>;104imQcQ := 2*D;105106return h, imPcP[1], imPcP[2], imQcQ[1], imQcQ[2];107end function;108109function FromJacToJac(h, D11, D12, D21, D22, a)110R<x> := Parent(h);111Fp2 := BaseRing(R);112113J := Jacobian(HyperellipticCurve(h));114D1 := elt<J | D11, D12>;115D2 := elt<J | D21, D22>;116117G1 := (2^(a-1)*D1)[1];118G2 := (2^(a-1)*D2)[1];119G3 := h div (G1*G2);120121delta := Matrix(Fp2, 3, 3, [Coefficient(G1, 0), Coefficient(G1, 1), Coefficient(G1, 2),122Coefficient(G2, 0), Coefficient(G2, 1), Coefficient(G2, 2),123Coefficient(G3, 0), Coefficient(G3, 1), Coefficient(G3, 2)]);124delta := Determinant(delta)^(-1);125126H1 := delta*(Derivative(G2)*G3 - G2*Derivative(G3));127H2 := delta*(Derivative(G3)*G1 - G3*Derivative(G1));128H3 := delta*(Derivative(G1)*G2 - G1*Derivative(G2));129130hnew := H1*H2*H3;131Jnew := Jacobian(HyperellipticCurve(hnew));132133// now compute image points134// first the point [D11, D12]:135136u0 := Coefficient(D11, 0);137u1 := Coefficient(D11, 1);138v0 := Coefficient(D12, 0);139v1 := Coefficient(D12, 1);140S<x1,y1,y2,x2> := PolynomialRing(Fp2, 4);141pr := hom<S -> R | 0, 0, 0, x>;142143eq1 := x1^2 + u1*x1 + u0;144eq2 := v1*x1 + v0 - y1;145eq3 := Evaluate(G1, x1)*Evaluate(H1, x2) + Evaluate(G2, x1)*Evaluate(H2, x2);146eq4 := y1*y2 - Evaluate(G1, x1)*Evaluate(H1, x2)*(x1 - x2);147eq5 := y1^2 - Evaluate(h, x1);148I := Ideal([eq1, eq2, eq3, eq4, eq5]);149G := GroebnerBasis(I); // last two are in non-reduced Mumford form: y2 + cubic(x2), quartic(x2)150unew := pr(G[#G]);151vnew := -pr(G[#G-1]);152// sanity check: (vnew^2 - hnew) mod unew;153imD1 := elt<Jnew | pr(G[#G]), -pr(G[#G-1])>;154155// now same for the point [D21, D22]:156157u0 := Coefficient(D21, 0);158u1 := Coefficient(D21, 1);159v0 := Coefficient(D22, 0);160v1 := Coefficient(D22, 1);161eq1 := x1^2 + u1*x1 + u0;162eq2 := v1*x1 + v0 - y1;163I := Ideal([eq1, eq2, eq3, eq4, eq5]);164G := GroebnerBasis(I);165unew := pr(G[#G]);166vnew := -pr(G[#G-1]);167imD2 := elt<Jnew | pr(G[#G]), -pr(G[#G-1])>;168169return hnew, imD1[1], imD1[2], imD2[1], imD2[2];170end function;171172function Does22ChainSplit(C, E, P_c, Q_c, P, Q, a)173Fp2 := BaseField(C);174// gluing step175h, D11, D12, D21, D22 := FromProdToJac(C, E, P_c, Q_c, P, Q, a);176// print "order 2^", a-1, "on hyp curve", h;177for i in [1..a-2] do178h, D11, D12, D21, D22 := FromJacToJac(h, D11, D12, D21, D22, a-i);179// print "order 2^", a - i - 1, "on hyp curve", h;180end for;181// now we are left with a quadratic splitting: is it singular?182G1 := D11;183G2 := D21;184G3 := h div (G1*G2);185// print G1, G2, G3;186delta := Matrix(Fp2, 3, 3, [Coefficient(G1, 0), Coefficient(G1, 1), Coefficient(G1, 2),187Coefficient(G2, 0), Coefficient(G2, 1), Coefficient(G2, 2),188Coefficient(G3, 0), Coefficient(G3, 1), Coefficient(G3, 2)]);189delta := Determinant(delta);190return delta eq 0;191end function;192193function OddCyclicSumOfSquares(n, factexpl, provide_own_fac)194if provide_own_fac then195fac := factexpl;196else197fac := Factorization(n);198end if;199if {f[1] mod 4 : f in fac} ne {1} then200return false, 0, 0;201else202Z<I> := GaussianIntegers();203prod := 1;204for f in fac do205p := f[1];206repeat207z := Random(GF(p));208until z^((p-1) div 2) eq -1;209z := Integers() ! (z^((p-1) div 4)); // square root of -1210prod *:= GCD(Z ! p, Z ! z + I)^f[2];211end for;212u := [Integers() ! e : e in Eltseq(prod)];213if IsOdd(u[1]) then u1 := u[1]; u2 := u[2] div 2; else u1 := u[2]; u2 := u[1] div 2; end if;214return true, Abs(u1), Abs(u2);215end if;216end function;217218219function Pushing3Chain(E, P, i) // compute chain of isogenies quotienting out a point P of order 3^i220Fp2 := BaseField(E);221R<x> := PolynomialRing(Fp2);222chain := [];223C := E;224remainingker := P;225for j in [1..i] do226kerpol := x - (3^(i-j)*remainingker)[1];227C, comp := IsogenyFromKernel(C, kerpol);228remainingker := comp(remainingker);229chain cat:=[comp];230end for;231return C, chain;232end function;233234235function Pushing9Chain(E, P, i) // compute chain of isogenies quotienting out a point P of order 9^i (obsolete)236Fp2 := BaseField(E);237R<x> := PolynomialRing(Fp2);238chain := [];239C := E;240remainingker := P;241for j in [1..i] do242kerpol := &*[x - (k*9^(i-j)*remainingker)[1] : k in [1..4]];243C, comp := IsogenyFromKernel(C, kerpol);244remainingker := comp(remainingker);245chain cat:=[comp];246end for;247return C, chain;248end function;249250251