While experimenting with this FPE based on FE1
http://botan.randombit.net/manual/fpe.html
(well actually a port of it in C#) I found when the string length gets too long (number of characters N) basically it's designed to throw an exception
So the byte array for the modulus is limited to this value
// Normally FPE is for SSNs, CC#s, etc, nothing too big
private const int MAX_N_BYTES = 128 / 8;
And this is where we check the length of the byte array
/// <summary>
/// A simple round function based on HMAC(SHA-256)
/// </summary>
private class FPE_Encryptor
{
private System.Security.Cryptography.HMACSHA256 mac;
private byte[] mac_n_t;
internal FPE_Encryptor(byte[] key,
BigInteger n,
byte[] tweak)
{
mac = new System.Security.Cryptography.HMACSHA256(key);
mac.Initialize();
byte[] n_bin = n.encode();
if (n_bin.Length > MAX_N_BYTES)
throw new Exception("N is too large for FPE encryption");
var ms = new MemoryStream();
ms.update_be(n_bin.Length);
ms.update(n_bin);
ms.update_be(tweak.Length);
ms.update(tweak);
mac_n_t = mac.ComputeHash(ms.ToArray());
}
internal BigInteger F(int round_no, BigInteger R)
{
byte[] r_bin = R.encode();
var ms = new MemoryStream();
ms.update(mac_n_t);
ms.update_be(round_no);
ms.update_be(r_bin.Length);
ms.update(r_bin);
byte[] X = mac.ComputeHash(ms.ToArray()).Reverse().ToArray();
var X_ = new byte[X.Length + 1];
X.CopyTo(X_, 0);
X_[X.Length] = 0; // guarantee a positive interpretation
BigInteger ret = new BigInteger(X_);
return ret;
}
}
However say I want to encode a long string like this "Asddasdasdasdasdasdasdasd"
I'm in Base 52 so my modulus is very large 7944811378381908491977011631194721432371200
Which after converting to byte array using
internal static byte[] encode(this BigInteger n)
{
if (n.IsZero) return new byte[0];
else return n.ToByteArray().Reverse().SkipWhile(h => h == 0).ToArray();
}
gives a length of 18, bigger that the maximum 16.
Does anyone have suggestion how to deal with the larger number of characters in the plaintext you want to encrypt? I was thinking to chop it up into fragments and encrypt the pieces if the string gets longer than a maximum value. Would this be acceptable?