//Primzahltest nach Rabin-Miller
//Autor: Germanos Efthimiadis
//letzte Änderung: 13.1.1998
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#define MAXINT 32767
#define MAXLONGINT 42949672951
#define SICHERHEIT 10001 //Anzahl der Tests mit verschiedenen a
//Autor: Bruce Schneier aus Angewandte Kryptografie S.285
//Funktion: mod
//Aufgabe: Berechnung der funktion modulo
//Parameter: unsigned long int a,x,n
//Rückgabe: unsigned long int (a^x mod n)
unsigned long int mod(unsigned long int a,unsigned long int x,unsigned long int n)
{
unsigned long int s,t,u;
s=1;
t=a;
u=x;
while(u)
{
if(u&1)
s=(s*t)%n;
u>>=1;
t=(t*t)%n;
}
return(s);
}
//Autor: Germnos Efthimiadis
//Funktion: Zufall
//Aufgabe: Berechnung einer zufallszahl<Obergrenze
//Parameter: unsigned long int i
//Rückgabe: unsigned long int (Zufallszahl)
unsigned long int Zufall(unsigned long int i)
{
unsigned long int x,x1,x2,x3;
x1=(unsigned long int)random(MAXINT);
x2=(unsigned long int)random(MAXINT);
x3=(unsigned long int)ramdom(MAXINT);
x=x1*x2*x3;
x%=i; //x<i;
return(x);
}
//Autor: Germanos Efthimiadis
//Funktion: Hauptprogramm
//Aufgabe: Primzahltest nach Rabin Miller
//Parameter: keine
//Rückgabe: keine
void main (void)
{
unsigned long int k,y,b,m,j,z;
//In diesem Array werden alle a's gespeichert
//So wird verhindert, dass man mit demselben a nochmal prüft
unsigned long int a[SICHERHEIT];
unsigned long int p;
int CursorY,CursorX; //Cursokoordinaten
randomize(); //Initialisierung des Z-Generators
printf("\n\nEs wird eine ungerade Zufallszahl p erzeugt");
p=Zufall(MAXLONGINT);
if (p%2==0)
p--; //Ungerade Zahl
if (p<10000000001)
p+=10000000001; //10-stellige Zahl
printf("\np=%lu\n",p);
printf("\np wird jetzt %lu mal getestet\n",SICHERHEIT);
b=0; // Wie oft lässt sich p-1 ohne Rest teilen?
m=p-1;
while (m%2==0)
{
m/=2;
b++;
}; //m ergibt sich aus der Berechnung von b
CursorX=wherex();
CursorY=wherey();
for (k=0;k<SICHERHEIT;k++)
{
gotoxy(CursorX,CursorY);
printf("%lu. Test",k+1);
//Schritt 1
a[k]=Zufall(p-2);
y=0;
while (y<k)
{
if (a[k]==a[y]) //Gibt's die Zahl schon?
{
a[k]=Zufall(p-2); //Erzeuge neue Zahl
y=0; //Beginne Vergleich von vorne
} else
y++; //Setze Vergleich fort
}
//Schritt 2
j=0;
z=mod(a[k],m,p);
//Schritt 3
if (!(z==1 || z==p-1))
goto keine_primzahl;
//Schritt 4
schritt4:
if (j>0 && z==1)
goto keine_primzahl;
//Schritt 5
j++;
if (j<b && z!=p-1)
{
z=mod(z,2,p);
goto schritt4;
}
if (z!=p-1)
goto keine_primzahl;
//Schritt 6
if (j!=b || z==p-1)
{
printf("\n%lu ist eine Primzahl",p);
return;
}
keine_primzahl:
printf("\n%lu ist keine Primzahl",p);
return;
}
}