Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
クライアントサイドでガチャ

目的

  • サーバー側でガチャのアイテムを選択すると確率操作している疑いがかかるので、事前に提示した確率から変更が出来ず疑いが掛からないような方式を提案する
  • サーバー側でもクライアント側でも不正が出来ないことが要件として求められる
  • 簡便なアルゴリズムで一般市民にも理解しやすく、また、解析によるアルゴリズムの把握が容易であることが望ましい

かんがえかた

これ相当のことを、サーバーとクライアントでやればいい。

  • ディーラーはカードを伏せた状態でプレイヤーに配る。プレイヤーは自分の責任でカードを選ぶ。選んだ後で選択していないものも含めて、全てのカードが公開される。

このような機能を実現するためには、次のような性質を持つアルゴリズムがあればいい。

  • サーバー側では中身が確定していて、宣言したカードの中身を後から変更することが出来ない(不正ができない)
  • クライアントからはカードの中身を推測することが出来ないが、後から何であったのかを証明することが出来る

「ハッシュ値を公開しておいて、後で元の値を明かす」「暗号文を渡しておいて、後から解読キーを渡す」といったものが馴染みがあるので、「カードを伏せた状態で配る → 後で開示する」のに利用する。

実装例

ガチャで出現するアイテムの候補を作る 確率分布にしたがって、1-1000といったIDが振られる。

出現アイテムの一覧をシャッフルした配列が事前にユーザーに開示されている。 多く出現するアイテムは多く入っている。 どのIDがどのアイテムに対応するのかは、シーザー暗号のように、決められた値分だけずらすことで決まる。

いくつずらすのか、を暗号化した状態でクライアントに開示しておく。※1 (よく知られているアルゴリズムで、共有鍵方式で良い) 暗号化されているためクライアント側ではわからない。 ガチャセッション情報として保持する。

クライアントサイドでIDを選択してサーバーに送る。 選択は完全にクライアントサイドのコードで実行される。 選んだIDの中身が何であるのかはこの段階ではわからない。

ガチャセッション情報に基づいて、選択したIDが何のアイテムであったのかを確定させる。 サーバーは共有鍵をクライアント側にも開示する。 クライアントはサーバーと同じアルゴリズムでIDとアイテムの対応表を作り不正が無いことを確認する。

※1 の例: 暗号文を開示しておいて後から解読キーを渡す、ハッシュ値(ずらす値+"ランダムな長い文字列")を開示しておいて後で元の値を開示する。

不正の方法

  • クライアント側がブルートフォースで暗号を解くことが出来れば(ID→アイテム対応表を事前に把握できれば) 自分が有利な選択をすることが出来る
  • サーバー側が、重複するハッシュ値を算出したり、暗号文から異なる復号結果を提示するようなことが出来れば、ID→アイテムの対応表を変更することが出来る

衝突が起きないアルゴリズムを使い、計算量が現実的でないように設計することで不正が出来なくなる。

参考文献

@tai2

This comment has been minimized.

Copy link

commented Jan 12, 2016

シーザー暗号と書いてあるので、ずらす数は、一回のセッションでひとつのように読めました(解釈間違ってたらすみません)。
しかし、ずらす数は、「出現アイテムの一覧」と同じ個数分、バラバラに生成したほうが良いと思います。その表を暗号化した状態で渡します。
そうしないと、含まれるIDの個数から、アイテムの候補がある程度推定できてしまう気がします。

そう考えると、単に暗号化された「出現アイテムの一覧」を事前に共有しておいて、何番目を選ぶというのをクライアントが決めたら、一覧を開封して答え合わせができればいい気もしますね。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.