/*richte die Chiffre ein(Erzeuge internen 128 oktet Schluessel) */ FranksFeistel::FranksFeistel(&String_16 schluesselZK) { betriebsBereit = 1; //String-Schluessel in die interne Schluessel-Struktur einmischen var PiQuelle piQuelle; if(piQuelle.ladeVonPlatte()==1) { for(var int i=0; i < piOktets.sz;i++) { var int oktet; if(piQuelle.leseOktet(oktet) == 1 ) { piOktets[i]= cast(char,oktet);} else { betriebsBereit = 0; } } } this.setzeSchluessel(schluesselZK); } void FranksFeistel::setzeSchluessel(&String_16 schluesselZK) { var PrintfClass pfc; var int abtaster = 0; for(var int i=0; i < schluessel.sz; i++) { var longlong schlWort = 0; for(var int j=0; j < 8; j++) { var int oktet; var longlong schlOktetLL = cast(longlong,piOktets[i*j]); schlOktetLL = schlOktetLL & 0xFF; schlWort = schlWort ^ schlOktetLL; pfc.fstr("ses 2 $").sa(schlWort).pr(); var char schlZeichen = schluesselZK.getAt(abtaster); var longlong schlZeichenLL = cast(longlong,schlZeichen); schlZeichenLL = schlZeichenLL & 0xFF; pfc.fstr("ses 3 $").sa(cast(int,schlZeichen)).pr(); abtaster = (abtaster + 1) % schluesselZK.length(); schlWort = schlWort ^ schlZeichenLL; if(j < 7){ schlWort = schlWort << 8; } } schluessel[i] = schlWort; pfc.fstr("ses $ $").sa(i).sa(schlWort).pr(); } } /* Feistel-Verschluesselung von 128 bit */ void FranksFeistel::verschluessle(&longlong links, &longlong rechts) { var PrintfClass pfc; if(betriebsBereit) { //Feistel-Leiter mit drei verschiedenen nichtlinearen Funktionen for(var int i=0; i < 11; ) { var longlong verwuerfelt; Nichtlinear::f1(rechts,schluessel[i],verwuerfelt); links = links ^ verwuerfelt; pfc.fstr("Feistel $ $ $").sa(i).sa(links).sa(rechts).pr(); i++; var longlong tausch = links; links = rechts; rechts = tausch; Nichtlinear::f2(rechts,schluessel[i],verwuerfelt); pfc.fstr("Feistel $ $ $").sa(i).sa(links).sa(rechts).pr(); links = links ^ verwuerfelt; i++; tausch = links; links = rechts; rechts = tausch; Nichtlinear::f3(rechts,schluessel[i],verwuerfelt); pfc.fstr("Feistel $ $ $").sa(i).sa(links).sa(rechts).pr(); links = links ^ verwuerfelt; i++; tausch = links; links = rechts; rechts = tausch; Nichtlinear::f4(rechts,schluessel[i],verwuerfelt); pfc.fstr("Feistel $ $ $").sa(i).sa(links).sa(rechts).pr(); links = links ^ verwuerfelt; i++; tausch = links; links = rechts; rechts = tausch; Nichtlinear::f5(rechts,schluessel[i],verwuerfelt); pfc.fstr("Feistel $ $ $").sa(i).sa(links).sa(rechts).pr(); links = links ^ verwuerfelt; i++; tausch = links; links = rechts; rechts = tausch; } } else { //Fehler links = cast(longlong,0); rechts = cast(longlong,0); } } void Nichtlinear::f1(longlong rechts,longlong schluessel,&longlong ergebnis) { var PrintfClass pfc; ergebnis = (rechts * schluessel) ^ ( rechts >> 37) ^ (rechts << 28); pfc.fstr("nl f1 $ $ $").sa(rechts).sa(schluessel).sa(ergebnis).pr(); } void Nichtlinear::f2(longlong rechts,longlong schluessel,&longlong ergebnis) { var PrintfClass pfc; var longlong nlf = rechts ^ schluessel; nlf = (nlf * 0x2fa2cab6e3dce535) ^ //Mult PI (nlf << 17) ^ (nlf >> 47) ^ //shift (nlf << 38) ^ (nlf >> 26) ^ //shift 2 (nlf + 0xad1f20ac607c); //Addition andere PI ergebnis = nlf; pfc.fstr("nl f2 $ $ $").sa(rechts).sa(schluessel).sa(ergebnis).pr(); } void Nichtlinear::f3(longlong rechts,longlong schluessel,&longlong ergebnis) { var PrintfClass pfc; var longlong zwischen = rechts ^ schluessel; var longlong quadrat = zwischen * zwischen; ergebnis = quadrat ^ (schluessel << 19) ^ (schluessel >> 51); pfc.fstr("nl f3 $ $ $").sa(rechts).sa(schluessel).sa(ergebnis).pr(); } void Nichtlinear::f4(longlong rechts,longlong schluessel,&longlong ergebnis) { var longlong zwischen = rechts ^ schluessel; var longlong quadrat = zwischen * zwischen; ergebnis = quadrat ^ (schluessel << 19) ^ (schluessel >> 51); } void Nichtlinear::f5(longlong rechts,longlong schluessel,&longlong ergebnis) { var longlong varSchiebung = (rechts >> (schluessel & 0x1F)) ^ (rechts << (schluessel & 0xF)) ^ rechts; ergebnis = varSchiebung * varSchiebung; } ZufallsQuelle::ZufallsQuelle() { inline_cpp[[ const char* random_dev = "/dev/urandom"; const int num_bytes = 32; // 256 bits char buffer[num_bytes]; // Open /dev/urandom ifstream urandom(random_dev, ios::in|ios::binary); if (!urandom) { cerr << "Konnte keine Zufallszahlen aus /dev/urandom lesen" << endl; betriebsBereit = 0; } // Read num_bytes octets from /dev/urandom into buffer urandom.read(buffer, num_bytes); // Close /dev/urandom urandom.close(); char stackPtr; for(int i=0; i < num_bytes; i++) schluessel.append(&stackPtr,buffer[i]); betriebsBereit = 1; ]] fFeistel = new FranksFeistel(schluessel); zustandLinks = cast(longlong,0); zustandRechts = cast(longlong,0); abtaster = 0; fFeistel.verschluessle(zustandLinks,zustandRechts); } /*erzeuge ein PRNG Zufallswort der Laenge 32 bit */ int ZufallsQuelle::gebe() { if(abtaster == 4) { //betrachte den Schluessel als Zahl und inkrementiert ihn um eins var int oktet; var int i=0; do { oktet = cast(int,schluessel.getAt(i)); oktet++; schluessel.setAt(i,cast(char,oktet)); i++; } while(oktet == 0); fFeistel.setzeSchluessel(schluessel); fFeistel.verschluessle(zustandLinks,zustandRechts);//Davies-Meyer Hash des CTR-Schluessel abtaster = 0; } var int ret; if(abtaster < 2) { ret = cast(int,(zustandLinks >>(abtaster*32))); } else { ret = cast(int,(zustandRechts >>((abtaster - 2)*32))); } abtaster++; return ret; }