///////////////////////////////////////////////////////////////////////////
//
// 		"Explicit characterization of the torsion growth
//  of rational elliptic curves with complex multiplication over quadratic fields"
//
// 		Enrique González-Jiménez
//
//      Magma script related to Remark 5
// 		
//
///////////////////////////////////////////////////////////////////////////
// Magma 2.24
//////////////////////////////////////////////////////////////////////////


// Bourdon, Abbey; Clark, Pete L.; Stankewicz, James 
// Torsion points on CM elliptic curves over real number fields. 
// Trans. Amer. Math. Soc. 369 (2017), no. 12, 8457–8496.
// Theorem 1.4 



function CM_EllipticCurve(Df2,d)
// Input: Df2=discriminant of the CM quadratic order and d=twist an integer
// return the d-twist of the elliptic curve E_cm
  case Df2: 
    when -3:   s:=[ 0, 1 ]; E:=EllipticCurve([0,d]); 
    when -12:  s:=[ -15, 22 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -27:  s:=[ -480, 4048 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -4:   s:=[ 1, 0 ]; E:=EllipticCurve([d,0]); 
    when -16:  s:=[ -11, 14 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -7:   s:=[ -2835, -71442 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -28:  s:=[ -595, 5586 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -8:   s:=[ -4320, 96768 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -11:  s:=[ -9504, 365904 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -19:  s:=[ -608, 5776 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -43:  s:=[ -13760, 621264 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -67:  s:=[ -117920, 15585808 ]; E:=QuadraticTwist(EllipticCurve(s),d);
    when -163: s:=[ -34790720, 78984748304 ]; E:=QuadraticTwist(EllipticCurve(s),d);
  end case;
  as:=aInvariants(E);
  A:=as[4];
  B:=as[5];
  return E,[A,B];
end function;


function Kubert(b,c)
	return EllipticCurve([1-c,-b,-b,0,0]);
end function;


/////////////////////////////////////////////////
//     QUADRATIC
/////////////////////////////////////////////////

// Z/3Z x Z/3Z

P2<X,Y,Z>:=ProjectiveSpace(Rationals(),2);
C:=Curve(P2,X^3+Y^3-Z^3);
E:=EllipticCurve(C);	

Ecm1:=CM_EllipticCurve(-3,16);;
Ecm2:=CM_EllipticCurve(-3,-432);;
assert IsIsomorphic(E,Ecm2);
K:=QuadraticField(-3);
Ecm1K:=BaseChange(Ecm1,K);
Ecm2K:=BaseChange(Ecm2,K);
assert IsIsomorphic(Ecm2K,Ecm1K);
assert [3,3] eq AbelianInvariants(TorsionSubgroup(Ecm1K));

// Z/2Z x Z/4Z

// case 1 ---> E_4^4 and E_4^-1
E:=Kubert(-1/8,0);
Ecm:=CM_EllipticCurve(-4,4);;
assert IsIsomorphic(E,Ecm);
K:=QuadraticField(-1);
EK:=BaseChange(E,K);
assert [2,4] eq AbelianInvariants(TorsionSubgroup(EK));
Ecm2:=CM_EllipticCurve(-4,-1);
Ecm2K:=BaseChange(Ecm2,K);
assert IsIsomorphic(EK,Ecm2K);


//case 2 ---> E_4^-4 and E_4^-1
K<a>:=QuadraticField(2);
EK:=Kubert(1+3/4*a,0);
assert [2,4] eq AbelianInvariants(TorsionSubgroup(EK));
assert 1728 eq jInvariant(EK);
Ecm:=CM_EllipticCurve(-4,-1);;
EcmK:=BaseChange(Ecm,K);
assert IsIsomorphic(EK,EcmK);

/*
> Ecm1:=CM_EllipticCurve(-4,-1);; 
> Ecm2:=CM_EllipticCurve(-4,-4);;
> IsQuadraticTwist(Ecm1,Ecm2);
true 2
*/


// case 3 ---> E_16^1 and E_16^2

E:=Kubert(-1/32,0);
Ecm:=CM_EllipticCurve(-16,2);;
assert IsIsomorphic(E,Ecm);
K<a>:=QuadraticField(2);
EK:=BaseChange(E,K);
assert [2,4] eq AbelianInvariants(TorsionSubgroup(EK));

/*
> Ecm1:=CM_EllipticCurve(-16,1);; 
> Ecm2:=CM_EllipticCurve(-16,2);; 
> IsQuadraticTwist(Ecm1,Ecm2);  
true 2
*/

// case 4 -->NO

K<a>:=QuadraticField(2);
EK:=Kubert(1/8+1/8*a,0);
assert [2,4] eq AbelianInvariants(TorsionSubgroup(EK));
assert 8000 eq jInvariant(EK);
Ecm:=CM_EllipticCurve(-8,1);;
EcmK:=BaseChange(Ecm,K);
boo,t:=IsQuadraticTwist(EcmK,EK);
assert boo;
assert not IsSquare(t);


// case 5 -->NO
K<a>:=QuadraticField(-7);
EK:=Kubert((-31+3*a)/512,0);
assert [2,4] eq AbelianInvariants(TorsionSubgroup(EK));


// case 6 -->NO
EK:=Kubert((-1+3*a)/32,0);
assert [2,4] eq AbelianInvariants(TorsionSubgroup(EK));

// Remark: curves with Delta=-7 are NOT iso over Q(sqrt(-7)) 
K<a>:=QuadraticField(-7);
EK1:=Kubert((-31+3*a)/512,0);
EK2:=Kubert((-1+3*a)/32,0);
assert not IsIsomorphic(EK1,EK2);


// Z/2Z x Z/6Z

// case 1 ---> E_3^1 and E_3^-27
E:=Kubert(-2/9,-1/3);
assert 0 eq jInvariant(E);
Ecm1:=CM_EllipticCurve(-3,1);
assert IsIsomorphic(E,Ecm1);
K:=QuadraticField(-3);
EK:=BaseChange(E,K);
assert [2,6] eq AbelianInvariants(TorsionSubgroup(EK));

Ecm1:=CM_EllipticCurve(-3,1);; 
Ecm2:=CM_EllipticCurve(-3,-27);; 
boo,s:=IsQuadraticTwist(Ecm1,Ecm2);    
assert boo and s eq -3;

// case 2  ---> E_12^1
K<a>:=QuadraticField(3);
EK:=Kubert((1-a)/9,(-2+a)/3);
assert 54000 eq jInvariant(EK);
Ecm:=CM_EllipticCurve(-12,1);; 
EcmK:=BaseChange(Ecm,K);
assert IsIsomorphic(EK,EcmK);
assert [2,6] eq AbelianInvariants(TorsionSubgroup(EK));

// case 2  ---> E_12^3
E:=Kubert(4/9,1/3);
assert 54000 eq jInvariant(EK);
K<a>:=QuadraticField(3);
Ecm:=CM_EllipticCurve(-12,3);; 
EcmK:=BaseChange(Ecm,K);
EK:=BaseChange(E,K);
assert IsIsomorphic(EK,EcmK);
assert [2,6] eq AbelianInvariants(TorsionSubgroup(EK));

// Remark: curves with Delta=-12 are iso over Q(sqrt(3)) 
K<a>:=QuadraticField(3);
EK:=Kubert((1-a)/9,(-2+a)/3);
E:=Kubert(4/9,1/3);

EK2:=BaseChange(E,K);
assert IsIsomorphic(EK,EK2);
