Open4

VRF(Verifiable Random Function)について

nunonuno

VRFとは検証可能な疑似乱数関数(ハッシュ関数)のこと。

疑似乱数関数H_s(x) はシード値sで指定されるハッシュ関数で、出力は一様分布と区別できない。通常の疑似乱数関数ではsは公開されている。つまり誰でもy = H_s(x)の値を計算することができる。

ブロックチェーンなどの分散ネットワークで乱数を生成したいとき、これではどのような乱数が出てくるか予想ができてしまう。この問題を解決するのがVRFである。

nunonuno

VRFの定義

VRFには秘密鍵skと、公開鍵pkが存在する。秘密鍵skを知っている人は、どんな入力xが来ても、その疑似乱数出力y= H_{sk}(x)を簡単に計算することができる。yxに対して一意的に定まり、また一様分布と区別できない。一方で秘密鍵skを知らない人は疑似乱数出力を計算することができない。

秘密鍵skを知っている人は、疑似乱数出力y= H_{sk}(x)の正しさを示す証明proofを生成することができる。誰でも、公開鍵pk, 入力x, 出力y, 証明proofを用いて、疑似乱数出力y= H_{sk}(x)の正しさを検証することができる。

Verify(x, y, pk, proof) \rightarrow bool
nunonuno

VRFによる乱数生成

VRFを使うと次のように乱数を生成することができる。

いま、ここにN人の参加者がいるとする。全員はそれぞれ秘密鍵sk_iをランダムに選び、それに対応する公開鍵pk_iを全員に公開する。公開鍵の交換が終了したら、全員は、同一のx (適当に選んで良い)に対して疑似乱数出力y_i = H_{sk_i}(x)を計算し、証明proof_iとともに公開する。全員の証明を検証した後に、全てのy_iのXORを取ったものを乱数とする。

ポイントは、秘密鍵が分からないとVRFの出力を予測することができないということである。そのため、N人のうち1人でも正直な参加者がいれば、攻撃者は正直な参加者の出力を予測することができず、最終的な乱数も予測することができない。またVRFの証明を検証することで、攻撃者が出力値をすり替えた場合に検出できるようになる。

nunonuno

VRFの構成

VRFの構成には様々な方法があるが、ここでは下記の記事の方法を取り上げる。

https://medium.com/asecuritysite-when-bob-met-alice/verifiable-random-functions-4563d6eb17ab
https://asecuritysite.com/zero/vrf

公開鍵

Gを楕円曲線の生成元とする。秘密鍵kに対して公開鍵をP = kGとする。

VRF
H_1を入力mから(ランダムな)楕円曲線上の点へマップする、hash-to-curve関数とする。入力mに対するVRFをV = kH_1(m)によって構成する。H_1(m)は楕円曲線上の点で、k H_1(m)はそのk倍の点であることに注意。

prove
rをランダムに選び、次のs, tを計算する。
s = H_2 (G, H_1(m), P, V, rG, rH_1(m))
t = r - sk
proofは(s, t)

verifiy
s \stackrel{?}{=} H_2(G, H_1(m), P, V, tG+sP, tH_1(m)+sV)
を検証する。
proverが正直なら
tG + sP = tG +skG = (t+sk)G = rG
と、
tH_1(m) + s V = (t + sk)H_1(m) = rH_1(m)
が成り立つことに注意