I have a good one for you guys. I’m trying to code a feistel network and it’s giving me some problems. Mainly, the issue is that whatever I encode, I don’t get back when I reverse it. I don’t see any problems with the code, so I’m wondering if the problem is with my implementation. A feistel network is used to turn an irreversible logic operation (and, or, nand, nor, etc…) into a reversible operation. It’s used extensively in cryptography for block ciphers. The most well known block cipher that uses this is DES.
local function feistelNetwork(data, key)
-- Splits a 32bit data word into two 16bit parts.
local function splitData(data)
local lo = bit32.band(data, 0x0000FFFF)
local hi = bit32.band(bit32.rshift(data, 16), 0x0000FFFF)
return lo, hi
end
-- Combines two 16bit parts into a single 32bit data word.
local function combineData(lo, hi)
return bit32.bor(bit32.band(bit32.lshift(hi, 16), 0xFFFF0000), bit32.band(lo, 0x0000FFFF))
end
-- Performs an AND operation using a feistel network.
local function feistelANDf(data, key)
local l1, r1 = splitData(data)
local k1, k2 = splitData(key)
local r2 = bit32.bxor(bit32.band(r1, k1), l1)
local l2 = r1
local r3 = bit32.bxor(bit32.band(r2, k2), l2)
local l3 = r2
print(string.format("0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X", l1, r1, l2, r2, l3, r3))
return combineData(l3, r3)
end
-- Performs an AND operation using a feistel network.
local function feistelANDr(data, key)
local l1, r1 = splitData(data)
local k1, k2 = splitData(key)
local r2 = bit32.bxor(bit32.band(r1, k2), l1)
local l2 = r1
local r3 = bit32.bxor(bit32.band(r2, k1), l2)
local l3 = r2
print(string.format("0x%08X 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X", l1, r1, l2, r2, l3, r3))
return combineData(l3, r3)
end
-- Testing
local rx = feistelANDf(data, key)
local ry = feistelANDr(rx, key)
print(string.format("0x%08X 0x%08X", rx, ry))
if data ~= ry then
print("Failed")
else
print("Success")
end
end
feistelNetwork(0x7B04829A, 0xC299BA74)
This is the result:
0x0000829A 0x00007B04 0x00007B04 0x0000B89E 0x0000B89E 0x0000FB9C
0x0000B89E 0x0000FB9C 0x0000FB9C 0x00007A06 0x00007A06 0x0000C198
0xFB9CB89E 0xC1987A06
Failed
It goes in with 0x7B04829A, but it comes out with 0xC1987A06. So I’m not sure if the problem is the encoding or decoding as I’m not sure what the expected encoded value is. The key in both cases is the same.
EDIT:
Well, I worked it out on paper and it does work. So I’m not sure what the problem with my code is.