これはもう必要ないことはわかっています。別の解決策がありますが、それを実装するための別の方法を追加したいと思います。double and add アルゴリズムmod(a + b, n)
と、オーバーフロー検出で処理するメソッドの 2 つの異なる手法が提供されます。
double and add アルゴリズムは通常、乗算が不可能であるか、コストがかかりすぎて直接計算できない分野 (楕円曲線など) で使用されますが、代わりにオーバーフローを処理する状況でそれを処理するために採用することができます。
次のコードは、(最適化しても) 一般に受け入れられているソリューションよりもおそらく遅いですが、速度が重要でない場合は、わかりやすくするためにこちらを使用することをお勧めします。
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;
}