ZZ := Integers(); x0 := -8702303353090049898316902; t := 6*x0 - 1; p := 12*x0^2 - 1; // this is a 170-bit prime cofactor_E := 7^2*313; ell := (p+1-t) div cofactor_E; // this is a 156-bit prime cofactor_E3 := (p^3 + 1 - t^3 + 3*p*t) div ell^2; cofactor_Fp3:=(p^3-1) div ell; a := 818416342594888291485044088811640789053085789975506; b := 666070443323978349780035881803413282865714842057992; Fp := FiniteField(p,1); E := EllipticCurve([Fp!a, Fp!b]); even_sqrt:=func; SetPrintLevel("Hex"); // generator of rational subgroup G0:=E![x,even_sqrt(x^3+a*x+b)] where x is Fp!2; G1 := cofactor_E*G0; printf "G1 = %o\n", ChangeUniverse(Eltseq(G1)[1..2],Integers()); // generator of subgroup over extension // an arbitrary representation of Fp3. Fp3 := ext; Q := E(Fp3)![x,even_sqrt(x^3+a*x+b)] where x is z+2; G2 := cofactor_E3*Q; // generator of image subgroup generator := ReducedTatePairing(E(Fp3) ! G1, G2, ell); // challenge x_P := Fp ! 314159265358979323846264338327950288419716939937510; P0:=E![x,even_sqrt(x^3+a*x+b)] where x is Fp!314159265358979323846264338327950288419716939937510; P := cofactor_E*P0; printf "P = %o\n", ChangeUniverse(Eltseq(P)[1..2],Integers()); challenge := ReducedTatePairing(E(Fp3)!P, G2, ell); // Our chosen representation of Fp3 g0:=Polynomial([-1,-3,0,1]); g1:=Polynomial([0,-1,-1]); y0:=66860548332739903465896435955260897778062220455483; Fpn:=ext; Embed(Fp3,Fpn,Roots(DefiningPolynomial(Fp3),Fpn)[1][1]); Fpn_challenge := Fpn ! challenge; Fpn_generator := Fpn ! generator; log_t:=1; // this is our normalization choice (for t == Fpn.1) // logarithm of generator e(G1,G2) log_generator:=0x8C58B66F0D8B2E99A1C0530B2649EC0C76501C3; // logarithm of challenge log_challenge:=0x48A6BCF57CACCA997658C98A0C196C25116A0AA; printf "// checking log(challenge) w.r.t. log(basis)"; assert (Fpn_generator^log_challenge/Fpn_challenge^log_generator) ^ cofactor_Fp3 eq 1; assert (generator^log_challenge/challenge^log_generator)^cofactor_Fp3 eq 1; assert (Fpn_generator / Fpn.1^log_generator) ^ cofactor_Fp3 eq 1; print " OK"; printf "// back to the elliptic curve: "; log_P := ZZ ! (GF(ell) ! log_challenge / log_generator); assert log_challenge*G1 eq log_generator*P and log_P * G1 eq P; print " OK";