Euler's factorization needs two different sums of squares, what if only one sum of squares is known?

154 Views Asked by At

Euler's factorization determines prime factors if two different sums of squares of number $n$ are given.
I just did that in Python not knowing Euler's method:

>>> (a,b),(c,d) = [(x,y) for x,y in diop_DN(-1, n) if x%2==0]
>>> (a**2 + b**2, c**2 + d**2) == (n, n)
True
>>> gcd(n, (a+c)**2 + (b-d)**2)
997
>>> gcd(n, (a+c)**2 + (b+d)**2)
509
>>> 

Euler's method relies on knowing two different sums of squares.
My question is, whether knowing only one ($n = a^2 + b^2$) with integers $n, a, b$ allows to efficiently factor $n$ as well, somehow?

P.S:
From the link user25406 provided, interpreting the square numbers of a sum as Gaussian integers, "Gaussian integer gcd" directly determines the sum of squares for each prime factor of $n$ (Python lib with ggcd() here):

>>> (a,b),(c,d) = [(x,y) for x,y in diop_DN(-1, n) if x%2==0]
>>> from RSA_numbers_factored import ggcd
>>> ggcd((a,b),(c,d))
(-22, -5)
>>> ggcd((a,b),(c,-d))
(6, -31)
>>> n % (22**2 + 5**2)
0
>>> n % (6**2 + 31**2)
0
>>> 

Or with sympy gcd():

>>> (a,b),(c,d) = [(x,y) for x,y in diop_DN(-1, n) if x%2==0]
>>> from sympy import gcd, I
>>> gcd(a + b * I, c + d * I)
22 + 5*I
>>> gcd(a + b * I, c - d * I)
31 + 6*I

P.P.S:
Analysis of algrorithm user25406 provided as answer.

Find $a,b$ for odd semiprime $n = a^2 + b^2$, by looking at fixed value $s = a + b$ and testing for integer solutions $a, b$ of $n = s^2 - 2ab$. Since $n$ is odd, $s$ has to be odd as well.

Good news, no search for a given $s$ needed, values for $a, b$ are solution of this quadratic equation system with constants $s, n$:
$$s = a + b$$ $$s^2 - 2ab = n$$ Solution:
$$a_{1,2} = \frac{s \pm \sqrt{2n - s^2}}{2}$$ Good if $a_{1,2}$ are integer values:
$s=9$ for $n=65$: $a_{1,2} = 8, 1$
$s=11$ for $n=65$: $a_{1,2} = 7, 4$

Bad if $a_{1,2}$ are non-integer values:
$s=27$ for $n=13*41$: $a_{1,2} = \frac{27 \pm \sqrt(337)}{2}$

So constant runtime for a single value $s$.

This is the range of odd values of $s$ that need to be looked at:
$n = 1^2 + \lfloor{\sqrt{n}}\rfloor^2$, example: $65 = 1^2 + 8^2$
...
$n = \lfloor{\sqrt{\frac{n}{2}}}\rfloor^2 + \lceil{\sqrt{\frac{n}{2}}}\rceil^2$, example: $85 = 6^2 + 7^2$
So $O(\frac{\sqrt{\frac{n}{2}}}{2}) = O(\sqrt{n})$ values need to be tested.

That is not an efficient algorithm (like eg. gcd()), they have polynomial runtime in (binary) input length $\log{n}$ .