数論において、一般数体篩法(GNFS )は、 10¹⁰⁰より大きい整数を素因数分解するための最も効率的な古典的アルゴリズムとして知られています。経験的に、整数nを素因数分解する際のその複雑さ( ⌊log 2 n ⌋ + 1ビットから構成される)は次の形式になります。
ビッグオー記法とL記法で表す。[ 1 ]これは特殊数体篩の一般化である。特殊数体篩は特定の特殊形式の数しか因数分解できないのに対し、一般数体篩は素数のべき乗(根を取ることで簡単に因数分解できる)以外の任意の数を因数分解できる。
数体篩法(特殊篩法と一般篩法の両方)の原理は、より単純な有理篩法や二次篩法の改良版として理解できます。このようなアルゴリズムを用いて大きな数nを因数分解する場合、 n 1/2のオーダーの滑らかな数(つまり、素因数が小さい数)を探す必要があります。これらの数の大きさはnの大きさに対して指数関数的に増加します(後述)。一方、一般的な数体篩法では、nの大きさに対して準指数関数的に増加する滑らかな数を探すことができます。これらの数は小さいため、以前のアルゴリズムで調べた数よりも滑らかである可能性が高くなります。これが数体篩法の効率性の鍵です。この高速化を実現するために、数体篩法は数体で計算と因数分解を実行する必要があります。このため、より単純な有理篩法と比較して、アルゴリズムには多くの複雑な側面が生じます。
アルゴリズムへの入力サイズはlog 2 n 、つまりnの二進表現におけるビット数です。定数 c に対してn cの次数を持つ任意の要素は、log n に対して指数関数的に増加します。数体篩法の実行時間は、入力サイズに対して超多項式的であり、準指数関数的です。
fがk次多項式であると仮定します。(有理数)、rはfの複素根です。すると、f ( r ) = 0となり、これをr k をk未満のrのべき乗の線形結合として表すことができます。この式は、指数e ≥ kのrのべき乗を消去するために使用できます。たとえば、f ( x ) = x 2 + 1でr が虚数単位iの場合、i 2 + 1 = 0、つまりi 2 = −1となります。これにより、複素積を定義できます。
一般的に、これは直接的に代数的数体へとつながる。これは、以下の式で定義される複素数の集合として表すことができます。
このような値の任意の 2 つの積は、積を多項式として扱い、上記のように指数e ≥ kのrのべき乗を簡約することで計算でき、同じ形式の値が得られます。この体が実際にk次元であり、さらに小さな体に縮退しないことを保証するには、 fが有理数上の既約多項式であれば十分です。同様に、整数環を定義することもできます。のサブセットとしてこれらは整数係数を持つ単多項式の根です。場合によっては、この整数環は環と等価です。しかし、多くの例外がある。[ 2 ]
次数が小さいdとeの2 つの多項式f ( x ) とg ( x )が選択されます。これらの多項式は整数係数を持ち、有理数上で既約であり、mod nで解釈すると共通の整数根mを持ちます。これらの多項式を選択するための最適な戦略は知られていません。 1 つの簡単な方法は、適切なmの選択に対してnのm基数展開からfを得ることです。 より正確には、任意のmの選択に対して、n をm基数で記述することは、定義により、桁を見つけることです。どこ各iについて、
つまり、mは多項式の根である。nを法とする。一般的な数体篩法の目的のために、まず適切な次数dを固定し、次にn 1/ dの次数mの値に対して上記の展開を実行し、その後、このようにして得られた候補の中で係数が全体的に最小となる多項式fを選択する。次に、単純に設定する。。
多項式の選択は、アルゴリズムの残りの処理にかかる時間に大きな影響を与える可能性があります。上記で示した、 mを底とするnの展開に基づく多項式の選択方法は、多くの実際的な状況において最適とは言えず、より優れた方法の開発につながっています。
そのような方法の一つはマーフィーとブレントによって提案されました。[ 3 ]彼らは、小さな素数を法とする根の存在と、多項式が篩い分け領域で取る平均値に基づいて、多項式の2つの部分からなるスコアを導入しました。
報告されている最良の結果[ 4 ]は、 Thorsten Kleinjung [ 5 ]の方法によって達成されました。この方法では、 g ( x ) = ax + bを許容し、2dを法として 1 に合同な小さな素因数で構成されるaと、 60 で割り切れるfの先頭係数を探索します。
数体環Z [ r 1 ] とZ [ r 2 ] を考えます。ここで、r 1とr 2は多項式fとgの根です。f は次数 d で係数は整数なので、 aとb が整数であれば、 b d · f ( a / b )も整数になります。これをrと呼びます。同様に、s = b e · g ( a / b ) も整数です。目標は、素数の基底の選択に対してrとsを同時に滑らかにするaとbの整数値を見つけることです。aとbが小さい場合、rとsもm程度の大きさに小さくなり、同時に滑らかになる可能性が高くなります。この探索に対する現在最もよく知られているアプローチは格子篩法です。許容できる収量を得るには、大きな因子基底を使用する必要があります。これらのペアは「関係」とも呼ばれます。[ 6 ]
十分な数のそのようなペアがあれば、ガウス消去法を用いることで、特定のrとそれに対応するsの積を同時に平方数にすることができます。もう少し強い条件、つまりそれらが我々の数体における平方数のノルムである必要がありますが、この条件もこの方法で満たすことができます。各rはa − r 1 bのノルムであり、したがって対応する因子a − r 1 bの積はZ [ r 1 ]の平方数であり、その「平方根」は ( Z [ r 1 ]の既知の因子の積として) 決定できます。これは通常、無理代数数として表されます。同様に、因子a − r 2 bの積はZ [ r 2 ]の平方数であり、その「平方根」も計算できます。ガウス消去法を使用しても、アルゴリズムの実行時間は最適ではないことに注意してください。その代わりに、ブロックランチョス法やブロックヴィーデマン法などの疎行列解法アルゴリズムが用いられる。
m はfとgの両方のmod nの根であるため、環Z [ r 1 ] とZ [ r 2 ] から環Z / n Z ( nを法とする整数)への準同型が存在し、 r 1とr 2 をmに写像します。これらの準同型は、各「平方根」(通常は有理数として表されない) をその整数表現に写像します。ここで、因数a − mb mod nの積は、2 つの方法で平方数として得られます。各準同型に対して 1 つずつです。したがって、x 2 − y 2がnで割り切れる2 つの数xとyを見つけることができ、 nとx − yの最大公約数を見つけることで、少なくとも 1/2 の確率でnの因数を得ることができます。
後処理ステップでは、前の 2 つのステップで生成された大量のデータが処理されます。実際には、これを 3 つのフェーズに分割して行います。[ 6 ]
GNFS は大量の計算を伴い、RSA-768のような大きな数値の場合、実用的な時間内に完了するには何らかの分散コンピューティングが必要です。以下の手順は並列で実行できます。[ 7 ]
二次特性テストは、行列解の結果に適用して真の解を特定することができます。RSA-768の場合、512個のうち460個が真でした。そのうち8個が二乗ステップに選択され、比較的少ない計算量で最終ステップで5つの同一の因数分解が得られました。[ 7 ]
RSA-240、DLP-240、およびRSA-250の分散処理に関するより詳細な説明は、CADO-NFSソフトウェアを使用して記載されています。完全な再現ファイルは、論文の付録からリンクされているリポジトリで提供されています。[ 8 ]
実装によっては、特定のより小さなクラスの数に焦点を当てるものもあります。これらは、カニンガム・プロジェクトなどで使用されているような、特殊数体篩(SNFS)技術として知られています。
2007年まで、ゴールドスタンダードとされていた実装は、オランダのCWIが開発・配布していたソフトウェア群であり、比較的制限の厳しいライセンスの下でのみ利用可能でした。 2007年、ジェイソン・パパドプロス氏が、パブリックドメインであるmsieveの一部として、より高速な最終処理実装を開発しました。どちらの実装も、十分な速度の相互接続を備えたクラスタ内の複数のノードに分散して使用できるという特徴を備えています。
NFSNET と呼ばれるプロジェクトは、2002 年[ 9 ]から少なくとも 2007 年まで実行されました。これは、インターネット上のボランティアによる分散コンピューティングを使用しました。[ 10 ]英国のPaul Leyland氏とテキサス州の Richard Wackerbarth 氏が関わっていました。[ 11 ]
NFS@Homeと呼ばれる新しい試みは、2025年9月現在も稼働している。これはこれまで、msieveの改良版を使用してきた。一般的に、特殊な数値フィールドふるいを使用している。