# How to force non-negative int64_t output for blowfish encryption with int32_t input?

I would like to encrypt a series of small integers one by one. The range of them is about 0~10^8. The output must be non-negative int64_t integers.

Since Blowfish is 64-bit cipher, I prefer to use it as symmetric encryption algorithm.

The problems are:

1. Since 32-63 bits of input is always 0, do I need to do certain pre-process step to enforce security?
2. The sign bit of Blowfish's output may be 1. I have to prevent this happen. What should I do?
3. How to design correct decryption procedure to get original integer int32_t?

One option is to encipher each number as follows:

1. concatenate one 0 bit, the index for the number to encipher (or a random value) on 31 bits, and the 32-bit number to encipher, to form a 64 bit value with the leftmost bit at 0
2. encipher with blowfish (and a fixed secret key)
3. if the leftmost bit of the result is set, loop to 2
4. output the 64-bit result (which matches the desired condition of having its leftmost bit clear)

Decryption is as follows

1. check that the input value matches the desired condition of having its leftmost bit clear
2. decipher with blowfish (and the same fixed secret key)
3. if the leftmost bit of the result is set, loop to 2
4. optionally, if the index is known: check that the leftmost 32 bits of the value match the intended index; that gives you a free Message Authentication Code with odds less than one in two billions of forgery!
5. extract the deciphered 32-bit number as the rightmost 32 bits of the result

That's cycling, a classical technique of Format Preserving Encryption. The average number of Blowfish encryptions is 2, and odds are about $1/2^n$ that more than $n$ Blowfish encryptions are necessary to encipher a number. It is not possible that steps 2/3 of encryption or decryption enter an infinite loop (including if the ciphertext was altered, thanks to the check made at step 1 of decryption); however it could be that we encounter by accident an input which requires 50 loops or slightly more, or (with a determined attacker knowing the key and giving us a rogue ciphertext) perhaps next to 100; and the only firm upper bound we have ($2^{63}+1$ iterations) is entirely impractical.

Other methods are possible that take bounded time, and can reduce the cryptogram size (at the expense of MAC robustness); but all the secure ones I know will have one of the following drawbacks:

• they will require significantly more Blowfish encryptions on average (as if we build a 63-bit block cipher from Blowfish and a Feistel structure);
• they will provide no integrity insurance (as if we encipher a 31-bit incremental index with blowfish, truncate the 64-bit result to 32 bits, XOR that with the 32-bit number to encipher, and form the cryptogram by prefixing the 32-bit result with a 0 bit and the index).