//
// File: cipher.h
// Sylvain Huet
// Created: 02/07/2001
//

#ifndef _CIPHER_H_
#define _CIPHER_H_

#include "scolPrerequisites.h"

//$BLG - v5.22: Modif (Moved all code from .cpp file)
//int getint(char *buf);
//int uncipher(char *buf, int size);
// fonction basique lisant un entier à partir de 4 octets (indépendant de little ou big endian)
int getint(char *buf)
{
	return (buf[0]&255) + ((buf[1]&255)<<8) + ((buf[2]&255)<<16) + ((buf[3]&255)<<24);
}


// fonction basique écrivant un entier à partir de 4 octets (indépendant de little ou big endian)
int storeint(char *buf, int x)
{
	buf[0] = x;
	x >>= 8;
	buf[1] = x;
	x >>= 8;
	buf[2] = x;
	x >>= 8;
	buf[3] = x;
	return 0;
}


void decipher(int v0, int v1, int *k, int *w0, int *w1)
{
  int y = v0, z = v1, sum = 0xC6EF3720, delta = 0x9E3779B9, n = 32;

   // sum = delta<<5, in general sum = delta * n 

  while(n-- > 0)
  {
		z -= (y<<4 ^ y>>5) + y ^ sum + k[sum>>11 & 3];
	  sum -= delta;
		y -= (z<<4 ^ z>>5) + z ^ sum + k[sum&3];
  }
   
	*w0 = y; *w1 = z;
}


// decodage d'un fichier
int uncipher(char *buf,int size)
{
	int l;
	int i;
	int k[4];
	int v0, v1, w0, w1;

	int header = 4;

	l = size-header;

	buf[0] = buf[1] = buf[2] = buf[3] = ' ';	// on écrase le header par des espaces

	buf += 4;

//$ LB (03/06/2002) : specific key for clubhouse server
#ifdef CLUBHOUSE_SERVER
	k[0] = 0xF067;	// initialisation de la clef
	k[1] = 0xE189;
	k[2] = 0xD245;
	k[3] = 0xCB63;
#else
	k[0] = 0x1234;	// initialisation de la clef
	k[1] = 0x5678;
	k[2] = 0x9abc;
	k[3] = 0xdef0;
#endif

	for(i = 0; i < l; i += 8)
	{
		v0 = getint(buf);		// lecture de la source (64 bits)
		v1 = getint(buf+4);
		decipher(v0, v1, k, &w0, &w1);	// decryptage
		storeint(buf, w0);	// écriture du résultat
		storeint(buf+4, w1);
		k[0] = w0;	// mise à jour de la moitié de la clef avec la valeur après décryptage
		k[1] = w1;
		buf += 8;
	}

	return 0;
}

#endif // cipher.h
