Algorithm in number theory
数論 において 、 ディクソン因数分解法 ( ディクソンのランダムスクエア法 [1] または ディクソンアルゴリズム とも呼ばれる)は、汎用的な 整数因数分解 アルゴリズム であり、典型的な 因数基底 法である。他の因数基底法とは異なり、その実行時限界は、多項式が取る値の滑らかさに関する推測に依存しない厳密な証明を伴う。
このアルゴリズムはカールトン大学 の数学者ジョン・D・ディクソンによって設計され 、1981年に発表されました。 [2]
基本的な考え方
ディクソン法は、 因数分解しようとする整数Nを法とする平方数 の合同性を求めることを基本としています。 フェルマー因数分解法は、ランダムまたは 擬似ランダムな x 値を 選択し、整数 x 2 mod Nが (整数において)
完全な平方数となることを期待することで、このような合同性を求めます。
x
2
≡
y
2
(
mod
N
)
,
x
≢
±
y
(
mod
N
)
.
{\displaystyle x^{2}\equiv y^{2}\quad ({\hbox{mod }}N),\qquad x\not \equiv \pm y\quad ({\hbox{mod }}N).}
例えば、 N = 84923の場合( √ N より大きい最初の数である 292 から始めて 数えていくと) 、 505 2 mod 84923 は 256 となり、これは 16 の平方です。つまり、 (505 − 16)(505 + 16) = 0 mod 84923 と なります。 ユークリッドの法則 を用いて 505 − 16 と N の 最大公約数を計算すると 163 となり、これは N の因数です 。
実際には、ランダムな x値を選択すると、 N より小さい正方形は √ N 個しかないため、正方形の合同を見つけるのに非現実的な長い時間がかかります 。
ディクソン法では、「整数の平方である」という条件を、「小さな素因数のみを持つ」というはるかに弱い条件に置き換えます。たとえば、84923 より小さい平方数は 292 個あります。84923 より小さい数で素因数が 2、3、5、または 7 のみである数は 662 個あります。また、素因数がすべて 30 未満の数は 4767 個あります。(このような数は、ある境界 B に関して B 滑らか と呼ばれます。)
固定された小さな素数集合に対して、 平方を因数分解できる 数が多数ある場合 、行列の 2 を法とする線型代数は、 平方が偶数乗の小さな素数の積に結合される の サブセット、つまり、 平方が N を法とする (できれば異なる) 数の平方に掛けられる
のサブセットを与えます。
a
1
…
a
n
{\displaystyle a_{1}\ldots a_{n}}
a
i
2
mod
N
=
∏
j
=
1
m
b
j
e
i
j
{\displaystyle a_{i}^{2}\mod N=\prod _{j=1}^{m}b_{j}^{e_{ij}}}
b
1
…
b
m
{\displaystyle b_{1}\ldots b_{m}}
e
i
j
{\displaystyle e_{ij}}
a
i
{\displaystyle a_{i}}
a
i
{\displaystyle a_{i}}
方法
合成数 N を因数分解するとする。境界値 B を選び、 因数分解の基数 (これをP と呼ぶ)を特定する。これは B 以下のすべての素数の集合である。次に、 z 2 mod N が B -滑らかとなるような正の整数 z を求める。したがって、適切な指数 a i に対して、
次のように書ける。
z
2
mod
N
=
∏
p
i
∈
P
p
i
a
i
{\displaystyle z^{2}{\text{ mod }}N=\prod _{p_{i}\in P}p_{i}^{a_{i}}}
これらの関係が十分に生成されたら(関係の数は一般にP のサイズより少し多くなれば十分です)、 ガウス消去法 などの 線形代数 の方法を 使用して、右側の素数の指数がすべて偶数になるようにこれらのさまざまな関係を乗算できます。
z
1
2
z
2
2
⋯
z
k
2
≡
∏
p
i
∈
P
p
i
a
i
,
1
+
a
i
,
2
+
⋯
+
a
i
,
k
(
mod
N
)
(
where
a
i
,
1
+
a
i
,
2
+
⋯
+
a
i
,
k
≡
0
(
mod
2
)
)
{\displaystyle {z_{1}^{2}z_{2}^{2}\cdots z_{k}^{2}\equiv \prod _{p_{i}\in P}p_{i}^{a_{i,1}+a_{i,2}+\cdots +a_{i,k}}\ {\pmod {N}}\quad ({\text{where }}a_{i,1}+a_{i,2}+\cdots +a_{i,k}\equiv 0{\pmod {2}})}}
これにより、 a 2 ≡ b 2 (mod N )という形式の 平方合同が得られ 、これは N の因数分解 、 N = gcd ( a + b , N ) × ( N /gcd( a + b , N ) に変換できます。この因数分解は、 a ≡ ± b (mod N )の場合にのみ発生する、つまり N = N × 1となる可能性があります。その場合は 、 関係の異なる組み合わせで再度試行する必要があります。ただし、 N の因数のペアが自明でない場合、アルゴリズムは終了します。
擬似コード
このセクションは Dixon (1981) から直接引用したものです。
ディクソンのアルゴリズム
初期化。L を 範囲[1, n ] の整数のリストとし 、 P = { p 1 , ..., p h }を h 個の素数≤ v のリストとする 。B と Zは 初期状態では空のリストとする( Zは B によってインデックス付けされる )。
ステップ1. L が空の場合、終了(アルゴリズム失敗)。そうでない場合、 L の 最初の項 z を取り、それを L から削除し、ステップ2に進む。
ステップ2. z 2 mod n の最小の正の剰余として w を計算します 。w を 次のように因数分解します。
w
=
w
′
∏
i
p
i
a
i
{\displaystyle w=w'\prod _{i}p_{i}^{a_{i}}}
ここで、 w ′ はPに因子を持たない。w ′ = 1 の 場合 は ステップ 3へ進み、それ以外の場合はステップ1に戻る。
ステップ3. a ← ( a 1 , ..., a h ) とする。a を B に 、 zを Z に追加する 。B の 要素数が最大で h であればステップ1に戻る。そうでない場合はステップ4に進む。
ステップ4. B 内の 最初のベクトル c の うち 、 B 内の以前のベクトルに線形従属(mod 2)するベクトル c を見つけます 。B と Z から c を 削除します。 次の係数を計算します。
z
c
{\displaystyle z_{c}}
f
b
{\displaystyle f_{b}}
c
≡
∑
b
∈
B
f
b
b
(
mod
2
)
{\displaystyle \mathbf {c} \equiv \sum _{b\in B}f_{b}\mathbf {b} {\pmod {2}}}
定義する:
d
=
(
d
1
,
…
,
d
n
)
←
1
2
(
c
+
∑
f
b
b
)
{\displaystyle \mathbf {d} =(d_{1},\dots ,d_{n})\gets {\frac {1}{2}}\left(\mathbf {c} +\sum f_{b}\mathbf {b} \right)}
ステップ5に進みます。
ステップ5. 計算:
x
←
z
c
∏
b
z
b
f
b
,
y
←
∏
i
p
i
d
i
{\displaystyle x\gets z_{c}\prod _{b}z_{b}^{f_{b}},\quad y\gets \prod _{i}p_{i}^{d_{i}}}
となることによって:
x
2
≡
∏
i
p
i
2
d
i
=
y
2
mod
n
.
{\displaystyle x^{2}\equiv \prod _{i}p_{i}^{2d_{i}}=y^{2}\mod n.}
または の場合は 、ステップ 1 に戻ります。それ以外の場合は、以下を返します。
x
≡
y
{\displaystyle x\equiv y}
x
≡
−
y
(
mod
n
)
{\displaystyle x\equiv -y{\pmod {n}}}
gcd
(
n
,
x
+
y
)
{\displaystyle \gcd(n,x+y)}
これはn の非自明な因数を提供し 、正常に終了します。
ステップバイステップの例:因数分解( n = 84923)ディクソンのアルゴリズムを使用して
この例はLeetArxivサブスタックから直接引用したものです。 [3] オリジナルの著者にクレジットが与えられています。
初期化 :
1から84923までの範囲の 数値のリスト Lを定義します。
L
=
{
1
,
…
,
84923
}
{\displaystyle L=\{1,\dots ,84923\}}
v
=
7
{\displaystyle v=7}
P
=
2
,
3
,
5
,
7
{\displaystyle P={2,3,5,7}}
2つの空リストB と Z を定義します 。B は べき乗のリスト、 Z は整数のリストです。
B
=
[
]
{\displaystyle B=[]}
Z
=
[
]
{\displaystyle Z=[]}
ステップ1 : 値の
反復
z
{\displaystyle z}
リスト をインデックスする for ループを記述します 。 の各要素は としてインデックス付けされます 。 for ループはリストの最後で終了します。
L
{\displaystyle L}
L
{\displaystyle L}
z
{\displaystyle z}
int n = 84923 ; for ( int i = 1 ; i <= n ; i ++ ) { int z = i ; }
ステップ2 : V滑らかな素因数分解の
計算
z
2
mod
n
{\displaystyle z^{2}\mod n}
続行するには、 各 z について計算し、結果を素因数分解として表現します。
z
2
mod
84923
{\displaystyle z^{2}\mod 84923}
1
2
mod
84923
≡
1
mod
84923
=
2
0
⋅
3
0
⋅
5
0
⋅
7
0
mod
84923
{\displaystyle 1^{2}\mod 84923\equiv 1\mod 84923=2^{0}\cdot 3^{0}\cdot 5^{0}\cdot 7^{0}\mod 84923}
⋮
{\displaystyle \vdots }
513
2
mod
84923
=
8400
mod
84923
=
2
4
⋅
3
1
⋅
5
2
⋅
7
1
mod
84923
{\displaystyle 513^{2}\mod 84923=8400\mod 84923=2^{4}\cdot 3^{1}\cdot 5^{2}\cdot 7^{1}\mod 84923}
⋮
{\displaystyle \vdots }
537
2
mod
84923
=
33600
mod
84923
=
2
6
⋅
3
1
⋅
5
2
⋅
7
1
mod
84923
{\displaystyle 537^{2}\mod 84923=33600\mod 84923=2^{6}\cdot 3^{1}\cdot 5^{2}\cdot 7^{1}\mod 84923}
538
2
mod
84923
=
34675
mod
84923
=
5
2
⋅
19
1
⋅
73
1
mod
84923
{\displaystyle 538^{2}\mod 84923=34675\mod 84923=5^{2}\cdot 19^{1}\cdot 73^{1}\mod 84923}
このステップは、範囲内のすべての z 値に対して続行されます。
ステップ 3 : が 7 滑らか な場合は、その累乗をリストに追加し 、 リストに追加します 。
z
2
mod
84923
{\displaystyle z^{2}\mod 84923}
B
{\displaystyle B}
z
{\displaystyle z}
Z
{\displaystyle Z}
Z
=
{
1
,
513
,
537
}
{\displaystyle Z=\{1,513,537\}}
B
=
{
[
0
,
0
,
0
,
0
]
,
[
4
,
1
,
2
,
1
]
,
[
6
,
1
,
2
,
1
]
}
{\displaystyle B=\{[0,0,0,0],[4,1,2,1],[6,1,2,1]\}}
ステップ 4 : このステップは 2 つの部分に分かれています。
パート 1 : 2 を法とする数を求めます。
B
{\displaystyle B}
B
=
(
0
0
0
0
4
1
2
1
6
1
2
1
)
mod
2
≡
B
=
(
0
0
0
0
0
1
0
1
0
1
0
1
)
{\displaystyle B={\begin{pmatrix}0&0&0&0\\4&1&2&1\\6&1&2&1\end{pmatrix}}\mod 2\equiv B={\begin{pmatrix}0&0&0&0\\0&1&0&1\\0&1&0&1\end{pmatrix}}}
パート2 : 合計が偶数になる 行の組み合わせがあるかどうかを確認する
B
{\displaystyle B}
たとえば、Row と Rowを合計すると 、偶数のベクトルが得られます。
2
{\displaystyle 2}
3
{\displaystyle 3}
R
2
=
{
0
,
1
,
0
,
1
}
{\displaystyle R_{2}=\{0,1,0,1\}}
そして
R
3
=
{
0
,
1
,
0
,
1
}
{\displaystyle R_{3}=\{0,1,0,1\}}
それから
R
2
+
R
3
=
{
0
,
1
,
0
,
1
}
+
{
0
,
1
,
0
,
1
}
{\displaystyle R_{2}+R_{3}=\{0,1,0,1\}+\{0,1,0,1\}}
R
2
+
R
3
=
{
0
,
2
,
0
,
2
}
{\displaystyle R_{2}+R_{3}=\{0,2,0,2\}}
。
ステップ 5 : このステップは 4 つの部分に分かれています。
パート1(xの求め方) : ステップ4 で求めた行の対応する値を掛け合わせます 。そして平方根を求めます。これでxが得られます 。
z
{\displaystyle z}
x
{\displaystyle x}
2 行目では、 がありました 。
2
4
∗
3
1
∗
5
2
∗
7
1
{\displaystyle 2^{4}*3^{1}*5^{2}*7^{1}}
3 行目では、 がありました 。
2
6
∗
3
1
∗
5
2
∗
7
1
{\displaystyle 2^{6}*3^{1}*5^{2}*7^{1}}
したがって、次のことがわかります 。
x
{\displaystyle x}
(
513
⋅
537
)
2
mod
84923
=
y
2
where
x
2
mod
84923
=
(
513
⋅
537
)
2
mod
84923
thus
x
=
(
513
⋅
537
)
mod
84923
so
x
=
275481
mod
84923
Finally
x
=
20712
mod
84923
{\displaystyle {\begin{array}{ll}(513\cdot 537)^{2}\mod 84923=y^{2}\\\\{\text{where}}\quad x^{2}\mod 84923=(513\cdot 537)^{2}\mod 84923\\\\{\text{thus}}\quad x=(513\cdot 537)\mod 84923\\\\{\text{so}}\quad x=275481\mod 84923\\\\{\text{Finally}}\quad x=20712\mod 84923\\\end{array}}}
パート2(yの求め方) : ステップ4 で求めた行に対応する滑らかな因数分解を掛け合わせます 。そして平方根を求めます。これで となります 。
y
{\displaystyle y}
y
2
=
(
2
4
⋅
3
1
⋅
5
2
⋅
7
1
)
×
(
2
6
⋅
3
1
⋅
5
2
⋅
7
1
)
By the multiplication law of exponents,
y
2
=
2
(
4
+
6
)
⋅
3
(
1
+
1
)
⋅
5
(
2
+
2
)
⋅
7
(
1
+
1
)
Thus,
y
2
=
2
10
⋅
3
2
⋅
5
4
⋅
7
2
Taking square roots on both sides gives
y
=
2
5
⋅
3
1
⋅
5
2
⋅
7
1
Therefore,
y
=
32
×
3
×
25
×
7
Finally,
y
=
16800
{\displaystyle {\begin{array}{ll}y^{2}=(2^{4}\cdot 3^{1}\cdot 5^{2}\cdot 7^{1})\times (2^{6}\cdot 3^{1}\cdot 5^{2}\cdot 7^{1})\\\\{\text{By the multiplication law of exponents,}}\\y^{2}=2^{(4+6)}\cdot 3^{(1+1)}\cdot 5^{(2+2)}\cdot 7^{(1+1)}\\\\{\text{Thus,}}\\y^{2}=2^{10}\cdot 3^{2}\cdot 5^{4}\cdot 7^{2}\\\\{\text{Taking square roots on both sides gives}}\\y=2^{5}\cdot 3^{1}\cdot 5^{2}\cdot 7^{1}\\\\{\text{Therefore,}}\\y=32\times 3\times 25\times 7\\\\{\text{Finally,}}\\y=16800\end{array}}}
パート3. (x + yとx - yを求めます) ここで、 x = 20712 、 y = 16800です 。
x
+
y
=
20712
+
16800
=
37512
{\displaystyle x+y=20712+16800=37512}
x
−
y
=
20712
−
16800
=
3912
{\displaystyle x-y=20712-16800=3912}
パート4. GCD(x+y, n)とGCD(xy, n)を計算します。 ここで、 n = 84923 、 x+y = 292281 、 xy = 258681です。
gcd
(
37512
,
84923
)
=
521
gcd
(
3912
,
84923
)
=
163
{\displaystyle {\begin{array}{ll}\gcd(37512,84923)=521\\\gcd(3912,84923)=163\end{array}}}
クイックチェックでは が表示されます 。
84923
=
521
×
163
{\displaystyle 84923=521\times 163}
最適化
二 次ふるい法 はディクソン法の最適化です。N の平方根に近い xの値を選択し、 Nを 法 とする x 2 が小さくなるようにすること で、滑らかな数を得る可能性を大幅に高めます。
ディクソン法を最適化する他の方法としては、行列方程式を解くためのより優れたアルゴリズムを用いることが挙げられます。これは、行列の疎性を利用するものです。数 z は 個以上の 因数を持てないため、行列の各行はほぼすべてゼロになります。実際には、 ブロックランチョス法が よく用いられます。また、因数基数の大きさは慎重に選択する必要があります。小さすぎると、その上で完全に因数分解できる数を見つけるのが難しくなり、大きすぎると、より多くの関係式を収集する必要が生じます。
log
2
z
{\displaystyle \log _{2}z}
より洗練された分析では、ある数の素因数がすべて より小さい 確率で程度になるという近似 ( ディックマン・ド・ブリュイン関数 の近似 ) を使用すると、因数基数が小さすぎると大きすぎる場合よりもはるかに悪い結果になり、理想的な因数基数のサイズは のべき乗であることが示されます 。
N
1
/
a
{\displaystyle N^{1/a}}
a
−
a
{\displaystyle a^{-a}}
exp
(
log
N
log
log
N
)
{\displaystyle \exp \left({\sqrt {\log N\log \log N}}\right)}
ディクソン法の最適な複雑さは
O
(
exp
(
2
2
log
n
log
log
n
)
)
{\displaystyle O\left(\exp \left(2{\sqrt {2}}{\sqrt {\log n\log \log n}}\right)\right)}
ビッグO記法 では 、または
L
n
[
1
/
2
,
2
2
]
{\displaystyle L_{n}[1/2,2{\sqrt {2}}]}
L表記法 で 。
参考文献
^ Kleinjung, Thorsten; et al. (2010). 「768ビットRSA係数の因数分解」. Advances in Cryptology – CRYPTO 2010 . Lecture Notes in Computer Science. Vol. 6223. pp. 333– 350. doi :10.1007/978-3-642-14623-7_18. ISBN 978-3-642-14622-0 . S2CID 11556080。
^ Dixon, JD (1981). 「整数の漸近的高速因数分解」 (PDF) . Math. Comp. 36 (153): 255– 260. doi : 10.1090/S0025-5718-1981-0595059-1 . JSTOR 2007743.
^ Kibicho, Murage (2025). 手書きの論文実装: 漸近的に高速な整数の因数分解.