Class: FFXCodec::Encrypt
- Inherits:
-
Object
- Object
- FFXCodec::Encrypt
- Defined in:
- lib/ffxcodec/encrypt.rb
Overview
WARNING: This was cooked up as an experimental proof of concept. It hasn’t been tested thoroughly and shouldn’t be considered secure.
Format-preserving != integer-size-preserving in base 10 (see below)
Implementation of AES-FFX mode format-preserving encryption
Cipher device encrypts integers where the resulting ciphertext has the same number of digits in the given base (radix).
The format-preserving characteristic of this cipher is best thought of as preserving the number of digits, not the integer size. For instance, in base 10, 4294967295 and 4294967296 would be considered to have the same format, but the first is a 32-bit unsigned integer and the second is 64.
So given base 10 input that fits within a 32 or 64-bit integer, it’s possible for the AES-FFX cipher to return a number that contains the same number of base 10 digits but exceeds the largest number that can be represented in 32 or 64 bits respectively.
You can work around this by using radix 2 so that the cipher returns an equal number of bits. As with all modes, you must supply input as a stringified integer in the base you’ve specified.
Be aware that when you convert between bases, leading zeros are sometimes dropped by the converter. You must supply the same number of digits to the decrypter as you did to the encrypter or you’ll get a different value. The encrypt and decrypt methods prepend zeros until the input is is of the length specified during initialization.
Instance Attribute Summary collapse
- #length ⇒ Object
-
#radix ⇒ Fixnum
Radix of the input.
- #rounds ⇒ Object
Instance Method Summary collapse
-
#decrypt(input) ⇒ Fixnum, Bignum
Decrypt.
-
#encrypt(input) ⇒ Fixnum, Bignum
Encrypt.
-
#initialize(key, tweak, length, radix = 10) ⇒ Encrypt
constructor
A new instance of Encrypt.
- #key=(key) ⇒ Object
- #tweak=(tweak) ⇒ Object
Constructor Details
#initialize(key, tweak, length, radix = 10) ⇒ Encrypt
Returns a new instance of Encrypt.
50 51 52 53 54 55 56 |
# File 'lib/ffxcodec/encrypt.rb', line 50 def initialize(key, tweak, length, radix = 10) self.key = key self.tweak = tweak self.radix = radix @length = length @rounds = 10 end |
Instance Attribute Details
#length ⇒ Object
36 37 38 |
# File 'lib/ffxcodec/encrypt.rb', line 36 def length @length end |
#radix ⇒ Fixnum
Returns radix of the input.
44 45 46 |
# File 'lib/ffxcodec/encrypt.rb', line 44 def radix @radix end |
#rounds ⇒ Object
This is set to 10 by the spec. Don’t change it unless you know what you’re doing.
41 42 43 |
# File 'lib/ffxcodec/encrypt.rb', line 41 def rounds @rounds end |
Instance Method Details
#decrypt(input) ⇒ Fixnum, Bignum
Decrypt
106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/ffxcodec/encrypt.rb', line 106 def decrypt(input) a, b = input.prepad_zeros(@length).bisect (@rounds - 1).downto(0) do |iter| c = b b = a f = feistel_round(input.size, iter, b) lmin = [c.size, f.size].min a = block_subtraction(lmin, c, f) end a + b end |
#encrypt(input) ⇒ Fixnum, Bignum
Encrypt
86 87 88 89 90 91 92 93 94 95 |
# File 'lib/ffxcodec/encrypt.rb', line 86 def encrypt(input) a, b = input.prepad_zeros(@length).bisect 0.upto(@rounds - 1) do |iter| f = feistel_round(input.size, iter, b) c = block_addition(a, f) a = b b = c end a + b end |
#key=(key) ⇒ Object
59 60 61 62 63 |
# File 'lib/ffxcodec/encrypt.rb', line 59 def key=(key) hexkey = [key].pack('H*') fail ArgumentError, "key must be a 16-byte hexidecimal" if hexkey.length != 16 @key = hexkey end |
#tweak=(tweak) ⇒ Object
66 67 68 69 |
# File 'lib/ffxcodec/encrypt.rb', line 66 def tweak=(tweak) fail ArgumentError, "tweak length must be under (2^32) - 1" if tweak.length > ((1 << 32) - 1) @tweak = tweak end |