Tripling-oriented Doche/Icart/Kohel coordinates represent an affine point (x,y) on a tripling-oriented Doche/Icart/Kohel-form elliptic curve y^2 = x^3 + 3a(x+1)^2 as (X:Y:Z:ZZ) satisfying Y^2 = X^3 + 3aZ^2(X+Z^2)^2 and ZZ = Z^2. Here (X:Y:Z:ZZ) = (s^2 X:s^3 Y:sZ:s^2 ZZ) for all nonzero s.
Speed records:
The following commands for the Magma computer-algebra system check various addition formulas for tripling-oriented Doche/Icart/Kohel coordinates.
Tripling-oriented Doche/Icart/Kohel scaling.
K<a,X1,Y1,X2,Y2>:=FieldOfFractions(PolynomialRing(Rationals(),5)); R<Z1,Z2>:=PolynomialRing(K,2); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; // here are the formulas: A:=1/Z1; AA:=A^2; X2:=X1*AA; Y2:=Y1*AA*A; Z2:=1; // check: x1:=X1/Z1^2; y1:=Y1/Z1^3; S!(y1^2-x1^3-3*a*(x1+1)^2); x2:=X2/Z2^2; y2:=Y2/Z2^3; S!(y2^2-x2^3-3*a*(x2+1)^2); S!(Z2-1); S!(x2-x1); S!(y2-y1);
Tripling-oriented Doche/Icart/Kohel addition (11M+6S+1D+13add+2times2+1times3+1times8+1times16) matches traditional addition. S,M counts stated in the literature: 11M + 6S in 2007 Bernstein/Birkner/Lange/Peters.
2006 Doche/Icart/Kohel, page 199, top display, Z2 set to 1, affine only:
K<a,x1,x2>:=FieldOfFractions(PolynomialRing(Rationals(),3)); R<y1,y2>:=PolynomialRing(K,2); S:=quo<R|y1^2-x1^3-3*a*(x1+1)^2,y2^2-x2^3-3*a*(x2+1)^2>; X1:=x1; Y1:=y1; Z1:=1; X2:=x2; Y2:=y2; Z2:=1; // here are the formulas: // uncached: A:=X1; B:=Y1; C:=X2-A; D:=Y2-B; Z3:=C; E:=Z3^2; F:=C^2; G:=C*F; H:=A*F; X3:=D^2-G-3*a*E-2*H; Y3:=D*(H-X3)-B*G; Z3Z3:=E; // back to affine: Z3Z3-Z3^2; x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: x1:=X1/Z1^2; y1:=Y1/Z1^3; x2:=X2/Z2^2; y2:=Y2/Z2^3; lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);Simplified, projectified:
K<a,X1,Y1,X2,Y2>:=FieldOfFractions(PolynomialRing(Rationals(),5)); R<Z1,Z2>:=PolynomialRing(K,2); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; S!(y1^2-x1^3-3*a*(x1+1)^2); x2:=X2/Z2^2; y2:=Y2/Z2^3; S!(y2^2-x2^3-3*a*(x2+1)^2); // here are the formulas: D:=Y2/Z2^3-Y1/Z1^3; Z3:=X2/Z2^2-X1/Z1^2; X3:=D^2-Z3^3-3*a*Z3^2-2*Z3^2*X1/Z1^2; Y3:=D*(Z3^2*X1/Z1^2-X3)-Z3^3*Y1/Z1^3; // back to affine: x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);Denominators cleared:
K<a,X1,Y1,X2,Y2>:=FieldOfFractions(PolynomialRing(Rationals(),5)); R<Z1,Z2>:=PolynomialRing(K,2); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; S!(y1^2-x1^3-3*a*(x1+1)^2); x2:=X2/Z2^2; y2:=Y2/Z2^3; S!(y2^2-x2^3-3*a*(x2+1)^2); // here are the formulas: A:=X2*Z1^2-X1*Z2^2; B:=Y2*Z1^3-Y1*Z2^3; X3:=B^2-A^3-Z1^2*Z2^2*3*a*A^2-Z2^2*2*A^2*X1; Y3:=B*(Z2^2*A^2*X1-X3)-Z2^3*A^3*Y1; Z3:=Z1*Z2*A; // back to affine: x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);Common subexpressions eliminated, 13M + 4S + 1D + 7add + 1times2 + 1times3:
K<a,X1,Y1,X2,Y2>:=FieldOfFractions(PolynomialRing(Rationals(),5)); R<Z1,Z2>:=PolynomialRing(K,2); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; S!(y1^2-x1^3-3*a*(x1+1)^2); x2:=X2/Z2^2; y2:=Y2/Z2^3; S!(y2^2-x2^3-3*a*(x2+1)^2); // already provided as part of input: Z1Z1:=Z1^2; Z2Z2:=Z2^2; // here are the formulas: A:=X2*Z1Z1-X1*Z2Z2; B:=Y2*Z1*Z1Z1-Y1*Z2*Z2Z2; C:=Z2*A; CC:=C^2; D:=X1*CC; Z3:=Z1*C; E:=Z3^2; X3:=B^2-A*A^2-3*a*E-2*D; Y3:=B*(D-X3)-Y1*C*CC; Z3Z3:=E; // back to affine: Z3Z3-Z3^2; x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);2007 Bernstein/Birkner/Lange/Peters, 11M + 6S + 1D + 13add + 2times2 + 1times3 + 1times8 + 1times16:
K<a,X1,Y1,X2,Y2>:=FieldOfFractions(PolynomialRing(Rationals(),5)); R<Z1,Z2>:=PolynomialRing(K,2); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; S!(y1^2-x1^3-3*a*(x1+1)^2); x2:=X2/Z2^2; y2:=Y2/Z2^3; S!(y2^2-x2^3-3*a*(x2+1)^2); // already provided as part of input: Z1Z1:=Z1^2; Z2Z2:=Z2^2; // cached: Z2Z2Z2:=Z2*Z2Z2; // uncached: Z1Z1Z1:=Z1*Z1Z1; A:=X2*Z1Z1-X1*Z2Z2; B:=Y2*Z1Z1Z1-Y1*Z2Z2Z2; AA:=A^2; C:=(Z2+A)^2-Z2Z2-AA; CC:=C^2; CC8:=8*CC; D:=X1*CC8; Z3:=(Z1+C)^2-Z1Z1-CC; E:=Z3^2; X3:=16*(B^2-A*AA)-D-3*a*E; Y3:=2*B*(D-2*X3)-Y1*C*CC8; Z3Z3:=E; // back to affine: Z3Z3-Z3^2; x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);
Tripling-oriented Doche/Icart/Kohel mixed addition (7M+4S+1D+10add+3times2+1times3+1times4) matches traditional addition. S,M,D counts stated in the literature: 8M+3S+1D in 2006 Doche/Icart/Kohel ("8M+3S to compute an addition. If u is a random element in the field, then an extra multiplication is required"). 7M+4S+1D in 2007 Bernstein/Lange.
2006 Doche/Icart/Kohel, page 199, top display, roles of 1 and 2 reversed, 8M+3S+1D+7add+1times2+1times3:
K<a,X1,Y1,X2>:=FieldOfFractions(PolynomialRing(Rationals(),4)); R<Z1,Y2>:=PolynomialRing(K,2); Z2:=1; S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; // here are the formulas: // already provided as part of input: Z1Z1:=Z1^2; // uncached: A:=X2*Z1Z1; B:=Y2*Z1Z1*Z1; C:=X1-A; D:=Y1-B; Z3:=Z1*C; E:=Z3^2; F:=C^2; G:=C*F; H:=A*F; X3:=D^2-G-3*a*E-2*H; Y3:=D*(H-X3)-B*G; Z3Z3:=E; // back to affine: Z3Z3-Z3^2; x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: x1:=X1/Z1^2; y1:=Y1/Z1^3; x2:=X2/Z2^2; y2:=Y2/Z2^3; lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);2007 Bernstein/Birkner/Lange/Peters, 7M+4S+1D+10add+3times2+1times3+1times4:
K<a,X1,Y1,X2>:=FieldOfFractions(PolynomialRing(Rationals(),4)); R<Z1,Y2>:=PolynomialRing(K,2); Z2:=1; S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; // here are the formulas: // already provided as part of input: Z1Z1:=Z1^2; // uncached: A:=X2*Z1Z1; B:=Y2*Z1Z1*Z1; C:=X1-A; D:=2*(Y1-B); F:=C^2; F4:=4*F; Z3:=(Z1+C)^2-Z1Z1-F; E:=Z3^2; G:=C*F4; H:=A*F4; X3:=D^2-G-2*H-3*a*E; Y3:=D*(H-X3)-2*B*G; Z3Z3:=E; // back to affine: Z3Z3-Z3^2; x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: x1:=X1/Z1^2; y1:=Y1/Z1^3; x2:=X2/Z2^2; y2:=Y2/Z2^3; lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);
Tripling-oriented Doche/Icart/Kohel addition with Z1=1 and Z2=1 (4M + 2S + 1D + 7add + 4times2 + 1times3 + 1times4) matches traditional addition. S,M,D counts stated in the literature: 8M+3S+1D in 2007 Bernstein/Lange.
2007 Bernstein/Birkner/Lange/Peters, 4M + 2S + 1D + 7add + 4times2 + 1times3 + 1times4:
K<a,X1,Y1,X2>:=FieldOfFractions(PolynomialRing(Rationals(),4)); R<Z1,Y2>:=PolynomialRing(K,2); Z1:=1; Z2:=1; S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2,Y2^2-X2^3-3*a*Z2^2*(X2+Z2^2)^2>; // here are the formulas: // uncached: C:=X1-X2; D:=2*(Y1-Y2); F:=C^2; F4:=4*F; Z3:=2*C; G:=C*F4; H:=X2*F4; X3:=D^2-G-2*H-3*a*F4; Y3:=D*(H-X3)-2*Y2*G; Z3Z3:=F4; // back to affine: Z3Z3-Z3^2; x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: x1:=X1/Z1^2; y1:=Y1/Z1^3; x2:=X2/Z2^2; y2:=Y2/Z2^3; lambda:=(y2-y1)/(x2-x1); r3:=lambda^2-3*a-x1-x2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);
Tripling-oriented Doche/Icart/Kohel doubling (2M + 7S + 2D + 12add + 3times2 + 2times3 + 1times8) matches traditional doubling. S,M,D counts stated in the literature: 4M+5S+2D in 2006 Doche/Icart/Kohel ("4M+5S as long as we neglect multiplications by u, otherwise a doubling can be obtained with 6M+4S"; no explanation of the 4S). 2M+7S+2D in 2007 Bernstein/Birkner/Lange/Peters.
2006 Doche/Icart/Kohel, page 198, bottom display, corrected by 2007 Bernstein/Birkner/Lange/Peters to incorporate the missing -3a term:
K<a,x1>:=FieldOfFractions(PolynomialRing(Rationals(),2)); R<y1>:=PolynomialRing(K,1); S:=quo<R|y1^2-x1^3-3*a*(x1+1)^2>; x2:=x1; y2:=y1; X1:=x1; Y1:=y1; Z1:=1; // already provided as part of input: Z1Z1:=Z1^2; // here are the formulas: // warning: 2006 Doche/Icart/Kohel is missing -3*a*Z3Z3 A:=Y1*Z1; Z3:=2*A; B:=4*Y1^2*X1; C:=B+6*a*A^2; Z3Z3:=4*A^2; D:=3*X1^2; E:=D+6*a*Z1Z1*(Z1Z1+X1); X3:=E^2-2*B-3*a*Z3Z3; Y3:=E*(B-X3)-8*Y1^4; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r3:=lambda^2-3*a-2*x1; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);2006 Doche/Icart/Kohel, page 198, bottom display, corrected by 2007 Bernstein/Birkner/Lange/Peters to incorporate the missing -3a term:
K<a,X1,Y1>:=FieldOfFractions(PolynomialRing(Rationals(),3)); R<Z1>:=PolynomialRing(K,1); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; // already provided as part of input: Z1Z1:=Z1^2; // here are the formulas: // warning: 2006 Doche/Icart/Kohel is missing -3*a*Z3Z3 A:=Y1*Z1; Z3:=2*A; B:=4*Y1^2*X1; C:=B+6*a*A^2; Z3Z3:=4*A^2; D:=3*X1^2; E:=D+6*a*Z1Z1*(Z1Z1+X1); X3:=E^2-2*B-3*a*Z3Z3; Y3:=E*(B-X3)-8*Y1^4; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r3:=lambda^2-3*a-2*x1; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);2006 Doche/Icart/Kohel, page 198, bottom display, corrected by 2007 Bernstein/Birkner/Lange/Peters to incorporate the missing -3a term, unused C eliminated, common subexpressions eliminated, 4M + 5S + 2D + 6add + 2times2 + 2times3 + 1times4 + 1times6 + 1times8:
K<a,X1,Y1>:=FieldOfFractions(PolynomialRing(Rationals(),3)); R<Z1>:=PolynomialRing(K,1); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; // already provided as part of input: Z1Z1:=Z1^2; // here are the formulas: Y1Y1:=Y1^2; A:=Y1*Z1; Z3:=2*A; B:=4*Y1Y1*X1; Z3Z3:=Z3^2; D:=3*X1^2; E:=D+6*a*Z1Z1*(Z1Z1+X1); X3:=E^2-2*B-3*a*Z3Z3; Y3:=E*(B-X3)-8*Y1Y1^2; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r3:=lambda^2-3*a-2*x1; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);2007 Bernstein/Birkner/Lange/Peters, 2M + 7S + 2D + 12add + 3times2 + 2times3 + 1times8:
K<a,X1,Y1>:=FieldOfFractions(PolynomialRing(Rationals(),3)); R<Z1>:=PolynomialRing(K,1); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; // already provided as part of input: Z1Z1:=Z1^2; // here are the formulas: A:=X1^2; B:=2*a*Z1Z1*(X1+Z1Z1); C:=3*(A+B); D:=Y1^2; E:=D^2; Z3:=(Y1+Z1)^2-D-Z1Z1; Z3Z3:=Z3^2; F:=2*((X1+D)^2-A-E); X3:=C^2-3*a*Z3Z3-2*F; Y3:=C*(F-X3)-8*E; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r3:=lambda^2-3*a-2*x1; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);
Tripling-oriented Doche/Icart/Kohel doubling with Z1=1 (1M + 5S + 2D + 9add + 4times2 + 2times3 + 1times4+ 1times8) matches traditional doubling. S,M,D counts stated in the literature: 1M + 5S + 2D in 2007 Bernstein/Lange.
K<a,X1,Y1>:=FieldOfFractions(PolynomialRing(Rationals(),3)); R<Z1>:=PolynomialRing(K,1); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2>; Z1:=1; x1:=X1/Z1^2; y1:=Y1/Z1^3; // here are the formulas: A:=X1^2; B:=2*a*(X1+1); C:=3*(A+B); D:=Y1^2; E:=D^2; Z3:=2*Y1; Z3Z3:=4*D; F:=2*((X1+D)^2-A-E); X3:=C^2-3*a*Z3Z3-2*F; Y3:=C*(F-X3)-8*E; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r3:=lambda^2-3*a-2*x1; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);
Tripling-oriented Doche/Icart/Kohel tripling (6M+6S+2D+7add+4times3+2times4+1times9) matches traditional tripling. S,M,D counts stated in the literature: 6M+6S+2D in 2006 Doche/Icart/Kohel ("6M+6S ... a multiplication by u is negligible. Otherwise, 8M+6S are necessary"). 6M+6S+2D in 2007 Bernstein/Birkner/Lange/Peters; thanks to Hisil for comments.
2006 Doche/Icart/Kohel, page 198, middle display:
K<a,x1>:=FieldOfFractions(PolynomialRing(Rationals(),2)); R<y1>:=PolynomialRing(K,1); S:=quo<R|y1^2-x1^3-3*a*(x1+1)^2>; x2:=x1; y2:=y1; X1:=x1; Y1:=y1; Z1:=1; // already provided as part of input: Z1Z1:=Z1^2; // here are the formulas: A:=(X1+3*Z1Z1)^2; B:=a*Z1Z1*A; Xt:=Y1^2+B; Yt:=Y1*(Y1^2-3*B); Zt:=X1*Z1; C:=Zt^2; D:=((4*a-9)*C-Xt)^2; E:=-3*a*C*D; X3:=(Yt^2+E); Y3:=Yt*(X3-4*E); Z3:=3*Xt*Zt; Z3Z3:=Z3^2; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r2:=lambda^2-3*a-2*x1; s2:=lambda*(x1-r2)-y1; lambda:=(s2-y1)/(r2-x1); r3:=lambda^2-3*a-x1-r2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);2006 Doche/Icart/Kohel, page 198, middle display:
K<a,X1,Y1>:=FieldOfFractions(PolynomialRing(Rationals(),3)); R<Z1>:=PolynomialRing(K,1); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; // already provided as part of input: Z1Z1:=Z1^2; // here are the formulas: A:=(X1+3*Z1Z1)^2; B:=a*Z1Z1*A; Xt:=Y1^2+B; Yt:=Y1*(Y1^2-3*B); Zt:=X1*Z1; C:=Zt^2; D:=((4*a-9)*C-Xt)^2; E:=-3*a*C*D; X3:=(Yt^2+E); Y3:=Yt*(X3-4*E); Z3:=3*Xt*Zt; Z3Z3:=Z3^2; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r2:=lambda^2-3*a-2*x1; s2:=lambda*(x1-r2)-y1; lambda:=(s2-y1)/(r2-x1); r3:=lambda^2-3*a-x1-r2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);2006 Doche/Icart/Kohel, page 198, middle display, common subexpressions eliminated, 6M + 6S + 2D + 7add + 4times3 + 2times4 + 1times9:
K<a,X1,Y1>:=FieldOfFractions(PolynomialRing(Rationals(),3)); R<Z1>:=PolynomialRing(K,1); S:=quo<R|Y1^2-X1^3-3*a*Z1^2*(X1+Z1^2)^2>; x1:=X1/Z1^2; y1:=Y1/Z1^3; // already provided as part of input: Z1Z1:=Z1^2; // here are the formulas: Y1Y1:=Y1^2; A:=(X1+3*Z1Z1)^2; B:=a*Z1Z1*A; Xt:=Y1Y1+B; Yt:=Y1*(Y1Y1-3*B); Zt:=X1*Z1; C:=Zt^2; Ca:=a*C; E:=3*Ca*(4*Ca-9*C-Xt)^2; X3:=Yt^2-E; Y3:=Yt*(X3+4*E); Z3:=3*Xt*Zt; Z3Z3:=Z3^2; // back to affine: S!(Z3Z3-Z3^2); x3:=X3/Z3^2; y3:=Y3/Z3^3; S!(y3^2-x3^3-3*a*(x3+1)^2); // versus traditional affine formulas: lambda:=(3*x1^2+6*a*x1+6*a)/(2*y1); r2:=lambda^2-3*a-2*x1; s2:=lambda*(x1-r2)-y1; lambda:=(s2-y1)/(r2-x1); r3:=lambda^2-3*a-x1-r2; s3:=lambda*(x1-r3)-y1; // check the answer: S!(x3-r3); S!(y3-s3);