事例62

暗号を解読せよ ~プログラミングで学ぶ公開鍵暗号

神奈川県立生田東高校 大石智広先生

問題解決に必要な力≒プログラミングを通して学べる力

今回お話しするのは、公開鍵暗号方式の解読困難性を学ぶ授業です。「社会と情報」の学習指導要領の(2)「情報通信ネットワークとコミュニケーション」の中の(イ)「情報通信ネットワークの仕組み」の内容として行いました。

 

この背景には、「社会と情報」の授業の中でプログラミングを扱う際に、改めてプログラミングを通して学べるものとは何かを考えたとき、問題解決に必要な力というのは、実はプログラミングを通して学べる力とほぼ同じものではないかと、思い至ったということがあります。

 

プログラムを通して学べる力は二つあると考えています。まず一つ目は、手順を分けて考える。プログラムを作るためには、目的に対して手順を分けて考えていく力が必要です。

 

もう一つは、プログラムというのは作って終わりではなく、本当に正しく動くかどうか確かめなければいけません。いわゆるテストと呼ばれるフェーズですが、ではどのようなテストすれば、本当にうまくいっているかどうかを確かめることができるかということを考える力が必要です。

 

では、問題解決力とは何か。それは手順化と検証の2つだと考えています。

まず、手順化ですが、これは、問題解決(=ゴール)までの過程を細かくステップに分けて考える力です。例えば、「文化祭を盛り上げよう」ということであれば、最初に「そもそも文化祭が盛り上がるとはどのようなことか」を決めなければなりません。来場者数が多いのか、あるいは顧客満足度が多いのか。例えば「来場者数を多くする」ということに決めたなら、ではどのように告知するか、SNSで宣伝しようか、というように計画を立てて実際やってみるというふうに、順番に分けて考える力が必要になります。これは、実はプログラムを書く能力とあまり変わらないと言うより、まさにそのものだと思います。

 

もう一つの検証は、考えた手順が本当に問題解決に向かっているのかどうかを確かめる力です。先ほどの例で言えば、SNSでアカウントやツイッターを作って、それが役立って来場者が増えたのかを確かめるなら、来場者に実際にツイッターを見たかどうか聞いてみないとわからないといったことですね。実は、これはプログラムをテストをする力と変わらない。先ほど「問題解決に必要な力というのは、実はプログラミングを通して学べる力とほぼ同じものだ」と言ったのは、つまりこのようなことなのです。

 

これらから出てくる授業のイメージとしては、まず「問題解決の手順を生徒に考えさせて、それをプログラムで表現する」、さらに「プログラムを実行しながら、手順が本当にうまくいくかどうか確かめる」というものになります。

 

題解決の授業は題材選びがポイント

そこで具体的な題材の設定をします。よく、問題解決の授業では身近な題材を取り上げようと言われますが、身近な題材というのは、実際は複雑で解決が難しいことばかりです。一方で、単純な題材というのは、人工的になったりして、生徒の興味を引きにくかったりする。このバランスが必要で、教員はうまくそれをモデル化して、バランスが取れた問題を生徒に提示しなければなりません。

 

そのバランスから選んだ今回のテーマが、「公開鍵暗号の解読困難性を学ぶ」です。公開鍵の手順自体は非常にシンプルですが、革命的で、学ぶ意義があるものだというのが理由の一つです。そして、公開鍵暗号が解けないのは素因数分解が難しいからですが、その手順というのはすごくシンプルで、かつプログラミングがしやすいので、コンピュータ利用のメリットを感じやすいというのが二つ目。そして三つ目に、暗号化は生徒は決して身近に感じてはいませんが、日常的に使っているのでイメージ化がしやすいということです。

 

スモールステップで課題をクリアしながら、大きな問題解決へ

改めて授業のねらいを整理します。まずは公開鍵暗号方式の手順と解読困難性を理解するというのが一つ。二つ目が、問題解決に必要な手順化と検証を実際にやってみて、少しでもそれ学んでもらうこと。最後に、それらを通してプログラムに表現することの利点と検証の必要性を学ぶ、という三つを目標にしました。

私が授業設計するときに心がけている三つのキーワードがあります。一つ目の「問題解決型の授業」というのは、授業を通して何か生徒に大きな課題を与えて、授業を通してそれを解決するという形です。2つ目の「スモールステップ」というのは、ステップ・バイ・ステップで教員が教え込むのではなくて、生徒が乗り越えられるぐらいの課題の幅に調節してあげましょうという意味です。山の頂上が問題解決であるとすると、それを生徒たちが乗り越えられるような、小さい階段に区切ってあげることです。そして、「言語活動」。生徒は、グループで相談したり、こちらから与えた知識や技能を使ったりしながら、自分で乗り越えていくというイメージです。

 

1時間目 人類2000年の難問を5分で解決?!

授業計画は3時間で考えました。1時間目は、公開鍵暗号方式の手順を生徒に発明させます。2時間目は素因数分解の手順を生徒に考えさせて、3時間目は実際にそれをコンピュータにやらせてみる、という流れの授業になっています。

 

具体的な授業の流れです。1時間目は三つのステップで行います。

 

まずは、「暗号化」を理解するのに必要な「鍵」と「手順」の概念を生徒に理解させます。これはシーザーローテーションを使います。

 

シーザーローテーションの「手順」は決められた数だけアルファベットをずらすこと、「鍵」は何文字ずらすかということです。ここを理解させた上で、シーザーローテーションで共通鍵方式の暗号を作ったとして、共通鍵方式の何が不便なのかというのを生徒に考えさせます。「途中で盗まれる」とか「忘れる」とかいろいろ出てきますが、一番の決定打は、初めて会う人とは暗号通信ができないということですよね。「だから、鍵を送らなくてもよい暗号を発明しよう」と生徒に持ちかけます。

 

これは3~4人のグループワークで行います。生徒にはボブ、イブ、アリスという3人の役割を割り振ります。そして、「アリスが持っている秘密の手紙を、ボブに送りたい。ところがスパイのイブがいるので、それをのぞき見ようとしている。そこで、ボブが持っている南京錠のかかるケースと南京錠(=公開鍵)、そして南京錠の鍵(=秘密鍵)の三つを使って、イブに見られないで、アリスからボブに手紙を送る手順を見つけましょう」というのがこの設定です。

 

やり方です。ボブ役、イブ役、アリス役の生徒3人を横並びで並べて、ボブとアリスの間で南京錠や手紙を送り合います。ルールとしては、何かを送るときは必ずイブを経由しなければなりません。

 

イブは、中をのぞいてみたり、鍵をコピーしたりすることはできます。ただし、ものを壊したり、破ったり盗んだりすることはできません。

 

これを「最初に手順を見つけた班にはお菓子をあげるよ」と班ごとで競わせると、非常にもりあがって、大体5分以内でどこかの班が手順を見つけられるので、その班に前に出てきて実演してもらうと、ほとんどの生徒は納得します。そして、見つけられた人もそうでない人も、実際に答えがわかると簡単だな、ということで、暗号の手順をよく理解することができます。

 

生徒の中には、「こんなに簡単なのに、なぜ2000年間、誰も思いつかなかったんだ?!」という感想を持つ人もいます。さらに鋭い生徒は、「これは情報を一方的に送るときには使えるけど、双方に送り合いたい場合は使えない」ということにも気付きます。

 

これをやっていくと、「公開鍵は必ずいったんイブを経由して送っているので、この公開鍵、(=南京錠)から秘密鍵を作れるんじゃないの?」ということを言い出す生徒がいるので、では次の時間はその方法を考えよう、ということで2時間目に入ります。

 

2時間目 公開鍵の素因数分解を手計算でやってみる

2時間目は、「公開鍵(=南京錠)を素因数分解できれば秘密鍵ができるんだよ」ということを説明して、まず個人で素因数分解の手順を考えます。それを、グループでうまくいっているかどうか確かめるという流れで授業を行います。

 

いちばん大事な公開鍵と秘密鍵の関係のところは、このスライドのように説明しています。そして、「秘密鍵を知らないと、公開鍵をかけ算に分解するのは難しいけど、でも分解すれば、秘密鍵がわかることはわかっているから、何とかその方法を見つけよう」と声をかけます。

 

まずは個人で素因数分解の手順を考えさせますが、あまり素因数分解という言葉は使わないようにしています。数学が嫌いな生徒が多いということもありますが、もう一つは、数学で扱う素因数分解は、因数が非常に小さい数であることを暗黙の前提にしているのです。ですから、生徒が知っている素因数分解のテクニックというのは、小さい数を前提にしたものなので、この内容にはあまり役に立たない。ですから、素因数分解という言葉はあえて使わないほうがよいと思います。

 

この段階で、個人でできなくても、そのあとグループでそれぞれ考えた方法を持ち寄って、一番いよい方法を考えよう、という活動でフォローしていきます。

 

生徒から出てくる方法は、例えば「2で割る、3で割る、5で割る、7で割る・・・」と素数で割っていく作戦です。実は、これはうまくいきません。数が大きくなると、次の素数が何かわからないからです。そこで、次に出てくるのは、「2で割ってみて割り切れなかったら、3、4、5、6、7、8、9…と割る数をだんだん増やしていく」。これは正解の一つですね。さらに、もっと良いアルゴリズムとしては、「2で割って、割り切れなければ次は3、5、7…と奇数で順番に割っていく」という方法で、これは先ほどのものよりさらに早くなります。

 

次に、皆が考えた手順がうまくいくのか確かめてみよう、ということで、あらかじめ準備したテスト用の数字をグループ内で分担して、自分たちで考えた手順で素因数分解ができるかどうかを調べます。これをすると、正しく分解できますが、時間はかかります。では次の時間は、今皆で考えた手順をコンピュータにやらせると何ができるかを考えよう、ということにします。

 

3時間目 プログラムを使ってコンピュータにやらせることでわかってくるのは・・・

3時間目は、プログラムというはあらかじめ決められた手順を速く・性格にコンピュータに実行させるものであるということを説明した上で、実際のプログラムが正しく動くか確かめてみよう、という流れで授業を進めます。

 

今回使うプログラムは、VBAを使って私の方で用意しました。VBAを使ったのは、どんな学校のパソコンにも必ずあること、また画面を作ったり、データを扱ったりすることが簡単にできるからです。

 

用意した画面はこのようなわかりやすいもので、公開鍵の数字を入れて「分解実行」ボタンを押すと、素因数分解して、実行時間も表示されます。

 

ソースコードは下図のようなものです。 

※クリックすると拡大します

これを生徒たちに、本当に正しく動くかどうか確かめるためにはどうしたらよいか考えさせると、「あらかじめ答えがわかっている数字を試してみればいい」ということになるので、自分たちで素数を2つ掛け合わせたテストの数字を作らせて実行させ、元通りになるかどうか確かめます。そうすると、正しく動きそうだというのがわかってくるので、実際に10の15乗の桁の数字で実行させてみます。10の15乗というのは、エクセルのセルに入力できる最大の数がこれくらいだからです。本校のコンピュータなら5秒ほどで分解できます。

 

このあたりになると、実際の暗号はこの程度の桁ではないことに気が付く生徒も出てきますので、実際の公開鍵は10の600乗あり、これは最新のコンピュータでも天文学的な時間がかかる、ということを話します。

 

そうすると、手計算であれだけ時間がかかったのを一瞬で解いてしまうコンピュータでも、実際の暗号解読には膨大な時間がかかるということが理解でき、解読困難性が実感できます。また、生徒から出てくる感想には、「手順は単純であっても、コンピュータを使うほうが速いから楽だ」というプログラム使う意義に関するものや、「プログラムを作るときが一番大事だ」「コンピュータでも間違えることはある」という検証の大切さに気付く人もいることがわかります。

 

工夫次第でさらに発展も可能

さらに改善するポイントを示しますと、まずはバグを発見させるという活動もたいへん重要だと思います。これは、プログラムでテストするときに、わざと暴走するケースも用意しておくもので、例えば公開鍵に小数や1以下の数をを入れたり、素数を入れたりすると無限ループになるようにしておいて、「実はこのプログラムにはうまくいかないケースがあるけど、誰が最初に見つけるかな」と声をかけると、本当に一生懸命やって見つけ出す生徒がいます。

 

次の時間に直したものを持って行って動かしてみると、今度は暴走しない。「実はこれが、皆がいつもアプリでやっているアップデートと一緒だよ。プログラムは作ったら終わりではなくて、どんどん直して改善していくんだよ」ということを示すことができます。

 

この授業は、ぜひ先生方にお試しいただきたいですが、ここに挙げたようにいろいろなバリエーションが可能であると思います。

 

例えば公開鍵の手順発見までであれば、1時間でできます。また、プログラム重視するのであれば、実際にプログラムを作成するのがいちばんよいと思います。今回は、「社会と情報」の中で行い、また全体で3時間と限られた時間だって野で、プログラムはこちらで準備しましたが、生徒に考えさせることもできると思います。

 

さらに、これは面白いのではないかと思うのが、素因数分解を速くやる方法が本当に数学的にないのかという話につなげることです。これは、大学で学ぶ数学への招待として、リーマン予想などの話をしても面白いのではと考えています。そういったことを最初に話してから入っても、すごく面白くなるのではないかと思います。

 

実際にプログラムを生徒に作らせる場合の注意としては、int型で作ろうとすると桁あふれしたり、割り切れるかどうか確かめるときにmod関数を使うと、あっさり桁あふれしてエラーになったりするので、変数の型を学ぶためにも良い題材になるのではないかと思います。

 

最後に生徒たちの授業全体に対する感想は、とても好評でした。「いつもより楽しい授業だった」という人までいました。公開鍵暗号方式を学ぶのは、普通はなかなか面白くならないと思いますが、やり方次第で楽しい授業を作ることができることがわかりました。ぜひ試してみてください。

 

[質疑応答]

 

Q1高校教員:暗号とプログラムというのは、授業の中に入れやすいと思いますが、実施にあたってアドバイスがあれば教えてください。

 

大石先生:最初の公開鍵暗号の手順を発明させるところを意識させるのであれば、「イブに見られないようにアリスからボブに手紙を送る」ときの、持ち物と席の初期配置を徹底することです。アリスは手紙を、ボブは南京錠・南京錠の鍵・南京錠のかかる入れ物を持っていること、何かを渡すときには必ずイブを経由しなければいけないということ、というルール付けがこの活動のキモだと思います。ここをきちんと押さえておけば、だいたいうまくいくと思います。

 

この辺りの説明をよく聞かないで、最初の配置が違ったりするとうまくいきません。また、イブを出し抜いて渡そうとする人も必ずいますが、それは絶対ダメだということも、あらかじめ言っておく必要があります。イブが意地悪をして南京錠を壊してしまえばいいと言い出す生徒もいますが、盗んだり壊したりはできない、ただ見るだけだという制約を付けておくのが、文字通り鍵かなと思います。

 

※第10回全国高等学校情報教育研究会全国大会(東京大会)(2017年8月8日・9日)の講演より