↓のゼロ知識証明の解説記事に掲載されている楕円曲線を使ったゼロ知識証明をbitcoin-rubyを使って検証してみた。
検証手順は↑のの記事の通りで、
証明者(アリス)と検証者がいて、楕円曲線上の点P
とアリスの秘密鍵a
があるとき、その公開鍵は
Q(公開鍵) = aP
となり、P
とQ
は検証者に共有されている。この状況でアリスは確実に秘密鍵a
を持っていることをa
を開示することなく、検証者に証明する。
まず、アリスはランダムな値r
を選択肢、 R = rP
とb = H(P, Q, R)
を計算する。Hはハッシュ関数で、今回はBitcoinのハッシュ関数hash160
を使用。
続いてc = r + ab
を計算し、検証者に(R, c)
を渡す。
検証者は共有された値P
、Q
、R
、c
を使ってアリスがa
を持っていることを確認する。
確認方法b = H(P, Q, R)
、X = cP
とY = R + bQ
を計算し、X
とY
が等しければアリスはa
を持っていると判断する。
どうしてX
とY
が等しければアリスはa
を知っていると判断できるのかというと、X = cP = (r + ab)P
は、秘密鍵a
にb
を乗算し、ランダムに選択した秘密鍵r
を加算した値になる。そしてY
は公開鍵Q
にb
を乗算し、秘密鍵r
の公開鍵R
を乗算した値になる。秘密鍵に対してr
を加算した場合、その楕円曲線上の点は公開鍵Q
にR
を加算したものと等しくなるという楕円曲線の特性と、仮にa
を知らない場合その計算式が成り立つようなR
や(ハッシュ関数によって生成された)c
をアリスが導出することは非常に難しいことから、X = Y
が等しい場合アリスはa
を知っていると判断することができる。
検証コードは↓