Drugą operacją mającą znaczący wpływ na czas generacji kluczy i tworzenia podpisów
jest operacja potęgowania w grupie
. Jest ona wykorzystywana również
w algorytmie generacji liczb pierwszych w teście Millera-Rabina [3].
Należy zauważyć, iż w czasie generacji poświadczeń elektronicznych wykonuje
się operacje
, gdzie
i
są stałymi. Zatem,
by policzyć
wystarczy mieć
i
, takie że
oraz policzone uprzednio
i
. Wtedy łatwo możemy obliczyć
. Niestety zapamiętywanie wszystkich obliczanych
potęg jest bardzo kosztowne i niezgodne z prawem (por dodatek A).
Pewnym rozwiązaniem jest zapamiętanie wszystkich potęg postaci
dla
. Można wtedy użyć następującego
algorytmu:
i:=1 for d := 0 to length( g ) if x[d] = 1 then i := i * a[d] mod p; return i;
W tablicy przechowujemy zapamiętane
.
Można oczywiście przechowywać obliczone wartości postaci
,
gdzie
to niewielkie liczby z przedziału
. Wtedy:
Niech , a
. Wtedy algorytm
będzie wyglądał następująco:
y := x; i:=1; for d := 0 to l i := i * a[d][y mod r] mod p; y := y div r; return i;
Jednak w tym przypadku skorzystano z tradycyjnego algorytmu
,,podnoś do kwadratu i mnóż''.
Korzystamy wtedy z reprezentacji liczby :
i := x[l]; for d := (l - 1) downto 0 i := i * i mod p; if x[d] = 1 then i := i * a mod p; return i;
W czasie implementacji brano pod uwagę wykorzystanie funkcji realizującej
taką operację, wchodzącej w skład biblioteki bignat. Niestety kod tej
funkcji zawiera pętlę for, której implementacja w języku funkcyjnym jest
bardzo niewydajna. Zapis funkcji umożliwiający wykorzystanie przez kompilator
optymalizacji rekursji ogonowej przyspieszył czas wykonywania potęgowania ponad
27 krotnie. W tabeli 5.1 przedstawiono czasy poszczególnych operacji
dla ,
i
równych 1024. Użyto takich długości, by test był
porównywalny z najczęściej spotykanymi wynikami dotyczącymi algorytmu RSA.