5017 Game Cryptography

11/27/2014 21:51 Super Aids#1
I seem to have an issue with my cryptography and I simply can't spot it. Been double checking and tried different implementations from different sources, but it just doesn't do it right.
Code:
module game.crypto.gamecrypto;

import network.packet;
private class CryptoData : DataPacket {
	this() {
		super();
	}
}


private class CryptoCounter {
	ushort m_counter = 0;
	@property {
		ubyte key1() {
			return cast(ubyte)(m_counter & 0xFF);
		}
		
		ubyte key2() {
			return cast(ubyte)(m_counter >> 8);
		}
	}
	
	void increment() {
		m_counter++;
	}
	
	void reset() {
		m_counter = 0;
	}
}
class GameCrypto {
private:
	enum keySize = 256;
	CryptoCounter m_encryptCounter, m_decryptCounter;
    ubyte[] crypt1;
	ubyte[] crypt2;
	ubyte[] crypt3;
	ubyte[] crypt4;
    bool m_alternate;
public:
	this() {
		m_alternate = false;
		
		m_encryptCounter = new CryptoCounter;
        m_decryptCounter = new CryptoCounter;

		crypt1 = new ubyte[256];
        crypt2 = new ubyte[256];
        ubyte i_key1 = 157;
        ubyte i_key2 = 98;
        foreach (i; 0 .. 256)
        {
            crypt1[i] = i_key1;
            crypt2[i] = i_key2;
            i_key1 = cast(ubyte)((0xF + cast(ubyte)(i_key1 * 0xFA)) * i_key1 + 0x13);
            i_key2 = cast(ubyte)((0x79 - cast(ubyte)(i_key2 * 0x5C)) * i_key2 + 0x6D);
        }
	}
	
	ubyte[] encrypt(ubyte[] inBuffer) {
		synchronized {
			ubyte[] buffer = inBuffer.dup;
			foreach (i; 0 .. buffer.length) {
				buffer[i] ^= 0xAB;
				buffer[i] = cast(ubyte)(buffer[i] >> 4 | buffer[i] << 4);
				buffer[i] ^= cast(ubyte)(crypt1[m_encryptCounter.key1] ^ crypt2[m_encryptCounter.key2]);
				m_encryptCounter.increment();
			}
			return buffer;
		}
	}
	
	ubyte[] decrypt(ubyte[] inBuffer) {
		synchronized {
			ubyte[] buffer = inBuffer.dup;
			if (!m_alternate) {
				foreach (i; 0 .. buffer.length) {
					buffer[i] ^= 0xAB;
					buffer[i] = cast(ubyte)(buffer[i] >> 4 | buffer[i] << 4);
					buffer[i] ^= cast(ubyte)(crypt2[m_decryptCounter.key2] ^ crypt1[m_decryptCounter.key1]);
					m_decryptCounter.increment();
				}
			}
			else {
				foreach (i; 0 .. buffer.length) {
					buffer[i] ^= 0xAB;
					buffer[i] = cast(ubyte)(buffer[i] >> 4 | buffer[i] << 4);
					buffer[i] ^= cast(ubyte)(crypt4[m_decryptCounter.key2] ^ crypt3[m_decryptCounter.key1]);
					m_decryptCounter.increment();
				}
			}
			return buffer;
		}
	}
	
	void setKeys(uint accountId, uint token)
    {
        synchronized {
			uint tmpkey1 = cast(uint)((((token) + accountId) ^ 0x4321) ^ (token));
			uint tmpkey2 = cast(uint)(tmpkey1 * tmpkey1);
			crypt3 = new ubyte[0x100];
			crypt4 = new ubyte[0x100];
		
			auto temp = new CryptoData;
			temp.write!uint(tmpkey1);
			ubyte[] tmp1 = temp.pBuffer;
		
			temp = new CryptoData;
			temp.write!uint(tmpkey2);
			ubyte[] tmp2 = temp.pBuffer;
		
			foreach (i; 0 .. 256)
			{
				crypt3[i] = cast(ubyte)(crypt1[i] ^ tmp1[i % 4]);
				crypt4[i] = cast(ubyte)(crypt2[i] ^ tmp2[i % 4]);
			}
			m_alternate = true;
		}
    }
}
#Edit
I don't know what the hell I did, but it works now.