Thursday, April 3, 2008

Simple Encryption methods

We all like to be sneaky every now and then, there is information we don't want anyone to read, or just someone who we trust. But as we all know, just talking around is insecure, using a public medium to transfer information will be viewable to anyone that has the knowledge to get it. So we employ encryption. For encryption we need to have something in mind all the time. The data we encrypt we need to decrypt later, so we need to use methods that won't end up in data being lost and we need to use methods we can remember later. Thanks to computers we can use more complex methods to encrypt our data, and let them remember how to decrypt it.
Most of the time all we have to do is reverse the process, so let me explain some computer level encryptions. And since everything is binary in computers most encryption can be done in the bitwise level.
I believe one of the most common processes used on basic encryptions is masking. Masking consists of using the bitwise operator XOR or ^ in order to "mask" a sequence of bits. XOR is the same as the logic exclusive or in logic, its truth table is
A|B|A^B
1|1|0
1|0|1
0|1|1
0|0|0
this sounds weird to be used as encryption but lets see what happens with larger numbers. Lets say we have this 10110101 and we want to encrypt it with the "mask" 10101010 (notice that both the code and the mask have the same amount of bits"
10110101
10101010 ^
00011111
the result is 00011111 now thats nothing like the mask or the original thing. The good thing about masking is that if we take the new object and mask it with the same mask...
00011111
10101010^
10110101 we get the original number. This way you can mask with different numbers each letters and only if someone knows the mask then they can decrypt it.
Another good operation is inverse, its not a very strong encryption since it only does one thing, but in combination with other encryptions it can become slightly powerful. Lets say we use what we got in the last encryption 00011111 and we decide to inverse it
~00011111 = 11100000
now if someone whanted to decrypt it, they had to inverse it first and mask it later.
since when you ~11100000 you get 11100000.

now getting deeper in the code lets use another kind of encryption. Rotation.

#define ROR(x, n) ((x>>n)|(x<<8*sizeof(x)-n))
#define ROL(x, n) ((x<<n)|(x>>8*sizeof(x)-n))
this two functions might be useful in encryption and are used in several encryptions. they rotate the bits to one side or the other.
lets go in depth with it lets say we have 11100000 and we rotate it twice to the left (the ROL function)
so first er have 11100000 << 2 and we get 10000000 then the other side of the function gets that the sizeof this is 1 byte (8 bits) so
11100000 >> 6 so we get 00000011
then we or this two values and we get 10000011
if we use ROR and rotate it to the right twice we get 11100000

so now we have 10000011 a number very different from 10110101 but if we trace back all our steps we will get that number. only you know what steps you took and what masks you used.

I guess I have time to explain one last function. Reverse. The reverse function is used to reverse the numbers for example 10000011 would turn 11000001 this function isn't very strong since it can only return one value of each letter but just like inverse it can be mixed. A good way to use this is to use a character table for speed.
static char REVtable[256] ={ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff };
using this table that is written in hex numbers you can quickly return the reverce of any character.

NOW well enough of binary lets look at some code. and mask one letter
unsigned char I = 'A';

printf("Original: %c\n",I);
I = REV(I);
printf("Reversed: %c\n",I);
I = ~I;
printf("Inverted: %c\n",I);
I = I ^ 'B';
printf("Masked: %c\n",I);
I = ROR(I,2);
printf("Rotated: %c\n Start Decoding:\n",I);
I = ROL(I,2);
printf("Rotated back: %c\n",I);
I = I ^ 'B';
printf("Masked: %c\n",I);
I = ~I;
printf("Inversed: %c\n",I);
I = REV(I);
printf("Reversed: %c\n",I);
this returns the following.
Original: A
Reversed: é
Inverted: }
Masked: ?
Rotated: ╧
Start Decoding:
Rotated back: ?
Masked: }
Inversed: é
Reversed: A

you could run this kind of processes in each letter of a sentence, make sure to remember the masks and the amount of rotation used in each letter. With a good ammount of combinations your encryption will be really hard to decode.

No comments: