I'm experimenting with this library Botan which includes a module for format preserving encryption based on FE1 mode.

The parameters for the Encrypt method are as follows

        /// <summary>
    /// Generic Z_n FPE encryption, FE1 scheme
    /// </summary>
    /// <param name="modulus">Use to determine the range of the numbers. Example, if the
    /// numbers range from 0 to 999, use "1000" here.</param>
    /// <param name="plaintext">The number to encrypt.</param>
    /// <param name="key">Secret key</param>
    /// <param name="tweak">Non-secret parameter, think of it as an IV</param>
    /// <returns>The encrypted number.</returns>
    public static BigInteger Encrypt(BigInteger modulus, BigInteger plaintext,
                       byte[] key,
                       byte[] tweak)

Modulus, plaintext and key I understand, but not clear on the tweak. How do you decide what it is and can you use the same value for all plaintext input. Can it be any number?


1 Answer 1


The tweak is a service that the encryption method provides for you. What it allows you to do is provide context separation for various encryptions using the same key.

Here's the problem that it is trying to help with: suppose you use the same key to encrypt a number of items; for example, suppose you're encrypting all the items in one column of a database with this key.

This leads to an issue: if the data record corresponding to Alice has a 5 in this field, and the one corresponding to Bob also has a 5 in this field, then both records would have the same encrypted value. Someone looking at the encrypted records won't be able to tell what that common value is, however they know they're the same. And, if Bob knows what his value is, then he knows what Alice's value is.

One obvious way to handle it is to just use a different key for each record. That'd work, but that's a lot of keys to handle and store.

The tweak provides an alternative way to handle it; it changes the mapping between plaintext and ciphertext; however (unlike the key) we don't assume that the attacker doesn't know what it is. In our database example, we might make the tweak the user's name ("Alice" and "Bob"); then, even if Alice's and Bob's encrypted record happen to have the same encrypted value, no one can deduce anything from that (because the mappings from the ciphertext to the plaintext is independent; they might map to the same value, and they might not).

What does this mean for you? Well, that depends on what you're using FE1 for. If you are literally encrypting one value with the key, well, you really don't need it - you can set it to a fixed value (say, the empty string). However, if you are encrypting multiple values with the same key, you might be able to take advantage of it.

One final note: why is this tweak especially important for Format Preserving Encryption? Well, with standard encryption modes, we add a randomization factor (IVs) during encryption (so that, even if you encrypt the same value twice, we'll pick different IVs), and so the encrypted text would look different. However, this randomization necessarily makes the ciphertext larger than the plaintext. With Format Preserving Encryption, we don't have that option; hence we need another way to address this.

  • $\begingroup$ I'm using it to encrypt strings like words and names. I'm using a key that is made from the input string, and throw it away. So each input is it's own key. I only care that the output will come out the same each time for a given input string, I don't care about decrypting the result. From what you are saying it sounds like I don't need a tweak in my case, is that right? $\endgroup$
    – erotavlas
    May 1, 2015 at 15:49
  • $\begingroup$ @erotavlas: actually, if you don't care about being able to decrypt, it would sound like a hashing method is more what you really want. In any case, if you go with your current method, yes, it sounds like a constant tweak would be appropriate in your case. $\endgroup$
    – poncho
    May 1, 2015 at 15:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.