katagaitai
CTF Workshop #7
Crypto
2017.02.25 TOKYO
trmr (@trmr105)
katagaitai
#7 はじまるよー!
 katagaitai CTF勉強会の歴史
 2012年~2014年:某所での下積み時代
 2014年冬:CTF勉強会 #1 共通素数を持つRSA
 2015年夏:CTF勉強会 #2 CRIME
 2015年冬:CTF勉強会 #3 SPN構造ブロック暗号の差分解析
 2015年冬:CTF勉強会 #4 Feistel構造ブロック暗号の差分解析
 2016年夏:CTF勉強会 #5 ハッシュ関数の衝突&Length Extention
 2016年夏:CTF勉強会 #6 ー
 2016年冬:CTF勉強会 #7 ナップサック暗号
 下記URLで過去の勉強会資料を公開中
 https://speakerdeck.com/bata_24
 http://www.slideshare.net/trmr105
イマココ!
2
katagaitai勉強会とは
好きなことを分かり合える人を増やしたい!
3
Special Thanks
 本資料は以下の方にご協力いただいてます
 Bonoさん(@bono_ipad)
 shiho midorikawaさん(@elliptic_shiho)
 nomeaningさん(@__nomeaning__ )
4
katagaitaiのモチベーション
Twitterの巡回 Writeup収集
#katagaitaiCTF
5
katagaitaiとの約束6
W
r
i
t
e
u
p
書
今日の問題
 [TW CTF 2nd 2016] Crypto200 – Backpacker’s cipher easy mode
 [Plaid CTF 2015] Crypto180 – Lazy
 [TW CTF 2nd 2016] Crypto450 – Backpacker’s cipher extra mode
7
TWCTF : Tokyo Westerns/MMA CTF
目次
 ナップサック暗号
 [TW CTF 2nd 2016] Crypto200 – Backpacker’s cipher easy mode
 数学のお話
 [Plaid CTF 2015] Crypto180 – Lazy
 [TW CTF 2nd 2016] Crypto450 – Backpacker’s cipher extra mode
8
ナップサック暗号9
公開鍵暗号
 公開鍵暗号
 暗号化用の鍵(公開鍵)と復号用の鍵(秘密鍵)が異なる暗
号
 一方向性関数を利用して構築
 一方向性関数
 入力→出力は容易に計算可能
 出力→入力が計算が困難
 一方向性関数の例
 素因数分解問題 -> RSA
 離散対数問題 -> Elgamal, 楕円曲線暗号
 部分和問題 -> ナップサック暗号 etc.
10
部分和問題
 部分和問題 (subset sum problem)
 (𝑣1, … , 𝑣 𝑛)からある値𝑊を構成する部分和を見つける問題
 𝑖=0
𝑛
𝑣𝑖 ∗ 𝑥𝑖 = 𝑊となるような (𝑥1, 𝑥2, ⋯ , 𝑥 𝑛)を導出する問題
 𝑥𝑖 ∈ 0,1 ; 𝑖 ∈ { 1, … , 𝑛}
 NP完全:多項式時間で答えを見つけることができない
 𝑛の値が大きい場合、 (𝑥1, 𝑥2, ⋯ , 𝑥 𝑛)を求めることは計算量的に困難
11
例
𝒗 = 1,3,7,15,40
𝒙 = 1,0,1,1,0
𝑊 = 1 + 7 + 15 = 23
Photo by Dake
ナップサック暗号
 ナップサック暗号 (knapsack crypto system)
 一方向性関数として部分和問題を利用
 秘密鍵:𝒂 = { 𝑎1, … , 𝑎 𝑛 | 𝑎𝑖 ∈ 𝑍}; 𝑝, 𝑞
 𝑞 > 𝑖=1
𝑛
𝑎𝑖
 𝑝, 𝑞は互いに素
 公開鍵:𝒃 = { 𝑏1, … , 𝑏 𝑛 | 𝑏𝑖 = 𝑝 ∗ 𝑎𝑖 mod 𝑞}
 平文:𝒎 = 𝑚1, … , 𝑚 𝑛 𝑚𝑖 ∈ {0,1}}
 暗号化
 𝑖=1
𝑛
𝑏𝑖 ∗ 𝑚𝑖 = 𝐶
 暗号文𝐶から平文/鍵を導出するには?
 部分和問題を解く必要
 このままでは受信者も平文を導出できないのでトラップドアが必要
 MHナップサック暗号
 トラップドアに超増加数列を利用
 超増加数列:𝑎 𝑥+1 > 𝑖=1
𝑥
𝑎𝑖 を満たす数列(𝑎1, … , 𝑎 𝑛)
12
トラップドアと超増加数列
 トラップドアを用いた部分和の導出
 超増加数列の性質より、下記で𝑥𝑖を導出可能
 ⓪ 𝑊 = 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑚 𝑥, 𝑥 = 𝑛 とする
 ① 𝑊 ≥ 𝑎 𝑥であれば、𝑚 𝑥 = 1とし、𝑆 = 𝑆 − 𝑎 𝑥とする
 ② 𝑊 < 𝑎 𝑥であれば、𝑚 𝑥 = 0とする
 ③ 𝑥をデクリメント
 ①~③を繰り返す
13
例
𝒗 = 1,3,7,15,40 , 𝑊 = 23, 𝑛 = 5
𝑣5 = 40 > 𝑊 よって𝑚5 = 0
𝑣4 = 15 ≤ 𝑊 よって𝑚4 = 1 W = 23 − 15 = 8
𝑣3 = 7 ≤ 𝑊 よって𝑚3 = 1 W = 8 − 7 = 1
𝑣2 = 3 > 𝑊 よって𝑚2 = 0
𝑣1 = 1 ≤ 𝑊 よって𝑚1 = 1 W = 1 − 1 = 0
𝒎 = 1,0,1,1,0
[TW CTF 2nd 2016] Crypto200
Backpacker’s cipher easy mode14
鍵生成
 下記が読み取れる
 秘密鍵: 𝑎1, … , 𝑎 𝑛 , 𝑝, 𝑞
 𝑎𝑖 = (𝑟𝑎𝑛𝑑(2 𝑛−𝑖
) 1 ∗ 2𝑖
 𝑝, 𝑞 :互いに素
 公開鍵: 𝑏1, … , 𝑏 𝑛
 𝑏𝑖 =q ∗ 𝑎𝑖 𝑚𝑜𝑑 𝑝
15
暗号化
 ①メッセージをDESで暗号化
 DES暗号文:DES 𝑀 = {(𝑑𝑚1, … , 𝑑𝑚 𝑛)|𝑑𝑚𝑖 ∈ {0,1}}
 鍵は秘密ではない(’testpass’)
 ②ナップサック暗号化
 𝑖=1
𝑛
𝑏𝑖 ∗ 𝑑𝑚𝑖 = 𝐶
16
復号
 疲れたらしい
17
方針
 バックパック暗号の「復号」を目指す
 復号に必要な秘密鍵は?
 復号に必要なトラップドアは?
 Step 1 秘密鍵の取得
 Step 2 トラップドアを利用した復号
18
Step1:15分
Step2:15分
秘密鍵の取得
 公開鍵:𝑏𝑖 = 𝑞 ∗ (rand(2 𝑛−𝑖 ) 1 ∗ 2𝑖 mod 𝑝
 𝑖 = 𝑛 の場合、𝑏 𝑛 = 𝑞 ∗ 2 𝑛
mod 𝑝
 rand(2 𝑛−𝑖
) 1 = rand 1 1 = 1
 𝑖 = 𝑛 − 1 の場合、𝑏 𝑛−1 = 𝑞 ∗ 2 𝑛−1 ∗ (1 or 3) mod 𝑝
 rand(2 𝑛−𝑖
) 1 = rand 2 1 = 1 or 3
 公開鍵(pubkey)を見てみると
 pubkey[1022](=𝑏 𝑛−1) とpubkey[1023](=𝑏 𝑛)が手に入る
19
秘密鍵の取得
 rand 2 |1 = 1の場合、𝑝 = 2 ∗ 𝑏 𝑛−1 − 𝑏 𝑛として導出可能
 2 ∗ 𝑏 𝑛−1 ≡ 𝑏 𝑛 mod 𝑝 ≡ 𝑏 𝑛 + 𝛼𝑝 (𝛼 ∈ 𝑁)
 rand 2 |1 = 3の場合も同様に導出可能
20
秘密鍵の取得
 𝑞 ≡ 𝑏 𝑛 ∗ 2−𝑛
mod 𝑝
 𝑝 が導出できたので、2−𝑛
mod 𝑝 が導出可能
 秘密鍵とメッセージの積も導出可能
 𝑎𝑖 = 𝑏𝑖 ∗ 𝑞−1
mod 𝑝
 𝐶 ∗ 𝑞−1
mod p = 𝑖=0
𝑛
𝑎𝑖 ∗ 𝑑𝑚𝑖
 まだ平文は手に入らない
 トラップドアが分からないから
 疲れちゃったから仕方ない
21
Step2:15分
トラップドア
 𝑎𝑖 = (rand(2 𝑛−𝑖
) 1 ∗ 2𝑖
 or 1 → 最下位ビットに1
 2𝑖
→ iビットシフト
 𝑎𝑖 ∗ 𝑑𝑚𝑖
 𝑑𝑚𝑖 = 0の場合:影響を与えない
 𝑑𝑚𝑖 = 1の場合:𝑖ビット目に1、𝑖 + 1ビット以上にランダム
ビット加算、𝑖ビット未満には影響を与えない
22
𝑎1 = 1111001011001
𝑎2 = 1100110001110
𝑎3 = 1011001100100
𝑎4 = 1111110111000
𝑑𝑚1 = 1
𝑑𝑚2 = 0
𝑑𝑚3 = 1
𝑑𝑚4 = 1
𝑖=1
4
𝑎𝑖 ∗ 𝑑𝑚𝑖 = 101010001110101
トラップドア
 復号アルゴリズム
 暗号文𝐶の下位ビットから順にビットをチェック
 もし𝑖ビット目が1ならば𝑑𝑚𝑖 = 1と判断し、C = 𝐶 − 𝑎𝑖とする
 もし𝑖ビット目が0ならば𝑑𝑚𝑖 = 0と判断
 次のビットへ移動
23
𝑖=1
4
𝑎𝑖 ∗ 𝑑𝑚𝑖 = 101010001110101
𝑎1 = 1111001011001 𝑑𝑚1 = 1
𝑖=1
4
𝑎𝑖 ∗ 𝑑𝑚𝑖 − 𝑎1 = 11011000011100
𝑑𝑚2 = 0
𝑑𝑚3 = 1𝑖=1
4
𝑎𝑖 ∗ 𝑑𝑚𝑖 − 𝑎1 = 11011000011100
𝑑𝑚4 = 1
𝑖=1
4
𝑎𝑖 ∗ 𝑑𝑚𝑖 − 𝑎1 − 𝑎3 = 1111110111000
𝑎2 = 1100110001110
𝑎3 = 1011001100100
トラップドア
 導出できるのはDESで暗号化された平文
 鍵はわかっているので復号するだけ
 KEY=‘testpass’
24
確認:10分
数学のお話25
基底
 基底:線形独立なベクトルから成る集合で、そのベクトル
の(有限個の)線型結合として、与えられたベクトル空間
の全てのベクトルを表すことができるもの(by wikipedia)
 もし2次元なら下記𝑏1, 𝑏2は基底となる
 𝑎1 𝑏1 + 𝑎2 𝑏2 (𝑎 ∈ 𝑅)で2次元のすべての空間を表せればよい
26
𝑏2
𝑏1
𝑏1 =
1
0
𝑏2 =
0
1
𝑏2
𝑏1
𝑏1 =
1
1/2
𝑏2 =
1
3
格子
 格子:実ベクトル空間 Rn を生成するような Rn の離散部分
群をいう。すなわち、Rn の任意の格子は、ベクトル空間と
しての基底から、その整数係数線型結合の全体として得ら
れる。(by wikipedia)
 もし2次元なら下記L(B) は基底となる
 𝐿 𝐵 = 𝑎1 𝑏1 + 𝑎2 𝑏2 𝑎 ∈ 𝑍
 係数が整数に限定
27
𝑏2
𝑏1
𝑏2
𝑏1
最短ベクトル問題
 格子に存在する最も距離(=ユークリッドノルム)が短い非
零ベクトルを見つける問題
 NP困難:NP完全と同等以上に難しい
 高次元の場合、 (𝑥1, 𝑥2, ⋯ , 𝑥 𝑛)を求めることは計算量が非常に
大きい
28
𝑏2
𝑏1
𝑏2
𝑏1
LLLアルゴリズム
 Lenstra, Lenstra, Lovaszらにより1982年に提案
 グラムシュミットの直行化を利用
 ある格子𝐿(𝐵)と同じ格子を生成する異なる基底𝐵′を導出す
るアルゴリズム
 導出された基底𝐵′はLLL簡約基底となる
 LLL簡約基底:距離が短い基底
 LLL簡約基底の第一ベクトルは、(近似)最短ベクトルとなる
 LLLアルゴリズムを格子に適用すると、確率的に(近似)最
短ベクトルが導出できる!
29
SageでLLLを使ってみる
 行列型のオブジェクトがLLL()メソッドを持つ
 強い
30
[Plaid CTF 2015] Crypto180
Lazy31
準備
 Plaid CTF 2015 Lazy
 https://github.com/ctfs/write-ups-2015/tree/master/plaidctf-
2015/crypto/lazy
32
鍵生成
 Markle-Hellmanナップサック暗号
 秘密鍵: 𝑎1, … , 𝑎 𝑛 , 𝑁, 𝑟
 𝑎はsuperincreasing(超増加数列) であり 𝑥=1
𝑖−1
𝑎 𝑥 < 𝑎𝑖 を満たす
 N, 𝑟は互いに素
 公開鍵: 𝑏1, … , 𝑏 𝑛
 𝑏𝑖 = 𝑟 ∗ 𝑎𝑖 mod 𝑁
33
暗号化
 ナップサック暗号化
 𝑖=1
𝑛
𝑏𝑖 ∗ 𝑚𝑖 = 𝐶
34
復号
 ナップサック復号
 𝐶 ∗ 𝑟−1
mod 𝑁 ≡ 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑚𝑖
 超増加数列の性質より、下記で𝑚𝑖を導出可能
 ⓪ S = 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑚𝑖, 𝑥 = 𝑛 とする
 ① S ≥ 𝑎 𝑥であれば、𝑚 𝑥 = 1とし、𝑆 = 𝑆 − 𝑎 𝑥とする
 ② S < 𝑎 𝑥であれば、𝑚 𝑥 = 0とする
 ③ 𝑥をデクリメント
 ①~③を繰り返す
35
方針
 Markle-Hellmanナップサック暗号
 とくにひねりはない(よね?)
 いくつか攻撃手法が報告
 低密度攻撃
 密度:平文のビット数/暗号文の平均ビット数
 平文空間と暗号文空間の大きさの違い
 密度𝑑 = 𝑛/ log2 max 𝑎𝑖
 密度が小さい場合、部分和問題を(近似)最短ベクトル問題
と結びつけナップサック暗号を解読可能
 LO法:𝑑 < 0.64のナップサック暗号を解読
 CLOS法:LO法で解読できる密度を𝑑 < 0.94まで改良
 Lazyの密度:0.90
 低密度攻撃で解ける!
36
低密度攻撃の考え方
 準備
 𝑖=1
𝑛
𝑏𝑖 ∗ 𝑚𝑖 = 𝐶は𝑛次元空間におけるベクトルとみなせる
 考え方
 𝑖=1
𝑛
𝑏𝑖
′
∗ 𝑚𝑖が最短ベクトルとなる格子𝐿(𝐵′
)を準備
 𝐵′
= (𝑏1
′
, … , 𝑏 𝑛
′
) ≠ (𝑏1, … , 𝑏 𝑛)
 格子𝐿(𝐵′
)の最短ベクトルを導出すれば平文が導出可能
 LLLアルゴリズム等で最短ベクトルを導出可能
37
Step1:15分
Step2:15分
都合の良い最短ベクトル
 次のような基底𝐵とベクトル𝑡を考える
 𝐵 = 𝑏1 𝑏2 ⋯ 𝑏 𝑛−1 𝑏 𝑛 =
𝑎1 𝑎2 ⋯ 𝑎 𝑛−1 𝑎 𝑛
2 0 ⋯ 0 0
0 2 ⋯ 0 0
⋮ ⋮ ⋯ ⋮ ⋮
0 0 ⋯ 2 0
0 0 ⋯ 0 2
=
𝑎
2𝐼 𝑛
 𝑡 = 𝑆 1 ⋯ 1 1 𝑇
 ここでS = 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑥𝑖より格子上のベクトル𝐵𝑥と𝑡の距離ベクトルは
下記で導出できる
 𝐵𝑥 − 𝑡 =
𝑖=1
𝑛
𝑎𝑖 ∗ 𝑥𝑖 − 𝑆
2𝑥1 − 1
2𝑥2 − 1
⋮
2𝑥 𝑛−1 − 1
2𝑥 𝑛 − 1
38
都合の良い最短ベクトル
 𝐵𝑥 − 𝑡の距離は下記で導出できる
 𝐵𝑥 − 𝑡 = ( 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑥𝑖 − S)2 + 𝑖=1
𝑛
2𝑥𝑖 − 1 2 = 𝑛
 𝑖−1
𝑛
𝑎𝑖 ∗ 𝑥𝑖 − 𝑆=0
 2𝑥𝑖 − 1 ∈ {−1,1}
 𝐵𝑥 − 𝑡の距離は𝑎𝑖や𝑆の大きさに左右されず、高々 𝑛におさまる
39
都合の良い格子
 次のような基底𝐵′を考える
 𝐵′
=
𝑐 ∗ 𝑎 −𝑐 ∗ 𝑆
2𝐼 −1
=
𝑐 ∗ 𝑎1 𝑐 ∗ 𝑎2 ⋯ 𝑐 ∗ 𝑎 𝑛 −𝑐 ∗ 𝑆
2 0 ⋯ 0 −1
0 2 ⋯ 0 −1
⋮ ⋮ ⋯ ⋮ ⋮
0 0 ⋯ 0 −1
0 0 ⋯ 2 −1
 𝑐は十分に大きな定数
 一般にベクトルが大きくなることが期待できる
 前頁より、この基底は1~𝑛列の係数が𝑥𝑖、𝑛 + 1列の係数が1の場合、
長さ 𝑛のベクトル(= 𝐵𝑥 − 𝑡)を持つ
 他のベクトルが大きい場合、最短ベクトルとなることが期待できる
 𝐿(𝐵′
)の最短ベクトルの係数が0,1, −1のみであれば、そのベクトル
は𝐵𝑥 − 𝑡である可能性が高い
40
部分和問題の解答
 最短ベクトルが𝐵𝑥 − 𝑡の条件を満たしているならば、
 𝐵𝑥 − 𝑡 =
0
2𝑥1 − 1
2𝑥2 − 1
⋮
2𝑥 𝑛−1 − 1
2𝑥 𝑛 − 1
 2番目~n+1番目の係数より下記手順で𝑥𝑖が導出できる
 係数が1の場合
 2𝑥𝑖 − 1 = 1よって𝑥𝑖 = 1
 係数が−1の場合
 2𝑥𝑖 − 1 = −1 よって𝑥𝑖 = 0
41
Step2:15分
こたえ
 基底𝐵′を生成
 LLLアルゴリズムを適用
 SageのLLLの仕様上、転置(transpose)
42
こたえ
 𝐵𝑥 − 𝑡の条件を満たすベクトルを探索
 𝑥𝑖を導出
43
確認:10分
[TW CTF 2nd 2016] Crypto450
Backpacker’s cipher extra mode44
準備
 TWCTF 2nd 2016 Backpacker's cipher - extra mode
 https://github.com/TokyoWesterns/twctf-2016-
problems/tree/master/Backpacker's%20cipher%20-%20extra%20mode
45
鍵生成
 ナップサック暗号っぽい
 秘密鍵:(s1, … , 𝑠 𝑛), 𝑝, 𝑒
 𝑠𝑖はランダムな整数
 𝑝は 𝑥=1
𝑛
𝑎 𝑥 < 𝑝 を満たす素数
 𝑒は
𝑝
2
< 𝑒 < 𝑝を満たす整数
 公開鍵: 𝑎1, … , 𝑎 𝑛 , 𝑏1, … , 𝑏 𝑛 , 𝑧 = 2128
, 𝑛 = 300
 𝑎𝑖 = 𝑒 ∗ 𝑠𝑖 𝑚𝑜𝑑 𝑝
 𝑏𝑖 = 𝑠𝑖 𝑚𝑜𝑑 𝑧
46
暗号化
 ナップサック暗号でAESの鍵(𝑘𝑒𝑦)を生成
 𝑥1, … , 𝑥 𝑛 𝑥 ∈ 0,1
 𝑘𝑒𝑦 = 𝑖=1
𝑛
𝑏𝑖 ∗ 𝑥𝑖 mod 𝑧
 𝑥𝑖はランダムな値
 ナップサック暗号でAESの初期化ベクトル(𝑒𝑛𝑐_𝑘𝑒𝑦)を生成
 𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑥𝑖
 AESでflag(𝑚𝑒𝑠𝑠𝑎𝑔𝑒)を暗号化
 𝑒𝑛𝑐_𝑚𝑒𝑠𝑠𝑎𝑔𝑒 = AES_enc 𝑘𝑒𝑦, 𝑒𝑛𝑐_𝑘𝑒𝑦, 𝑚𝑒𝑠𝑠𝑎𝑔𝑒
 初期化ベクトル, 暗号文を公開
 暗号化に使った鍵(𝑘𝑒𝑦)は公開しない
47
復号
 𝑒𝑛𝑐_𝑘𝑒𝑦から𝑘𝑒𝑦を導出し、AESを復号
 𝑒𝑛𝑐_𝑘𝑒𝑦 ∗ 𝑒−1
mod 𝑝 mod 𝑧 ≡ 𝑖=1
𝑛
𝑠𝑖 mod 𝑧 ≡ 𝑘𝑒𝑦
 𝑚𝑒𝑠𝑠𝑎𝑔𝑒 = AES_dec(𝑘𝑒𝑦, 𝑒𝑛𝑐_𝑘𝑒𝑦, 𝑒𝑛𝑐_𝑚𝑒𝑠𝑠𝑎𝑔𝑒)
48
ナップサック鍵共有
 ナップサック鍵共有
 暗号化に利用する鍵(𝑘𝑒𝑦, 𝑒𝑛𝑐_𝑘𝑒𝑦)=ナップサック暗号で生成
 暗号化自体はAESで実施
 AESの復号には𝑘𝑒𝑦が必要
 𝑒𝑛𝑐_𝑘𝑒𝑦は公開されているが𝑘𝑒𝑦は秘密
 𝑘𝑒𝑦の導出には𝑒, 𝑝が必要
 𝑒−1
∗ 𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑘𝑒𝑦を導出するため
49
低密度攻撃(LLLアルゴリズム
を用いた解法)の注意
 𝑒𝑛𝑐_𝑘𝑒𝑦は𝑥をナップサック暗号化した暗号文
 𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑥𝑖
 𝑒𝑛𝑐_𝑘𝑒𝑦にLLLアルゴリズムを適用して𝑥𝑖を求めればよい?
 低密度攻撃を実施する際の注意
 LLLアルゴリズムを利用する攻撃=低密度攻撃
 密度が0.94よりも大きい場合、𝑥𝑖を導出できない
 密度:平文のビット数/暗号文の平均ビット数
 𝑑 = 𝑛/ log2 max 𝑎𝑖
 本問題の密度:1.21
50
密度が1を超えるとは?
 密度:平文のビット数/暗号文の平均ビット数
 密度が1よりも小さい場合、平文空間<暗号文空間
 一つの暗号文を生成する平文は一つ(の可能性が高い)
 平文空間から暗号文空間への写像は単射(の可能性が高い)
 密度が1よりも大きい場合、平文空間>暗号文空間
 一つの暗号文を生成する平文が多数存在(の可能性が高い)
 平文空間から暗号文空間への写像は全射(の可能性が高い)
 本問題は𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑥𝑖を構成する𝑥𝑖が複数存在する
(可能性が高い)
51
方針
 密度が1を超える場合、複数の平文が同じ暗号文を生成
 この状況で𝑒𝑛𝑐_𝑘𝑒𝑦 に対して、前問と同様にLLLアルゴリズ
ムを利用すると?
 𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑖=1
𝑛
𝑎𝑖 ∗ 𝑥𝑖′を生成する𝑥𝑖
′
を導出可能
 𝑥𝑖 ≠ 𝑥𝑖
′
∈ 𝑍 (not only 0 or 1)
 本問題では𝑥𝑖′ ≠ 𝑥𝑖であっても𝑘𝑒𝑦 = 𝑖=1
𝑛
𝑏𝑖 ∗ 𝑥𝑖′ mod 𝑧を導
出可能
 𝑖=1
𝑛
𝑏𝑖 ∗ 𝑥𝑖′ mod 𝑧 ≡ ( 𝑖=1
𝑛
𝑒−1
∗ 𝑎𝑖 ∗ 𝑥𝑖
′
mod 𝑝) mod 𝑧
≡ 𝑒𝑛𝑐_𝑘𝑒𝑦 ∗ 𝑒−1
mod 𝑝 mod 𝑧 ≡ 𝑖=1
𝑛
𝑠𝑖 mod 𝑧 ≡ 𝑘𝑒𝑦
52
Step1:15分
Step2:15分
都合のよい格子
 次のような基底𝐵′を考える
 𝐵′
=
1 0 ⋯ 0 0
0 1 ⋯ 0 0
⋮ ⋮ ⋯ ⋮ ⋮
0 0 ⋯ 1 0
𝑐 ∗ 𝑎1 𝑐 ∗ 𝑎2 ⋯ 𝑐 ∗ 𝑎 𝑛 −𝑐 ∗ 𝑆
0 0 ⋯ 0 1
 𝑐は十分に大きな定数
 Lazyの基底でも導出できるが、より簡単に導出するため
 この基底は1~𝑛列の係数が𝑥𝑖′、𝑛 + 1列の係数が1の場合、下記
ベクトル𝑣を持つ
 𝑣 =
𝑥1′
𝑥2′
𝑥3′
⋮
𝑖−1
𝑛
𝑎𝑖 ∗ 𝑥𝑖 − 𝑆 =0
1
 他のベクトルが大きい場合、最短ベクトルとなることが期待できる
 𝐿(𝐵′
)の最短ベクトルのn + 1番目の係数が0, 𝑛 +
2番目の係数が1であれば、ベクトルは𝑣である可能性が高い
 𝑥𝑖
′
を構成する値は0,1だけではないことに注意
53
こたえ
 基底𝐵′を生成
 LLLアルゴリズムを適用
 SageのLLLの仕様上、転置(transpose)
54
こたえ
 𝑣の条件を満たすベクトルを探索
 𝐾𝑒𝑦を導出し、AESを復号
55
確認:10分
まとめ
 [TW CTF 2nd 2016] Crypto200 – Backpacker’s cipher easy mode
 ナップサック暗号の基本について学習した
 [Plaid CTF 2015] Crypto180 – Lazy
 低密度攻撃について学習した
 [TW CTF 2nd 2016] Crypto450 – Backpacker’s cipher extra mode
 高密度攻撃?について学習した
56
今日から君もナップサック暗号マスターだ!
参考文献
 Ralph Merkle, Martin Hellman, "Hiding Information and Signatures in Trapdoor Knapsacks", IEEE
Trans. Information Theory, 24(5), September 1978, pp.525–530.
 J. C. Lagarias and A. M. Odlyzko, “Solving Low Density Subset Sum Problems,” J. Assoc.
Comp.Math., vol.32, pp.229–246, Preliminary version in Proc. 24th IEEE, 1985
 M. J. Coster, B. A. LaMacchia, A. M. Odlyzko and C. P. Schnorr, “An Improved Low-Density Subset
Sum Algorithm,” In Advances in Cryptology Proc. EUROCRYPTO'91,LNCS, pp.54–67.Springer-Verlag,
Berlin, 1991.
 D.ミッチアンチオ, S. ゴールドヴァッサー, “暗号理論のための格子の数学” シュプリン
ガー・ジャパン, 2006.
 https://github.com/everping/ctfs/blob/master/2015/4/plaidctf/crypto/lazy/solve.py
 http://www.gnoobz.com/plaid-ctf-2015-lazy-writeup.html
 https://gist.github.com/Bono-iPad/2731d096a3756d582d9c0310fb145543
 http://bono-ipad.github.io/burningctf2015_writeup.html
57

katagaitai workshop #7 crypto ナップサック暗号と低密度攻撃

  • 1.
    katagaitai CTF Workshop #7 Crypto 2017.02.25TOKYO trmr (@trmr105) katagaitai
  • 2.
    #7 はじまるよー!  katagaitaiCTF勉強会の歴史  2012年~2014年:某所での下積み時代  2014年冬:CTF勉強会 #1 共通素数を持つRSA  2015年夏:CTF勉強会 #2 CRIME  2015年冬:CTF勉強会 #3 SPN構造ブロック暗号の差分解析  2015年冬:CTF勉強会 #4 Feistel構造ブロック暗号の差分解析  2016年夏:CTF勉強会 #5 ハッシュ関数の衝突&Length Extention  2016年夏:CTF勉強会 #6 ー  2016年冬:CTF勉強会 #7 ナップサック暗号  下記URLで過去の勉強会資料を公開中  https://speakerdeck.com/bata_24  http://www.slideshare.net/trmr105 イマココ! 2
  • 3.
  • 4.
    Special Thanks  本資料は以下の方にご協力いただいてます Bonoさん(@bono_ipad)  shiho midorikawaさん(@elliptic_shiho)  nomeaningさん(@__nomeaning__ ) 4
  • 5.
  • 6.
  • 7.
    今日の問題  [TW CTF2nd 2016] Crypto200 – Backpacker’s cipher easy mode  [Plaid CTF 2015] Crypto180 – Lazy  [TW CTF 2nd 2016] Crypto450 – Backpacker’s cipher extra mode 7 TWCTF : Tokyo Westerns/MMA CTF
  • 8.
    目次  ナップサック暗号  [TWCTF 2nd 2016] Crypto200 – Backpacker’s cipher easy mode  数学のお話  [Plaid CTF 2015] Crypto180 – Lazy  [TW CTF 2nd 2016] Crypto450 – Backpacker’s cipher extra mode 8
  • 9.
  • 10.
    公開鍵暗号  公開鍵暗号  暗号化用の鍵(公開鍵)と復号用の鍵(秘密鍵)が異なる暗 号 一方向性関数を利用して構築  一方向性関数  入力→出力は容易に計算可能  出力→入力が計算が困難  一方向性関数の例  素因数分解問題 -> RSA  離散対数問題 -> Elgamal, 楕円曲線暗号  部分和問題 -> ナップサック暗号 etc. 10
  • 11.
    部分和問題  部分和問題 (subsetsum problem)  (𝑣1, … , 𝑣 𝑛)からある値𝑊を構成する部分和を見つける問題  𝑖=0 𝑛 𝑣𝑖 ∗ 𝑥𝑖 = 𝑊となるような (𝑥1, 𝑥2, ⋯ , 𝑥 𝑛)を導出する問題  𝑥𝑖 ∈ 0,1 ; 𝑖 ∈ { 1, … , 𝑛}  NP完全:多項式時間で答えを見つけることができない  𝑛の値が大きい場合、 (𝑥1, 𝑥2, ⋯ , 𝑥 𝑛)を求めることは計算量的に困難 11 例 𝒗 = 1,3,7,15,40 𝒙 = 1,0,1,1,0 𝑊 = 1 + 7 + 15 = 23 Photo by Dake
  • 12.
    ナップサック暗号  ナップサック暗号 (knapsackcrypto system)  一方向性関数として部分和問題を利用  秘密鍵:𝒂 = { 𝑎1, … , 𝑎 𝑛 | 𝑎𝑖 ∈ 𝑍}; 𝑝, 𝑞  𝑞 > 𝑖=1 𝑛 𝑎𝑖  𝑝, 𝑞は互いに素  公開鍵:𝒃 = { 𝑏1, … , 𝑏 𝑛 | 𝑏𝑖 = 𝑝 ∗ 𝑎𝑖 mod 𝑞}  平文:𝒎 = 𝑚1, … , 𝑚 𝑛 𝑚𝑖 ∈ {0,1}}  暗号化  𝑖=1 𝑛 𝑏𝑖 ∗ 𝑚𝑖 = 𝐶  暗号文𝐶から平文/鍵を導出するには?  部分和問題を解く必要  このままでは受信者も平文を導出できないのでトラップドアが必要  MHナップサック暗号  トラップドアに超増加数列を利用  超増加数列:𝑎 𝑥+1 > 𝑖=1 𝑥 𝑎𝑖 を満たす数列(𝑎1, … , 𝑎 𝑛) 12
  • 13.
    トラップドアと超増加数列  トラップドアを用いた部分和の導出  超増加数列の性質より、下記で𝑥𝑖を導出可能 ⓪ 𝑊 = 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑚 𝑥, 𝑥 = 𝑛 とする  ① 𝑊 ≥ 𝑎 𝑥であれば、𝑚 𝑥 = 1とし、𝑆 = 𝑆 − 𝑎 𝑥とする  ② 𝑊 < 𝑎 𝑥であれば、𝑚 𝑥 = 0とする  ③ 𝑥をデクリメント  ①~③を繰り返す 13 例 𝒗 = 1,3,7,15,40 , 𝑊 = 23, 𝑛 = 5 𝑣5 = 40 > 𝑊 よって𝑚5 = 0 𝑣4 = 15 ≤ 𝑊 よって𝑚4 = 1 W = 23 − 15 = 8 𝑣3 = 7 ≤ 𝑊 よって𝑚3 = 1 W = 8 − 7 = 1 𝑣2 = 3 > 𝑊 よって𝑚2 = 0 𝑣1 = 1 ≤ 𝑊 よって𝑚1 = 1 W = 1 − 1 = 0 𝒎 = 1,0,1,1,0
  • 14.
    [TW CTF 2nd2016] Crypto200 Backpacker’s cipher easy mode14
  • 15.
    鍵生成  下記が読み取れる  秘密鍵:𝑎1, … , 𝑎 𝑛 , 𝑝, 𝑞  𝑎𝑖 = (𝑟𝑎𝑛𝑑(2 𝑛−𝑖 ) 1 ∗ 2𝑖  𝑝, 𝑞 :互いに素  公開鍵: 𝑏1, … , 𝑏 𝑛  𝑏𝑖 =q ∗ 𝑎𝑖 𝑚𝑜𝑑 𝑝 15
  • 16.
    暗号化  ①メッセージをDESで暗号化  DES暗号文:DES𝑀 = {(𝑑𝑚1, … , 𝑑𝑚 𝑛)|𝑑𝑚𝑖 ∈ {0,1}}  鍵は秘密ではない(’testpass’)  ②ナップサック暗号化  𝑖=1 𝑛 𝑏𝑖 ∗ 𝑑𝑚𝑖 = 𝐶 16
  • 17.
  • 18.
    方針  バックパック暗号の「復号」を目指す  復号に必要な秘密鍵は? 復号に必要なトラップドアは?  Step 1 秘密鍵の取得  Step 2 トラップドアを利用した復号 18 Step1:15分 Step2:15分
  • 19.
    秘密鍵の取得  公開鍵:𝑏𝑖 =𝑞 ∗ (rand(2 𝑛−𝑖 ) 1 ∗ 2𝑖 mod 𝑝  𝑖 = 𝑛 の場合、𝑏 𝑛 = 𝑞 ∗ 2 𝑛 mod 𝑝  rand(2 𝑛−𝑖 ) 1 = rand 1 1 = 1  𝑖 = 𝑛 − 1 の場合、𝑏 𝑛−1 = 𝑞 ∗ 2 𝑛−1 ∗ (1 or 3) mod 𝑝  rand(2 𝑛−𝑖 ) 1 = rand 2 1 = 1 or 3  公開鍵(pubkey)を見てみると  pubkey[1022](=𝑏 𝑛−1) とpubkey[1023](=𝑏 𝑛)が手に入る 19
  • 20.
    秘密鍵の取得  rand 2|1 = 1の場合、𝑝 = 2 ∗ 𝑏 𝑛−1 − 𝑏 𝑛として導出可能  2 ∗ 𝑏 𝑛−1 ≡ 𝑏 𝑛 mod 𝑝 ≡ 𝑏 𝑛 + 𝛼𝑝 (𝛼 ∈ 𝑁)  rand 2 |1 = 3の場合も同様に導出可能 20
  • 21.
    秘密鍵の取得  𝑞 ≡𝑏 𝑛 ∗ 2−𝑛 mod 𝑝  𝑝 が導出できたので、2−𝑛 mod 𝑝 が導出可能  秘密鍵とメッセージの積も導出可能  𝑎𝑖 = 𝑏𝑖 ∗ 𝑞−1 mod 𝑝  𝐶 ∗ 𝑞−1 mod p = 𝑖=0 𝑛 𝑎𝑖 ∗ 𝑑𝑚𝑖  まだ平文は手に入らない  トラップドアが分からないから  疲れちゃったから仕方ない 21 Step2:15分
  • 22.
    トラップドア  𝑎𝑖 =(rand(2 𝑛−𝑖 ) 1 ∗ 2𝑖  or 1 → 最下位ビットに1  2𝑖 → iビットシフト  𝑎𝑖 ∗ 𝑑𝑚𝑖  𝑑𝑚𝑖 = 0の場合:影響を与えない  𝑑𝑚𝑖 = 1の場合:𝑖ビット目に1、𝑖 + 1ビット以上にランダム ビット加算、𝑖ビット未満には影響を与えない 22 𝑎1 = 1111001011001 𝑎2 = 1100110001110 𝑎3 = 1011001100100 𝑎4 = 1111110111000 𝑑𝑚1 = 1 𝑑𝑚2 = 0 𝑑𝑚3 = 1 𝑑𝑚4 = 1 𝑖=1 4 𝑎𝑖 ∗ 𝑑𝑚𝑖 = 101010001110101
  • 23.
    トラップドア  復号アルゴリズム  暗号文𝐶の下位ビットから順にビットをチェック もし𝑖ビット目が1ならば𝑑𝑚𝑖 = 1と判断し、C = 𝐶 − 𝑎𝑖とする  もし𝑖ビット目が0ならば𝑑𝑚𝑖 = 0と判断  次のビットへ移動 23 𝑖=1 4 𝑎𝑖 ∗ 𝑑𝑚𝑖 = 101010001110101 𝑎1 = 1111001011001 𝑑𝑚1 = 1 𝑖=1 4 𝑎𝑖 ∗ 𝑑𝑚𝑖 − 𝑎1 = 11011000011100 𝑑𝑚2 = 0 𝑑𝑚3 = 1𝑖=1 4 𝑎𝑖 ∗ 𝑑𝑚𝑖 − 𝑎1 = 11011000011100 𝑑𝑚4 = 1 𝑖=1 4 𝑎𝑖 ∗ 𝑑𝑚𝑖 − 𝑎1 − 𝑎3 = 1111110111000 𝑎2 = 1100110001110 𝑎3 = 1011001100100
  • 24.
  • 25.
  • 26.
    基底  基底:線形独立なベクトルから成る集合で、そのベクトル の(有限個の)線型結合として、与えられたベクトル空間 の全てのベクトルを表すことができるもの(by wikipedia) もし2次元なら下記𝑏1, 𝑏2は基底となる  𝑎1 𝑏1 + 𝑎2 𝑏2 (𝑎 ∈ 𝑅)で2次元のすべての空間を表せればよい 26 𝑏2 𝑏1 𝑏1 = 1 0 𝑏2 = 0 1 𝑏2 𝑏1 𝑏1 = 1 1/2 𝑏2 = 1 3
  • 27.
    格子  格子:実ベクトル空間 Rnを生成するような Rn の離散部分 群をいう。すなわち、Rn の任意の格子は、ベクトル空間と しての基底から、その整数係数線型結合の全体として得ら れる。(by wikipedia)  もし2次元なら下記L(B) は基底となる  𝐿 𝐵 = 𝑎1 𝑏1 + 𝑎2 𝑏2 𝑎 ∈ 𝑍  係数が整数に限定 27 𝑏2 𝑏1 𝑏2 𝑏1
  • 28.
  • 29.
    LLLアルゴリズム  Lenstra, Lenstra,Lovaszらにより1982年に提案  グラムシュミットの直行化を利用  ある格子𝐿(𝐵)と同じ格子を生成する異なる基底𝐵′を導出す るアルゴリズム  導出された基底𝐵′はLLL簡約基底となる  LLL簡約基底:距離が短い基底  LLL簡約基底の第一ベクトルは、(近似)最短ベクトルとなる  LLLアルゴリズムを格子に適用すると、確率的に(近似)最 短ベクトルが導出できる! 29
  • 30.
  • 31.
    [Plaid CTF 2015]Crypto180 Lazy31
  • 32.
    準備  Plaid CTF2015 Lazy  https://github.com/ctfs/write-ups-2015/tree/master/plaidctf- 2015/crypto/lazy 32
  • 33.
    鍵生成  Markle-Hellmanナップサック暗号  秘密鍵:𝑎1, … , 𝑎 𝑛 , 𝑁, 𝑟  𝑎はsuperincreasing(超増加数列) であり 𝑥=1 𝑖−1 𝑎 𝑥 < 𝑎𝑖 を満たす  N, 𝑟は互いに素  公開鍵: 𝑏1, … , 𝑏 𝑛  𝑏𝑖 = 𝑟 ∗ 𝑎𝑖 mod 𝑁 33
  • 34.
  • 35.
    復号  ナップサック復号  𝐶∗ 𝑟−1 mod 𝑁 ≡ 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑚𝑖  超増加数列の性質より、下記で𝑚𝑖を導出可能  ⓪ S = 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑚𝑖, 𝑥 = 𝑛 とする  ① S ≥ 𝑎 𝑥であれば、𝑚 𝑥 = 1とし、𝑆 = 𝑆 − 𝑎 𝑥とする  ② S < 𝑎 𝑥であれば、𝑚 𝑥 = 0とする  ③ 𝑥をデクリメント  ①~③を繰り返す 35
  • 36.
    方針  Markle-Hellmanナップサック暗号  とくにひねりはない(よね?) いくつか攻撃手法が報告  低密度攻撃  密度:平文のビット数/暗号文の平均ビット数  平文空間と暗号文空間の大きさの違い  密度𝑑 = 𝑛/ log2 max 𝑎𝑖  密度が小さい場合、部分和問題を(近似)最短ベクトル問題 と結びつけナップサック暗号を解読可能  LO法:𝑑 < 0.64のナップサック暗号を解読  CLOS法:LO法で解読できる密度を𝑑 < 0.94まで改良  Lazyの密度:0.90  低密度攻撃で解ける! 36
  • 37.
    低密度攻撃の考え方  準備  𝑖=1 𝑛 𝑏𝑖∗ 𝑚𝑖 = 𝐶は𝑛次元空間におけるベクトルとみなせる  考え方  𝑖=1 𝑛 𝑏𝑖 ′ ∗ 𝑚𝑖が最短ベクトルとなる格子𝐿(𝐵′ )を準備  𝐵′ = (𝑏1 ′ , … , 𝑏 𝑛 ′ ) ≠ (𝑏1, … , 𝑏 𝑛)  格子𝐿(𝐵′ )の最短ベクトルを導出すれば平文が導出可能  LLLアルゴリズム等で最短ベクトルを導出可能 37 Step1:15分 Step2:15分
  • 38.
    都合の良い最短ベクトル  次のような基底𝐵とベクトル𝑡を考える  𝐵= 𝑏1 𝑏2 ⋯ 𝑏 𝑛−1 𝑏 𝑛 = 𝑎1 𝑎2 ⋯ 𝑎 𝑛−1 𝑎 𝑛 2 0 ⋯ 0 0 0 2 ⋯ 0 0 ⋮ ⋮ ⋯ ⋮ ⋮ 0 0 ⋯ 2 0 0 0 ⋯ 0 2 = 𝑎 2𝐼 𝑛  𝑡 = 𝑆 1 ⋯ 1 1 𝑇  ここでS = 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑥𝑖より格子上のベクトル𝐵𝑥と𝑡の距離ベクトルは 下記で導出できる  𝐵𝑥 − 𝑡 = 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑥𝑖 − 𝑆 2𝑥1 − 1 2𝑥2 − 1 ⋮ 2𝑥 𝑛−1 − 1 2𝑥 𝑛 − 1 38
  • 39.
    都合の良い最短ベクトル  𝐵𝑥 −𝑡の距離は下記で導出できる  𝐵𝑥 − 𝑡 = ( 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑥𝑖 − S)2 + 𝑖=1 𝑛 2𝑥𝑖 − 1 2 = 𝑛  𝑖−1 𝑛 𝑎𝑖 ∗ 𝑥𝑖 − 𝑆=0  2𝑥𝑖 − 1 ∈ {−1,1}  𝐵𝑥 − 𝑡の距離は𝑎𝑖や𝑆の大きさに左右されず、高々 𝑛におさまる 39
  • 40.
    都合の良い格子  次のような基底𝐵′を考える  𝐵′ = 𝑐∗ 𝑎 −𝑐 ∗ 𝑆 2𝐼 −1 = 𝑐 ∗ 𝑎1 𝑐 ∗ 𝑎2 ⋯ 𝑐 ∗ 𝑎 𝑛 −𝑐 ∗ 𝑆 2 0 ⋯ 0 −1 0 2 ⋯ 0 −1 ⋮ ⋮ ⋯ ⋮ ⋮ 0 0 ⋯ 0 −1 0 0 ⋯ 2 −1  𝑐は十分に大きな定数  一般にベクトルが大きくなることが期待できる  前頁より、この基底は1~𝑛列の係数が𝑥𝑖、𝑛 + 1列の係数が1の場合、 長さ 𝑛のベクトル(= 𝐵𝑥 − 𝑡)を持つ  他のベクトルが大きい場合、最短ベクトルとなることが期待できる  𝐿(𝐵′ )の最短ベクトルの係数が0,1, −1のみであれば、そのベクトル は𝐵𝑥 − 𝑡である可能性が高い 40
  • 41.
    部分和問題の解答  最短ベクトルが𝐵𝑥 −𝑡の条件を満たしているならば、  𝐵𝑥 − 𝑡 = 0 2𝑥1 − 1 2𝑥2 − 1 ⋮ 2𝑥 𝑛−1 − 1 2𝑥 𝑛 − 1  2番目~n+1番目の係数より下記手順で𝑥𝑖が導出できる  係数が1の場合  2𝑥𝑖 − 1 = 1よって𝑥𝑖 = 1  係数が−1の場合  2𝑥𝑖 − 1 = −1 よって𝑥𝑖 = 0 41 Step2:15分
  • 42.
    こたえ  基底𝐵′を生成  LLLアルゴリズムを適用 SageのLLLの仕様上、転置(transpose) 42
  • 43.
    こたえ  𝐵𝑥 −𝑡の条件を満たすベクトルを探索  𝑥𝑖を導出 43 確認:10分
  • 44.
    [TW CTF 2nd2016] Crypto450 Backpacker’s cipher extra mode44
  • 45.
    準備  TWCTF 2nd2016 Backpacker's cipher - extra mode  https://github.com/TokyoWesterns/twctf-2016- problems/tree/master/Backpacker's%20cipher%20-%20extra%20mode 45
  • 46.
    鍵生成  ナップサック暗号っぽい  秘密鍵:(s1,… , 𝑠 𝑛), 𝑝, 𝑒  𝑠𝑖はランダムな整数  𝑝は 𝑥=1 𝑛 𝑎 𝑥 < 𝑝 を満たす素数  𝑒は 𝑝 2 < 𝑒 < 𝑝を満たす整数  公開鍵: 𝑎1, … , 𝑎 𝑛 , 𝑏1, … , 𝑏 𝑛 , 𝑧 = 2128 , 𝑛 = 300  𝑎𝑖 = 𝑒 ∗ 𝑠𝑖 𝑚𝑜𝑑 𝑝  𝑏𝑖 = 𝑠𝑖 𝑚𝑜𝑑 𝑧 46
  • 47.
    暗号化  ナップサック暗号でAESの鍵(𝑘𝑒𝑦)を生成  𝑥1,… , 𝑥 𝑛 𝑥 ∈ 0,1  𝑘𝑒𝑦 = 𝑖=1 𝑛 𝑏𝑖 ∗ 𝑥𝑖 mod 𝑧  𝑥𝑖はランダムな値  ナップサック暗号でAESの初期化ベクトル(𝑒𝑛𝑐_𝑘𝑒𝑦)を生成  𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑥𝑖  AESでflag(𝑚𝑒𝑠𝑠𝑎𝑔𝑒)を暗号化  𝑒𝑛𝑐_𝑚𝑒𝑠𝑠𝑎𝑔𝑒 = AES_enc 𝑘𝑒𝑦, 𝑒𝑛𝑐_𝑘𝑒𝑦, 𝑚𝑒𝑠𝑠𝑎𝑔𝑒  初期化ベクトル, 暗号文を公開  暗号化に使った鍵(𝑘𝑒𝑦)は公開しない 47
  • 48.
    復号  𝑒𝑛𝑐_𝑘𝑒𝑦から𝑘𝑒𝑦を導出し、AESを復号  𝑒𝑛𝑐_𝑘𝑒𝑦∗ 𝑒−1 mod 𝑝 mod 𝑧 ≡ 𝑖=1 𝑛 𝑠𝑖 mod 𝑧 ≡ 𝑘𝑒𝑦  𝑚𝑒𝑠𝑠𝑎𝑔𝑒 = AES_dec(𝑘𝑒𝑦, 𝑒𝑛𝑐_𝑘𝑒𝑦, 𝑒𝑛𝑐_𝑚𝑒𝑠𝑠𝑎𝑔𝑒) 48
  • 49.
    ナップサック鍵共有  ナップサック鍵共有  暗号化に利用する鍵(𝑘𝑒𝑦,𝑒𝑛𝑐_𝑘𝑒𝑦)=ナップサック暗号で生成  暗号化自体はAESで実施  AESの復号には𝑘𝑒𝑦が必要  𝑒𝑛𝑐_𝑘𝑒𝑦は公開されているが𝑘𝑒𝑦は秘密  𝑘𝑒𝑦の導出には𝑒, 𝑝が必要  𝑒−1 ∗ 𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑘𝑒𝑦を導出するため 49
  • 50.
    低密度攻撃(LLLアルゴリズム を用いた解法)の注意  𝑒𝑛𝑐_𝑘𝑒𝑦は𝑥をナップサック暗号化した暗号文  𝑒𝑛𝑐_𝑘𝑒𝑦= 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑥𝑖  𝑒𝑛𝑐_𝑘𝑒𝑦にLLLアルゴリズムを適用して𝑥𝑖を求めればよい?  低密度攻撃を実施する際の注意  LLLアルゴリズムを利用する攻撃=低密度攻撃  密度が0.94よりも大きい場合、𝑥𝑖を導出できない  密度:平文のビット数/暗号文の平均ビット数  𝑑 = 𝑛/ log2 max 𝑎𝑖  本問題の密度:1.21 50
  • 51.
    密度が1を超えるとは?  密度:平文のビット数/暗号文の平均ビット数  密度が1よりも小さい場合、平文空間<暗号文空間 一つの暗号文を生成する平文は一つ(の可能性が高い)  平文空間から暗号文空間への写像は単射(の可能性が高い)  密度が1よりも大きい場合、平文空間>暗号文空間  一つの暗号文を生成する平文が多数存在(の可能性が高い)  平文空間から暗号文空間への写像は全射(の可能性が高い)  本問題は𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑥𝑖を構成する𝑥𝑖が複数存在する (可能性が高い) 51
  • 52.
    方針  密度が1を超える場合、複数の平文が同じ暗号文を生成  この状況で𝑒𝑛𝑐_𝑘𝑒𝑦に対して、前問と同様にLLLアルゴリズ ムを利用すると?  𝑒𝑛𝑐_𝑘𝑒𝑦 = 𝑖=1 𝑛 𝑎𝑖 ∗ 𝑥𝑖′を生成する𝑥𝑖 ′ を導出可能  𝑥𝑖 ≠ 𝑥𝑖 ′ ∈ 𝑍 (not only 0 or 1)  本問題では𝑥𝑖′ ≠ 𝑥𝑖であっても𝑘𝑒𝑦 = 𝑖=1 𝑛 𝑏𝑖 ∗ 𝑥𝑖′ mod 𝑧を導 出可能  𝑖=1 𝑛 𝑏𝑖 ∗ 𝑥𝑖′ mod 𝑧 ≡ ( 𝑖=1 𝑛 𝑒−1 ∗ 𝑎𝑖 ∗ 𝑥𝑖 ′ mod 𝑝) mod 𝑧 ≡ 𝑒𝑛𝑐_𝑘𝑒𝑦 ∗ 𝑒−1 mod 𝑝 mod 𝑧 ≡ 𝑖=1 𝑛 𝑠𝑖 mod 𝑧 ≡ 𝑘𝑒𝑦 52 Step1:15分 Step2:15分
  • 53.
    都合のよい格子  次のような基底𝐵′を考える  𝐵′ = 10 ⋯ 0 0 0 1 ⋯ 0 0 ⋮ ⋮ ⋯ ⋮ ⋮ 0 0 ⋯ 1 0 𝑐 ∗ 𝑎1 𝑐 ∗ 𝑎2 ⋯ 𝑐 ∗ 𝑎 𝑛 −𝑐 ∗ 𝑆 0 0 ⋯ 0 1  𝑐は十分に大きな定数  Lazyの基底でも導出できるが、より簡単に導出するため  この基底は1~𝑛列の係数が𝑥𝑖′、𝑛 + 1列の係数が1の場合、下記 ベクトル𝑣を持つ  𝑣 = 𝑥1′ 𝑥2′ 𝑥3′ ⋮ 𝑖−1 𝑛 𝑎𝑖 ∗ 𝑥𝑖 − 𝑆 =0 1  他のベクトルが大きい場合、最短ベクトルとなることが期待できる  𝐿(𝐵′ )の最短ベクトルのn + 1番目の係数が0, 𝑛 + 2番目の係数が1であれば、ベクトルは𝑣である可能性が高い  𝑥𝑖 ′ を構成する値は0,1だけではないことに注意 53
  • 54.
    こたえ  基底𝐵′を生成  LLLアルゴリズムを適用 SageのLLLの仕様上、転置(transpose) 54
  • 55.
  • 56.
    まとめ  [TW CTF2nd 2016] Crypto200 – Backpacker’s cipher easy mode  ナップサック暗号の基本について学習した  [Plaid CTF 2015] Crypto180 – Lazy  低密度攻撃について学習した  [TW CTF 2nd 2016] Crypto450 – Backpacker’s cipher extra mode  高密度攻撃?について学習した 56 今日から君もナップサック暗号マスターだ!
  • 57.
    参考文献  Ralph Merkle,Martin Hellman, "Hiding Information and Signatures in Trapdoor Knapsacks", IEEE Trans. Information Theory, 24(5), September 1978, pp.525–530.  J. C. Lagarias and A. M. Odlyzko, “Solving Low Density Subset Sum Problems,” J. Assoc. Comp.Math., vol.32, pp.229–246, Preliminary version in Proc. 24th IEEE, 1985  M. J. Coster, B. A. LaMacchia, A. M. Odlyzko and C. P. Schnorr, “An Improved Low-Density Subset Sum Algorithm,” In Advances in Cryptology Proc. EUROCRYPTO'91,LNCS, pp.54–67.Springer-Verlag, Berlin, 1991.  D.ミッチアンチオ, S. ゴールドヴァッサー, “暗号理論のための格子の数学” シュプリン ガー・ジャパン, 2006.  https://github.com/everping/ctfs/blob/master/2015/4/plaidctf/crypto/lazy/solve.py  http://www.gnoobz.com/plaid-ctf-2015-lazy-writeup.html  https://gist.github.com/Bono-iPad/2731d096a3756d582d9c0310fb145543  http://bono-ipad.github.io/burningctf2015_writeup.html 57