How can you inexpensively two-way encrypt a 32 bit int, such that every number maps to some other int in that space and back in a way that's difficult to predict?
And doesn't require pre-storing 4.29 billion ints in a mapping table, of course.
How can you inexpensively two-way encrypt a 32 bit int, such that every number maps to some other int in that space and back in a way that's difficult to predict?
And doesn't require pre-storing 4.29 billion ints in a mapping table, of course.
Obviously, you need some kind of random key for it to be secure. In that case:
int original = 42;
int key = give_me_a_random_int();
int encrypted = original ^ key;
int unencrypted = encrypted ^ key;
// now, unencrypted == original == 42
This is just a simple XOR. XORing again will reverse this process.
Also, I should note that this is only secure for one use. It's called the One time pad. If you use the same key twice on non-random data, it may be possible for an attacker to decipher it.
One way is to XOR with a secret 32 bit number. When you XOR with this secret number again, it will return to the original number. This is quick but not very secure. If a secure method is needed, i'd be interested in seeing other methods here too.
I used to use XOR + ADD with a 64 bit secret key. I also used to change the key every couple of minutes and trying to decrypt with current or previous key. (In my domain the integer didn't need to be secure for more than about four minutes.)
There are two simple and reversible operations that you can use to scramble an integer value. You can use the xor operation, and you can swap bits in the number.
If you use both, then it won't be that trivial to figure out the method used. They will somewhat protect each other.
If all you want is something real simple that the average user wont notice then use a series of XOR and shift operators.
The problem with not using an array to store the 4 billion or so INTs is that you need a function that does a one to one random map across a domain of 4 billion INTs. You can mix a number of XOR and shift operators to create your own but it wont be hard to crack. Even if there was a well known one to one map it would also fail. Without a salt someone could just generate a simple rainbow table to break it.
The problem with a salt in two way communication is that you have to securely communicate it. Salts have to be secret and once you know what they are they are pointless.
If your looking to setup a secure channel of communication take a look at Off-the-Record Messaging Protocol version 2. It will give you an example of how complex communication encryption can become. I'd suggest you find something well known that someone else has already created and tested. Even if you do use something someone else has created if you use it incorrectly it will fail.
What you want is a 32-bit block cipher. Unfortunately, most block ciphers are 64-bits or more due to the weaknesses of a short block size. If you can handle the encrypted int being twice as large as the input, then you can just use Blowfish, TDES, or some other nicely vetted 64-bit block cipher.
If you really need 32 bits and don't mind the decreased security then its easy enough to trim a Feistel network cipher like Blowfish down to any block length that's a multiple of 2 and less than the starting cipher. For Blowfish, just split your input number evenly between the two half blocks, and trim the output of the F function and the P-values down to 1/2 your target block size. This can all be done after keying the algorithm as usual.
Use a standard algorithm and a random pad (assuming the ciphertext doesn't need be the same length as the plane text).
So basically, use a standard algo that uses chaining and plug four random 32-bit numbers in front of it. That should help to disguise any regularities/redundancy in your 32-bit message. Hell, pad at the end too, if it pleases you.
Basically, the less you write, the better off you are. Everyone screws this stuff up.
Take your 32 bit input, cut it into two 16 bit halves L and R, then repeat the following steps: compute a pseudorandom function of R, xor the result of this pseudorandom function to L and swap L and R. This is a Luby-Rackoff construction. The pseudorandom function does not need to be invertible. So you could for example take a block cipher, encrypt 16-bits and cut the result to 16 bit. Make sure that not all rounds use the same pseudorandom function (rsp. use different round keys).
Use a 32-bit block cipher, skip32 is the only one that I found: http://www.qualcomm.com.au/PublicationsDocs/skip32.c