[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Sorry to put this all in the subject line but my german account heregoes nuts if i type below it. So anyway, here's my most updated version ofa program I've been working on. i'm getting the bugs of really weak encryptionand incorrect decryption and it'd be great if I could have some people whowhat they're doing look at it. The padding routine should be sound and theonly place I can think of the problem being is the Feistel network, but Ican't pinpoint it. It's structure is similar to GOST with Sboxes along thelines of Blowfish. The coding may not be the best in the world so if youhave questions or comments about it, send it to: zinthefe@hrzpub.tu-darmstadt.de If you want to send working code, it'dbe a good idea to send it to my acount in America to avoid any legalunpleasantness at zinthefe@ews.uiuc.edu This isn't the finished product, I plan to do all sorts ofcosmetic changes when i get the algorithm working right like turning theecho off, putting it on the command line, etc. But for the moment, I'd loveif if y'all could figure out why it's encrypting crappy and decryptingincorrectly. Thanks in advance
- To: coderpunks@toad.com, cypherpunks@toad.com
- Subject: Sorry to put this all in the subject line but my german account heregoes nuts if i type below it. So anyway, here's my most updated version ofa program I've been working on. i'm getting the bugs of really weak encryptionand incorrect decryption and it'd be great if I could have some people whowhat they're doing look at it. The padding routine should be sound and theonly place I can think of the problem being is the Feistel network, but Ican't pinpoint it. It's structure is similar to GOST with Sboxes along thelines of Blowfish. The coding may not be the best in the world so if youhave questions or comments about it, send it to: zinthefe@hrzpub.tu-darmstadt.de If you want to send working code, it'dbe a good idea to send it to my acount in America to avoid any legalunpleasantness at zinthefe@ews.uiuc.edu This isn't the finished product, I plan to do all sorts ofcosmetic changes when i get the algorithm working right like turning theecho off, putting it on the command line, etc. But for the moment, I'd loveif if y'all could figure out why it's encrypting crappy and decryptingincorrectly. Thanks in advance
- From: Marc Zinthefer <zinthefe@rbg.informatik.tu-darmstadt.de>
- Date: Wed, 23 Jun 1999 18:32:26 +0200 (MET DST)
- cc: John Hackworth <zooko@wildgoose.tandu.com>
- Sender: owner-cypherpunks@toad.com
/*
author - Mark Zinthefer, zinthefe@uiuc.edu
title - olaf.C
c++
Symetric block encryption algorithm
64 bit block size
128 bit key (entered as 4 32-bit unsigned integers)
Feistel network
compiles with CC at a unix prompt
*/
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
struct olaf{
unsigned Sbox[4][765],
keys[48],
left,
right;
};
///left bitwise rotation by c bits///
unsigned ROTL32(unsigned, short);
unsigned ROTL32(unsigned x, short c){
return (((x)<<(c))|((x)>>(32-(c))));
}
void menu(); //outputs menu
void gs_keys(olaf *); //get, set, check keys
void sc_Sbox(olaf *); //set, check Sboxes
void pad_file(fstream &, fstream &); //pads the _from_ file
void unpad_file(fstream &, fstream &); //removes padding
void olaf_encr(olaf *, unsigned *, unsigned *); //encrypt
void olaf_decr(olaf *, unsigned *, unsigned *); //decrypt
unsigned to_unsign(char *, char *, char *, char *); //turns 4 chars into 32 bit unsigned
unsigned F(olaf *, unsigned *, unsigned *); //the round function
void menu(){
cout<<"############################################"<<endl;
cout<<"Enter 1 to encrypt, 2 to decrypt, 3 to exit."<<endl;
cout<<"############################################"<<endl;
}
void gs_keys(olaf *o){
unsigned //the keys. 32 bit unsigned ints.
key1,
key2,
key3,
key4;
short shifter = 0;
cout<<"Enter first key:"<<endl; //prompt
cin>>key1;
cout<<"Enter second key:"<<endl;
cin>>key2;
cout<<"Enter third key:"<<endl;
cin>>key3;
cout<<"Enter fourth key:"<<endl;
cin>>key4;
// setting key array based on input keys
for (char i = 0; i < 48; i+=6){
o->keys[i] = ROTL32( key1, shifter) ^ key2;
o->keys[i+1] = ROTL32( key1, shifter) ^ key3;
o->keys[i+2] = ROTL32( key1, shifter) ^ key4;
o->keys[i+3] = ROTL32( key2, shifter) ^ key3;
o->keys[i+4] = ROTL32( key2, shifter) ^ key4;
o->keys[i+5] = ROTL32( key3, shifter) ^ key4;
shifter++;
}
//checking and fixing redundant key array entries
for (short j = 0; j < 48; j++){
char flag = 1;
while (flag > 0)
for (char k = 0; k < 48; k++){
if ((o->keys[j])==(o->keys[k]))
flag++;
if (flag > 2){
(o->keys[j])=
((key1^key2^key3^key4)+1+(o->keys[j]))%4294967291;
k=0;
flag=1;
}
else if(k==47 && flag==2)
flag = 0;
}
}
}
void sc_Sbox(olaf *o){
unsigned
set1 = o->keys[0], //the seeds of the sboxes are the first 4 entries of
set2 = o->keys[1], //the keys array.
set3 = o->keys[2],
set4 = o->keys[3];
/*
The S-boxes are completely key dependent. They are generated
in the followong loop. Like with the keys, i'm going to make
them more math sound later.
*/
for (short y = 0; y < 256; y++)
for (short x = 0; x < 4; x++){
o->Sbox[x][y] = (set1 & set2) | (set3 & set4);
set1 = set2;
set2 = set3;
set3 = set4;
set4 = (o->Sbox[x][y] + set4) % 4294967296;
}
cout<<"Fixing s-boxes..."<<endl;
///fixing Sboxes///
/*
Here I check to see if there are any duplicate entries in any of
the S-boxes. After the loops are done, all entries should be unique
You don't have to bother with a close look at this as
long as you agree that the S-boxes will be the same for encr and decr
so long as the key is the same.
*/
for (char i = 0; i < 4; i++)
for (short j = 0; j < 256; j++){
char flag = 1;
while (flag > 0)
for (char k = 0; k < 4; k++)
for (short l = 0; l < 256; l++){
if (o->Sbox[i][j]==o->Sbox[k][l])
flag++;
if (flag > 2){
o->Sbox[i][j]=
((o->keys[0]^
o->keys[1]^
o->keys[2]^
o->keys[3])
+1
+o->Sbox[i][j])
%4294967291;
k=l=0;
flag=1;
}
else if(k==3 && l==255 && flag==2)
flag = 0;
}
}
cout<<"s-boxes set."<<endl;
}
//Any suggestions???
void pad_file(fstream &to, fstream &from){
}
void unpad_file(fstream &to, fstream &from){
}
void olaf_encr(olaf *o, unsigned *XL, unsigned *XR){
// similar to GOST's gostcrypt(...)
// for 48 rounds, do the Feistel network swapping sides rather than names,
// use keys[] 0 to 47
for (char i = 0; i < 48; i+=2){
*XL ^= F(o, XR, &(o->keys[i])); *XR ^= F(o, XL, &(o->keys[i+1]));
}
// set the olaf struct's values left and right to XL and XR
o->left = *XL;
o->right = *XR;
}
void olaf_decr(olaf *o, unsigned *XL, unsigned *XR){
// basicaly the same as the encr function but with key order reversed
// and left and right sides flipped
for (char i = 47; i > 0; i-=2){
*XR ^= F(o, XL, &(o->keys[i])); *XL ^= F(o, XR, &(o->keys[i-1]));
}
o->left = *XL;
o->right = *XR;
}
unsigned to_unsign(char *a, char *b, char *c, char *d){
unsigned num = (*a + (*b)*256 + (*c)*65536 + (*d)*16777216);
return num;
}
unsigned F(olaf *o, unsigned *x, unsigned *k){
//almost a clone of Schneier's Blowfish function
short a, b, c, d;
d = *x & 255;
*x >>= 8;
c = *x & 255;
*x >>= 8;
b = *x & 255;
*x >>= 8;
a = *x & 255;
// x = ((Sbox[0][a+b+c]*Sbox[1][a+c+d]%4294967391) ^ Sbox[2][a+b+d]) + Sbox[3][b+c+d];
*x = (o->Sbox[0][a+b+c] * o->Sbox[1][a+c+d]) % 4294967291;
*x ^= o->Sbox[2][a+b+d];
*x += o->Sbox[3][b+c+d];
*x^=*k;
*x = ROTL32(*x, 11);
return *x;
}
main(){
olaf o;
short choice = 0;
char
block[8], //block
fn[20], //file name
ch, //generic char value for use throughout program
IV[8]; //IV
fstream from;
fstream to;
do{
menu();
cin>>choice;
if(choice == 1 || choice == 2){
gs_keys(&o);
cout<<"Enter 8 character pass:"<<endl;
cin>>IV;
cout<<"Enter file to be processed:"<<endl;
cin>>fn;
cout<<"Please wait..."<<endl;
sc_Sbox(&o);
}
switch(choice){
case 1:{
///open files///
to.open( "dead.letter", ios::out); from.open( fn, ios::in);
if(!from) {cout<<"file not there."<<endl;break;}
///get file length///
from.seekg(0 , ios::end);
long length = from.tellg();
from.seekg(0);
char padd = (8 - length%8);
for (char pad = 0; pad < padd; pad++)
to.put(padd);
///padding file///
for (int put = 0; put < length; put++){
ch = from.get();
to.put(ch);
}
from.close();
to.close();
from.open("dead.letter", ios::in);
to.open(fn, ios::out);
for (int bloc = 0; bloc < length + padd ; bloc += 8){
//reads 8 chars and fills the block register with them
for(char i = 0; i < 8; i++)
block[i]=from.get();
//commented out to make it ECB for the time being
// for(char q = 0; q < 8; q++)
// block[q]^=IV[q];
unsigned
xl=to_unsign(&block[0], &block[1], &block[2], &block[3]),
xr=to_unsign(&block[4], &block[5], &block[6], &block[7]);
olaf_encr(&o,
&xl, //left side
&xr); //right side
//makes the block come from olaf struct//
block[0] = o.left % 256;
block[1] = (o.left / 256) % 256;
block[2] = (o.left / 65536) % 256;
block[3] = o.left / 16777216;
block[4] = o.right % 256;
block[5] = (o.right/ 256) % 256;
block[6] = (o.right/ 65536) % 256;
block[7] = o.right / 16777216;
//commented out CBC loop
// for (char n = 0; n < 8; n++)
// IV[n]=block[n];
//putting the block into target file
for (char m = 0; m < 8; m++)
to.put(block[m]);
}
//after the file is encrypted close files
from.close();
to.close();
// here i clear the contents of dead.letter
// to.open( "dead.letter", ios::out);
// to.close();
break;
}
case 2:{
to.open( "dead.letter", ios::out);from.open( fn, ios::in);
if(!from)
{cout<<"file not there."<<endl; break;}
///get file length///
from.seekg(0 , ios::end);
long length = from.tellg();
from.seekg(0);
char nextIV[8];
for (int bloc = 0; bloc < length ; bloc += 8){
for(char i = 0; i < 8; i++)
block[i]=from.get();
//commented out to make it ECB
// for (char n = 0; n < 8; n++)
// nextIV[n]=block[n];
unsigned
xl=to_unsign(&block[0], &block[1], &block[2], &block[3]),
xr=to_unsign(&block[4], &block[5], &block[6], &block[7]);
olaf_decr(&o,
&xl, //left side
&xr); //right side
//make this come from olaf struct//
block[0] = o.left % 256;
block[1] = (o.left / 256) % 256;
block[2] = (o.left / 65536) % 256;
block[3] = o.left / 16777216;
block[4] = o.right % 256;
block[5] = (o.right/ 256) % 256;
block[6] = (o.right/ 65536) % 256;
block[7] = o.right / 16777216;
// old IV loops
// for(char q = 0; q < 8; q++)
// block[q]^=IV[q];
// for (char r = 0; r < 8; r++)
// IV[r]=nextIV[r];
for (char m = 0; m < 8; m++)
to.put(block[m]);
}
from.close();
to.close();
//The decrypted file is unpadded here by reading the first char
//and replacing the origional file with the decryption in dead.letter
from.open("dead.letter", ios::in);
to.open(fn, ios::out);
char depadd = from.get();
from.seekg(depadd);
for (int putback = 0; putback < length-depadd; putback++){
ch = from.get();
to.put(ch);
}
from.close();
to.close();
// to.open( "dead.letter", ios::out);
// to.close();
break;
}
case 3:{
for (char i = 0; i < 35; i++)
cout<<endl;
cout<<"Program terminated"<<endl<<endl;
return 0;
}
default:
cout<<"Invalid option."<<endl;
break;
}
}
while(choice!=3);
}