Square-And-Multiply-Methode zum Potenzieren

Eine Methode um schnell

admodna^d\bmod n

zu berechnen.

Diese Methode lässt sich rekursiv definieren als:

c0=amodnc_0=a\bmod n ci+1=ci2modnc_{i+1}=c_i^2\bmod n d0=dd_0=d di+1=di2d_{i+1}=\lfloor\frac{d_i}{2}\rfloor δi=dimod2\delta_i=d_i \bmod 2 b0=aδ0modnb_0=a^{\delta_0}\bmod n bi+1=bici+1δi+1modnb_{i+1}=b_ic_{i+1}^{\delta_{i+1}}\bmod n

Ist di1d_i \leq 1, so ist bi=admodn.b_i=a^d\bmod n.

Laufzeit

Die Laufzeit ist durch die Größe von dd beschränkt. In jeder Iteration wird did_i halbiert. Wir berechnen also schnell, dass wir nur

l=log2d<3.33log10dl=\lfloor\log_2d\rfloor<3.33\log_{10}d

Schleifenwiederholungen brauchen. Wir müssen also ll mal ein Quadrat bilden und höchstens ll Multiplikationen durchführen.

Die Laufzeit lässt sich also mit O((logn)3)O((\log n)^3) abschätzen.

Variante 2

In der zweiten Variante versuchen wir den Exponenten stückweise kleiner zu machen. Dabei müssen wir dann immer nur kleine Potenzen berechnen, da die Modulo Operation die Zahlen immer kleiner gleich nn hält.

Wir verwenden also einmal für gerades dd

bcdb(c2modn)d2modnb \cdot c^d \equiv b \cdot\left(c^2 \bmod n\right)^{\frac{d}{2}} \bmod n

und für ungeraded dd

bcd(bcmodn)cd1modn.b \cdot c^d \equiv(b c \bmod n) \cdot c^{d-1} \bmod n.

Algorithmisch lässt sich auch dieses Verfahren rekursiv definieren, mit:

b0=1,c0=amodn,do=d.b_0=1, \quad c_0=a\bmod n,\quad d_o=d.

Wenn di=0d_i=0, dan ist bi=admodnb_i=a^d\bmod n.

Für di>0d_i>0 und did_i gerade:

bi+1=bi,ci+1=ci2modn,di+1=di2.b_{i+1}=b_i, \quad c_{i+1}=c_i^2 \bmod n, \quad d_{i+1}=\frac{d_i}{2}.

Für di>0d_i >0 und did_i ungerade:

bi+1=bicimodn,ci+1=ci,di+1=di1.b_{i+1}=b_i c_i \bmod n, \quad c_{i+1}=c_i, \quad d_{i+1}=d_i-1.

#code paste here

Variante 3

#code paste here