Mathematica.FEE   [plain text]


(* Elliptic algebra functions: FEE format.

   y^2 = x^3 + c x^2 + a x + b.

   Montgomery: b = 0, a = 1;
   Weierstrass: c = 0;
   Atkin3: c = a = 0;
   Atkin4: c = b = 0;

   Parameters c, a, b, p must be global.
 *)

elleven[pt_] := Block[{x1 = pt[[1]], z1 = pt[[2]], e, f },
  	e = Mod[(x1^2 - a z1^2)^2 - 4 b (2 x1 + c z1) z1^3, p];
  	f = Mod[4 z1 (x1^3 + c x1^2 z1 + a x1 z1^2 + b z1^3), p];
  	Return[{e,f}]
];

ellodd[pt_, pu_, pv_] := Block[
		{x1 = pt[[1]], z1 = pt[[2]],
		 x2 = pu[[1]], z2 = pu[[2]],
		 xx = pv[[1]], zz = pv[[2]], i, j},
  	     i = Mod[zz ((x1 x2 - a z1 z2)^2 -
  	          4 b(x1 z2 + x2 z1 + c z1 z2) z1 z2), p];
  	     j = Mod[xx (x1 z2 - x2 z1)^2, p];
  		 Return[{i,j}]
];

bitList[k_] := Block[{li = {}, j = k},
	While[j > 0,
	    li = Append[li, Mod[j,2]];
	    j = Floor[j/2];
	];
	Return[Reverse[li]];
	];

elliptic[pt_, k_] := Block[{porg, ps, pp, q},

	If[k ==1, Return[pt]];
	If[k ==2, Return[elleven[pt]]];
	porg = pt;
	ps = elleven[pt];
	pp = pt;
	bitlist = bitList[k];
	Do[
	   If[bitlist[[q]] == 1,
	   	   pp = ellodd[ps, pp, porg];
	   	   ps = elleven[ps],
	   	      ps = ellodd[pp, ps, porg];
		      pp = elleven[pp]
	   ],
	   {q,2,Length[bitlist]}
    ];
    Return[Mod[pp,p]]
];
ellinv[n_] := PowerMod[n,-1,p];
ex[pt_] := Mod[pt[[1]] * ellinv[pt[[2]]], p];