{"id":8154,"library":"ff3","title":"Format Preserving Encryption (FPE) with FF3","description":"The `ff3` library provides Format Preserving Encryption (FPE) using the NIST FF3 and FF3-1 algorithms. It is currently at version 1.0.3 and receives minor updates for features and compatibility, with the core encryption logic stable since v1.0.0.","status":"active","version":"1.0.3","language":"en","source_language":"en","source_url":"https://github.com/mysto/python-fpe","tags":["encryption","fpe","cryptography","ff3","format-preserving"],"install":[{"cmd":"pip install ff3","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"FF3Cipher","correct":"from ff3 import FF3Cipher"}],"quickstart":{"code":"from ff3 import FF3Cipher\nimport os\n\n# Key must be 16, 24, or 32 bytes (128, 192, or 256 bits)\n# Example uses a 32-byte key\nkey = os.environ.get('FF3_KEY', '0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF').encode('utf-8')[:32]\n\n# Tweak must be 7 bytes for FF3-1, 8 bytes for FF3 (default)\n# Example uses an 8-byte tweak for standard FF3\ntweak = os.environ.get('FF3_TWEAK', '1234567890ABCDEF').encode('utf-8')[:8]\n\n# Initialize FF3 cipher with key and tweak\ncipher = FF3Cipher(key, tweak)\n\n# The default alphabet includes digits 0-9\nplaintext = \"1234567890\"\n\nciphertext = cipher.encrypt(plaintext)\ndecrypted_text = cipher.decrypt(ciphertext)\n\nprint(f\"Original: {plaintext}\")\nprint(f\"Encrypted: {ciphertext}\")\nprint(f\"Decrypted: {decrypted_text}\")\n\nassert plaintext == decrypted_text\n","lang":"python","description":"Encrypt and decrypt a numeric string using the default FF3 algorithm with a specified key and tweak."},"warnings":[{"fix":"Ensure your tweak data matches the expected length for FF3 (8 bytes) or FF3-1 (7 bytes). The default `FF3Cipher` constructor uses FF3; use `FF3Cipher.withFF3_1(key, tweak)` for FF3-1.","message":"FF3 (64-bit tweak) and FF3-1 (56-bit tweak) have different tweak length requirements. Using a tweak of incorrect length for the chosen algorithm variant will lead to `ValueError` or incorrect encryption/decryption.","severity":"breaking","affected_versions":"All versions since v1.0.0"},{"fix":"Verify key and tweak byte lengths before instantiation. For string literals, ensure they are encoded to bytes (e.g., `'your_key_string'.encode('utf-8')`) and then sliced or padded to the exact required length.","message":"The `key` must be 16, 24, or 32 bytes (128, 192, or 256 bits) and the `tweak` must be 7 or 8 bytes. Providing incorrect lengths will result in a `ValueError`.","severity":"gotcha","affected_versions":"All versions since v1.0.0"},{"fix":"Persist and reuse the `FF3Cipher` instance or reconstruct it with the identical custom alphabet for decryption operations.","message":"When using a custom alphabet via `FF3Cipher.withCustomAlphabet(key, tweak, custom_alphabet)`, the exact same alphabet must be used for both encryption and decryption, or decryption will fail.","severity":"gotcha","affected_versions":"All versions since v1.0.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure the `key` byte string is exactly 16, 24, or 32 bytes long. Use `.encode('utf-8')` and slice/pad if starting from a string.","cause":"The provided encryption key does not meet the AES key length requirements (128, 192, or 256 bits).","error":"ValueError: Key length must be 16, 24, or 32 bytes"},{"fix":"Ensure `tweak` is 8 bytes for standard FF3 (default `FF3Cipher` constructor) or 7 bytes for FF3-1 (if using `FF3Cipher.withFF3_1`). Use `.encode('utf-8')` and slice/pad if starting from a string.","cause":"The provided `tweak` byte string is not the correct length for the FF3 algorithm variant being used.","error":"ValueError: Tweak length must be 7 bytes (FF3-1) or 8 bytes (FF3)"},{"fix":"First, ensure installation with `pip install ff3`. If installed, verify the import statement is exactly `from ff3 import FF3Cipher`.","cause":"The `ff3` package is either not installed or the import path is incorrect.","error":"ImportError: cannot import name 'FF3Cipher' from 'ff3'"},{"fix":"Ensure `plaintext` and `ciphertext` passed to `encrypt`/`decrypt` are `str` type. Note that `key` and `tweak` *must* be `bytes` type.","cause":"The `encrypt` or `decrypt` method received a bytes object when it expects a string plaintext/ciphertext.","error":"TypeError: argument 'text' must be str, not bytes"}]}