#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "xlogin.h"
#include "key.h"

// This table is 64 bytes long and each byte is unique. Its derrived from the user KEY, this is the only active
// key as far as the code is concerned. The user key XLOGINKEY <=64 Bytes is repeatadly copied into the 
// non repeating table, then this function makes this 64 byte table non repeating in value (no duplicates).
// Its important that this table is non repeating as the values are used as the offsets into the final data structure
// so any repeats would result in overwritten data. 
unsigned char nonrepeatingtable[64];					
nonrepeating_table()
{
	// Copy key in over and over again
	int x;
	int y=0;
        for (x=0;x<64;x++)
        {
                nonrepeatingtable[x]=XLOGINKEY[y];
                y++;
                if (y>=strlen(XLOGINKEY))
                        y=0;
        }

	// Make non repeating.  For each element of the array in turn compare it to the elements to all other elements. When
	// a duplicate is found add one to the unsigned duplicate value.
	unsigned short int element;
	int founddup=TRUE;								// Assume we have duplicates
	int goneround=0;

	while (founddup==TRUE)
	{
		founddup=FALSE;								// enter the loop assuming no duplicates exist
		for (x=0;x<64;x++)
		{
			element=nonrepeatingtable[x];					// Get the next element in turn
			{
				for (y=0;y<64;y++)					// For all elements in the array 
				{
					if (y!=x)					// Except for the current element 
					{						// Duplicate found, alter the duplicate
						if ((element==nonrepeatingtable[y])|(element==0))
						{
							nonrepeatingtable[y]=nonrepeatingtable[y]+(x<<3>>3);
							founddup=TRUE;
						}
					}
				}
			}
		}
		goneround++;
	}
}



// ********************************************************************************************************************************
// Pretty weak encryption !  The results look good but is far from non crackable.
weakencrypt(char username[], char password[], char filename[])
{
	FILE *idfile;
	idfile=fopen(filename,"w");
	if (idfile==NULL)
	{
		printf("Opening file %s FAILED\n",filename);
		exit(1);
	}

	srand(time(NULL));								// Seed random number generator
	int x;
	char buffer[FILESIZE];
	for (x=0;x<FILESIZE;x++)
	{
		buffer[x]=rand();							// 8k of partially overlapping crap
		//buffer[x]='_';							// For testing only
	}
	nonrepeating_table();


	// Hide the username in the lower Nk bytes of data
	int offset;
	for (x=0;x<=strlen(username);x++)
	{
		offset=nonrepeatingtable[x];						// Extract an unsigned digit, positive 8 bit value
		offset=offset*16;							// Spread it out into half of the 8k
		buffer[offset]=~username[x];						// Invert the bits as well with ~
	}

	// Hide the password in the upper Nk bytes of data
	for (x=0;x<=strlen(password);x++)
	{
		offset=nonrepeatingtable[x];
		offset=offset*16;							// Spread it out into upper half 
		buffer[offset+(FILESIZE/2)]=~password[x];
	}

	fwrite(&buffer,1,FILESIZE,idfile);
	fclose(idfile);
}





// ********************************************************************************************************************************
// Pretty weak decryption
weakdecrypt(char username[], char password[], char filename[])
{
	FILE *idfile;
	idfile=fopen(filename,"r");
	if (idfile==NULL)
	{
		printf("Opening file %s FAILED\n",filename);
		exit(1);
	}


	int x;
	char buffer[FILESIZE];
	fread(&buffer,1,FILESIZE,idfile);
	fclose(idfile);

	nonrepeating_table();

	// Extract Username
	username[0]='\0';
	int offset;
	for (x=0;x<128;x++)
	{
		offset=nonrepeatingtable[x];						// Extract an unsigned digit, positive 8 bit value
		offset=offset*16;							// Spread it out into half of the 8k
		username[x]=~buffer[offset];						// Invert the bits as well with ~
	}

	password[0]='\0';
	for (x=0;x<128;x++)
	{
		offset=nonrepeatingtable[x];
		offset=offset*16;							// Spread it out into upper half 
		password[x]=~buffer[offset+(FILESIZE/2)];
	}
}

