村人ちょるの日記

2018年の目標はブログを100本あげることです

pythonでAES暗号

プロローグ


なんで,ヤギさん達は
お手紙を読まずに食べたのだろう?


僕の予想だけど,
黒ヤギさんからお手紙ついた


僕は,鍵を教えてないのに

暗号化して手紙を出してたんじゃない?

だから読めなくて,食べちゃった的な!


これまでは?


毎日のようにポエム記事をあげるのもどうかと思うので

文系大学院生の僕だけど

たまには,プログラミングでもしてみようかな〜
と思って,記事を書いてみるね.


でも,本当にあってるかどうかは責任を持たないので
自己責任で使って欲しい.

そもそもあってるのか知らないよ.


そんなあやふやなこと書くなよ

って感じかもしれないけど,僕も書いてみたかったんだよ!!

ごめんな!



今回のテーマは

とりあえず,pythonでAESを動かしてみようぜ

ってやつ.


何を見つけた?


よくわからないけど,python のライブラリ
があるみたいだから,動かしてみるわ!

import binascii
from Crypto.Cipher import AES

key = '0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d'
message = '00112233445566778899aabbccddeeff0123456789abcdef0123456789abcdef'

secret_key = binascii.unhexlify(key)
plain_text = binascii.unhexlify(message)

print('secret_key:',secret_key.hex())
print('plain_text:', plain_text.hex())

cipher = AES.new(secret_key)
data = cipher.encrypt(plain_text)

print('cipher:', data.hex())
print('decode:', cipher.decrypt(data).hex())


とりあえず,戻ってるからこれでよし!!



さてさて.AESで暗号化するときに

よくわからないけど
「The MixColumns step」というのをするらしい.

数学が苦手な文系大学院生なので
困ってるんだけど,取り合えず
英語のウィキペディアを読んだら

ガロア体 ってものを使うらしい
それも2の8乗の!!

まぁよくわからないんだけど

ウィキペディアに載ってる擬似コードを写して
みたんだけど,思ったように動かない(無能僕)


こまったこまった.

そこから何を見出せる?


そこで,グーグルで色々調べてみて
自分なりに,ガロア体を理解してみた!


ガロア体による表現は,xの何乗って形で
係数が0か1の多項式を使うみたい.

この0と1を2進法のそれぞれの桁のビット
としてみれば,どうも普通の排他的論理和による演算
をすればいいだけになるらしい!

でも,8bitを超えた場合は
既約多項式なるものを使って,8bitの内側に
落とし込むらしい.閉じてるってやつやね.

既約多項式の2進数表現 = 100011011

これを使う!

9bit目に超えた時は,既約多項式の2進数で
そのまま排他的論理和で演算すれば
一番左のビットは1と1になって0になるから
消えて,9bitの中に戻るよね?多分.

んで,10bit目が1になる繰り上げが起こった場合は
100011011 を 1回左ビットシフトして
1000110110 と排他的論理和を取れば10bit目消えるよね.

まぁこのようにして,8bitより左側の1を消して行くと・・・
おそらくそんな感じ.

それで演算を定義できたら
その演算を使って,ある行列に対してベクトルを掛ける
行列ベクトル積ってやつか.

そうすると,なんか計算できてるっぽい!

def gl8(a,b):
    r = 0
    p = '11b'  # x^8 + x^4 + x^3 + x + 1
    px = int(p,16)
    
    #普通に排他的論理和を取る
    for i in range(8):
        if ((b & 1) != 0):
            r ^= a;
        a <<= 1
        b >>= 1
        
    #溢れてる部分の処理
    s = r >> 8 #溢れてるbitだけ取り出す
    sz = len(format(s,'0b'))
    for i in range(sz):
        if ((s & 1) == 1):
            r ^= px;
        px <<= 1
        s >>= 1
    return r

#ガロア体 2^8 に使う行列
a = "02 03 01 01 01 02 03 01 01 01 02 03 03 01 01 02"
#計算したいベクトル
b = "2d 26 31 4c"

A = [[int(x,16) for x in a.split()][4*y:4*(y+1)] for y in range(len(a)//4)]
B = [int(x,16) for x in b.split()]
C = [0 for i in range(4)]

#行列計算
for i in range(4):
    for j in range(4):
        C[i] ^= gl8(A[i][j],B[j])
        
#16進数のベクトルに変換
c = [format(x,'0x') for x in C]
print(c)

う〜ん.できてるのかな〜

よくわかんないや☆


もし,わかる人は教えて!
コメント待ってます!

あってる場合も,あってるって教えてください!



ちなみに参考にしたのはこれ!

www.wikiwand.com

エピローグ


黒ヤギさんからお手紙ついた

白ヤギったら,復号せずに食べた


しかたがないのでお手紙書いた

「さっきの手紙の暗号の鍵はなぁに?」


これを,暗号化して送ろう・・・