2020年ごろの位置情報ベースの暗号資産のアイデアの多くが静かに消えていったのは、GPSを信頼していたからです。GPSはどんな受信機でも受け取れる放送型の信号で、受信機に、受け取った内容について嘘をつかせることができます。そのためのツールはAmazonで30ドルほどで手に入り、2015年からずっとそうです。座標に立っていることに対してウォレットに支払い、その「立っていること」をGPSだけで検証するプロトコルは、ソファの上にいる偽のウォレットにお金を奪われます。難しい攻撃でも、巧妙な攻撃でもありません。

位置証明は、それを解決するレイヤーです。この言葉は定義されるより使われることのほうが多いので、まず定義から始めましょう。位置証明とは、その場にいなかった第三者が検証できる、特定の端末が特定の時間枠の中で特定の座標にあったという主張です。座標についての主張ではなく、存在についての主張です。エンジニアリングの大部分は、この区別の中にあります。

脅威モデル。私たちが防御の対象にしているのは国家ではありません。その極端なケースは最後に触れます。対象は、スマホとノートパソコンと午後の時間を持った平均的な攻撃者です。この攻撃者は、市販のツールでGPSを偽装し、エミュレーターでアプリを動かし、1行のコードでウォレットを作れます。どの対策も、単独ならこの攻撃者に破られます。エンジニアリングの目標は、それらをまとめて破るコストを、ドロップの報酬より高くすることです。

この記事では、Seekが現在何をしているのかをわかりやすく説明し、今後何が来るのかも紹介します。あえてマーケティングの部分は短く、仕組みの部分は長くしています。

レイヤー1、キャッチ時:端末アテステーション。すべてのキャッチリクエストには、OSが署名した宣言が含まれます。iOSではApple App Attest、AndroidではGoogle Play Integrityです。Seekはどちらもサーバー側で検証します。アテステーションはひとつの署名で三つのことを伝えます。これは本物の端末であること、アプリのバイナリが改ざんされていないこと、呼び出し元がこの端末上で私たちのアプリのために生成された鍵を持っていること。root化されたスマホは通りません。エミュレーターも通りません。位置チェックを省いて再パッケージされたアプリも通りません。アテステーションはスマホがどこにあるかを証明するものではなく、スマホが「スマホであること」について嘘をついていないことを証明するものです。それがあるからこそ、ほかのシグナルを読む意味が生まれます。

レイヤー2、キャッチ時:猶予範囲つきの距離チェック。クライアントは、スポーンの取得半径の内側にいるときだけキャッチボタンをタップできるようにします。サーバーは、送られてきた座標をスポーンの座標と独立して照合し、75メートルまでの距離を許容します。ボタンの半径とサーバーの半径の差は意図的なものです。壁に立てかけたスマホのGPSは、あなたのせいではない理由で数メートルずれることがあり、そのずれの範囲内でキャッチを拒否すると理不尽に感じられます。75メートルを超えると、リクエストはその場で拒否され、そのレイヤーではスコアリングも異議申し立てもありません。

レイヤー2の続き:レート制限とスポーンごとの上限。5秒未満の間隔で送られた2つの取得リクエストには、サーバーレスのインスタンスをまたいでも維持されるPostgresベースのゲートから429が返ります。1つのスポーンが同じアカウントから受け付けるのは最大2回までで、2回目の価値は1回目の65パーセントです。これらの上限は不正検知のためのものではありません。すでにほかのレイヤーを突破したボットでも、人が遊ぶより速くエンドポイントを掘り尽くせないようにするためのものです。

レイヤー3、キャッチ時:環境シグナル。記録はしますが強制はしません。すべてのキャッチには、いくつかのフラグも含まれます。リクエストがシミュレーターから来たかどうか、Androidが位置情報を偽の位置情報プロバイダーからのものと報告したかどうか、そして報告されたGPS精度(メートル単位)です。これらは記録されますが、キャッチそのものを拒否するためには決して使いません。これらについて嘘をつくクライアントこそ、判断を任せたくないクライアントなので、判断は別の場所で行います。これらが意味を持つのはレイヤー4です。

レイヤー4、支払い時:不正検知ゲート。出金は、そのアカウントの過去90日間のキャッチを読み込むサーバー関数を通ります。そのキャッチのいずれかがシミュレーターから来ていた場合、Androidが偽の位置情報プロバイダーを報告していた場合、アカウントが10秒未満の間隔で2回キャッチに成功していた場合、2つのキャッチ地点の間を人が移動できるより速く移動していた場合、あるいは別のアカウントが同じ端末フィンガープリントからすでに出金していた場合、その出金は自動承認ではなく人による審査に回されます。どの条件に引っかかったかはユーザーには伝えられず、アカウントはそのまま普通に遊び続けられます。検知は支払いに関するビジネス上の判断であって、罰ではありません。

キャッチと支払いを分けているのは、守っているものが違うからです。キャッチのレイヤーはゲームを守ります。不正なキャッチだったとしても、それはアプリの外に出ることのないゲーム内通貨になるだけで、コストはかかりません。支払いのレイヤーは本物のお金を守ります。システムから出ていく1ドル1ドルが、その残高に至るまでの90日間の審査を通り、その期間に疑わしいシグナルがひとつでもあれば、判断を人に委ねるのに十分です。二つのレイヤーを合わせることで、正当なプレイヤーはキャッチの瞬間に一切の引っかかりを感じず、不正なキャッチを紛れ込ませた攻撃者はお金を手にすることがありません。

レイヤー5、キャッチ時:モーショントレース。どのスマホにも、GPSとつながっている同じチップ上に加速度センサーとジャイロスコープがあります。Seekは現在、キャッチ直前の数秒間の短い動きの記録を取り、少数の統計値(加速度の大きさの分散、回転の活動量、静止フレームの数)を計算し、その要約を取得リクエストと一緒に送っています。スポーンまで歩いてきたスマホは、GPSシミュレーターを動かしたまま机の上に置かれたスマホとは違う動きの特徴を持っています。この特徴は、環境フラグと同じ理由、つまり改造されたクライアントは嘘をつけるという理由で、現在キャッチのレイヤーでは強制していません。代わりに、シミュレーターや偽の位置情報プロバイダーのシグナルと並んで90日間の不正検知ゲートに入り、記録上の平坦なモーショントレースは、出金を人による審査に回すもうひとつの条件になります。

具体例を挙げます。あるテスターがGPS偽装ツールを起動し、座標を街の反対側にあるSeekのドロップに設定して、キャッチをタップします。偽装した座標が一致するので、距離チェックは通ります。アプリは改造されていないので、アテステーションも通ります。キャッチは記録されます。2時間後、同じテスターがさらに3回キャッチし、そのうち1回は10キロ離れた別の座標からです。4回すべてのモーショントレースは平坦で(スマホは一度も動いていません)、2時間では歩いてたどり着けない2つの座標について、あり得ない移動のチェックが反応します。アカウントは遊び続け、集め続け、何かがおかしいとは気づきません。テスターが支払いを申請すると、その申請はあり得ない移動のフラグと平坦なモーショントレースを添えて、人による審査の机に届きます。審査担当者は却下します。テスターが集めた40ドル分の残高は、アプリの外では何の価値も持ちません。

経済的な枠組み。大事なのは、キャッチそのものの偽装が不可能であることではなく、支払いゲートが、アカウントがその残高に至るまでに行ったすべてをさかのぼって読むことです。アテステーションと距離で守られた2ユーロのドロップは、1回攻撃するのは安くても、繰り返し攻撃する意味はありません。パターンがお金になる前に、出金チェックがそのパターンを捕まえるからです。1万ユーロのドロップには、キャッチのレイヤーでもっと強い枠組みが必要で、以下のロードマップはそのためのものです。

ロードマップにあるもの。次に導入される対策は、屋内ドロップ向けのビーコンによる代替手段です。GPSが意味をなさない建物の中に置かれたスポーンでは、ドロップに登録された小さなBluetoothビーコンによって、衛星測位にまったく頼らずにアプリが来訪を証明できます。二つ目の取り組みは、アテステーションの強制です。現在、アテステーションのないリクエストは記録されますがまだ受け付けています。スイッチを切り替えてそれらを即座に拒否する前に、正当な端末での誤拒否率を測定できるようにするためです。どちらも、すでに使われているキャッチと支払いのパターンに、小さく、地味で、検証可能な追加として加わります。

まだうまく機能しないこと。ショッピングモールでは屋内GPSが10〜15メートルずれ、サーバー側でどれだけ工夫してもそれは直りません。本当の答えはビーコンで、だからこそロードマップに入っています。1秒未満のレイテンシーは実現しておらず、おそらく今後も実現しません。不正検知ゲートは単一のリクエストではなく履歴を読むからです。ウェアラブルはスマホよりセンサー構成が小さいため、スマホ向けに調整された位置証明の設計は、グラスにそのままうまく移せません。そして、トラック1台分の無線機器を持つ国家なら、現在のどんなスマホの検証も破れます。そうではないと主張するプロトコルは、あなたに正直ではありません。私たちはそんな主張はしません。

声に出して言う価値のある設計原則。検証者は、自分が何を証明でき、何を証明できないかについて正直であるべきです。確率的なスコアを絶対的なイエスかノーのように見せるのは、厳格なルールから導いた絶対的なイエスかノーを示すより悪いことです。スコアはスライダーを生み、エンゲージメントの目標に届いていないときには、どんなスライダーもより多くの主張を受け入れる方向に押されるからです。私たちのキャッチのレイヤーにはスライダーがありません。チェックを通るか、通らないかです。不正検知のレイヤーにはスライダーがあり、そのスライダーを握っているのはコードではなく人です。

これが、アンカー型アセットや位置で検証されたエアドロップを成り立たせている、Seekの土台となる仕組みです。パブリッシャーが本物のお金の価値があるトークンを座標に置くのは、最終的にそれを手にする人が、アテステーション済みの端末でその座標にいたからであり、お金が動く前に支払いゲートがアカウントの履歴をさかのぼって読むからです。完全な仕様はホワイトペーパーにあります。この記事は、アプリの中で起きていることを平易な言葉で説明したものです。

まとめ。存在は座標ではありません。ひとつのシグナルだけでは存在を証明できません。Seekは存在を二つのレイヤーで検証します。キャッチの瞬間にはアテステーション、距離、モーショントレースで、支払いの瞬間には90日間の不正検知ゲートで。まだ残っているひとつ、屋内ドロップ向けのビーコンによる代替手段は、GPSだけでは対応できない最後の座標のケースを埋めます。これが今のSeekにおける位置証明の実際の姿であり、このレイヤーが、それによって可能になるどんな派手な機能よりも重要である理由です。