「暗号技術のすべて」メモ
inabajunmr は数学の素養がまったくない状態で都度調べながらこの文章を書いているので、メチャクチャなことを言っている可能性が十分にあります。
p124 の統計的距離の式
は、n ビットのすべての集合 x に対する、Xn が x である確率 - Zn が x である確率の合計を表す。
Xn について
各要素の確率は
Zn について
全部 1 はやり直しなので、確率は 0、それ以外の各要素の確率は
まとめると
Xn も Zn も、発生しうる値のパターンは
さらに、全部 1 のパターンは 1 パターンのみで、その確率はそれぞれ
全部足すと p124 に出てくる数式になる。
p124 の 図 3.19
そもそも b って何?
識別子 D は b の推測値 b' を出力します
p130
「オラクルがランダム置換である状況」を b = 0、「オラクルがブロック暗号の暗号化アルゴリズムである状況」を b = 1 とします。
これか?
とすると、
なので、
となると、演習問題の回答は 1 なのでなんか違う。なんとなく p132 の式変形で吸収されている、という理解でよさそう。つまり、
b は多分、分布 Xn を使っているという事実=1、Yn を使っているという事実=0 のマッピングで、その推測が b' で、b'=b とは推測があたっている、という状態を表す。で、それをブロック暗号の暗号アルゴリズム、という具体的な例に当てはめると、
「オラクルがランダム置換である状況」を b = 0、「オラクルがブロック暗号の暗号化アルゴリズムである状況」を b = 1 とします。
となる。
p127 確率分布の族とは
そもそも確率分布とは
確率変数がとる値とその値をとる確率の対応の様子を「確率分布」と言います。
https://bellcurve.jp/statistics/course/6596.html より
確率分布 Xn は
Xn, Yn を
上の確率分布とします。 {0, 1} ^n
p124
とあるので、n ビットの各ビット列が起きうる確率のこと。識別子にこの発生確率を入力した時に、それがランダムかどうかを判定してくれる。
これに対して、確率分布 Xn ではなく 確率分布の族{Xn} でも識別不可能性を定義できる、と書いてある。
で、確率分布の族とは? // TODO
p132 の (1) 式の変形
言い換えると
条件付き確率の定義(p102)
なので、
と変形できる。b がいずれかの値である可能性は
となり、
結果、
となる。あとは単純に展開していくと最終的な式が得られる。
p151 の IP と E の組み合わせと S-box の対応とは
p153 暗号文が元の平文に戻ることを確認する式
全然わからない
p154 相補性の証明
縮小転置 PG1 の結果の反転と、PG1 の入力 64 ビットの前半 32 ビットをそれぞれ反転させて拡大転置 E に入力した結果はおなじになる?
拡大転置は入力された位置にしたがってビットを拡大しているだけなので、ビットの値は拡大の方法に影響しないので、反転したビットを拡大転置しても拡大転置してから反転しても結果は変わらない、というのはわかるんだけど、PG1 がなんで絡んでくるのかよくわからない。
p147 を見るに、この PG1 は E だったりしない?
-> といあわせたら E であってた(https://www.shoeisha.co.jp/book/detail/9784798148816 )
反転した値を転置すると、結果も反転している、はわかる。
反転した値を XOR した結果と、反転していない値を XOR した結果がおなじになる、もわかる。
p168 Rcon の算出方法
x、どこから出てきた?(任意の x でも Rcon の値は i によって一意に決まる?)
FIPS 197 より
The round constant word array, Rcon[i], contains the values given by [
,{00},{00},{00}], with x^{i-1} being powers of x (x is denoted as {02}) in the field GF( x^{i-1} ), as discussed in Sec. 4.2 (note that i starts at 1, not 0). 2^8
FIPS 197 の 4.2 にもなんか書いてあるけどよくわからない
p175 S-box の作り方
これはもう全然わからない
この辺をみてみる
GF はなんとなくわかった
多分 GF(2) は 0, 1 から構成される有限体のこと
MixColumns について
多項式の掛け算
x をかけて既約多項式を引くと法を既約多項式とした時に x でかけた結果がわかる、はわかる気がするんだけど、
→ならない
→この場合、9 ビット目のビットが立ってる状態になるので、割ってあまりを出さないと駄目
掛け算のアルゴリズム
と 1,2,4,8,16,…,1281,2,4,8,16,…,128 を掛け算したときの結果を用意します。 \{\text{57}\}{57}
の表がわからない
なんで 8 の次 10 なんだろ
適当に計算すると計算結果自体はあってる気がするんだけど、なんで 08 の次が 10 になる?
func Test(t *testing.T) {
x2 := xtime(0x57)
fmt.Printf("%02x\n", x2)
x3 := xtime(x2)
fmt.Printf("%02x\n", x3)
x4 := xtime(x3)
fmt.Printf("%02x\n", x4)
x5 := xtime(x4)
fmt.Printf("%02x\n", x5)
x6 := xtime(x5)
fmt.Printf("%02x\n", x6)
x7 := xtime(x6)
fmt.Printf("%02x\n", x7)
x8 := xtime(x7)
fmt.Printf("%02x\n", x8)
t.Error()
}
func xtime(b byte) byte {
data := binary.LittleEndian.Uint16([]byte{b, 0})
x := data << 1
r := make([]byte, 8)
if x&0x100 != 0 {
binary.LittleEndian.PutUint16(r, x^0x1b)
} else {
binary.LittleEndian.PutUint16(r, x)
}
return r[0]
}
→ふつうに 2 進数で桁があがっていくのを 16 進数で書いてるだけだった・・・
dot は
x=01010111(57)
y=10000011(83)
で考えると、
mask=00000001
y の 00000001 が立ってるので
product = product xor x = 01010111
x = xtime(x) = 10101110(ae)
mask=00000010
y の 00000010 が立ってるので
product = product xor x = 11111001
x = xtime(x) = 10101110(ae)
mask=00000100
y の 00000100 が立ってないので
x = xtime(x) = 10101110(47)
...
mask=10000000
y の 10000000 が立ってるので
product = product xor x = (57 * 1 + 57 * 2) xor 57 * 80
つまり、x に 57 * n を入れておいて都度
0 xor x を product に代入
57 * 1 xor 57 * 2 を product に代入
...
57 * 1 xor 57 * 2 xor 57 * 80 を product に代入
実装してみた感じ AES の復号で invMixColumns をスキップするのは i != 1 じゃなくて i != N っぽい
それであってた