I found question: Algorithm for Hensel's Lifting
I implemented an algorithm for $p^2$.
Works correctly.
But I do not fully understand how to implement for $p^n$ for $n>2$.
Can someone help? To explain how to calculate for higher powers?
I do not understand how to continue calculating.
--- EDIT:
I add my code as an attachment:
#include <stdio.h>
#include <math.h>
unsigned long long int ipow( unsigned long long int base, unsigned long long int exp )
{
unsigned long long int result = 1ULL;
while( exp )
{
if ( exp & 1 )
{
result *= (unsigned long long int)base;
}
exp >>= 1;
base *= base;
}
return result;
}
long pow_mod(long x, long n, long p)
{
if (n == 0) return 1;
if (n & 1)
return (pow_mod(x, n-1, p) * x) % p;
x = pow_mod(x, n/2, p);
return (x * x) % p;
}
/* Takes as input an odd prime p and n < p and returns r
* such that r * r = n [mod p]. */
long int tonelli_shanks(long n, long p)
{
long s = 0;
long q = p - 1;
while ((q & 1) == 0)
{
q /= 2; ++s;
}
if (s == 1)
{
long r = pow_mod(n, (p+1)/4, p);
if ((r * r) % p == n)
return r;
return 0;
}
// Find the first quadratic non-residue z by brute-force search
long z = 1;
while (pow_mod(++z, (p-1)/2, p) != p - 1 && z < 2*ceil(log(p)*log(p))+2);
if(z == (long int) 2*ceil(log(p)*log(p))+2)
return 0;
long c = pow_mod(z, q, p);
long r = pow_mod(n, (q+1)/2, p);
long t = pow_mod(n, q, p);
long m = s;
while (t != 1)
{
long tt = t;
long i = 0;
while (tt != 1)
{
tt = (tt * tt) % p;
++i;
if (i == m)
return 0;
}
long b = pow_mod(c, pow_mod(2, m-i-1, p-1), p);
long b2 = (b * b) % p;
r = (r * b) % p;
t = (t * b2) % p;
c = b2;
m = i;
}
if ((r * r) % p == n)
return r;
return 0;
}
int main()
{
long long int xs[100], fx, fpx, t;
long long int C = 3483;
long long int p = 3;
long long int degree = 6;
xs[1] = tonelli_shanks(C%p, p);
long long int residues;
long int xi;
for(xi=1; xi <= degree; xi++)
{
fx = xs[xi]*xs[xi] - C%(ipow(p, xi));
fpx = 2*xs[xi];
long long int factors_pow_m1 = ipow(p, xi);
t = 1;
while ( ((fx/p) + t*fpx) % factors_pow_m1 != 0 && t < 100000 )
t++;
xs[xi+1] = xs[xi] + t*p;
residues = xs[xi+1] % ipow(p, xi);
} // loop xi
printf("residue=%lld\n", residues);
return 0;
}
In code we looking: $x^2 \equiv 567 \pmod{3^6}$; ($3483 \equiv 567 \pmod{3^6}$). Program return $294$, but this is a bad result because $294^2 \equiv 414 \pmod{3^6}$.
Function tonelli_shanks() is good. The logic error must be in the main() function.
Maybe someone has an idea what is wrong? How should I count this?