Explicit-Formulas Database

Jacobi intersections

An elliptic curve in Jacobi-intersection form is a curve in three variables (s,c,d) defined by two equations s^2 + c^2 = 1, a s^2 + d^2 = 1 where a(1-a) is nonzero. The neutral element of the curve is the point (0,1,1).

A Jacobi intersection s^2 + c^2 = 1, a s^2 + d^2 = 1 is birationally equivalent to the Weierstrass-form elliptic curve y^2 = x^3 + (2-a)x^2 + (1-a)x. A typical point (s,c,d) on the Jacobi intersection corresponds to the point (x,y) on the Weierstrass curve defined by x = (d-1)(1-a)/p, y = s(1-a)a/p where p = ca-d+1-a.

Jacobi-intersection coordinates represent an affine point (s,c,d) on a Jacobi intersection s^2 + c^2 = 1, a s^2 + d^2 = 1 as (S:C:D:Z) satisfying S^2 + C^2 = Z^2, a S^2 + D^2 = Z^2. Here (S:C:D:Z) = (rS:rC:rD:rZ) for all nonzero r.

Speed records:

The following commands for the Magma computer-algebra system check various addition formulas for Jacobi-intersection coordinates.

Jacobi-intersection scaling.

     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // here are the formulas:
     A:=1/Z1;
     S2:=S1*A;
     C2:=C1*A;
     D2:=D1*A;
     Z2:=1;
     // check:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     S!(Z2-1);
     S!(s2-s1); S!(c2-c1); S!(d2-d1);
Jacobi-intersection negation.
     K<a,s1>:=FieldOfFractions(PolynomialRing(Rationals(),2));
     R<c1,d1>:=PolynomialRing(K,2);
     S:=quo<R|s1^2+c1^2-1,a*s1^2+d1^2-1>;
     // here are the formulas:
     s2:=-s1;
     c2:=c1;
     d2:=d1;
     // map to the Weierstrass curve:
     p1:=c1*a-d1+1-a; x1:=(d1-1)*(1-a)/p1; y1:=s1*(1-a)*a/p1;
     S!(y1^2-x1^3-(2-a)*x1^2-(1-a)*x1);
     p2:=c2*a-d2+1-a; x2:=(d2-1)*(1-a)/p2; y2:=s2*(1-a)*a/p2;
     S!(y2^2-x2^3-(2-a)*x2^2-(1-a)*x2);
     // check the answer:
     S!(x2-x1); S!(y2+y1);

Jacobi-intersection addition (13M+2S+1D+7add) matches traditional addition. Multiplication counts stated in the literature: 17 in 1986 Chudnovsky/Chudnovsky, formula (4.9i) ("17 multiplications, including one multiplication by a constant"). 16 in 2001 Liardet/Smart, page 396 ("16 field multiplications"). 16 in 2007 Bernstein/Lange.

1986 Chudnovsky/Chudnovsky, formula (4.9i), specialized to affine, strongly unified:

     // beware that this calculation takes days! nice computer-algebra benchmark
     K<a,s1,s2>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<c1,c2,d1,d2>:=PolynomialRing(K,4);
     S:=quo<R|s1^2+c1^2-1,a*s1^2+d1^2-1,s2^2+c2^2-1,a*s2^2+d2^2-1>;
     // here are the formulas:
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     // map to the Weierstrass curve:
     p1:=c1*a-d1+1-a; x1:=(d1-1)*(1-a)/p1; y1:=s1*(1-a)*a/p1;
     S!(y1^2-x1^3-(2-a)*x1^2-(1-a)*x1);
     p2:=c2*a-d2+1-a; x2:=(d2-1)*(1-a)/p2; y2:=s2*(1-a)*a/p2;
     S!(y2^2-x2^3-(2-a)*x2^2-(1-a)*x2);
     p3:=c3*a-d3+1-a; x3:=(d3-1)*(1-a)/p3; y3:=s3*(1-a)*a/p3;
     S!(y3^2-x3^3-(2-a)*x3^2-(1-a)*x3);
     // add on the Weierstrass curve:
     lambda:=(y2-y1)/(x2-x1);
     r3:=lambda^2-(2-a)-x1-x2; s3:=lambda*(x1-r3)-y1;
     // check the answer:
     S!(x3-r3); S!(y3-s3);
1986 Chudnovsky/Chudnovsky, formula (4.9i), strongly unified:
     K<a,S1,C1,S2,C2>:=FieldOfFractions(PolynomialRing(Rationals(),5));
     R<D1,Z1,D2,Z2>:=PolynomialRing(K,4);
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2,S2^2+C2^2-Z2^2,a*S2^2+D2^2-Z2^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     S3:=Z1*C2*S1*D2+D1*S2*C1*Z2;
     C3:=Z1*C2*C1*Z2-D1*S2*S1*D2;
     D3:=Z1*D1*Z2*D2-a*S1*C1*S2*C2;
     Z3:=(Z1*C2)^2+(D1*S2)^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
1986 Chudnovsky/Chudnovsky, formula (4.9i), common subexpressions eliminated, 14M + 2S + 1D + 4add, strongly unified:
     K<a,S1,C1,S2,C2>:=FieldOfFractions(PolynomialRing(Rationals(),5));
     R<D1,Z1,D2,Z2>:=PolynomialRing(K,4);
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2,S2^2+C2^2-Z2^2,a*S2^2+D2^2-Z2^2>;
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     Z1C2:=Z1*C2;
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     C1Z2:=C1*Z2;
     S3:=Z1C2*S1D2+D1S2*C1Z2;
     C3:=Z1C2*C1Z2-D1S2*S1D2;
     D3:=Z1*D1*Z2*D2-a*S1*C1*S2*C2;
     Z3:=Z1C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
13M + 2S + 1D + 7add, strongly unified:
     K<a,S1,C1,S2,C2>:=FieldOfFractions(PolynomialRing(Rationals(),5));
     R<D1,Z1,D2,Z2>:=PolynomialRing(K,4);
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2,S2^2+C2^2-Z2^2,a*S2^2+D2^2-Z2^2>;
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     Z1C2:=Z1*C2;
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     C1Z2:=C1*Z2;
     U:=Z1C2*C1Z2;
     V:=D1S2*S1D2;
     S3:=(Z1C2+D1S2)*(C1Z2+S1D2)-U-V;
     C3:=U-V;
     D3:=Z1*D1*Z2*D2-a*S1*C1*S2*C2;
     Z3:=Z1C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
11M + 2S + 1D + 7add after 2M for caching, strongly unified:
     K<a,S1,C1,S2,C2>:=FieldOfFractions(PolynomialRing(Rationals(),5));
     R<D1,Z1,D2,Z2>:=PolynomialRing(K,4);
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2,S2^2+C2^2-Z2^2,a*S2^2+D2^2-Z2^2>;
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     // cached:
     Z2D2:=Z2*D2;
     S2C2:=S2*C2;
     // uncached:
     Z1C2:=Z1*C2;
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     C1Z2:=C1*Z2;
     U:=Z1C2*C1Z2;
     V:=D1S2*S1D2;
     S3:=(Z1C2+D1S2)*(C1Z2+S1D2)-U-V;
     C3:=U-V;
     D3:=Z1*D1*Z2D2-a*S1*C1*S2C2;
     Z3:=Z1C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

Jacobi-intersection mixed addition (11M+2S+1D+7add) matches traditional addition. 2001 Liardet/Smart, substituting Z2=1 in the above, 11M + 2S + 1D + 7add:

     K<a,S1,C1,S2>:=FieldOfFractions(PolynomialRing(Rationals(),4));
     R<D1,Z1,C2,D2>:=PolynomialRing(K,4);
     Z2:=1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2,S2^2+C2^2-Z2^2,a*S2^2+D2^2-Z2^2>;
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     Z1C2:=Z1*C2;
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     U:=Z1C2*C1;
     V:=D1S2*S1D2;
     S3:=(Z1C2+D1S2)*(C1+S1D2)-U-V;
     C3:=U-V;
     D3:=Z1*D1*D2-a*S1*C1*S2*C2;
     Z3:=Z1C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

Jacobi-intersection addition with S2=1 (11M + 2S + 1D + 7add) matches traditional addition. Substituting S2=1 in the above (as suggested by 2007 Hisil/Carter/Dawson), 10M + 2S + 1D + 7add after 1M to cache Z2*D2:

     K<a,S1,C1,C2>:=FieldOfFractions(PolynomialRing(Rationals(),4));
     R<Z1,D1,Z2,D2>:=PolynomialRing(K,4);
     S2:=1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2,S2^2+C2^2-Z2^2,a*S2^2+D2^2-Z2^2>;
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // cached:
     Z2D2:=Z2*D2;
     // uncached:
     E:=Z1*C2;
     F:=S1*D2;
     G:=C1*Z2;
     H:=E*G;
     J:=D1*F;
     S3:=(E+D1)*(G+F)-H-J;
     C3:=H-J;
     D3:=Z1*D1*Z2D2-a*S1*C1*C2;
     Z3:=E^2+D1^2;
     // check:
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

Jacobi-intersection addition with Z1=1 and Z2=1. 2001 Liardet/Smart, substituting Z1=1 and Z2=1 in the addition formula 8M + 2S + 1D + 7add:

     K<a,S1,S2>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<C1,D1,C2,D2>:=PolynomialRing(K,4);
     Z1:=1;Z2:=1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2,S2^2+C2^2-Z2^2,a*S2^2+D2^2-Z2^2>;
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     U:=C2*C1;
     V:=D1S2*S1D2;
     S3:=(C2+D1S2)*(C1+S1D2)-U-V;
     C3:=U-V;
     D3:=D1*D2-a*S1*S2*U;
     Z3:=C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

Jacobi-intersection doubling (3M+4S+5add+1times2) matches traditional doubling. Multiplication counts stated in the literature: 8 in 1986 Chudnovsky/Chudnovsky. 7 in 2001 Liardet/Smart ("seven field multiplications"). 7 in 2007 Bernstein/Lange.

S,M counts stated in the literature: 5M+3S in 1986 Chudnovsky/Chudnovsky ("8 ... 3 of which are squaring"). 3M+4S in 2007 Bernstein/Lange.

1986 Chudnovsky/Chudnovsky, formula (4.9i), specialized to affine, strongly unified:

     K<a,s1>:=FieldOfFractions(PolynomialRing(Rationals(),2));
     R<c1,d1>:=PolynomialRing(K,2);
     s2:=s1; c2:=c1; d2:=d1;
     S:=quo<R|s1^2+c1^2-1,a*s1^2+d1^2-1>;
     // here are the formulas:
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     // map to the Weierstrass curve:
     p1:=c1*a-d1+1-a; x1:=(d1-1)*(1-a)/p1; y1:=s1*(1-a)*a/p1;
     S!(y1^2-x1^3-(2-a)*x1^2-(1-a)*x1);
     p2:=c2*a-d2+1-a; x2:=(d2-1)*(1-a)/p2; y2:=s2*(1-a)*a/p2;
     S!(y2^2-x2^3-(2-a)*x2^2-(1-a)*x2);
     p3:=c3*a-d3+1-a; x3:=(d3-1)*(1-a)/p3; y3:=s3*(1-a)*a/p3;
     S!(y3^2-x3^3-(2-a)*x3^2-(1-a)*x3);
     // double on the Weierstrass curve:
     lambda:=(3*x1^2+2*(2-a)*x1+(1-a))/(2*y1);
     r3:=lambda^2-(2-a)-x1-x2; s3:=lambda*(x1-r3)-y1;
     // check the answer:
     S!(x3-r3); S!(y3-s3);
1986 Chudnovsky/Chudnovsky, formula (4.9i), strongly unified:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     S3:=Z1*C2*S1*D2+D1*S2*C1*Z2;
     C3:=Z1*C2*C1*Z2-D1*S2*S1*D2;
     D3:=Z1*D1*Z2*D2-a*S1*C1*S2*C2;
     Z3:=(Z1*C2)^2+(D1*S2)^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
1986 Chudnovsky/Chudnovsky, formula (4.9i), common subexpressions eliminated, 14M + 2S + 1D + 4add, strongly unified:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     Z1C2:=Z1*C2;
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     C1Z2:=C1*Z2;
     S3:=Z1C2*S1D2+D1S2*C1Z2;
     C3:=Z1C2*C1Z2-D1S2*S1D2;
     D3:=Z1*D1*Z2*D2-a*S1*C1*S2*C2;
     Z3:=Z1C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
13M + 2S + 1D + 7add, strongly unified:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     Z1C2:=Z1*C2;
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     C1Z2:=C1*Z2;
     U:=Z1C2*C1Z2;
     V:=D1S2*S1D2;
     S3:=(Z1C2+D1S2)*(C1Z2+S1D2)-U-V;
     C3:=U-V;
     D3:=Z1*D1*Z2*D2-a*S1*C1*S2*C2;
     Z3:=Z1C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
2M cached plus 11M + 2S + 1D + 7add uncached, strongly unified:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     S!(s1^2+c1^2-1); S!(a*s1^2+d1^2-1);
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     // cached:
     Z2D2:=Z2*D2;
     S2C2:=S2*C2;
     // uncached:
     Z1C2:=Z1*C2;
     S1D2:=S1*D2;
     D1S2:=D1*S2;
     C1Z2:=C1*Z2;
     U:=Z1C2*C1Z2;
     V:=D1S2*S1D2;
     S3:=(Z1C2+D1S2)*(C1Z2+S1D2)-U-V;
     C3:=U-V;
     D3:=Z1*D1*Z2D2-a*S1*C1*S2C2;
     Z3:=Z1C2^2+D1S2^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
1986 Chudnovsky/Chudnovksy, formula 4.9ii:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     S3:=2*C1*Z1*D1*S1;
     C3:=(C1*Z1)^2-(D1*Z1)^2+(C1*D1)^2;
     D3:=(D1*Z1)^2-(C1*Z1)^2+(C1*D1)^2;
     Z3:=(D1*Z1)^2+(C1*Z1)^2-(C1*D1)^2;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
1986 Chudnovsky/Chudnovksy, formula 4.9ii, eliminating common subexpressions, 5M + 3S + 5add + 1times2:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     C1Z1:=C1*Z1;
     C1D1:=C1*D1;
     D1Z1:=D1*Z1;
     D1S1:=D1*S1;
     U:=C1Z1^2;
     V:=C1D1^2;
     W:=D1Z1^2;
     UV:=U-V;
     S3:=2*C1Z1*D1S1;
     C3:=U-W+V;
     D3:=W-UV;
     Z3:=W+UV;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
2001 Liardet/Smart, page 397, 4M + 3S + 5add + 3times2:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     a0:=S1;
     a1:=C1;
     a2:=D1;
     a3:=Z1;
     l1:=a3*a1;
     l2:=a0*a2;
     l3:=2*(a1*a2)^2;
     r0:=2*l1*l2;
     r3:=(l1+l2)^2-r0;
     r1:=r3-2*l2^2;
     r2:=-r1+l3;
     S3:=r0;
     C3:=r1;
     D3:=r2;
     Z3:=r3;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);
2007 Bernstein/Lange, 3M + 4S + 5add + 1times2:
     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     R<D1,Z1>:=PolynomialRing(K,2);
     S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     a0:=S1;
     a1:=C1;
     a2:=D1;
     a3:=Z1;
     l1:=a3*a1;
     m:=l1^2;
     l2:=a0*a2;
     n:=l2^2;
     l3:=2*(a1*a2)^2;
     r3:=m+n;
     r0:=(l1+l2)^2-r3;
     r1:=m-n;
     r2:=l3-r1;
     S3:=r0;
     C3:=r1;
     D3:=r2;
     Z3:=r3;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

Jacobi-intersection doubling with Z1=1. 2007 Bernstein/Lange, 2M + 4S + 5add + 1times2:

     K<a,S1>:=FieldOfFractions(PolynomialRing(Rationals(),2));
     R<C1,D1>:=PolynomialRing(K,2);
     Z1:=1; S2:=S1; C2:=C1; D2:=D1; Z2:=Z1;
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     s2:=S2/Z2; c2:=C2/Z2; d2:=D2/Z2;
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     a0:=S1;
     a1:=C1;
     a2:=D1;
     m:=a1^2;
     l2:=a0*a2;
     n:=l2^2;
     l3:=2*(a1*a2)^2;
     r3:=m+n;
     r0:=(a1+l2)^2-r3;
     r1:=m-n;
     r2:=l3-r1;
     S3:=r0;
     C3:=r1;
     D3:=r2;
     Z3:=r3;
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

Jacobi-intersection tripling (4M + 10S + 6D + 29add + 6times2 + 1times3) matches traditional tripling. 2007 Hisil/Carter/Dawson:

     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     b:=a-1;
     R<D1,Z1>:=PolynomialRing(K,2);
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     r:=c1^2+(d1*s1)^2;
     s2:=(c1*s1*d1+d1*s1*c1)/r;
     c2:=(c1*c1-d1*s1*s1*d1)/r;
     d2:=(d1*d1-a*s1*c1*s1*c1)/r;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     E := S1^2;
     F := C1^2;
     G := E^2;
     H := F^2;
     J := 2*H;
     K := 2*J;
     L := (2*F+E)^2-G-K;
     M := b*G;
     N := K+J;
     P := M^2;
     R := N*M;
     U := M*L;
     V := H^2;
     W := H*L;
     S3 := S1*(R+b*W+2*(P-V)-W-P-V);
     C3 := C1*(2*(P-V)-U+P+V-R+b*U);
     D3 := D1*(U-P-V+R+b*W);
     Z3 := Z1*(R-b*U-W-P-V);
     // check:
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

2007 Hisil/Carter/Dawson, 7M + 7S + 3D + 16add + 4times2:

     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     b:=a-1;
     R<D1,Z1>:=PolynomialRing(K,2);
     S:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     r:=c1^2+(d1*s1)^2;
     s2:=(c1*s1*d1+d1*s1*c1)/r;
     c2:=(c1*c1-d1*s1*s1*d1)/r;
     d2:=(d1*d1-a*s1*c1*s1*c1)/r;
     S!(s2^2+c2^2-1); S!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     S!(s3^2+c3^2-1); S!(a*s3^2+d3^2-1);
     // here are the formulas:
     R0 := S1^2;
     R1 := C1^2;
     R2 := R0^2;
     R3 := R1^2;
     R4 := 2*R3;
     R5 := 2*R4;
     R6 := 2*R1;
     R6 := R6+R0;
     R6 := R6^2;
     R6 := R6-R2;
     R6 := R6-R5;
     R2 := b*R2;
     R5 := R5+R4;
     R4 := R2^2;
     R0 := R5*R2;
     R5 := R2*R6;
     R2 := R3^2;
     R1 := R3*R6;
     R3 := R4-R2;
     R2 := R4+R2;
     R4 := 2*R3;
     R3 := b*R1;
     R6 := b*R5;
     R3 := R0+R3;
     R1 := R1+R2;
     R0 := R0-R6;
     R2 := R5-R2;
     R5 := R3+R4;
     R5 := R5-R1;
     S3 := S1*R5;
     R4 := R4-R2;
     R4 := R4-R0;
     C3 := C1*R4;
     R2 := R2+R3;
     D3 := D1*R2;
     R0 := R0-R1;
     Z3 := Z1*R0;
     // check:
     S!(s3-S3/Z3); S!(c3-C3/Z3); S!(d3-D3/Z3);

2007 Hisil/Carter/Dawson, 4M + 10S + 6D + 29add + 6times2 + 1times3:

     K<a,S1,C1>:=FieldOfFractions(PolynomialRing(Rationals(),3));
     b:=a-1;
     R<D1,Z1>:=PolynomialRing(K,2);
     SS:=quo<R|S1^2+C1^2-Z1^2,a*S1^2+D1^2-Z1^2>;
     // affine:
     s1:=S1/Z1; c1:=C1/Z1; d1:=D1/Z1;
     r:=c1^2+(d1*s1)^2;
     s2:=(c1*s1*d1+d1*s1*c1)/r;
     c2:=(c1*c1-d1*s1*s1*d1)/r;
     d2:=(d1*d1-a*s1*c1*s1*c1)/r;
     SS!(s2^2+c2^2-1); SS!(a*s2^2+d2^2-1);
     r:=c2^2+(d1*s2)^2;
     s3:=(c2*s1*d2+d1*s2*c1)/r;
     c3:=(c2*c1-d1*s2*s1*d2)/r;
     d3:=(d1*d2-a*s1*c1*s2*c2)/r;
     SS!(s3^2+c3^2-1); SS!(a*s3^2+d3^2-1);
     // here are the formulas:
     E:=S1^2;
     F:=C1^2;
     G:=E^2;
     H:=F^2;
     J:=G^2;
     K:=H^2;
     L:=(E+F)^2-H-G;
     M:=L^2;
     N:=(G+L)^2-J-M;
     P:=(H+L)^2-K-M;
     R:=2*b*b*J;
     S:=2*b*N;
     Z:=3*b*M;
     U:=2*P;
     V:=2*K;
     W:=a*U;
     Y:=a*S;
     S3:=S1*((R-V)+(Z+W)-2*(U+V));
     C3:=C1*((R-V)-(Z-Y)+2*(R-S));
     D3:=D1*((Z+W)-(R-S)-(U+V));
     Z3:=Z1*((Z-Y)-(R-S)-(U+V));
     // check:
     SS!(s3-S3/Z3); SS!(c3-C3/Z3); SS!(d3-D3/Z3);