/*
 *	Keys Class
 *	By Jeremy Lennert
 *	March 10, 2001
 *	v. 1.0.2
 *
 *	Keys.cpp
 *
 *	Defines the methods for the class defined in Keys.h.
 */

#include "Keys.h"

Keys::Keys(int t)
{
	type = (keytype)t;
	/*
	 *	Initialize unused key values to zero:
	 */
	ckey = 0;
	for (int x = 0; x < 256; x++) skey[x] = 0;
}

Keys::Keys(int t, unsigned char c)
{
	type = (keytype)t;
	ckey = c;

	/*
	 *	Initialize unused key values to zero:
	 */
	for (int x = 0; x < 256; x++) skey[x] = 0;
}

Keys::Keys(int t, const unsigned char *s)
{
	type = (keytype)t;
	for (int x = 0; x < 256; x++)
	{
		skey[x] = s[x];
	}
	
	/*
	 *	Initialize unused key values to zero:
	 */
	ckey = 0;
}

Keys::Keys(Keys *k)
{
	int x;	// Loop variable

	type = k->Type();
	switch(type)
	{
	case KEYTYPE_XOR:
	case KEYTYPE_SHIFT:
		ckey = k->Ckey();
		/*
		 *	Initialize unused key values to zero:
		 */
		for (x = 0; x < 256; x++) skey[x] = 0;
		break;
	case KEYTYPE_SUBST:
		for (x = 0; x < 256; x++)
		{
			skey[x] = k->Skey()[x];
		}
		/*
		 *	Initialize unused key values to zero:
		 */
		ckey = 0;
		break;
	default:
		ckey = k->Ckey();
		for (x = 0; x < 256; x++)
		{
			skey[x] = k->Skey()[x];
		}
		break;
	}
}

keytype Keys::Type()
{
	return type;
}

int Keys::Ckey()
{
	if ( (type == 1) || (type == 2) ) return ckey;
	else return -1;
}

const unsigned char* Keys::Skey()
{
	return skey;
}

void Keys::decrypt(unsigned char *ciphertext)
{
	int x;
	switch(type)
	{
	case KEYTYPE_XOR:
		for (x = 0; ciphertext[x] != '\0'; x++)
		{
			if ((ciphertext[x] ^ ckey) != '\0') ciphertext[x] ^= ckey;
		}
		break;
	case KEYTYPE_SHIFT:
		int y;
		for (x = 0; ciphertext[x] != '\0'; x++)
		{
			y = (int)ciphertext[x] - (int)ckey;
			if (y < 0) y += 256;
			if (y != '\0') ciphertext[x] = y;
		}
		break;
	case KEYTYPE_SUBST:
		for (x = 0; ciphertext[x] != '\0'; x++)
		{
			if (skey[ciphertext[x]] != '\0') ciphertext[x] = skey[ciphertext[x]];
		}
		break;
	}
}

Keys::~Keys()	// The destructor doesn't need to do anything
{
}