background image

 
SYSTEMY SZYFROWANIA Z KLUCZEM JAWNYM 
 
Konwencjonalnie – szyfrowanie i deszyfrowanie  to ten sam  klucz(hasło) 
Można  inaczej    szyfrowanie-- pierwszy klucz(A), deszyfrowanie  inny 
B=B(A) 
Co to daje    
1.

 

Nie można „obliczyć” klucza deszyfrującego znając jedynie klucz A i 
algorytm szyfrujący 

2.

 

Są algorytmy, dla których każdy ze związanych ze sobą kluczy A i B można 
użyć do szyfrowanie i deszyfrowania 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1.

 

SYSTEMY KOŃCOWE GENERUJĄ PARĘ KLUCZY DO 
SZYFROWANIA I DESZYFROWANIA 

2.

 

KAŻDY SYSTEM UDOSTĘPNIA, PUBLIKUJE SWÓJ KLUCZ 
SZYFRUJĄCY, JEST TO KLUCZ JAWNY. DRUGI KLUCZ JEST 
PRYWATNY 

3.

 

JEŻELI A WSYLA TO SZYFRUJE DANE KLUCZEM JAWNYM 
ODBIORCY B 

4.

 

ODBIORCA B DESZYFRUJE DANE ZA POMOCĄ SWEGO KLUCZA 
PRYWATNEGO. TYLKO ON MOŻE TO WYKONAĆ. 

Taki sposób posługiwania się kluczami zapewnia poufność.  Kryptoanalityk  
musi wygenerować bardzo wiele hipotetycznych kluczy prywatnych B  aby 
rozszyfrować dane. 
Jeśli użyjemy algorytmu umożliwiającego przestawianie kluczy to możemy 
zrealizować funkcję uwierzytelnienia.  A  swój komunikat szyfruje go za 
pomocą swego klucza prywatnego i przesyła go do B, ten zaś odszyfrowuje go 

Algorytm 
szyfrujący 

Algorytm  
deszyfrujący 

Tekst  
zaszyfrowany 

Tekst 
jawny 

Tekst 
jawny 

Użytkownik A 

Użytkownik B 

Klucz jawny B 

Klucz prywatny 

background image

za pomocą klucza jawnego pochodzącego od A. Odbiorca B ma pewność, że 
tylko A mógł wysłać komunikat.  Nikt po drodze nie może przechwycić 
komunikatu w celu   jego podmiany bo nie zna klucza prywatnego nadawcy A. 
Ale każdy, kto ma dostęp do bazy z kluczem publicznym nadawcy A może 
łatwo odszyfrować tekst czyli nie jest to poufne. 
  Należy zastosować podwójne szyfrowanie 
1

 

Nadawca szyfruje komunikat za pomocą swojego klucza prywatnego. 

2

 

Nadawca szyfruje otrzymany wynik drugi raz za pomocą klucza jawnego 
odbiorcy 

3

 

Otrzymane  dane   może odszyfrować tylko B swoim kluczem prywatnym 
czyli jest zapewniona poufność bo wiadomość jest tylko dla niego. 

4

 

Jawny tekst otrzyma stosując klucz publiczny nadawcy. 

Ale aż 4 razy trzeba stosować algorytm szyfrowania. 
 
Wymagania dla algorytmów szyfrująco / deszyfrujących z wykorzystaniem 
kluczy prywatnych i publicznych są wysokie. Na dziś powszechnie 
akceptowalny jest algorytm RSA (system Rivesta-Shamira-Adlemana) 
 

 

******************************************************************* 
 
Przedstawione poniżej algorytmy szyfrowania danych są szyframi blokowymi.

  

Omówione zostaną:

  

1)z grupy szyfrów wykładniczych szyfr Pohliga-Hallmana

  

2)z grupy szyfrów wykładniczych szyfr RSA(Rivest-Shamir-Adleman)

  

W grupie szyfrów wykładniczych i plecakowych w celu zrozumienia zasad 
szyfrowania i ewentualnej próby złamania szyfru należy wprowadzić niezbędne 
definicje i twierdzenia z zakresu teorii liczb.

  

Wstęp do arytmetyka modularnej:  
Definicja1:  
Dwie liczby całkowite a i b przystają do siebie według modułu n tzn.  
a

nb ,

  

gdzie n jest liczbą całkowitą różną od 0 wtedy i tylko wtedy, gdy istnieje  
liczba całkowita k, dla której:  
a-b = kn.  
Np. 17

5

7, ponieważ 17-7 =2*5.   tą liczbą k  jest 2 

Wówczas dla a

≡≡≡≡

nb

, b jest nazywane residuum a modulo n.  

Definicja2:  
Zbiór liczb całkowitych (r

1,...,rn

) nazywamy zbiorem zupełnym residuów modulo 

n, jeśli dla każdej liczby całkowitej a istnieje w tym zbiorze dokładnie jeden 

element

 r

i

dla którego zachodzi

 

a

 

n

ri

  

Można zauważyć, że dla dowolnego modulo n zbiór liczb (0,1,....,n-1) stanowi 
zbiór zupełny residuów modulo n.

  

background image

W arytmetyce modularnej liczb całkowitych modulo n obowiązują te same prawa 
łączności, rozdzielności i przemienności działań co w arytmetyce liczb 
całkowitych.

 

 

Twierdzenie1

  

Niech a1 i a2 będą liczbami całkowitymi ,zaś op  jest operatorem: +,-, lub *. 
Wtedy:

  

(a1 op a2) mod n= [(a1 mod n) op (a2 mod n)] mod n.  

 
Czyli prawdziwe są działania:

  

 
(a1 +a2) mod n=[(a1 mod n) +(a2 mod n)] mod n  
i  
(a1*a2) mod n=[(a1 mod n) * (a2 mod n)] mod n  

oraz co najważniejsze możliwe jest skuteczne potęgowanie to znaczy że:

  

=

t

i

t

n

n

e

n

e

1

mod

)]

mod

(

[

mod

 

gdzie 0 

 

 n-1

  

Kolejne mnożenia modulo n zmniejszają wielkość pośrednich wyników. W 
praktyce dla k-bitowej liczby n to znaczy takiej ze 2

k-1

 

n < 2

wynik 

odejmowania, dodawania lub mnożenia nie przekroczy długości 2k bitów. To 
oznacza wykonywanie operacji potęgowania modulo n bez konieczności 
rezerwowania zbyt dużej pamięci na wyniki pośrednie.  

Dowód twierdzenia 1:

  

niech a1=k1*n+r1 oraz a2=k2*n+r2 wtedy:

  

 

(a1+ a2) mod n= [(k1*n+r1)+(k2*n+r2)] mod n=

  

 

[((k1+k2)*n +(r1+r2)]mod n= (r1+r2) mod n=

  

[(a1 mod n)+(a2 mod n)] mod n.

  

 

Poniżej podano przykładową funkcję w C szybkiego potęgowania liczb mod n

  

 
long int fastexp(long a, long z, long n)

  

{

  

 long z1=z;

  

 long x=1;

  

 long a1=a;

  

 while (z1)

  

{

  

 while(!(z1%2))

  

 {

  

  z1=(int)(z1/2);

  

background image

  a1=((int)(a1*a1)) % n;

  

 }

  

 z1-=1;

  

 x=((int)(x*a1)) % n;

  

}

  

return(x);

  

}

  

 

Bardzo ważnym zagadnieniem w arytmetyce modularnej jest obliczanie 
odwrotności iloczynowych modulo n. Np. liczby 3 i 7 są odwrotnościami mod 
10 ponieważ:  

3*7 mod 10 =1  
   
   
Twierdzenie 2  

Można dowieść że dla równania : ax mod n = 1 jeśli tylko gcd(a,n)=1 (greatest 
common divisor) to znaczy: że liczby a i n są liczbami wzajemnie pierwszymi, to 
istnieje pewna liczba 0< x < n, która jest odwrotnością liczby a modulo n.

  

Twierdzenie powyższe jedynie stwierdza możliwość istnienia odwrotności liczby, 
ale nie określa sposobu wyliczenia tejże odwrotności. W tym celu wprowadźmy 
pewne dodatkowe definicje:

  

Definicja3:

  

Zbiorem zredukowanym residuów mod n nazywamy podzbiór residuów {0,1,...,n-
1} względnie pierwszych z n

  

Na przykład zbiorem zredukowanym residuów mod 10 jest zbiór {1,3,7,9}

  

Uwaga do definicji 3:

  

Jeśli n jest liczbą pierwszą, to zredukowany zbiór jest równoważny zbiorowi 
zupełnemu residuów o elementach {1,...,n-1}, z wyłączeniem zera!

  

Definicja4:

  

Funkcja Eulera 

Φ

(n) 

określa liczbę elementów w zredukowanym zbiorze 

residuów modulo n, czyli

 

Φ(

n) jest liczbą całkowitych liczb dodatnich mniejszych 

od n i względnie pierwszych z n.

  

Na przykład 

Φ(10) = 4, 

Φ(11) = 10,

 czyli funkcja Eulera dla n=11 wynosi n-1, 

ponieważ wszystkie elementy zbioru residuum zupełnego są względnie pierwsze 
względem 11.

  

Twierdzenie 3

  

Dla pewnej liczby n będącej iloczynem liczb pierwszych p i q zachodzi zależność: 

Φ(

n

)

 =

 Φ(

p

)

 * 

Φ(

q

)

 =(p-1) *(q-1)

  

Na przykład: 

φ(21)

 = 

φ(7)

 * 

φ(3)

 = (7-1)*(3-1) =12, czyli występuje 12 elementów 

w granicach {1,...,21-1} względnie pierwszych z 21.

  

  

Twierdzenie4

  

Niech dana będzie liczba pierwsza p, wtedy dla każdej liczby a względnie 
pierwszej z p tj. gcd(a,p)=1 zachodzi równość:

  

background image

p-1

mod p =1

  

Z uogólnienia Eulera wynika, że rozwiązanie równości:

  

ax mod n =1 ma postać:

  

x=a

 

Φ

(n)-1

 mod n  

Uwaga do rozwiązania powyższej równości:

  

Je

ś

li liczba n jest liczb

ą

 pierwsz

ą

 to obliczenie odwrotno

ś

ci liczby a upraszcza si

ę

  

do postaci:

  

x=a

n-2

 mod n

  

Przykład:

  

dla a=3, n=7, czyli dla równania:    3x mod 7=1 otrzymujemy rozwiązanie:

  

x=3

5

 mod 7 co równa się 5

  

ponieważ: 3*5 mod 7 =1.

  

Uwaga:

  

Do obliczania odwrotności x w stosunku do liczby a modulo n, jeśli tylko znana 
jest wartość funkcji Eulera 

Φ

(n), można się posłużyć przytoczoną powyżej funkcją 

szybkiego potęgowania, fastexp(a,z,n), która zwraca wartość określoną wzorem:

  

a

z

 mod n

  

Inny sposób obliczania odwrotności x liczby a modulo n polega zastosowaniu 
rozszerzonego algorytmu Euklidesa do obliczania gcd(największego wspólnego 
podzielnika). W przykładzie  podano funkcję liczącą według algorytmu 
Euklidesa gcd dwóch liczb całkowitych a i n.  

 
long gcd(long a, long n)

  

{

  

 long g0=n;

  

 long g1=a;

  

 long g2;

  

 long i=1;

  

while(g1)

  

{

  

 g2=g0 % g1;

  

 g0=g1;

  

 g1=g2;

  

 i++;

  

}

  

return(g0);

  

}

  

 
Do obliczania odwrotności liczby a modulo n przydałby się rozszerzony algorytm 
Euklidesa:

  

Program nr.3

  

#include<stdio.h>

  

#include<stdlib.h>

  

#include<conio.h>

  

long inv(long a, long n)

  

background image

{

  

long g0=n;

  

long g1=a;

  

long g2;

  

long u0=1;

  

long u1=0;

  

long u2;

  

long v0=0;

  

long v1=1;

  

long v2;

  

long i=1;

  

long y;

  

while(g1)

  

{

  

 y=(int)(g0/g1);

  

 g2=g0-(int)(y*g1);

  

 u2=u0-(int)(y*u1);

  

 v2=v0-(int)(y*v1);

  

 g0=g1;

  

 g1=g2;

  

 u0=u1;

  

 u1=u2;

  

 v0=v1;

  

 v1=v2;

  

 i++;

  

}

  

if(v0>=0)

  

 return(v0);

  

else

  

 return(v0+n);

  

}

  

 
Przeciętna liczba dzieleń wykonywanych w tym algorytmie została oszacowana 
przez Knutha na około (0,843 ln n + 1,47).

  

Oczywiście omawiany algorytm można rozszerzyć, w celu obliczania liczby x z 
bardziej ogólnego równania:

  

ax mod n =b , gdzie a i n spełniają równanie gcd(a,n)=1

  

W tym celu:  

1)należy obliczyć x

z równania   

axo mod n = 1  

2)po przekształceniu tego powyższego równania otrzymamy:

  

abx

o

 mod n =1 skąd :  

x=bx

o

 mod n  

Do obliczenia liczby x może posłużyć zdefiniowane wcześniej funkcje w postaci 
wyrażenia dla nieznanej funkcji Eulera:  
x=(b*inv(a,n)) mod n  
lub też dla znanej funkcji Eulera:  
x=(b*fastexp(a, 

Φ

(n) -1,n)) mod n  

Szyfry potęgowe:

  

background image

 

Obydwa szyfry pot

ę

gowe, które zostan

ą

 tutaj omówione realizuj

ą

 szyfrowanie 

bloku tekstu jawnego M od długo

ś

ci co najmniej 200 bitów.  

1)

Szyfr Pohliga-Hallmana realizuje szyfrowanie w następujący sposób:

  

(1) C=M

e

mod n, gdzie:  

 

M (message)- oznacza tekst jawny  
C - oznacza tekst zaszyfrowany  
e - pewien wykładnik wynikający z uogólnienia Eulera  
n - pewna duża liczba, której wybór zależy od metody szyfrowania 
wykładniczego.  

Uwaga:

  

M musi należeć do przedziału [0,...,n-1] , stąd też po długości bloków tekstu 
poddawanego szyfrowaniu można w przybliżeniu określić wielkość liczby n.

  

Deszyfracja polega na wykonaniu następującej operacji:

  

 

(2) M=C

d

mod n, 

gdzie:

  

d - to pewien wykładnik wynikający z uogólnienia Eulera

  

Z uogólnienia Eulera twierdzenia Fermata wynika, że dla każdej liczby M 
względnie pierwszej z n      M

Φ

Φ

Φ

Φ

(n)mod n = 

1     zachodzi zależność:  

   

(3)   ed mod 

Φ

Φ

Φ

Φ

(n) =1  

 
Można udowodnić, ze dla e i d spełniających zależność (3) równania (1) i (2) 
realizują operacje wzajemnie odwrotne.

  

Twierdzenie5:  

Dla danych e i d spełniających równanie (3) oraz wiadomości M zawierającej 
się w przedziale [0,..,n-1] oraz względnie pierwszej z n to znaczy: gcd(M,n)=1

  

 
(4)   (M

e

mod n)

d

 mod n=M  

 
Znając wartość funkcji Eulera 

Φ

(n) dla danej liczby n, z łatwością można 

wygenerować parę liczb e i d . W tym celu dokonuje się wyboru liczby d względnie 
pierwszej z 

Φ

(n) po czym zgodnie z zależnością (3) dokonuje się wyliczenia 

odwrotności e liczby d modulo 

Φ

(n), na przykład korzystając z algorytmu 

rozszerzonego Euklidesa:

  

e=inv(d,

Φ

(n)).

  

Uwagi co do łamalności przedstawionego szyfru wykładniczego:

  

Mając d łatwo można obliczyć e mając 

Φ

(n).

 Tajemnicę szyfru można więc ukryć 

zachowując w tajemnicy 

Φ

(n) i d, liczby potrzebne do deszyfracji, podczas gdy e 

wykładnik potrzebny do szyfracji tekstu może być powszechnie znany.

  

Ewentualnie zachowując e i d, czyli szyfr ten może posłużyć jedynie do 
klasycznego szyfrowania    (

bez klucza jawnego

)  

background image

Przykład:

  

   
   

1.

 

Niech n=11, czyli jest to liczba pierwsza, czyli 

Φ

(n)=n-1=10,

  

2.

 

wybieramy d=7, a więc zgodnie z równaniem 7*e mod 10=1, odwrotnością 
liczby 7 modulo 10 jest 3. Można to obliczyć :

  

e=inv(7,10)=3

  

   

3.

 

Niech M=5 będzie tekstem jawnym do zaszyfrowania, w takim razie:

  

C=M

e

mod n = 5

3

 mod 11 = 4

  

oraz

  

M =C

d

mod n = 4

7

mod 11=5

  

Bezpieczeństwo powyższego szyfru opiera się na złożoności obliczania 
logarytmów dyskretnych w postaci:  

e=log

M

C

  

lub

  

d=log

C

M, przy czym kryptoanalityk musi dysponować tekstem jawnym i 

zaszyfrowanym.

  

Wzór szacunkowej liczby operacji niezbędnych do wykonania celem złamania 
szyfru Pohliga-Hallamana:  

Najszybszy ze znanych algorytmów obliczania logarytmów dyskretnych przy 
zadanym n będącym liczbą pierwszą potrzebuje wykonania około:

  

 
exp(sqrt(sqrt(ln(n)ln(ln(n)))) operacji tj.  
dla liczby n 200-bitowej potrzeba:2,7*10

11

 operacji do wykonania.  

 
Zakładając, ze potrzeba 100 nS  na wykonanie jednej takiej operacji, cała operacja 

deszyfracji będzie trwała około 0.1 dnia.Dla n o długości 664 bitów, liczba 
operacji wynosi ok. 1.2*10

23

 czyli zajmuje to ok. 10

11

 dni, czyli cośok. miliard 

lat.  

   
   
   
   

Szyfr RSA(Rivest-Shamir-Adleman)

 

   

Realizacja szyfru RSA:

  

Róznica między tym szyfrem a poprzednio omawianą odmianą szyfru 
wykładniczego polega na odmiennym doborze liczby n. Dobierana ona jest jako 
iloczyn dwóch wielkich liczb pierwszych p i q .

  

n=pq, z czego zgodnie z 

twierdzeniem 3

 funkcja Eulera dla n wynosi:

  

   

Φ

(n)=(p-1)*(q-1).

 

   

background image

Wówczas:

  

1)zalecane jest wybór liczby d względnie pierwszej z 

φ

(n) oraz takiej, ze zawiera 

się ona w przedziale [(max(p.,q)

+1,n-1]

  

2)wartość e oblicza się analogicznie jak w poprzednim algorytmie szyfrowania:

  

e=inv(d,

Φ

(n))

  

z tym ,że jeśli e<log

2

n, to nie nastąpi dla każdego szyfrogramu w czasie deszyfracji 

operacja redukcji modulo n. To oznacza pewne podobieństwo bloków szyfrogramu 
do tekstu jawnego. Dlatego należy wybrać w tym przypadku nową liczbę d 
powtórzyć algorytm od punktu 1).

  

Przykład:

  

1)Niech p.=5 i q=7, czyli n=35 a 

Φ

(n)=(p-1)(q-1)=24  

2)wybieramy d=11  
3)obliczamy e=inv(11,24)=11, co oznacza akurat jednakowy wykładnik 
szyfracji i deszyfracji.  
4)Niech M.=2(tekst jawny), wówczas:  
C=M

e

mod n = 2

11

 mod 35 = 2048 mod 35 = 18  

i oczywi

ś

cie:  

M=C

d

mod n = 18

11

 mod 35 = 2 = M 

 

Bezpieczeństwo tego szyfru opiera się na trudności wyliczenia F(n), czyli na 
faktoryzacji liczby n na czynniki pierwsze(Twierdzenie 3). Liczba operacji 
potrzebna do rozkładu liczby n    na czynniki pierwsze według najszybszego 
algorytmu Schroeppela równa się szacunkowo liczbie operacji obliczania 
algorytmów dyskretnych czyli:  

exp(sqrt(ln(n)ln(ln(n)))).

  

W takim razie w przeciwieństwie do algorytmu Pohliga-Hallmana w tym 
algorytmie można podać całą procedurę szyfracji czyli liczby n i e, ponieważ z 
liczby n nie wynika w sposób prosty liczba 

Φ

(n), a ta liczba jest właśnie potrzebna 

do wyliczenia d- wykładnika potrzebnego do deszyfracji.

  

Protokół wymiany klucza w algorytmie szyfrowania RSA:

  

Załóżmy, że wymiany informacji chcą dokonać dwie osoby mianowicie: Alicja i 
Beata, przy czym Alicja jest osobą nadającą informację, a Beata jest osobą 
odbierającą zaszyfrowaną informację. W takim razie protokół wymiany kluczy 
może być następujący:  
1) Beata generuje dwie wielkie liczby pierwsze p i i oblicza ich iloczyn n=p*q  
2) Następnie Beata na podstawie obliczonej wartości funkcji Eulera tj.  

Φ

Φ

Φ

Φ

(n)=(p-1)*(q-1)  generuje liczbę e  

3) Beata, na podstawie wygenerowanej liczby takiej, że e>log

2n, 

z równania:  

   
ed mod 

Φ

Φ

Φ

Φ

(n) = 1, 

   
oblicza wartość liczby d  
4) Beata przekazuje liczby e i n Alicji jako swój klucz publiczny, a liczbę d  

background image

zachowuje jako swój klucz prywatny.  
5) Na podstawie liczb n i e Alicja szyfruje wiadomość i wysyła ją do Beaty  
5) Beata posiada tylko sobie znany klucz prywatny d, komplementarny do 
klucza publicznego e i n i deszyfruje wiadomość otrzymaną od Alicji.  
 

Problem wiarygodności przesłanej wiadomości

  

Załóżmy, że w trakcie przesyłania wiadomości od Alicji do Beaty, Tomek 
przechwycił wiadomość przesyłaną przez Alicję i podmienił ją swoją informacją 
szyfrowaną ( klucz publiczny Beaty 

i n

 jest przecież powszechnie dostępny).

  

Występuje więc problem potwierdzenia wiarygodności otrzymanej wiadomości.

  

Rozwiązuje się go przez stosowanie podpisów albo inaczej nazwanych sygnatur 
elektronicznych. W opisanym powyżej przypadku wymiany informacji między 
Alicją a Beatą, wiadomość szyfrowaną Alicja podpisuje dodatkowo, stosując swój 
klucz prywatny (zakładamy, że Beata posiada komplementarny do tego klucza 
prywatnego Alicji, klucz publiczny Alicji w swojej bazie kluczy publicznych osób 
z którymi chcę się kontaktować). W takim razie Beata posługując się kluczem 
p

u

blicznym Alicji potwierdzi autentyczność informacji.

  

Dodatkowo w pakietach szyfracji i wymiany informacji szyfrowanej takich jak 
PGP(Pretty Good Privacy), stosuje się skrót z informacji przesyłanej, generowany 
za pomocą jednokierunkowej funkcji skrótu (one - way hash function). 
Właściwością takiej funkcji jest to, że otrzymana informacja jest trudna do 
podrobienia. Tzn: że generacja tego "odcisku palca" na podstawie funkcji skrótu 
jest mało czasochłonna, ale stworzenie dokumentu fałszywego, który posiadałby 
taką samą wartość funkcji skrótu nastręcza fałszerzowi poważne problemy, 
związane z wielkimi nakładami obliczeniowymi. Inaczej mówiąc dla funkcji 
jednokierunkowych nie istnieje funkcja odwrotna, którą można by przedstawić w 
sposób jawny.

  

 

Problem generowania wielkich liczb pierwszych:

  

Gdy n jest liczbą 200-cyfrową(w układzie dziesiętnym, czyli ok. 600-bitową), to 
zachodzi potrzeba wygenerowania wielkich liczb pierwszych p i q o długości około 
100- cyfr. Oczywiście liczbę taką generuje się z prawdopodobieństwem bliskim 
jedności.

  

W tym celu:

   

 

generujemy liczbę b, która jest “prawdopodobnie liczbą pierwszą

  

 

generujemy 100 liczb a z przedziału [1,b-1]

  

 

liczba a jest prawie na pewno liczbą pierwszą, gdy spełnione są warunki:

  

        a)  gcd(a,b)=1 co jest oczywiste, bo liczby a i b muszą względnie pierwsze.

  

        b)  spełniona musi być równość:

  

                J(a/b)mod b=a

(b-1)/2

 mod b

  

gdzie: J(a/b) jest symbolem Jacobiego.

  

background image

Gdy więc b nie jest liczbą pierwszą równania mogą być niespełnione z prawdp.1/2 
co dla 100 udanych prób daje prawdp. wystąpienia liczby b, która nie jest liczbą 
pierwszą równe: 1/2

100

  

Przykład 

 

long J(long a, long b)

  

{

  

 long Jac;

  

 if(a==1)

  

  Jac=1;

  

else

  

  if((a%2)==0)

  

{

  

 if((( (((int)(b*b-1))>>3) )%2)==0)

  

 Jac=J(a>>1,b);

  

else

  

 Jac=-J(a>>1,b);

  

}

  

else if(((((int)(a-1)*(b-1))>>2)%2)==0)

  

 Jac=J(b%a,a);

  

else

  

 Jac=-J(b%a,a);

  

return(Jac);

  

}

  

 
Przy użyciu powyżej zdefiniowanych w C funkcji należałoby 100-krotnie 
sprawdzic czy następujące wyrazenie jest spełnione(jest prawdz

iwe):

  

(J(a,b) %b)= =fastexp(a,(b-1)>>1,b) //w notacji języka C.

  

background image