✲゚。.ヾ(⌒(ノ'ω')ノ☆.。

変色系男子の日常。

ぼけることに対する恐怖について

f:id:quanon:20150911223951g:plain

季節の変わり目のためか、自律神経が不調なようで、身体のこりがひどく頭がもやもやする日々が続く。脳内が霧につつまれたミッドガルのようだ。 さらにそのためか、会話の際に言葉に詰まったりすることが普段より多いような気がする。

こういうときに抱くのが「脳に異常があるのではないか」、よりありていに言えば「ぼけているのではないか」という恐怖だ。

数年前にも似たような症状に悩んでいた時期があり、その際は心療内科の先生の紹介で脳外科を受診したのだが、脳に異常は無かった。 それでも同じような症状が出るたびに、脳の異常が心配になる。 それくらいにぼけることに対する恐怖が大きいのだ。

その強迫観念のようにしつこい恐怖がストレスを生み、さらにストレスを悪化させるという悪循環に陥っている気がする。 じゃあどうすればいいのかと考えてみた。

そうして導き出したひとつの結論が「『ぼけてもいいや』とあきらめる」ということだ。 「ぼけてはいけない」という観念がぼけることに対する恐怖を生むので、それを捨てるということだ。 ぼけることはやはり恐ろしいこと、それはどうしても否定できないが、それでも「ぼけてもしかたない」と肯定的にあきらめることだ。 「ぼける」という状態自体は、それ自体が良いとか悪いとか平気とか恐ろしいとかそういう概念はなく、 恐ろしいと解釈するのはあくまで僕らの主観だ (もしかしたら、ぼけることはなんでもないことだと考える人もこの世にいるかもしれない) 。

と、この間読んだ仏教関連の本の「ものごとをありのままに認める」という旨の内容を思い返してそう思った。

認知症に罹って症状が進行中の段階にある人のことを思うと、その恐怖は察するに余りある。 ぼけて大切な記憶がどんどん欠落していくという事実を当人が認識できてしまうからだ。 しかし、それすら認識できなくなる、つまり「自分がぼけていることすら分からないくらいぼけてしまう」と そんな恐怖を感じることすらなくなり、心に平穏が訪れるのではないだろうか。

まあ実際にぼけきってみないと分からないが、ぼけたらぼけたでそれを認知する能力を失ってしまうので、 とどのつまり「ぼけたあとに心に平穏が訪れるのか否か」は誰にも分からない問題なのだろう。 死後の世界がどのようなものなのか (そもそも存在するのか) は死者にしか分からないが、死んだらそれを認識することができないのと同じように。

そういえば明日スプラトゥーンで開催されるフェスのお題は「まんざいをするなら? ボケ vs ツッコミ」だったな。 そして僕は「ボケ」に投票したんだった。 書いてる途中でお題を思いだした (マジだぜ) 。タイムリーすぎる。

あと 4 ヶ月前にも同じような内容の記事を投稿していたことにあとで気付いた。あはは、やはり僕のぼけに対する恐怖と執着は相当なもののようだ。

日本語名と英語名の対応表 (WIP)

チマチマ更新していく予定。

対応表

武器

日本語 英語
わかばシューター Splattershot Jr.
もみじシューター Custom Splattershot Jr.
スプラシューター Splattershot
ヒーローシューター レプリカ Hero Shot Replica
プライムシューター Splattershot Pro
プライムシューターコラボ Forge Splattershot Pro
スプラシューターコラボ Tentatek Splattershot
プロモデラーMG Aerospray MG
プロモデラーRG Aerospray RG
ジェットスイーパー Jet Squelcher
ジェットスイーパーカスタム Custom Jet Squelcher
デュアルスイーパー Dual Squelcher

サブウェポン

日本語 英語
スプラッシュボム Splat Bomb
スプリンクラー Sprinkler
チェイスボム Seekers
キューバンボム Suction Bomb
クイックボム Burst Bomb
トラップ Ink Mine
ポイントセンサー Point Sensor
ジャンプビーコン Squid Beakon
スプラッシュシールド Splash Wall
ポイズンボール Disruptor

スペシャルウェポン

日本語 英語
バリア Bubbler
スーパーショット Inkzooka
ボムラッシュ Bomb Rush
メガホンレーザー Killer Wail
トルネード Inkstrike
スーパーセンサー Echolocator
ダイオウイカ Kraken

参考

http://splatoon.wikia.com/wiki/Splatoon_Wiki:Main_Menusplatoon.wikia.com

Diffie-Hellman で鍵交換しましょ★

概要

暗号技術入門 を読み終えて、はや 2 ヶ月弱が経過しました。だいぶん中身を忘れてきているので、復習がてら Diffie-Hellman 鍵交換 についてまとめてみたいと思います。

鍵配送問題について

Diffie-Hellman 鍵交換について語るには、まず鍵配送問題について話しておく必要があります。

暗号は 2 つに大別できます。
その 1 つは対象暗号です。対象暗号では暗号化と復号化に同じ鍵を使用します。つまり、送信者 (平文を暗号化して受信者へ暗号を送信する人) と受信者 (送信者から受信した暗号を復号化して平文を得る人) は同じ鍵を所有する必要があります。 強固な暗号化アルゴリズムを用いて最強の暗号を用意することができれば、たとえ盗聴者に暗号を盗聴されたとしても、それを解読される心配はないでしょう。しかし、ここで問題となるのは、送信者が暗号化に用いた鍵を受信者に渡さなければいけないということです。いかに最強の暗号でも鍵を盗聴されてしまえば意味がありません。では鍵も暗号化すればよいでしょうか。…そしたら鍵を暗号化する際に使用した鍵はどうやって渡すのでしょうか。

というように鍵の配送にはこのようなジレンマがつきまといます。それを解決する手段の 1 つが、2 つ目の暗号である非対称暗号です。以前にブログで取り上げた公開鍵暗号 (RSA) がそれにあたり、この暗号の発明のおかげで鍵配送問題は解決されましたが、詳細は割愛します。 代わりに今回は別の鍵配送問題の解決法についてお話します。

f:id:quanon:20150520205751p:plain にこちゃんに鍵を盗まれない (鍵の内容を盗聴されない) ようにするにはどうしたら!?

Diffie-Hellman 鍵交換

ここで登場するのが Diffie-Hellman 鍵交換 です。

Diffie-Hellman 鍵交換では鍵の代わりに以下の 4 つの数を交換します。

  1. P : 非常に大きな素数
    • 送信者が受信者に送ります。
  2. G : P の原始根 (生成元)
    • 送信者が受信者に送ります。
    • 原始根については後述します。
  3. GA mod P
    • A は送信者が用意した乱数 (1 以上 P-2 以下) です。この A は秘密にしなければなりません。
  4. GB mod P
    • B は受信者が用意した乱数 (1 以上 P-2 以下) です。この B は秘密にしなければなりません。

これらの 4 つの数は盗聴者に盗聴されても構いません。秘密にしておかなくてはならないのは A, B のみです。 なんとこのように特定の数を公開するだけで 2 人だけの秘密の鍵を共有する (鍵を生成する) ことができるのです!

f:id:quanon:20150520211812p:plain

次に送信者と受信者はそれぞれ、これら 4 つの数をもとに鍵を生成します。

送信者は受信者から受け取った GB mod P と自身が持っている秘密の乱数 A を元に以下の数を計算します。

(GB mod P)A mod P = (G mod P)A×B

受信者は、送信者から受け取った GA mod P と自身が持っている秘密の乱数 B を元に以下の数を計算します。

(GA mod P)B mod P = (G mod P)B×A

送信者と受信者が計算したそれぞれの値は同じ値となるはずです。

僕は (GB mod P)A mod P = (G mod P)A×B となる理由が理解できていません (書中でさらっと流されている) 。なぜこの法則がなりたつのか、参考になる資料があればご教示ください orz

原始根とは

原始根の定義は以下のとおりです。

素数 p と 1 以上 p 未満の整数 r が以下の性質を満たすとき r を法 p に対する原始根と呼ぶ。
「r, r2, ⋯, rp−2 のいずれもが p で割って余り 1 でない。」

うーん、よく分からんので具体例を挙げてみます。

P = 5 として GA mod P を計算すると、結果は以下のようになります。

G\A 1 2 3 4
1 1 1 1 1
2 2 4 3 1
3 3 4 2 1
4 4 1 4 1

この表の G = 2, 3 の行に注目して下さい。これらの行は各列の値がすべて異なります。 この 2, 3 が法 5 に対する原始根です。原始根のべき乗は 1 〜 P-1 の値に 1 対 1 で対応しているわけです。

なぜ Diffie-Hellman 鍵交換が安全なのか

これは有限上の離散対数問題を解くことの難しさを利用しています。これは G, P が判明していても GA mod P から A を、あるいは GB mod P から B を算出することが困難ということです。 そのため A, B さえ秘密にしておけば、G, P, GA mod P, GB mod P は公開しても問題ありません。

実際にやってみた

Ruby を使って実際に Diffie-Hellman 鍵交換を再現してみました。

(1) 送信者が P と G を決定して受信者に送る

まずは任意の素数 P を決定します。本当は十分に大きい素数である必要がありますが、今回は計算の都合上小さい数を選択します。

P = 499

次に法 P に対する原始根 G を求めます。 これを算出するための具体的な法則を僕は知らないので、プログラムを使って強引に求めます。

# 整数 n を法とする原始根を求める。
def calcurate_primitive_roots(n)
  range = (1..n-1)

  range.select do |g|
    # g が法 n に対する原始根ならば計算結果は重複しない。
    range.map { |a| g ** a % n }.uniq.length == range.to_a.length
  end
end

# 複数の原始根の中から 1 つをランダムに選ぶ。
G = calcurate_primitive_roots(P).sample #=> 86

これで P, G が決定しました。これらの値は受信者に公開します。

(2) 送信者が A を決定する

A = rand(1..P-2) #=> 173

これで A が決定しました。この値は秘密にしておきます。

(3) 受信者が B を決定する

B = rand(1..P-2) #=> 354

これで B が決定しました。この値は秘密にしておきます。

(4) 送信者が受信者に GA mod P を送る

G ** A % P #=> 398

(5) 受信者が送信者に GB mod P を送る

G ** B % P #=> 406

(6) 送信者が鍵を計算する

406 ** A % P #=> 447

(7) 受信者が鍵を計算する

398 ** B % P #=> 447

これで盗聴者に盗聴されることなく、共通の鍵 447 を得られました。

感想

公開鍵暗号 (RSA) と同様に、とてもシンプルなアルゴリズムで実現できるのは不思議ですね。RSA素因数分解問題、Diffie-Hellman 鍵交換は離散対数問題という数学上の困難さをうまく暗号技術に応用している点が非常に面白いなと思いました。

ドラえもんやモノクマの声でお馴染みの声優、大山のぶ代さんが認知症だというニュースを耳にした。
あまりに馴染み深い声優さんの悲報に衝撃を受けた。

シャワーを浴びながら、認知症のことを考えていた。

自分のことが自分でわからなくなるってどれだけ恐ろしいことなんだろう。
完全にわからなくなってしまったのなら、まだマシかもしれない。
まだ進行段階、だんだんと自分のことがわからなくなっていく過程にあるときのことを想像すると、恐怖にすくみあがってしまいそうになる。
その不安を想像すると、どんな痛みよりも恐ろしいのではないだろうかと思える。
むしろ死んでしまったほうが楽なのではないか。

それ以上なにも考えることができなくなってしまった。

僕は今でも自分で何を考えているのかよく分からずに生きているが、
「自分で何を考えているのかよく分からない」ということすら分からなくなるその前に、
分からないままでもこの瞬間の自分をしっかりと生きねばと思った。

きっとそれが分からなくなったときが来ても、取るべき生き方は変わらないのであろう。
ならば、今からそういう生き方を身に染み込ませておきたい。

Carpe diem

夜のイメージ、静謐、内省、想像。

静かなひとときの中で自分と向き合う。
十分にそうした後は、想像の世界に身を投じる。
そして、夜明けとともに新たな自分を迎える。

人生は日々終りを迎え、また始まっているのだ。
夜と朝、終焉と開闢。 ああ、闇と光が絶妙にとけあうこの日常がたまらなく尊い。

謎ポエム。 ちなみに月のタロットが好きです。

公開鍵暗号アルゴリズム RSA を使ってデジタル署名してみた

先日の 公開鍵暗号アルゴリズム RSA を使って実際に暗号化してみる のおまけ的な記事です。

デジタル署名 にも実は公開鍵暗号アルゴリズムが利用されています。

デジタル署名とは、送信者が受信者へメッセージを送信した際に、そのメッセージの改ざんの検出、送信者のなりすましの検出、送信者の否認の防止などを行うための技術です。これ以上の詳しい説明は省きますが、今回は公開鍵暗号アルゴリズムをデジタル署名にも流用できるという点だけ述べたいと思います。

公開鍵暗号は、メッセージの送信者が (受信者が公開している) 公開鍵を使ってメッセージを暗号化し、それを受け取った受信者が自身のプライベート鍵を使って暗号文を復号化するというものでした。一方デジタル署名では、メッセージの送信者がプライベート鍵を使ってメッセージ*1を暗号化し (これが署名に相当します)、それを受信者が公開鍵を使って復号化します (これが署名の検証に相当します) 。

まとめると、公開鍵暗号とデジタル署名それぞれの鍵の使い方は以下の通りです。

プライベート鍵 公開鍵
公開鍵暗号 受信者が復号化に使う 送信者が暗号化に使う
デジタル署名 送信者が署名に使う 受信者が署名の検証に使う

では、今回も実際にやってみたいと思います。 せっかくなので前回作成した鍵をそのまま流用したいと思います。

プライベート鍵が

{ \displaystyle
\{ D, N \} = \{ 92615, 930473 \}
}

公開鍵が

{ \displaystyle
\{ E, N \} = \{ 5, 930473 \}
}

でした。

今回は 2521 という整数値をメッセージとし、それに署名します。

署名はプライベート鍵を使用して、以下の式の通りに行います。

{ \displaystyle
署名 =  {メッセージ}^{D} \bmod N
}

実際にやってみます。

message = 2521
d, n = 92615, 930473

signature = (message ** d) % n #=> 251690

この 251690 という整数値が署名です。 送信者には 2521 というメッセージに 251690 という署名を添えて送信します。

にっこにっこにー J(*‘ヮ‘*)し →  \{ 2521, 251690 \} → (‘ヘ‘ ζ ナニソレ、イミワカンナイ!

署名の検証は公開鍵を使用して、以下の式の通りに行います。

{ \displaystyle
署名から得られたメッセージ =  {署名}^{E} \bmod N
}

実際にやってみます。

message = 2521
signature = 251690
e, n = 5, 930473

verified_message = (signature ** e) % n #=> 2521
message == verified_message #=> true

送信されたメッセージと署名から得られたメッセージが見事にマッチしました。つまり、署名の検証に成功です!

(‘ヘ‘ ζ 間違いないわ!このメッセージは正真正銘、にこちゃんからだわ!

デジタル署名にも使えるなんて、公開鍵暗号って素晴らしい!!!

*1:メッセージ全体を暗号化する手法では時間が掛かるため、実際はメッセージの ハッシュ値 に対して署名を行うことが多いです。

公開鍵暗号アルゴリズム RSA を使って実際に暗号化してみる

はじめに

新版暗号技術入門 秘密の国のアリス

新版暗号技術入門 秘密の国のアリス

引き続き「暗号技術入門」を読んでいます。 昨晩 公開鍵暗号 について読んだので、その復習がてら、実際に公開鍵暗号を使った暗号化にチャレンジしたいと思います。

そもそも公開鍵暗号とは何かという説明ついては、この記事では触れません。

RSA を使った暗号化について

RSA とは

RSA公開鍵暗号アルゴリズムのひとつです。現在、公開鍵暗号アルゴリズムの中では最も広く使われています。RSA でプライベート鍵*1を作る際に id_rsa というファイルを作ることが多いので、見覚えがあるという方も少なくないのではないでしょうか。

RSA による暗号化・復号化のアルゴリズムについて

RSAアルゴリズムはべき乗と余剰のみで表すことのできる、非常にシンプルなものです。

暗号化は次の式で表せます。

{ \displaystyle
暗号文 =  {平文}^{E} \bmod N
}

ここでの { E, N } のペアが公開鍵に相当します。

復号化は次の式で表せます。

{ \displaystyle
平文 =  {暗号文}^{D} \bmod N
}

ここでの { D, N } のペアがプライベート鍵に相当します。

また、E, N, D という値は以下の手順で求めます。

(1) N を求める

{ \displaystyle
N = p \times q
}

p, q はそれぞれランダムで十分に大きい素数です。

(2) L を求める

L は前述の式には登場しない値ですが、残りの値を求めるために利用します。

{ \displaystyle
L = lcm (p - 1, q - 1)
}

lcm とは最小公倍数 (Least Common Multiple) のことです。

(3) E を求める

{ \displaystyle
1 \lt E \lt L
}

{ \displaystyle
gcd (E, L) = 1
}

gcd とは最大公約数 (Greatest Common Divisor) のことです。 つまり E は L と互いに素な任意の整数です。

(4) D を求める

{ \displaystyle
1 \lt D \lt L
}

{ \displaystyle
(E \times D) \bmod L = 1
}

つまり D は E との積の余剰が 1 となる任意の整数です。

実際にやってみる

杏子とさやかは相思相愛♥

この文字列を平文として使って、実際に RSA を用いた暗号化・復号化を試してみます。 計算は面倒なのでお馴染みの Ruby 先生の手を借ります。

(1) 文字列を整数に変換する

平文を整数に変換します。ここでの整数にはそれぞれの文字の Unicode コードポイント を利用します。

plain_text = '杏子とさやかは相思相愛♥'
plain_integers = plain_text.each_codepoint.to_a
#=> [26447, 23376, 12392, 12373, 12420, 12363, 12399, 30456, 24605, 30456, 24859, 9829]

(2) N, L, E, D を求める

最初に N を求めます。p, q の整数はそれぞれ僕が勝手に選んだ素数です。 本来は安全性のために十分に大きい素数である必要がありますが、そうすると計算が大変なので意図的に小さめの数を選んでいます。

p = 227
q = 4099
n = p * q
#=> 930473

次に L を求めます。

l = (p - 1).lcm(q - 1)
#=> 463074

それから E を求めます。

e = (2...l).find { |i| i.gcd(l) == 1 }
#=> 5

最後に D を求めます。

d = (2...l).find { |i| (e * i) % l == 1 }
#=> 92615

これで公開鍵 {E, N} とプライベート鍵 {D, N} が用意出来ました。

(3) 公開鍵を使って暗号化する

plain_integers
#=> [26447, 23376, 12392, 12373, 12420, 12363, 12399, 30456, 24605, 30456, 24859, 9829]
encrypted_integers = plain_integers.map { |i| i ** e % n }
#=> [64809, 281306, 590262, 572608, 645260, 329917, 458957, 630062, 616040, 630062, 679686, 614873]

encrypted_integers が暗号文です。 これを文字列に無理やり変換しようとしても、わけのわからない文字列になってしまいます。

cipher_text = encrypted_integers.map { |i| i.chr(Encoding::UTF_8) }.join
#=> "ﴩ\u{44ADA}\u{901B6}\u{8BCC0}\u{9D88C}\u{508BD}\u{700CD}\u{99D2E}\u{96668}\u{99D2E}\u{A5F06}\u{961D9}"

(4) プライベート鍵を使って復号化する

decrypted_intergers = encrypted_integers.map { |i| i ** d % n }
#=> [26447, 23376, 12392, 12373, 12420, 12363, 12399, 30456, 24605, 30456, 24859, 9829]
decrypted_intergers.map { |i| i.chr(Encoding::UTF_8) }.join
#=> "杏子とさやかは相思相愛♥"

杏子とさやかは相思相愛♥ という平文が無事に復号化できました!

感想

プログラマとして日頃よくお世話になっている公開鍵暗号がこれほどシンプルなアルゴリズムだとは思っていなかったので、目からうろこでした。 公開鍵暗号は非常に画期的な発明だったそうで、画期的なものほど意外とシンプルだったりするんですね。 対称暗号の章で出てきた、絶対に破られない無敵の暗号 使い捨てパッド も (画期的ではないかもしれないけど) すごく単純なアルゴリズムでしたし。

暗号の世界っておもしろ!

*1:秘密鍵」という呼び方も一般的ですが、「秘密鍵」は 対称暗号 の鍵の意味でも使われるため、それと区別するために書中では「プライベート鍵」という呼称が採用されています。