問題文
現在、世界中で使用されているRSA暗号の仕組みは以下の通り。
1.相異なる2つの素数p,qを選び、n=pqとする。また、ϕ(n)=(p−1)(q−1)とする。
2.ϕ(n)未満の正の整数で、ϕ(n)と互いに素な数eを1つ選ぶ。n,eは公開鍵として公開される。
3.de≡1(mod ϕ(n))を満たすようなdを求める。このdは秘密鍵である。
4.平文(暗号化する前の文)を0以上n未満の整数とし、これをaとする。送り主は盗聴された場合に備え、aそのものではなくaeをnで割った余りbを送信する。
5.受け取り主は暗号文bを受け取った上で、aeをnで割った余りがbとなるようなaを計算する。これにより暗号文を平文に復号することができる。
公開鍵n,e及び文の長さLを与えるので、以下の2つの問に答えられるプログラムを作成せよ。
1.平文列a1,a2,⋯,aLが与えられたときに、各aiを暗号化し暗号文列b1,b2,⋯,bLを出力せよ。
2.暗号文列b1,b2,⋯,bLが与えられたときに、各biを復号し平文列a1,a2,⋯,aLを出力せよ。
制約
- p,qは相異なる素数であり、pq≤2×109+1000
- n=pqである。また、eはϕ(n)=(p−1)(q−1)と互いに素
- 0≤ai,bi<n
- 1≤L≤105
入力
入力は以下のどちらかの形式で与えられる。
<暗号化>
encode
n e L
a_1 a_2 ... a_L
<復号>
decode
n e L
b_1 b_2 ... b_L
出力
計算結果を半角スペース区切りで出力せよ。
サンプル
入力1-A
encode
21 5 5
16 7 8 12 11
各aiに対し、ai5を21で割った余りを出力すれば良い。
入力1-B
decode
21 5 5
4 7 8 3 2
各biに対し、ai5を21で割った余りがbiになるようなaiは1つに定まるので、それを出力すれば良い。
入力2-A
encode
2000000014 10001 5
314159265 358979323 846264338 327950288 419716939
出力2-A
1114575615 1064628669 1590103890 1142765810 529554705
ai10001を求める過程でのオーバーフローに注意せよ。
入力2-B
decode
2000000014 10001 5
1114575615 1064628669 1590103890 1142765810 529554705
出力2-B
314159265 358979323 846264338 327950288 419716939
数が大きすぎるので、210001,310001,⋯と1つずつ調べて行っても間に合わない。さて、どうすれば良いか?
ヒント
dの決め方から、mod nにおいてbd≡aed=al(p−1)(q−1)+1=a⋅al(p−1)(q−1) (lは整数)と書けるのだが、2つ目の項の指数がp−1の倍数かつq−1の倍数であるということから何が言えるのだろうか?