Calculating the integral points of an elliptic curve

You can find the integer points with Solve:

With[{s = 10^5},
  Solve[n == 9 + 108 x^2 (1 + x) && -s <= n <= s && -s <= x <= s,
        {n, x}, Integers]]

(*    {{n -> -97191, x -> -10}, {n -> -69975, x -> -9}, {n -> -48375, x -> -8},
       {n -> -31743, x -> -7}, {n -> -19431, x -> -6}, {n -> -10791, x -> -5},
       {n -> -5175, x -> -4}, {n -> -1935, x -> -3}, {n -> -423, x -> -2},
       {n -> 9, x -> -1}, {n -> 9, x -> 0}, {n -> 225, x -> 1},
       {n -> 1305, x -> 2}, {n -> 3897, x -> 3}, {n -> 8649, x -> 4},
       {n -> 16209, x -> 5}, {n -> 27225, x -> 6}, {n -> 42345, x -> 7},
       {n -> 62217, x -> 8}, {n -> 87489, x -> 9}}    *)

Thanks to @MichaelE2: if you want only square values for $n=y^2$,

Solve[y^2 == 9 + 108 x^2 (1 + x) && 0 <= y <= 10^6, {y, x}, Integers]

(*    {{y -> 3, x -> -1}, {y -> 3, x -> 0}, {y -> 15, x -> 1},
       {y -> 93, x -> 4}, {y -> 165, x -> 6}}    *)

This takes 0.7 seconds. The same calculation up to $y\le10^9$ gives the same solutions but takes 29 seconds.

For much larger search spaces you can adapt the 128-bit-integer C code from this solution.


You see a number of integral points by inspection: e.g. {1,15},{1,-15},{0,3},{0,-3},{-1,3},{-1,-3}.

You can pick a "generator point" and scalar multiply and filter rational solutions to get other integers. For example:

Defining addition operation:

f[x_] := 9 + 108 x^2 (x + 1)
fun[{xa_, ya_}, {"O", "O"}] := {xa, ya}
fun[{"O", "O"}, {xa_, ya_}] := {xa, ya}
fun[{xp_, yp_}, {xq_, yq_}] :=
 Module[{s, res},
  If[{xp, yp} == {xq, yq}, s = (324 xp^2 + 216 xp)/(2 yp),
   If[xp - xq == 0, Return[{"O", "O"}],
    s = (yp - yq)/(xp - xq)]];
  res = Simplify[{x, (s (x - xp) + yp)}] /. 
    Solve[ (s (x - xp) + yp)^2 == f[x], x, Reals];
  Complement[res, {{xp, yp}, {xq, yq}}][[1]] {1, -1}
  ]

Iterating:

pts = NestList[fun[#, {1, 15}] &, {1, 15}, 30];
ip = Cases[pts, {_?IntegerQ, _?IntegerQ}];
ContourPlot[y^2 == f[x], {x, -2, 7}, {y, -200, 200}, 
 Epilog -> {{Red, PointSize[0.02], 
    Point[ip~Join~(# {1, -1} & /@ ip)]}, 
   Arrow /@ Partition[pts, 2, 1]}]
Column[ip~Join~(# {1, -1} & /@ ip)]

enter image description here

This is not systematic or comprehensive. Perhaps you can play around.


Here is a brute force approach using NumberTheory`PowersRepresentationsDump`ProbablePerfectSquareQ, which I got from this comment by JM on a question asking for the Fastest square number test.

Quiet@PowersRepresentations[];(* Just to load the necessary context *)

nums =
  Table[{x, NumberTheory`PowersRepresentationsDump`ProbablePerfectSquareQ[9 + 108 x^2 (1 + x)]}, 
        {x, 1, 1000000}];
(candidates = Cases[nums, {n_, True} :> n]) // Length

(* Out: 98132 *)

So this approach found close to 100,000 tentative values of $x$ for which that expression may be a perfect square. That should be followed up with an exact check:

Select[candidates, IntegerQ@Sqrt@(9 + 108 #^2 (1 + #)) &]

(* Out: {1, 4, 6} *)