DES

鍵長: 56bit(64bitの鍵を与えるが、その後8bit捨てられる)

ブロック長: 64bit

16ラウンドのFeistel構造を用いたブロック暗号

DESは次のような疑似コードで表される

def feistel(m, k):
    m = expand(m) # 32bit -> 48bit
    m = m ^ k
    return [sboxes[i](m[i*8:(i+1)*8]) for i in range(0, 48 // 8)]

k1, k2 = key_IP(key) # 64bit -> 28 + 28 bit
rotsize = [1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1]
keys = []
for i in range(16):
    k1, k2 = rot_left(k1, rotsize[i]), rot_left(k2, rotsize[i])
    keys.append(key_permute(k1,k2))

u, v = IP(m)
for i in range(16):
    u, v = v, feistel(v, keys[i])^u
    if i == 15:
        u, v = v, u # do NOT swap u and v at last
c = FP(u, v)

FP, IP は適当な撹拌

Sboxは6bit -> 4bit変換を行う2次元行列(4bit x 2bitの行列で、前4bit 後ろ2bitがindexになる感じ)

exapndは32 -> 48bitの撹拌

key_permuteは56bit -> 48bitの撹拌

key_IPも64 -> 56bitの適当な撹拌

復号は鍵を逆から適用して同じ過程を回すとできる

特性とか

  • rotsizeは全部回すと28なので、key0 と key16は同じになる(!)(まあkey16なんて出てこないんですが)

  •  FP = IP^{-1}

  • sbox 以外の(平文に対する)操作は線形性を持つ

  • つまり、  S(m \oplus k) \neq S(m) \oplus S(k) ということ。まあこうじゃなくても良いんだけど、とにかく  S(m \oplus k) と等式が成り立つ項が無い

  • ので X -> Sbox -> Y となっているとき、XとYの関係性をうまく推測できない

  • 忘れがちだけどexpandとかも線形、なぜなら入力を規則に従って並べ替えているだけなので。対してS-boxは入力→出力がテーブルによって決まっていて、そこが非線形