いくつかのRSA暗号化/復号化方法を研究して、この記事を見つけました:RSAアルゴリズムの例
このメッセージを解読するにはこれが必要です
の合計結果は非常に大きく、64ビット/ 32ビットマシンでは、1つのレジスタにこのような大きな値を保持できるとは思わない。コンピューターはオーバーフローせずにどのようにそれを行いますか?
この質問は今週のスーパーユーザー質問でした。詳細について
はブログエントリを読むか、自分でブログに投稿してください
いくつかのRSA暗号化/復号化方法を研究して、この記事を見つけました:RSAアルゴリズムの例
このメッセージを解読するにはこれが必要です
の合計結果は非常に大きく、64ビット/ 32ビットマシンでは、1つのレジスタにこのような大きな値を保持できるとは思わない。コンピューターはオーバーフローせずにどのようにそれを行いますか?
この質問は今週のスーパーユーザー質問でした。詳細について
はブログエントリを読むか、自分でブログに投稿してください
回答:
整数モジュラス演算は、ℤ->ℤ/nℤからのリング準同型(Wikipedia)であるため、
(X * Y) mod N = (X mod N) * (Y mod N) mod N
少し簡単な代数でこれを自分で確認できます。(mod
右側のファイナルは、モジュラーリングの乗算の定義により表示されることに注意してください。)
コンピューターはこのトリックを使用して、多数の桁を計算することなく、モジュラーリングの指数を計算します。
/ 1 I = 0、 | (X ^ I)mod N = <(X *(X ^(I-1)mod N))mod NI奇数、 | \(X ^(I / 2)mod N)^ 2 mod NI even&I / = 0
アルゴリズム形式では、
-- compute X^I mod N
function expmod(X, I, N)
if I is zero
return 1
elif I is odd
return (expmod(X, I-1, N) * X) mod N
else
Y <- expmod(X, I/2, N)
return (Y*Y) mod N
end if
end function
(855^2753) mod 3233
必要に応じて、これを使用して16ビットレジスタのみで計算できます。
ただし、RSAのXおよびNの値は非常に大きく、大きすぎてレジスタに収まりません。モジュラスは通常1024-4096ビット長です!したがって、手動で乗算を行うのと同じように、コンピューターに「長い」方法で乗算を実行させることができます。0-9の数字を使用する代わりに、コンピューターは0-2 16 -1などの「単語」を使用します。(16ビットのみを使用すると、アセンブリ言語に頼らずに2つの16ビット数を乗算し、32ビットの完全な結果を得ることができます。アセンブリ言語では、通常64ビットの完全な結果、または64ビットのコンピューター、完全な128ビットの結果。)
-- Multiply two bigints by each other
function mul(uint16 X[N], uint16 Y[N]):
Z <- new array uint16[N*2]
for I in 1..N
-- C is the "carry"
C <- 0
-- Add Y[1..N] * X[I] to Z
for J in 1..N
T <- X[I] * Y[J] + C + Z[I + J - 1]
Z[I + J - 1] <- T & 0xffff
C <- T >> 16
end
-- Keep adding the "carry"
for J in (I+N)..(N*2)
T <- C + Z[J]
Z[J] <- T & 0xffff
C <- T >> 16
end
end
return Z
end
-- footnote: I wrote this off the top of my head
-- so, who knows what kind of errors it might have
これは、Xの単語数にYの単語数を掛けた時間にほぼ等しい時間でXにYを掛けます。これはO(N 2)時間ます。上記のアルゴリズムを見て、それを分解すると、彼らが学校で教えるのと同じ「長い掛け算」です。10桁まで記憶されたタイムテーブルはありませんが、座ってそれを解決すれば、まだ1,926,348 x 8,192,004を掛けることができます。
長い乗算:
1,234
x 5,678
---------
9,872
86,38
740,4
6,170
---------
7,006,652
実際には、Strassenの高速フーリエ法などの乗算用の高速アルゴリズム(Wikipedia)や、追加と減算を追加するが乗算は少ない単純なメソッドがあり、全体的に高速になります。GMPのような数値ライブラリは、数値の大きさに基づいて異なるアルゴリズムを選択できます。フーリエ変換は最大の数値に対してのみ最速であり、数値が小さいほど単純なアルゴリズムを使用します。
mod N
、中国剰余定理の最後に余分なものがありません。((16 mod 5)
等しくない(4 mod 5) * (4 mod 5)
:前者は1、後者は16)
mod
は、これは不要です。
(X * Y) mod N = (X mod N) * (Y mod N) mod N
本当ですが、中国の剰余定理とは何の関係もありません。
簡単な答えは、彼ら自身ではなく、できないということです。確かに、x-bitマシンの概念を採用する場合、限られた数のビットで表すことができる限られた数の数字があります。 10進法。
そうは言っても、非常に大きな数のコンピューター表現は、暗号化の分野の大きな要素です。コンピュータで非常に大きな数を表す方法は多数あり、それぞれが次のように変化します。
これらの方法にはそれぞれ長所と短所があり、ここにすべての方法をリストすることはできません/できませんが、非常に簡単な方法を紹介します。
整数が0〜99の値のみを保持できるとします。どうすれば100を表すことができますか?これは最初は不可能に思えるかもしれませんが、それは単一の変数のみを考慮するためです。という整数units
と1つの整数があればhundreds
、100:を簡単に表すことができますhundreds = 1; units = 0;
。9223:のように、もっと大きな数字を簡単に表すことができますhundreds = 92; units = 23
。
これは簡単な方法ですが、非常に非効率的であると言えます。コンピューターができることの限界を押し上げるほとんどのアルゴリズムと同様に、それは通常、力(多数を表す)と効率(高速検索/保存)の間の綱引きです。先ほど言ったように、コンピューターで多数を表現する方法はたくさんあります。メソッドを見つけて試してみてください!
これであなたの質問に答えてくれることを願っています!この
参考文献:記事とこれは、詳細については役に立つかもしれません。
同じ方法で。
342 * 189が何であるかを知らないことを推測します。しかし、あなたは次の事実を知っています:
9 * 2 = 18
9 * 4 = 36
9 * 3 = 27
8 * 2 = 16
8 * 4 = 32
8 * 3 = 24
1 * 2 = 2
1 * 4 = 4
1 * 3 = 3
18 + 360 + 2700 + 160 + 3200 + 24000 + 200 + 4000 + 30000 = 64638
これらの単純な事実を知り、それらを操作する技術を学んだことで、そうでなければできなかった算術を行うことができます。
同様に、一度に64ビット以上の数学を処理できないコンピューターは、大きな問題を小さな断片に簡単に分割し、それらの小さな断片を実行し、それらを元に戻して、より大きな、以前の答えられない問題。
加算と減算に関する限り、多くのCPUには、算術演算がオーバーフローした場合に設定される「キャリービット」があります。そのため、結果の保存に8バイトが必要で、CPUが32ビット(4つの8ビットバイトに相当)の場合、2つの加算演算を実行できます。最初に「低ワード」で、次に「高ワード」でキャリービットがオーバーフローを処理します。最初にキャリービットをクリアする必要があります。これは、高ビットCPUがパフォーマンスを向上させる理由の1つです。これは、これをそれほど行う必要がないためです。
もちろん、これは8ビットCPUでのアセンブラーの経験が限られているためです。キャリービットが乗算および除算命令を備えた最新のCPUでどのように機能するかはわかりません。非Intel RISC CPUの動作も異なる場合があります。
浮動小数点演算についてはあまり知りませんが、基本的にバイトは特定の場所ではなく、固定数の場所を表します。それが「浮動」ポイントと呼ばれる理由です。したがって、たとえば、数値34459234は、3.4459234または3.4459234E + 20(3.4459234 x 10 ^ 20)とほぼ同じメモリ空間を消費します。