| Author | Message | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Sun Aug 22, 2004 7:50 am     Post subject: Port of twCore encryption to C++ |  |   |  |  
				| 
 |  
				| I finally got my encryption by porting the encryption of twCore to C++ and in the spirit of open source I now return it: 	|             Uint32 encClientKey,encServerKey;
Uint8 encKeyStream[520];
 bool encryptionEnabled;
 
 
 void InitEncryption(){
 Uint32 oldSeed,tempSeed=encServerKey;
 Uint16 res;
 for(int i=0;i<520;i+=sizeof(res)){
 oldSeed=tempSeed;
 tempSeed=((oldSeed * 0x834E0B5F) >> 48) & 0xffffffff;
 tempSeed=((tempSeed + (tempSeed >> 31)) & 0xffffffff);
 tempSeed=((((oldSeed % 0x1F31D) * 16807) - (tempSeed * 2836) + 123) & 0xffffffff);
 if(tempSeed > 0x7fffffff)
 tempSeed=((tempSeed + 0x7fffffff) & 0xffffffff);
 res=(Uint16)(tempSeed & 0xffff);
 memcpy(encKeyStream+i,&res,sizeof(res));
 }
 
 encryptionEnabled=true;
 }
 
 void SwitchEndianness(void *ptr,int size){
 for(int i=0;i<size/2;i++){
 ((char*)ptr)[i]^=((char*)ptr)[size-1-i];
 ((char*)ptr)[size-1-i]^=((char*)ptr)[i];
 ((char*)ptr)[i]^=((char*)ptr)[size-1-i];
 }
 }
 
 void Encrypt(char *packet,int size){
 if(!encryptionEnabled)
 return;
 
 char *data=packet+1;
 int len=size-1;
 if(!packet[0]){
 data++;
 len++;
 }
 
 Uint32 dataInt,streamInt,tempKey=encServerKey,resInt;
 int count=len + (sizeof(tempKey) - len%sizeof(tempKey));
 
 for(int i=0;i<count;i+=sizeof(tempKey)){
 memcpy(&dataInt,data+i,sizeof(dataInt));
 SwitchEndianness(&dataInt,sizeof(dataInt));
 memcpy(&streamInt,encKeyStream+i,sizeof(streamInt));
 SwitchEndianness(&streamInt,sizeof(streamInt));
 
 resInt=dataInt ^ streamInt ^ tempKey;
 
 tempKey=resInt;
 SwitchEndianness(&resInt,sizeof(resInt));
 memcpy(data+i,&resInt,sizeof(resInt));
 }
 }
 
 void CSSConnection::Decrypt(char *packet,int size){
 if(!encryptionEnabled)
 return;
 
 char *data=packet+1;
 int len=size-1;
 if(!packet[0]){
 data++;
 len++;
 }
 
 Uint32 dataInt,streamInt,tempKey=encServerKey,resInt;
 int count=len + (sizeof(tempKey) - len%sizeof(tempKey));
 
 for(int i=0;i<count;i+=sizeof(tempKey)){
 memcpy(&dataInt,data+i,sizeof(dataInt));
 SwitchEndianness(&dataInt,sizeof(dataInt));
 memcpy(&streamInt,encKeyStream+i,sizeof(streamInt));
 SwitchEndianness(&streamInt,sizeof(streamInt));
 
 resInt=streamInt ^ tempKey ^ dataInt;
 
 tempKey=dataInt;
 SwitchEndianness(&resInt,sizeof(resInt));
 memcpy(data+i,&resInt,sizeof(resInt));
 }
 }
 | 
 _________________
 some ship
 AngryAnt
 http://angryant.com
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Cyan~Fire I'll count you!
 
  
 
 Age:37
 Gender:
  Joined: Jul 14 2003
 Posts: 4608
 Location: A Dream
 Offline
 
 | 
			
			  | 
				
					|  Posted: Sun Aug 22, 2004 11:43 am     Post subject: |  |   |  |  
				| 
 |  
				| Talk about hard-to-read code...  _________________
 This help is informational only. No representation is made or warranty given as to its content. User assumes all risk of use. Cyan~Fire assumes no responsibility for any loss or delay resulting from such use.
 Wise men STILL seek Him.
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Solo Ace Yeah, I'm in touch with reality...we correspond from time to time.
 
  
 Age:38
 Gender:
  Joined: Feb 06 2004
 Posts: 2583
 Location: The Netherlands
 Offline
 
 | 
			
			  | 
				
					|  Posted: Sun Aug 22, 2004 11:59 am     Post subject: |  |   |  |  
				| 
 |  
				| Restyled.   
 
 	| Uint32 encClientKey, encServerKey; 
Uint8 encKeyStream[520];
 bool encryptionEnabled;
 
 void InitEncryption()
 {
 Uint32 oldSeed, tempSeed = encServerKey;
 Uint16 res;
 
 for (int i = 0;i < 520;i += sizeof(res))
 {
 oldSeed = tempSeed;
 
 tempSeed = ((oldSeed * 0x834E0B5F) >> 48) & 0xffffffff;
 tempSeed = ((tempSeed + (tempSeed >> 31)) & 0xffffffff);
 tempSeed = ((((oldSeed % 0x1F31D) * 16807) - (tempSeed * 2836) + 123) & 0xffffffff);
 
 if(tempSeed > 0x7fffffff)
 tempSeed = ((tempSeed + 0x7fffffff) & 0xffffffff);
 
 res = (Uint16) (tempSeed & 0xffff);
 memcpy(encKeyStream + i, &res, sizeof(res));
 }
 
 encryptionEnabled = true;
 }
 
 void SwitchEndianness(void *ptr, int size)
 {
 for(int i = 0;i < size / 2;i++)
 {
 ((char *) ptr)[i] ^= ((char *) ptr) [size - 1 - i];
 ((char *) ptr)[size - 1 - i] ^= ((char *) ptr)[i];
 ((char *) ptr)[i] ^= ((char *) ptr) [size - 1 - i];
 }
 }
 
 void Encrypt(char *packet, int size)
 {
 if (!encryptionEnabled)
 return;
 
 char *data = packet + 1;
 int len = size - 1;
 
 if(!packet[0])
 {
 data++;
 len++;
 }
 
 Uint32 dataInt, streamInt, tempKey = encServerKey, resInt;
 
 int count = len + (sizeof(tempKey) - len % sizeof(tempKey));
 
 for(int i = 0;i < count;i += sizeof(tempKey))
 {
 memcpy(&dataInt, data + i, sizeof(dataInt));
 SwitchEndianness(&dataInt, sizeof(dataInt));
 
 memcpy(&streamInt, encKeyStream + i, sizeof(streamInt));
 SwitchEndianness(&streamInt, sizeof(streamInt));
 
 resInt = dataInt ^ streamInt ^ tempKey;
 
 tempKey = resInt;
 SwitchEndianness(&resInt, sizeof(resInt));
 memcpy(data + i, &resInt, sizeof(resInt));
 }
 }
 
 void CSSConnection::Decrypt(char *packet, int size)
 {
 if (!encryptionEnabled)
 return;
 
 char *data = packet + 1;
 int len = size - 1;
 
 if(!packet[0])
 {
 data++;
 len++;
 }
 
 Uint32 dataInt, streamInt, tempKey = encServerKey, resInt;
 int count = len + (sizeof(tempKey) - len % sizeof(tempKey));
 
 for(int i = 0;i < count; i += sizeof(tempKey))
 {
 memcpy(&dataInt, data+i, sizeof(dataInt));
 SwitchEndianness(&dataInt, sizeof(dataInt));
 
 memcpy(&streamInt, encKeyStream + i, sizeof(streamInt));
 SwitchEndianness(&streamInt, sizeof(streamInt));
 
 resInt = streamInt ^ tempKey ^ dataInt;
 tempKey = dataInt;
 
 SwitchEndianness(&resInt, sizeof(resInt));
 memcpy(data + i, &resInt, sizeof(resInt));
 }
 }
 | 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Sun Aug 22, 2004 2:01 pm     Post subject: |  |   |  |  
				| 
 |  
				| Thanks ace - I know my coding style is a bit evil   |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Cyan~Fire I'll count you!
 
  
 
 Age:37
 Gender:
  Joined: Jul 14 2003
 Posts: 4608
 Location: A Dream
 Offline
 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Sun Aug 22, 2004 7:01 pm     Post subject: |  |   |  |  
				| 
 |  
				| Argh! It seems now that it doesnt work after all - I get further when connecting to as3 test server unencrypted than I do encrypted   |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| -Smong- Guest
 
 
 Offline
 
 | 
			
			  | 
				
					|  Posted: Mon Aug 23, 2004 9:06 am     Post subject: |  |   |  |  
				| 
 |  
				| This was originally Java, which does not have any unsigned data types. 	  | Cyan~Fire wrote: |  	  | What the hay is the point of the "& 0xffffffff". Doesn't that ALWAYS give the same result as before? | 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Mon Aug 23, 2004 11:31 am     Post subject: Hmm |  |   |  |  
				| 
 |  
				| Scratch that - Mr. Ekted has tested the ported encryption and found that it works just fine. Strange problem I have then... |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Cyan~Fire I'll count you!
 
  
 
 Age:37
 Gender:
  Joined: Jul 14 2003
 Posts: 4608
 Location: A Dream
 Offline
 
 | 
			
			  | 
				
					|  Posted: Mon Aug 23, 2004 5:36 pm     Post subject: |  |   |  |  
				| 
 |  
				|  	  | Smong wrote: |  	  | This was originally Java, which does not have any unsigned data types. | 
 But how exactly does "& 0xffffffff" emulate unsigned data types?
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| -Smong- Guest
 
 
 Offline
 
 | 
			
			  | 
				
					|  Posted: Mon Aug 23, 2004 7:25 pm     Post subject: |  |   |  |  
				| 
 |  
				| I'm not entirely sure, but I think it is only unsigned while being stored and retrieved, so during a calculation you can sort of change/cast it to some other type that I don't know the name to, hey it works so I'm not bothered. |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Miesco Newbie
 
 
 Joined: Aug 23 2004
 Posts: 24
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 6:08 am     Post subject: |  |   |  |  
				| 
 |  
				|  	  | Quote: |  	  | But how exactly does "& 0xffffffff" emulate unsigned data types? | 
 If you convert 0xffffffff to binary it is:
 11111111111111111111111111111111
 
 If you still do not understand from that, I will explain.
 
 first of all, for a signed byte to be negative it has to go over 127: 10000000 is -128, 01111111 is 127
 
 TO make an unsigned byte you use 9 & 0xFF, 0xFF == 11111111, 9 == 00001001
 
 they are 32 bit integers, so really they are:
 00000000 00000000 00000000 11111111 and
 00000000 00000000 00000000 00001001
 
 the & bit operator makes the value 1 if both of the coresponding operands (9 & 0xFF0) bits are 1, so the result is:
 00000000 00000000 00000000 00001001
 
 same thing, but if you made the left operand above 255 (max number in a unsigned byte), if you made it for example: 256 (256 & 0xFF) then you would have:
 00000000 00000000 00000001 00000000
 00000000 00000000 00000000 11111111
 when you apply the & operator you have a result of:
 00000000 00000000 00000000 00000000
 it goes back to 0, thus it will make sure the left operand is never over 1 byte, which makes it an unsigned byte, same thing applies to making sure it is an unsigned long or quad (64 bit integer)
 
 I hope this helps you understand why you use 0xffffffff
   |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Mr Ekted Movie Geek
 
  
 Gender:
  Joined: Feb 09 2004
 Posts: 1379
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 6:13 am     Post subject: |  |   |  |  
				| 
 |  
				| In C or C++, any 32-bit value bitwise AND'ed with 0xffffffff does not change value or sign since none of the bits are affected by the operation. In fact, the optimizer would simply remove the expression from the resulting code. _________________
 4,691 irradiated haggis!
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Miesco Newbie
 
 
 Joined: Aug 23 2004
 Posts: 24
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 6:20 am     Post subject: |  |   |  |  
				| 
 |  
				| Yes, but it was from the java code |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Cyan~Fire I'll count you!
 
  
 
 Age:37
 Gender:
  Joined: Jul 14 2003
 Posts: 4608
 Location: A Dream
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 6:25 am     Post subject: |  |   |  |  
				| 
 |  
				|  	  | Miesco wrote: |  	  | same thing applies to making sure it is an unsigned long or quad (64 bit integer) | 
 Except that here we're ANDing a 32-bit variable with 32 bits of 1s. I see no point.
 
 
  	  | Miesco wrote: |  	  | I hope this helps you understand why you use 0xffffffff | 
 It doesn't. I can see the uses of ANDs for limiting what numbers can go where, it's called a mask. But I don't see a point in limiting between data-types. If you want something not to go over 255, just make it a char. And, of course, I still don't understand what this has to do with signing/unsigning.
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Miesco Newbie
 
 
 Joined: Aug 23 2004
 Posts: 24
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 6:39 am     Post subject: |  |   |  |  
				| 
 |  
				| Ok I ment 32 bits, err and no it does not change it to unsigned, I am pretty sure of this, I mean how would it?  It is not changing on how the number is stored.  And there is a point for using &, if you make it a char, it is a byte and is not a number, you can not make any calculalations with it, you would have to put it back to an integer, which is more work. |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Miesco Newbie
 
 
 Joined: Aug 23 2004
 Posts: 24
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 7:07 am     Post subject: |  |   |  |  
				| 
 |  
				| emileej: 
 res=(Uint16)(tempSeed & 0xffff);
 memcpy(encKeyStream+i,&res,sizeof(res));
 
 encKeyStream is Uint8, how can you put a 16 bit integer in a 8 bit element?
 
 This is what I did and it works:
 
 sub initialize {
 use bigint;
 my $seed = $_[0];
 my ($tempSeed, $oldSeed);
 $tempSeed = $seed;
 
 # use Math::BigInt;
 # my $seed = Math::BigInt->new($_[0]);
 # my ($tempSeed, $oldSeed);
 # $tempSeed = Math::BigInt->new("$seed");
 
 for ($i = 0; $i < (520 / 2); $i++) {
 $oldSeed = $tempSeed;
 
 $tempSeed = (($oldSeed * 0x834E0B5F) >> 4
  & 0xffffffff; $tempSeed = (($tempSeed + ($tempSeed >> 31)) & 0xffffffff);
 $tempSeed = (((($oldSeed % 0x1F31D) * 16807) - ($tempSeed * 2836) + 123) & 0xffffffff);
 if ($tempSeed > 0x7fffffff ) {
 $tempSeed = (($tempSeed + 0x7fffffff) & 0xffffffff);
 }
 push(@table, ence_short(short($tempSeed & 0xffff)));
 }
 }
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 7:15 am     Post subject: |  |   |  |  
				| 
 |  
				| Because memcpy treats it as a 8bit memory block and its size is given by the sizeof function which returns the size of a type or variable in bytes. 	  | Miesco wrote: |  	  | res=(Uint16)(tempSeed & 0xffff);
 memcpy(encKeyStream+i,&res,sizeof(res));
 
 encKeyStream is Uint8, how can you put a 16 bit integer in a 8 bit element?
 | 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Miesco Newbie
 
 
 Joined: Aug 23 2004
 Posts: 24
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 7:21 am     Post subject: |  |   |  |  
				| 
 |  
				| Why would you treat a short as a byte?  Also you need each element has to be 1 byte, each 16 bit integer you put into it needs to be 2 elements |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 7:24 am     Post subject: |  |   |  |  
				| 
 |  
				| Why I would treat it a s abyte? Well how on earth do you expect me to put it in my byte array if I was not to? And yes ofcourse it needs to be two elements. When I said that sizeof returns the size of a variable or type in bytes then exactly which number do you think it returns when it is fed a 16bit variable?
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Miesco Newbie
 
 
 Joined: Aug 23 2004
 Posts: 24
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 7:52 am     Post subject: |  |   |  |  
				| 
 |  
				| You need to put each 2 bytes from each short into 2 seperate elements |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 8:07 am     Post subject: |  |   |  |  
				| 
 |  
				| I know what you mean: Split each 16 bytes into two 8 bytes elements. 	  | Miesco wrote: |  	  | You need to put each 2 bytes from each short into 2 seperate elements | 
 And you know what? Thats exactly what I'm doing.
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| Miesco Newbie
 
 
 Joined: Aug 23 2004
 Posts: 24
 Offline
 
 | 
			
			  | 
				
					|  Posted: Tue Aug 24, 2004 8:09 am     Post subject: |  |   |  |  
				| 
 |  
				| Ok |  | 
	
		| Back to top |  | 
	
		|  | 
	
		| emileej Newbie
 
 
 Age:40
 Gender:
  Joined: Aug 20 2004
 Posts: 23
 Location: Copenhagen - Denmark
 Offline
 
 | 
			
			  | 
				
					|  Posted: Wed Aug 25, 2004 2:36 am     Post subject: InitEncryption |  |   |  |  
				| 
 |  
				| It seems though that youre partly right - the bug is in fact in the InitEncryption. Take a look at this log of the server key and the resulting keystream. 
 
 
 
  EncryptionDebug.log - 2.57 KB File downloaded or viewed 15 time(s)
 
 |  | 
	
		| Back to top |  | 
	
		|  | 
	
		|  |