is a quadratic residue modulo if has a solution. For an odd prime , exactly of the non-zero residues are quadratic residues.
Euler’s criterion
int legendre(long long a, long long p) {
a %= p; if (a < 0) a += p;
if (a == 0) return 0;
return powmod(a, (p - 1) / 2, p) == 1 ? 1 : -1;
}— this is the Legendre symbol .
The Legendre symbol’s rules
| Rule | |
|---|---|
| Multiplicative | |
| iff | |
| iff | |
| depends only on |
QR × QR = QR, QR × NR = NR, NR × NR = QR — the residues form an index-2 subgroup.
Quadratic reciprocity
For distinct odd primes :
In words: unless both , in which case they differ in sign.
Combined with the supplementary rules, this gives a Euclidean-style algorithm for the Jacobi symbol that needs no exponentiation:
int jacobi(long long a, long long n) { // n odd positive
a %= n; if (a < 0) a += n;
int result = 1;
while (a) {
while (a % 2 == 0) {
a /= 2;
if (n % 8 == 3 || n % 8 == 5) result = -result;
}
swap(a, n);
if (a % 4 == 3 && n % 4 == 3) result = -result;
a %= n;
}
return n == 1 ? result : 0;
}Jacobi vs Legendre
The Jacobi symbol extends the Legendre symbol to odd composite by multiplying the Legendre symbols of ‘s prime factors.
Jacobi does not mean is a QR
For composite , can happen when is a non-residue modulo two prime factors. Only is conclusive (it proves is a non-residue). This asymmetry is the basis of the Solovay-Strassen primality test.
Finding the square root
| Case | Method | Cost |
|---|---|---|
| a short closed form | ||
| general | Tonelli-Shanks | |
| general , has a big | Cipolla | |
| solve mod , Hensel lift | ||
| special bit-by-bit lifting | ||
| composite | factor, solve per prime power, CRT | as hard as factoring |
That last row is the crux of Rabin cryptography: computing square roots modulo a composite is equivalent to factoring it.
Counting solutions
has solutions: two if is a QR, one if , zero otherwise.
Modulo (odd primes), the count is — so solutions when is a residue modulo all distinct primes. Powers of 2 contribute up to 4.
Where it appears
| Problem | Use |
|---|---|
| Solve | Tonelli-Shanks |
| Count solutions of a quadratic congruence | Legendre symbol |
| Sum of two squares () | needs , then Cornacchia |
| Elliptic curve point decompression | recover from |
| Solovay-Strassen primality test | Jacobi vs Euler criterion |
| Counting points on a conic mod | character sums |
| Is a perfect square? | quick filter: check and before taking a root |
The perfect-square filter
bool maybeSquare(long long n) {
static bool ok[64] = {}; // precompute squares mod 64
return ok[n & 63];
}Only 12 of the 64 residues mod 64 are squares, so this rejects 81% of non-squares in one instruction — a useful speedup inside tight loops.
See also: Tonelli-Shanks · Cipolla · Discrete Root