// Miscellaneous EC testing


// Check that the point order computation is producing correct results
// for torsion points over Q.  (This code was recently changed, as of
// writing this test.)

procedure check_torsion_computation(P)
    n := Order(P);

    kP := P;
    for k in [1..n-1] do
	assert not IsId(kP);
	kP +:= P;
    end for;
    assert IsId(kP);

end procedure;

procedure torsion_point_order_test()
    ainvs := [
	// minimal curves with all torsion points integral; note that
	// we don't have examples of C2xC6 or C2xC8 for this
	[ 0, -1, 1, -7820, -263580 ],	// C1
	[ 1, 0, 1, -171, -874 ],	// C2
	[ 0, 1, 1, -9, -15 ],		// C3
	[ 1, 1, 1, 0, 0 ],		// C4
	[ 0, -1, 1, -10, -20 ],		// C5
	[ 1, 0, 1, 4, -6 ],		// C6
	[ 1, -1, 1, -3, 3 ],		// C7
	[ 1, 1, 1, -4, 5 ],		// C8
	[ 1, -1, 1, -14, 29 ],		// C9
	[ 1, 0, 0, -45, 81 ],		// C10
	[ 1, -1, 1, -122, 1721 ],	// C12
	[ 0, -1, 0, -24, -36 ],		// C2 x C2
	[ 0, -1, 0, -4, 4 ],		// C2 x C4

	// minimal curves with some torsion points non-integral; note
	// that we only have examples with two-torsion points
	[ 1, 0, 1, -2731, -55146 ],	// C2
	[ 1, 1, 1, -80, 242 ],		// C4
	[ 1, 0, 1, -36, -70 ],		// C6
	[ 1, 1, 1, 35, -28 ],		// C8
	[ 1, 0, 0, 115, 561 ],		// C10
	[ 1, 0, 1, 1922, 20756 ],	// C12
	[ 1, 1, 1, -135, -660 ],	// C2 x C2
	[ 1, 1, 1, -10, -10 ],		// C2 x C4
	[ 1, 0, 1, -19, 26 ],		// C2 x C6
	[ 1, 0, 0, -1070, 7812 ]	// C2 x C8
    ];
    pts := [
	[ [ 0, 1, 0 ] ],
	[ [ 0, 1, 0 ], [ 15, -8, 1 ] ],
	[ [ 0, 1, 0 ], [ 5, 9, 1 ], [ 5, -10, 1 ] ],
	[ [ 0, 1, 0 ], [ 0, 0, 1 ], [ -1, 0, 1 ], [ 0, -1, 1 ] ],
	[ [ 0, 1, 0 ], [ 16, 60, 1 ], [ 5, 5, 1 ], [ 5, -6, 1 ],
	  [ 16, -61, 1 ] ],
	[ [ 0, 1, 0 ], [ 9, -33, 1 ], [ 2, -5, 1 ], [ 1, -1, 1 ],
	  [ 2, 2, 1 ], [ 9, 23, 1 ] ],
	[ [ 0, 1, 0 ], [ 1, 0, 1 ], [ -1, -2, 1 ], [ 3, -6, 1 ],
	  [ 3, 2, 1 ], [ -1, 2, 1 ], [ 1, -2, 1 ] ],
	[ [ 0, 1, 0 ], [ -1, -3, 1 ], [ 1, 1, 1 ], [ 5, -15, 1 ],
	  [ -3, 1, 1 ], [ 5, 9, 1 ], [ 1, -3, 1 ], [ -1, 3, 1 ] ],
	[ [ 0, 1, 0 ], [ 9, 19, 1 ], [ 3, 1, 1 ], [ 1, 3, 1 ],
	  [ -3, 7, 1 ], [ -3, -5, 1 ], [ 1, -5, 1 ], [ 3, -5, 1 ],
	  [ 9, -29, 1 ] ],
	[ [ 0, 1, 0 ], [ 0, 9, 1 ], [ 6, 3, 1 ], [ -6, -9, 1 ],
	  [ 18, -81, 1 ], [ 2, -1, 1 ], [ 18, 63, 1 ], [ -6, 15, 1 ],
	  [ 6, -9, 1 ], [ 0, -9, 1 ] ],
	[ [ 0, 1, 0 ], [ -9, -41, 1 ], [ 21, 79, 1 ], [ 9, -41, 1 ],
	  [ 1, 39, 1 ], [ 81, -761, 1 ], [ -15, 7, 1 ], [ 81, 679, 1 ],
	  [ 1, -41, 1 ], [ 9, 31, 1 ], [ 21, -101, 1 ], [ -9, 49, 1 ] ],
	[ [ 0, 1, 0 ], [ 6, 0, 1 ], [ -3, 0, 1 ], [ -2, 0, 1 ] ],
	[ [ 0, 1, 0 ], [ -2, 0, 1 ], [ 0, -2, 1 ], [ 4, 6, 1 ],
	  [ 2, 0, 1 ], [ 1, 0, 1 ], [ 0, 2, 1 ], [ 4, -6, 1 ] ],

	[ [ 0, 1, 0 ], [ -121/4, 117/8, 1 ] ],
	[ [ 0, 1, 0 ], [ 5, -2, 1 ], [ 19/4, -23/8, 1 ], [ 5, -4, 1 ] ],
	[ [ 0, 1, 0 ], [ -4, 5, 1 ], [ 10, -30, 1 ], [ -9/4, 5/8, 1 ],
	  [ 10, 19, 1 ], [ -4, -2, 1 ] ],
	[ [ 0, 1, 0 ], [ 32, 171, 1 ], [ 7, 21, 1 ], [ 2, 6, 1 ],
	  [ 3/4, -7/8, 1 ], [ 2, -9, 1 ], [ 7, -29, 1 ], [ 32, -204, 1 ] ],
	[ [ 0, 1, 0 ], [ 4, -35, 1 ], [ -2, 19, 1 ], [ 70, 559, 1 ],
	  [ 16, -89, 1 ], [ -17/4, 17/8, 1 ], [ 16, 73, 1 ], [ 70, -629, 1 ],
	  [ -2, -17, 1 ], [ 4, 31, 1 ] ],
	[ [ 0, 1, 0 ], [ -5, -103, 1 ], [ 100, 1052, 1 ], [ 37, -397, 1 ],
	  [ 10, 197, 1 ], [ 415, -8713, 1 ], [ -41/4, 37/8, 1 ],
	  [ 415, 8297, 1 ], [ 10, -208, 1 ], [ 37, 359, 1 ],
	  [ 100, -1153, 1 ], [ -5, 107, 1 ] ],
	[ [ 0, 1, 0 ], [ 13, -7, 1 ], [ -7, 3, 1 ], [ -29/4, 25/8, 1 ] ],
	[ [ 0, 1, 0 ], [ -1, 0, 1 ], [ -2, -2, 1 ], [ 8, -27, 1 ],
	  [ 3, -2, 1 ], [ -13/4, 9/8, 1 ], [ -2, 3, 1 ], [ 8, 18, 1 ] ],
	[ [ 0, 1, 0 ], [ 3, -2, 1 ], [ -2, 8, 1 ], [ 1, -4, 1 ],
	  [ 4, -7, 1 ], [ 13, 38, 1 ], [ 7/4, -11/8, 1 ], [ -5, 2, 1 ],
	  [ 4, 2, 1 ], [ 13, -52, 1 ], [ -2, -7, 1 ], [ 1, 2, 1 ] ],
	[ [ 0, 1, 0 ], [ -36, 18, 1 ], [ 244, 3658, 1 ], [ -26, -122, 1 ],
	  [ 64, 418, 1 ], [ -8, -122, 1 ], [ 34, 88, 1 ], [ 4, -62, 1 ],
	  [ 28, -14, 1 ], [ 31/4, -31/8, 1 ], [ 34, -122, 1 ], [ 4, 58, 1 ],
	  [ 64, -482, 1 ], [ -8, 130, 1 ], [ 244, -3902, 1 ], [ -26, 148, 1 ] ]
    ];

    for k in [1..#ainvs] do
	E := EllipticCurve(ainvs[k]);
	for P in [ E!coords : coords in pts[k] ] do
	    check_torsion_computation(P);
	end for;
    end for;
end procedure;


torsion_point_order_test();

for c := 1 to 100 do
    K := GF(2^3);
    k<w> := ExtensionField<K,X | X^5 + X^4 + K.1^6*X^3 + K.1^6*X + 1>;
    E := EllipticCurve([k ! 1,K.1^4*w^4 + K.1^3*w^3 + K.1^4*w +
    K.1^3,0,0,K.1*w^4 + K.1^2*w^3 + K.1^5*w^2 + K.1*w + K.1^6]);
    P := Random(E(k));
    assert IsOrder(P,Order(P));
end for;

///// Sep 22

A := -131150645198;
B := 4437570722116028627601;
E := EllipticCurve([0,A,0,B,0]);
phi := TwoIsogeny(E![0,0]);
time SG, selmap := SelmerGroup(phi);
assert AbelianInvariants(SG) eq [2, 2];

///// Dec 22

SetClassGroupBounds("GRH");
for x1 in [1..8] do
  for x2 in [x1..8] do
    for x3 in [x2..8] do
      phi:=x1^8+x2^8+x3^8-2*(x1^4*x2^4+x1^4*x3^4+x2^4*x3^4);
      x1, x2, x3;
      if phi ne 0 then
        E:=MinimalModel(EllipticCurve([0,0,0,phi/4,0]));
        Coefficients(E);
        F2 := DivisionPolynomial(E,2);
        F := Factorization(F2)[1][1];
        E2 := MinimalModel(IsogenyFromKernel(E,F));
        Coefficients(E2);
        x1, x2, x3, IsogenousCurves(E);
      end if;
    end for;
  end for;
end for;

//// Selmer (from M Voznyy)

C := [
[ 1, 0, 1, -17990652859554778, 834858189981709376588348 ],
[ 1, 0, 1, -1640340922439842644974, 24511546383301407010638230027372 ],
[ 1, 0, 0, -125068235939686110, 17774107388243610895928772 ],
[ 1, 0, 1, -914282239396643, -1938976711913417160742 ],
[ 1, 0, 0, -1258305628499046, 17171212115293097768676 ],
[ 1, 0, 0, -164882691024932166, 25773304726347619388016996 ],
[ 1, -1, 1, -3335952773845148, 74904576629160936538847 ],
[ 1, 0, 1, -1169605604078734, 15786833026663402817132 ],
[ 1, 0, 0, -830436886830236, 9211020572149798342416 ],
[ 1, 0, 1, -486000116646038, 4776844722304630670156 ],
[ 1, 0, 1, -248219145268748, 1505196106044064187006 ],
[ 1, 0, 1, -198489664790214673, 22524560187123153568231928 ],
[ 1, 0, 0, -1480836026213711, 17452524841705461121785 ],
[ 1, 0, 1, -15036323944029018, 709912066976100728195008 ],
[ 1, -1, 1, -951408893413483538, 356822138088765481670587217 ],
[ 1, 0, 0, -141826401458791, 671659472993365294025 ],
[ 1, 0, 1, -1444706885023133, 21476742900056179877468 ],
[ 1, 0, 0, -59268258917371, 184507412214263280401 ],
[ 1, 0, 0, -17447802029601379436, -8078938505181963885457123440 ],
[ 1, 0, 0, -39748214484035770, 3050283987801914511068900 ],
[ 1, 0, 0, -1785994821860003124706, 29046994147337093901625356423236 ],
[ 1, -1, 1, -140947241732120859548, 644069868747374164987691569631 ]
];

"SelmerGroup:";
time for i in [1 .. #C] do
 E := MinimalModel(EllipticCurve(C[i]));
i, E;
 time two := MultiplicationByMMap(E, 2);
 SetSeed(0);
 time S, AtoS := SelmerGroup(two : Raw);
 #S;
end for;
