I know you no longer need this, and there is an alternative solution, but I want to add an alternative method to implement it. It provides two different techniques: the double and add algorithm, and the method to handle mod(a + b, n)
with overflow detection.
Double and add algorithm is usually used in fields where multiplication is not possible or too costly to calculate directly (such as elliptic curves), but we could adopt it to handle it in our situation to handle overflows instead.
The following code is probably slower than the accepted solution (even when you optimize it), but if speed is not critical, you may prefer it for clarity.
unsigned addmod(unsigned x, unsigned y, unsigned n)
{
// Precondition: x<n, y<n
// If it will overflow, use alternative calculation
if (x + y <= x) x = x - (n - y);
else x = (x + y) % n;
return x;
}
unsigned sqrmod(unsigned a, unsigned n)
{
unsigned b;
unsigned sum = 0;
// Make sure original number is less than n
a = a % n;
// Use double and add algorithm to calculate a*a mod n
for (b = a; b != 0; b >>= 1) {
if (b & 1) {
sum = addmod(sum, a, n);
}
a = addmod(a, a, n);
}
return sum;
}