views:

272

answers:

7

Is there a simple algorithm to encrypt integers? That is, a function E(i,k) that accepts an n-bit integer and a key (of any type) and produces another, unrelated n-bit integer that, when fed into a second function D(E(i),k) (along with the key) produces the original integer?

Obviously there are some simple reversible operations you can perform, but they all seem to produce clearly related outputs (e.g. consecutive inputs lead to consecutive outputs). Also, of course, there are cryptographically strong standard algorithms, but they don't produce small enough outputs (e.g. 32-bit). I know any 32-bit cryptography can be brute-forced, but I'm not looking for something cryptographically strong, just something that looks random. Theoretically speaking it should be possible; after all, I could just create a dictionary by randomly pairing every integer. But I was hoping for something a little less memory-intensive.

Edit: Thanks for the answers. Simple XOR solutions will not work because similar inputs will produce similar outputs.

+4  A: 

Would not this amount to a Block Cipher of block size = 32 bits ?

Not very popular, because it's easy to break. But theorically feasible. Here is one implementation in Perl : http://search.cpan.org/~esh/Crypt-Skip32-0.15/lib/Crypt/Skip32.pm.

UPDATE: See also Format preserving encryption

UPDATE 2: RC5 supports 32-64-128 bits for its block size

leonbloy
Yes, but I don't know of any block ciphers that operate on such small block sizes.
tloflin
Ah, that Skip32 seems to be what I'm looking for. Is it generalizable to n-bit blocks?
tloflin
FPE is exactly what I was looking for, thanks!
tloflin
No, it doesnt seem generalizable. And it does not seem a trivial problem.
leonbloy
Indeed it does not.
tloflin
A: 

You could take an n-bit hash of your key (assuming it's private) and XOR that hash with the original integer to encrypt, and with the encrypted integer to decrypt.

Probably not cryptographically solid, but depending on your requirements, may be sufficient.

Eric J.
A: 

If you just want to look random and don't care about security, how about just swapping bits around. You could simply reverse the bit string, so the high bit becomes the low bit, second highest, second lowest, etc, or you could do some other random permutation (eg 1 to 4, 2 to 7 3 to 1, etc.

bdk
A: 

A simple one:

rand = new Random(k);
return (i xor rand.Next())

(the point xor-ing with rand.Next() rather than k is that otherwise, given i and E(i,k), you can get k by k = i xor E(i,k))

BlueRaja - Danny Pflughoeft
A: 

How many integers do you want to encrypt? How much key data do you want to have to deal with?

If you have few items to encrypt, and you're willing to deal with key data that's just as long as the data you want to encrypt, then the one-time-pad is super simple (just an XOR operation) and mathematically unbreakable.

The drawback is that the problem of keeping the key secret is about as large as the problem of keeping your data secret.

It also has the flaw (that is run into time and again whenever someone decides to try to use it) that if you take any shortcuts - like using a non-random key or the common one of using a limited length key and recycling it - that it becomes about the weakest cipher in existence. Well, maybe ROT13 is weaker.

But in all seriousness, if you're encrypting an integer, what are you going to do with the key no matter which cipher you decide on? Keeping the key secret will be a problem about as big (or bigger) than keeping the integer secret. And if you're encrypting a bunch of integers, just use a standard, peer reviewed cipher like you'll find in many crypto libraries.

RC4 will produce as little output as you want, since it's a stream cipher.

Michael Burr
RC5 is a block cipher; you may be thinking of RC4.
caf
Keeping the key secret would not be an issue, but it would have to be the *same* key every time, for an unlimited number of integers. Which I believe means that for a one-time pad type of encryption, the key would need to be as long as the concatenation of every integer. While I don't mind large keys, they should probably be on the order of the integer's length.
tloflin
@caf: oops, you're right. I made the correction.
Michael Burr
A: 

How about XORing it with a prime or two? Swapping bits around seems very random when trying to analyze it.
Try something along the lines of XORing it with a prime and itself after bit shifting.

Rubys
+2  A: 

I wrote an article some time ago about how to generate a 'cryptographically secure permutation' from a block cipher, which sounds like what you want. It covers using folding to reduce the size of a block cipher, and a trick for dealing with non-power-of-2 ranges.

Nick Johnson
Thanks, that was a good writeup. It sounds like the cycle-walking algorithm in the article leonbloy linked.
tloflin
Indeed it is exactly that.
GregS
Cycle walking, combined with a folding technique to reduce the length of a block cipher.
Nick Johnson