合同算術の基礎と応用:暗号・アルゴリズム・実装ガイド

導入:合同算術とは何か

合同算術(ごうどうさんじゅつ、modular arithmetic)は、整数のあまり(剰余)を用いた算術体系で、IT・暗号・アルゴリズム分野で必須の概念です。a ≡ b (mod n) の形で表され、「a と b は n で割った余りが等しい」ことを意味します。合同算術は有限の数の元からなる環として振る舞い、効率的な計算方法や理論的性質が多くの実用的応用を生み出しています。

基本的な定義と表記

整数 a, b と正の整数 n に対して、a ≡ b (mod n) は n が a−b を割る、つまり n | (a−b) を意味します。集合的には、整数全体は n に関して同値類に分割され、これを Z/nZ(または Z_n)と表します。Z/nZ の元は 0,1,2,...,n−1 の代表元で扱うのが一般的です。

合同の基本性質

  • 反射性:a ≡ a (mod n)
  • 対称性:a ≡ b (mod n) ⇔ b ≡ a (mod n)
  • 推移性:a ≡ b (mod n) かつ b ≡ c (mod n) なら a ≡ c (mod n)
  • 四則演算の閉性:a ≡ b (mod n) と c ≡ d (mod n) が成り立つとき、a±c ≡ b±d (mod n) および a·c ≡ b·d (mod n)

逆元と単元(単数)

Z/nZ における乗法逆元 a^{-1}(つまり a·x ≡ 1 (mod n) を満たす x)は、a と n が互いに素(gcd(a,n)=1)のときに限り存在します。この性質は拡張ユークリッド互除法で具体的に x を求められる点で重要です。逆元の存在は暗号プロトコル(RSA 等)や逆行列計算などで決定的な役割を果たします。

拡張ユークリッド互除法(逆元の計算)

拡張ユークリッド互除法は、gcd(a,n) とそれに対する係数 s,t を求めるアルゴリズムで、s·a + t·n = gcd(a,n) を満たします。gcd(a,n)=1 の場合は s·a ≡ 1 (mod n) となり、s が a の逆元です。計算量は a, n のビット長を m とすると、O(m^2) 程度から高速化によりさらに改善されます(大整数を扱う場合)。

高速べき乗法(モジュラーべき乗)

合同算術で頻繁に現れる操作は a^e mod n の計算です。二進法に基づく累乗(二乗・乗算法、binary exponentiation)は指数 e のビット数に比例する回数の乗算で済むため効率的です。暗号ではこれをさらに高速化するためにモンゴメリ乗算やバレット減算を用います。また、実装上は常に大整数ライブラリを用い、定数時間操作(タイミング攻撃対策)を考慮する必要があります。

重要な定理:フェルマーの小定理とオイラーの定理

素数 p に対して、p ∤ a のとき a^{p-1} ≡ 1 (mod p) が成り立ちます(フェルマーの小定理)。一般化したオイラーの定理は、φ(n) をオイラーのトーシェント関数とすると、gcd(a,n)=1 のとき a^{φ(n)} ≡ 1 (mod n) が成り立ちます。これらは、公開鍵暗号(RSA 等)や素数判定、剰余演算に基づく最適化に直接利用されます。

中国剰余定理(CRT)

互いに素なモジュラス n1,...,nk に対して、同時合同式 x ≡ a_i (mod n_i) (i=1..k) は、積 N=∏ n_i に対して唯一解を持ちます(同値類としては一意)。CRT を用いると大きなモジュラスでの計算を小さなモジュラスに分割して並列化でき、RSA の高速化(CRT を使った復号)や分散計算、ハッシュ関数設計で効率化が図れます。

素数判定と暗号への応用

合同算術は素数判定アルゴリズム(フェルマー試験、ミラー=ラビン確率試験、AKS)や公開鍵暗号(RSA、DSA、ElGamal、ECC の一部理論)と深く結びついています。RSA の基本モデルは、N=pq(p,q は大きな素数)とし、公開鍵 (N,e)、秘密鍵 d は ed ≡ 1 (mod φ(N)) を満たす数です。復号は合同算術に基づくべき乗により行われ、安全性は主に大きな整数の素因数分解の困難性に依存します。

実装上の注意点と最適化

  • 負の剰余:言語によって剰余演算の符号ルールが異なるため、非負の代表に正規化する((a % n + n) % n)。
  • オーバーフロー対策:固定幅整数ではなく大整数(bignum)ライブラリを使用する。C/C++ では GMP、OpenSSL の BIGNUM、Java の BigInteger など。
  • 高速化手法:モンゴメリ乗算、バレット減算、CRT による分割、平方乗・多乗法の最適化。
  • セキュリティ:暗号用途では定数時間実装(タイミング攻撃対策)、適切なランダム生成、パディング(OAEP 等)を必ず行う。

アルゴリズム的複雑性

基本的なモジュラー演算のコストは大整数の掛け算と除算に帰着します。整数のビット長を m とすると、古典的な掛け算は O(m^2) ですが、Karatsuba や FFT を用いる高速アルゴリズムにより O(m^{1.58}) や O(m log m) 台まで改善できます。モジュラーべき乗は O(log e) 回のモジュラー乗算が必要で、基底のビット長や乗算アルゴリズムに依存します。

応用例(実務的な視点)

  • 暗号通信:RSA、デジタル署名、鍵交換における主要演算。
  • ハッシュ・チェックサム:CRC 等は多項式除算だが、合同算術的な考え方が検査値設計に用いられる。
  • 擬似乱数生成:線形合同法(LCG)は合同算術に基づく広く知られた乱数生成器。
  • アルゴリズム設計:ハッシュテーブル、合同条件による分割や分散アルゴリズム。

実務での設計指針

合同算術を用いるシステムでは、まず正確な数学的前提(互いに素であることなど)を確認すること、暗号用途なら既存の信頼できるライブラリを使うこと、そして実装の安全性(定数時間、乱数源、鍵長の選定)を最優先にすることが重要です。例えば RSA では鍵長 2048 ビット以上が推奨され、パディングスキームの採用は必須です。

まとめ

合同算術は単純な「余り」の概念から出発しますが、その理論とアルゴリズムは現代の情報技術、特に暗号とアルゴリズム設計で中心的役割を果たします。数学的性質(逆元、CRT、オイラーの定理)を正しく理解し、拡張ユークリッド法や高速べき乗法、モンゴメリ乗算などの実装技術を組み合わせることで、安全かつ高性能なシステムが構築できます。

参考文献