Da die Ganzzahlmoduloperation ein Ringhomomorphismus ( Wikipedia ) von ℤ -> ℤ / nℤ ist,
(X * Y) mod N = (X mod N) * (Y mod N) mod N
Sie können dies selbst mit ein wenig einfacher Algebra überprüfen. (Beachten Sie, dass das Finale mod
auf der rechten Seite aufgrund der Definition der Multiplikation in einem modularen Ring angezeigt wird.)
Computer verwenden diesen Trick, um Exponentiale in modularen Ringen zu berechnen, ohne eine große Anzahl von Ziffern berechnen zu müssen.
/ 1 I = 0,
|
(X ^ I) mod N = <(X * (X ^ (I-1) mod N)) mod NI ungerade,
|
\ (X ^ (I / 2) mod N) ^ 2 mod NI gerade & I / = 0.
In algorithmischer Form
-- 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
Sie können dies verwenden, um (855^2753) mod 3233
mit nur 16-Bit-Registern zu rechnen , wenn Sie möchten.
Die Werte von X und N in RSA sind jedoch viel größer, zu groß, um in ein Register zu passen. Ein Modul ist typischerweise 1024-4096 Bits lang! Sie können also von einem Computer die Multiplikation auf die "lange" Strecke ausführen lassen, genauso wie wir die Multiplikation von Hand ausführen. Nur anstelle der Ziffern 0-9 verwendet der Computer "Wörter" 0-2 16 -1 oder ähnliches. (Mit nur 16 Bit können wir zwei 16-Bit-Zahlen multiplizieren und das vollständige 32-Bit-Ergebnis erhalten, ohne auf die Assemblersprache zurückgreifen zu müssen. In der Assemblersprache ist es normalerweise sehr einfach, das vollständige 64-Bit-Ergebnis zu erhalten, oder für einen 64-Bit-Computer , das vollständige 128-Bit-Ergebnis.)
-- 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
Dies multipliziert X mit Y in einer Zeitspanne, die ungefähr der Anzahl der Wörter in X multipliziert mit der Anzahl der Wörter in Y entspricht. Dies wird als O (N 2 ) -Zeit bezeichnet. Wenn Sie sich den obigen Algorithmus anschauen und auseinander nehmen, ist es die gleiche "lange Multiplikation", die sie in der Schule unterrichten. Sie haben keine auf 10 Stellen gespeicherten Zeittabellen, aber Sie können dennoch 1.926.348 x 8.192.004 multiplizieren, wenn Sie sich hinsetzen und es herausarbeiten.
Lange Multiplikation:
1,234
x 5,678
---------
9,872
86,38
740,4
6,170
---------
7,006,652
Tatsächlich gibt es einige schnellere Algorithmen zum Multiplizieren ( Wikipedia ), wie die schnelle Fourier-Methode von Strassen, und einige einfachere Methoden, die zusätzliche Addition und Subtraktion, aber weniger Multiplikation ausführen und so insgesamt schneller enden. Numerische Bibliotheken wie GMP können verschiedene Algorithmen basierend auf der Größe der Zahlen auswählen: Die Fourier-Transformation ist für die größten Zahlen nur die schnellste, kleinere Zahlen verwenden einfachere Algorithmen.