Bill Allombert on Sat, 02 Mar 2024 18:03:30 +0100


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: a hopeful request


On Fri, Mar 01, 2024 at 04:56:23PM -0800, American Citizen wrote:
> To all:
> 
> I have been looking for this for a long time.
> 
> Suppose I have an elliptic curve in Weierstrass format [a1,a2,a3,a4,a6] and
> a two-covering or quartic a*x^4 + b*x^3 + c*x^2 + d*x + e and they share the
> same invariants, the I invariant and the J invariant.
> 
> Is it possible to develop the forward and inverse maps for points on either
> the elliptic curve mapping to the quartic two-cover, or the points on the
> two-cover mapping back to the elliptic curve?
> 
> I would like to obtain the forward and inverse maps for points on either the
> elliptic curve -> quartic or quartic -> elliptic curve

Please find the following GP script with a function
quartic_to_ellmap(Q) that given a quartic y^2=q(x), returns 
[E,f,g] where E is an elliptic curve, f a map from q to E and
g a (one-to-many) map from E to q.

There is a test.

Cheers,
Bill.
quartic_IJ(g)=
{
  my([a,b,c,d,e]=Vec(g));
  my(ae = a*e, bd = b*d, c2 = c^2, d2=d^2, b2 = b^2);
  my(iI = 12*ae - 3*bd + c2);
  my(iJ = (72*ae  + 9*bd - 2*c2)*c  - 27*a*d2 - 27*b2*e);
  [iI,iJ];
}
IJ_to_ell(V)= ellinit(-27*V);

quartic_to_ell(g)=IJ_to_ell(quartic_IJ(g));

quartic_disc(g)=
{
  my([iI,iJ]=quartic_IJ(g));
  4*iI^3-iJ^2
}
quartic_hessian(g)=
{
  my([A,B,C,D,E]=Vec(g));
  Pol([(3*B^2 - 8*A*C), (4*B*C - 24*A*D), (4*C^2 - 6*B*D - 48*A*E), (4*C*D - 24*B*E), 3*D^2 - 8*C*E]);
}

quartic_bracket(g1,g2)=
{
  my(h1=quartic_hessian(g1),h2=quartic_hessian(g2));
  g1*subst(h2,x,y)-subst(g2,x,y)*h1;
}

quartic_isom(g1, g2)=
{
  my(b = quartic_bracket(g1,g2));
  my(S=select(f->poldegree(f)==1,factor(b)[,1]));
  if (#S==0, return(0));
  my([a,b,c,d]=concat([Vecrev(simplify(x),2)|x<-Vecrev(S[1],2)]));
  [-c,-a;d,b];
}

quartic_to_g4g6(g)=
{
  my([a,b,c,d,e]=Vec(g));
  my(g4 = (3*b^2 - 8*a*c)*X^4 + 4*(b*c - 6*a*d)*X^3*Y + 2*(2*c^2 - 24*a*e - 3*b*d)*X^2*Y^2 + 4*(c*d - 6*b*e)*X*Y^3 + (3*d^2 - 8*c*e)*Y^4);
  my(g6 = (b^3 + 8*a^2*d - 4*a*b*c)*X^6 + 2*(16*a^2*e + 2*a*b*d - 4*a*c^2 + b^2*c)*X^5*Y + 5*(8*a*b*e + b^2*d - 4*a*c*d)*X^4*Y^2 + 20*(b^2*e - a*d^2)*X^3*Y^3 - 5*(8*a*d*e + b*d^2 - 4*b*c*e)*X^2*Y^4 - 2*(16*a*e^2 + 2*b*d*e - 4*c^2*e + c*d^2)*X*Y^5 - (d^3 + 8*b*e^2 - 4*c*d*e)*Y^6);
  [g4,g6];
}

elltocover(Q,F,P)=
{
  my(S,T,A);
  S = simplify((F[1]-P[1]*Q)%('y^2-Q));
  T = simplify(F[2]%('y^2-Q));
  A = apply(x->[x,if(1,my(R=subst(T-P[2]*'y*Q,'X,x));-polcoeff(R,0)/polcoeff(R,1))],nfroots(,S));
  if (poldegree(S)<4, my(R=T-P[2]*'y*Q, Y = -pollead(polcoeff(R,0))/pollead(polcoeff(R,1)));
    A=concat(A,[[1,Y,0]]));
  A;
}

quartic_to_ellmap(q)=
{
  my(E=quartic_to_ell(q),[g4,g6]=quartic_to_g4g6(q));
  my(p =substvec(g4,[X,Y],[1,0]), r = substvec(g6,[X,Y],[1,0]));
  my(f=P->
    if(#P==2,[3*substvec(g4,[X,Y],[P[1],1])/(2*P[2])^2, 27*substvec(g6,[X,Y],[P[1],1])/(2*P[2])^3],
       #P==3,[3*p/(2*P[2])^2, 27*r/(2*P[2])^3]));
  my(Q=subst(q,variable(q),X),F=subst([3*g4/4,27*g6/8],Y,1));
  my(g=P->elltocover(Q,F,P));
  [E,f,g]
}

test()=
{
  [E,f,g]=quartic_to_ellmap(-33*x^4+85*x^3+198*x^2-85*x-33);
  P=f([-186067/136146,22644340289/2059525924]);
  if(!ellisoncurve(E,P),error("f not correct"));
  [hyperellisoncurve(-33*x^4+85*x^3+198*x^2-85*x-33,Q)|Q<-g(P)]
}